OSDN Git Service

Do not rewrite out of SSA scalar dependences crossing the limits of the scop.
[pf3gnuchains/gcc-fork.git] / gcc / genautomata.c
1 /* Pipeline hazard description translator.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4
5    Written by Vladimir Makarov <vmakarov@redhat.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3, or (at your option) any
12 later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* References:
24
25    1. The finite state automaton based pipeline hazard recognizer and
26       instruction scheduler in GCC.  V. Makarov.  Proceedings of GCC
27       summit, 2003.
28
29    2. Detecting pipeline structural hazards quickly. T. Proebsting,
30       C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
31       Principles of Programming Languages, pages 280--286, 1994.
32
33       This article is a good start point to understand usage of finite
34       state automata for pipeline hazard recognizers.  But I'd
35       recommend the 1st and 3rd article for more deep understanding.
36
37    3. Efficient Instruction Scheduling Using Finite State Automata:
38       V. Bala and N. Rubin, Proceedings of MICRO-28.  This is the best
39       article about usage of finite state automata for pipeline hazard
40       recognizers.
41
42    The current implementation is described in the 1st article and it
43    is different from the 3rd article in the following:
44
45    1. New operator `|' (alternative) is permitted in functional unit
46       reservation which can be treated deterministically and
47       non-deterministically.
48
49    2. Possibility of usage of nondeterministic automata too.
50
51    3. Possibility to query functional unit reservations for given
52       automaton state.
53
54    4. Several constructions to describe impossible reservations
55       (`exclusion_set', `presence_set', `final_presence_set',
56       `absence_set', and `final_absence_set').
57
58    5. No reverse automata are generated.  Trace instruction scheduling
59       requires this.  It can be easily added in the future if we
60       really need this.
61
62    6. Union of automaton states are not generated yet.  It is planned
63       to be implemented.  Such feature is needed to make more accurate
64       interlock insn scheduling to get state describing functional
65       unit reservation in a joint CFG point.  */
66
67 /* This file code processes constructions of machine description file
68    which describes automaton used for recognition of processor pipeline
69    hazards by insn scheduler and can be used for other tasks (such as
70    VLIW insn packing.
71
72    The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
73    `gen_bypass', `gen_excl_set', `gen_presence_set',
74    `gen_final_presence_set', `gen_absence_set',
75    `gen_final_absence_set', `gen_automaton', `gen_automata_option',
76    `gen_reserv', `gen_insn_reserv' are called from file
77    `genattrtab.c'.  They transform RTL constructions describing
78    automata in .md file into internal representation convenient for
79    further processing.
80
81    The translator major function `expand_automata' processes the
82    description internal representation into finite state automaton.
83    It can be divided on:
84
85      o checking correctness of the automaton pipeline description
86        (major function is `check_all_description').
87
88      o generating automaton (automata) from the description (major
89        function is `make_automaton').
90
91      o optional transformation of nondeterministic finite state
92        automata into deterministic ones if the alternative operator
93        `|' is treated nondeterministically in the description (major
94        function is NDFA_to_DFA).
95
96      o optional minimization of the finite state automata by merging
97        equivalent automaton states (major function is `minimize_DFA').
98
99      o forming tables (some as comb vectors) and attributes
100        representing the automata (functions output_..._table).
101
102    Function `write_automata' outputs the created finite state
103    automaton as different tables and functions which works with the
104    automata to inquire automaton state and to change its state.  These
105    function are used by gcc instruction scheduler and may be some
106    other gcc code.  */
107
108 #include "bconfig.h"
109 #include "system.h"
110 #include "coretypes.h"
111 #include "tm.h"
112 #include "rtl.h"
113 #include "obstack.h"
114 #include "errors.h"
115 #include "gensupport.h"
116
117 #include <math.h>
118 #include "hashtab.h"
119 #include "vec.h"
120
121 #ifndef CHAR_BIT
122 #define CHAR_BIT 8
123 #endif
124
125 /* Positions in machine description file.  Now they are not used.  But
126    they could be used in the future for better diagnostic messages.  */
127 typedef int pos_t;
128
129 /* The following is element of vector of current (and planned in the
130    future) functional unit reservations.  */
131 typedef unsigned HOST_WIDE_INT set_el_t;
132
133 /* Reservations of function units are represented by value of the following
134    type.  */
135 typedef set_el_t *reserv_sets_t;
136 typedef const set_el_t *const_reserv_sets_t;
137
138 /* The following structure describes a ticker.  */
139 struct ticker
140 {
141   /* The following member value is time of the ticker creation with
142      taking into account time when the ticker is off.  Active time of
143      the ticker is current time minus the value.  */
144   int modified_creation_time;
145   /* The following member value is time (incremented by one) when the
146      ticker was off.  Zero value means that now the ticker is on.  */
147   int incremented_off_time;
148 };
149
150 /* The ticker is represented by the following type.  */
151 typedef struct ticker ticker_t;
152
153 /* The following type describes elements of output vectors.  */
154 typedef HOST_WIDE_INT vect_el_t;
155
156 /* Forward declaration of structures of internal representation of
157    pipeline description based on NDFA.  */
158
159 struct unit_decl;
160 struct bypass_decl;
161 struct result_decl;
162 struct automaton_decl;
163 struct unit_pattern_rel_decl;
164 struct reserv_decl;
165 struct insn_reserv_decl;
166 struct decl;
167 struct unit_regexp;
168 struct result_regexp;
169 struct reserv_regexp;
170 struct nothing_regexp;
171 struct sequence_regexp;
172 struct repeat_regexp;
173 struct allof_regexp;
174 struct oneof_regexp;
175 struct regexp;
176 struct description;
177 struct unit_set_el;
178 struct pattern_set_el;
179 struct pattern_reserv;
180 struct state;
181 struct alt_state;
182 struct arc;
183 struct ainsn;
184 struct automaton;
185 struct state_ainsn_table;
186
187 /* The following typedefs are for brevity.  */
188 typedef struct unit_decl *unit_decl_t;
189 typedef const struct unit_decl *const_unit_decl_t;
190 typedef struct decl *decl_t;
191 typedef const struct decl *const_decl_t;
192 typedef struct regexp *regexp_t;
193 typedef struct unit_set_el *unit_set_el_t;
194 typedef struct pattern_set_el *pattern_set_el_t;
195 typedef struct pattern_reserv *pattern_reserv_t;
196 typedef struct alt_state *alt_state_t;
197 typedef struct state *state_t;
198 typedef const struct state *const_state_t;
199 typedef struct arc *arc_t;
200 typedef struct ainsn *ainsn_t;
201 typedef struct automaton *automaton_t;
202 typedef struct automata_list_el *automata_list_el_t;
203 typedef const struct automata_list_el *const_automata_list_el_t;
204 typedef struct state_ainsn_table *state_ainsn_table_t;
205
206 /* Undefined position.  */
207 static pos_t no_pos = 0;
208
209 /* All IR is stored in the following obstack.  */
210 static struct obstack irp;
211
212 \f
213 /* Declare vector types for various data structures: */
214
215 DEF_VEC_P(alt_state_t);
216 DEF_VEC_ALLOC_P(alt_state_t, heap);
217 DEF_VEC_P(ainsn_t);
218 DEF_VEC_ALLOC_P(ainsn_t, heap);
219 DEF_VEC_P(state_t);
220 DEF_VEC_ALLOC_P(state_t, heap);
221 DEF_VEC_P(decl_t);
222 DEF_VEC_ALLOC_P(decl_t, heap);
223 DEF_VEC_P(reserv_sets_t);
224 DEF_VEC_ALLOC_P(reserv_sets_t, heap);
225
226 DEF_VEC_I(vect_el_t);
227 DEF_VEC_ALLOC_I(vect_el_t, heap);
228 typedef VEC(vect_el_t, heap) *vla_hwint_t;
229 \f
230 /* Forward declarations of functions used before their definitions, only.  */
231 static regexp_t gen_regexp_sequence    (const char *);
232 static void reserv_sets_or             (reserv_sets_t, reserv_sets_t,
233                                         reserv_sets_t);
234 static reserv_sets_t get_excl_set      (reserv_sets_t);
235 static int check_presence_pattern_sets (reserv_sets_t,
236                                         reserv_sets_t, int);
237 static int check_absence_pattern_sets  (reserv_sets_t, reserv_sets_t,
238                                         int);
239 static arc_t first_out_arc             (const_state_t);
240 static arc_t next_out_arc              (arc_t);
241
242 \f
243
244 /* Options with the following names can be set up in automata_option
245    construction.  Because the strings occur more one time we use the
246    macros.  */
247
248 #define NO_MINIMIZATION_OPTION "-no-minimization"
249 #define TIME_OPTION "-time"
250 #define STATS_OPTION "-stats"
251 #define V_OPTION "-v"
252 #define W_OPTION "-w"
253 #define NDFA_OPTION "-ndfa"
254 #define PROGRESS_OPTION "-progress"
255
256 /* The following flags are set up by function `initiate_automaton_gen'.  */
257
258 /* Make automata with nondeterministic reservation by insns (`-ndfa').  */
259 static int ndfa_flag;
260
261 /* Do not make minimization of DFA (`-no-minimization').  */
262 static int no_minimization_flag;
263
264 /* Value of this variable is number of automata being generated.  The
265    actual number of automata may be less this value if there is not
266    sufficient number of units.  This value is defined by argument of
267    option `-split' or by constructions automaton if the value is zero
268    (it is default value of the argument).  */
269 static int split_argument;
270
271 /* Flag of output time statistics (`-time').  */
272 static int time_flag;
273
274 /* Flag of automata statistics (`-stats').  */
275 static int stats_flag;
276
277 /* Flag of creation of description file which contains description of
278    result automaton and statistics information (`-v').  */
279 static int v_flag;
280
281 /* Flag of output of a progress bar showing how many states were
282    generated so far for automaton being processed (`-progress').  */
283 static int progress_flag;
284
285 /* Flag of generating warning instead of error for non-critical errors
286    (`-w').  */
287 static int w_flag;
288
289
290 /* Output file for pipeline hazard recognizer (PHR) being generated.
291    The value is NULL if the file is not defined.  */
292 static FILE *output_file;
293
294 /* Description file of PHR.  The value is NULL if the file is not
295    created.  */
296 static FILE *output_description_file;
297
298 /* PHR description file name.  */
299 static char *output_description_file_name;
300
301 /* Value of the following variable is node representing description
302    being processed.  This is start point of IR.  */
303 static struct description *description;
304
305 \f
306
307 /* This page contains description of IR structure (nodes).  */
308
309 enum decl_mode
310 {
311   dm_unit,
312   dm_bypass,
313   dm_automaton,
314   dm_excl,
315   dm_presence,
316   dm_absence,
317   dm_reserv,
318   dm_insn_reserv
319 };
320
321 /* This describes define_cpu_unit and define_query_cpu_unit (see file
322    rtl.def).  */
323 struct unit_decl
324 {
325   const char *name;
326   /* NULL if the automaton name is absent.  */
327   const char *automaton_name;
328   /* If the following value is not zero, the cpu unit reservation is
329      described in define_query_cpu_unit.  */
330   char query_p;
331
332   /* The following fields are defined by checker.  */
333
334   /* The following field value is nonzero if the unit is used in an
335      regexp.  */
336   char unit_is_used;
337
338   /* The following field value is order number (0, 1, ...) of given
339      unit.  */
340   int unit_num;
341   /* The following field value is corresponding declaration of
342      automaton which was given in description.  If the field value is
343      NULL then automaton in the unit declaration was absent.  */
344   struct automaton_decl *automaton_decl;
345   /* The following field value is maximal cycle number (1, ...) on
346      which given unit occurs in insns.  Zero value means that given
347      unit is not used in insns.  */
348   int max_occ_cycle_num;
349   /* The following field value is minimal cycle number (0, ...) on
350      which given unit occurs in insns.  -1 value means that given
351      unit is not used in insns.  */
352   int min_occ_cycle_num;
353   /* The following list contains units which conflict with given
354      unit.  */
355   unit_set_el_t excl_list;
356   /* The following list contains patterns which are required to
357      reservation of given unit.  */
358   pattern_set_el_t presence_list;
359   pattern_set_el_t final_presence_list;
360   /* The following list contains patterns which should be not present
361      in reservation for given unit.  */
362   pattern_set_el_t absence_list;
363   pattern_set_el_t final_absence_list;
364   /* The following is used only when `query_p' has nonzero value.
365      This is query number for the unit.  */
366   int query_num;
367   /* The following is the last cycle on which the unit was checked for
368      correct distributions of units to automata in a regexp.  */
369   int last_distribution_check_cycle;
370
371   /* The following fields are defined by automaton generator.  */
372
373   /* The following field value is number of the automaton to which
374      given unit belongs.  */
375   int corresponding_automaton_num;
376   /* If the following value is not zero, the cpu unit is present in a
377      `exclusion_set' or in right part of a `presence_set',
378      `final_presence_set', `absence_set', and
379      `final_absence_set'define_query_cpu_unit.  */
380   char in_set_p;
381 };
382
383 /* This describes define_bypass (see file rtl.def).  */
384 struct bypass_decl
385 {
386   int latency;
387   const char *out_insn_name;
388   const char *in_insn_name;
389   const char *bypass_guard_name;
390
391   /* The following fields are defined by checker.  */
392
393   /* output and input insns of given bypass.  */
394   struct insn_reserv_decl *out_insn_reserv;
395   struct insn_reserv_decl *in_insn_reserv;
396   /* The next bypass for given output insn.  */
397   struct bypass_decl *next;
398 };
399
400 /* This describes define_automaton (see file rtl.def).  */
401 struct automaton_decl
402 {
403   const char *name;
404
405   /* The following fields are defined by automaton generator.  */
406
407   /* The following field value is nonzero if the automaton is used in
408      an regexp definition.  */
409   char automaton_is_used;
410
411   /* The following fields are defined by checker.  */
412
413   /* The following field value is the corresponding automaton.  This
414      field is not NULL only if the automaton is present in unit
415      declarations and the automatic partition on automata is not
416      used.  */
417   automaton_t corresponding_automaton;
418 };
419
420 /* This describes exclusion relations: exclusion_set (see file
421    rtl.def).  */
422 struct excl_rel_decl
423 {
424   int all_names_num;
425   int first_list_length;
426   char *names [1];
427 };
428
429 /* This describes unit relations: [final_]presence_set or
430    [final_]absence_set (see file rtl.def).  */
431 struct unit_pattern_rel_decl
432 {
433   int final_p;
434   int names_num;
435   int patterns_num;
436   char **names;
437   char ***patterns;
438 };
439
440 /* This describes define_reservation (see file rtl.def).  */
441 struct reserv_decl
442 {
443   const char *name;
444   regexp_t regexp;
445
446   /* The following fields are defined by checker.  */
447
448   /* The following field value is nonzero if the unit is used in an
449      regexp.  */
450   char reserv_is_used;
451   /* The following field is used to check up cycle in expression
452      definition.  */
453   int loop_pass_num;
454 };
455
456 /* This describes define_insn_reservation (see file rtl.def).  */
457 struct insn_reserv_decl
458 {
459   rtx condexp;
460   int default_latency;
461   regexp_t regexp;
462   const char *name;
463
464   /* The following fields are defined by checker.  */
465
466   /* The following field value is order number (0, 1, ...) of given
467      insn.  */
468   int insn_num;
469   /* The following field value is list of bypasses in which given insn
470      is output insn.  Bypasses with the same input insn stay one after
471      another in the list in the same order as their occurrences in the
472      description but the bypass without a guard stays always the last
473      in a row of bypasses with the same input insn.  */
474   struct bypass_decl *bypass_list;
475
476   /* The following fields are defined by automaton generator.  */
477
478   /* The following field is the insn regexp transformed that
479      the regexp has not optional regexp, repetition regexp, and an
480      reservation name (i.e. reservation identifiers are changed by the
481      corresponding regexp) and all alternations are the top level
482      of the regexp.  The value can be NULL only if it is special
483      insn `cycle advancing'.  */
484   regexp_t transformed_regexp;
485   /* The following field value is list of arcs marked given
486      insn.  The field is used in transformation NDFA -> DFA.  */
487   arc_t arcs_marked_by_insn;
488   /* The two following fields are used during minimization of a finite state
489      automaton.  */
490   /* The field value is number of equivalence class of state into
491      which arc marked by given insn enters from a state (fixed during
492      an automaton minimization).  */
493   int equiv_class_num;
494   /* The following member value is the list to automata which can be
495      changed by the insn issue.  */
496   automata_list_el_t important_automata_list;
497   /* The following member is used to process insn once for output.  */
498   int processed_p;
499 };
500
501 /* This contains a declaration mentioned above.  */
502 struct decl
503 {
504   /* What node in the union? */
505   enum decl_mode mode;
506   pos_t pos;
507   union
508   {
509     struct unit_decl unit;
510     struct bypass_decl bypass;
511     struct automaton_decl automaton;
512     struct excl_rel_decl excl;
513     struct unit_pattern_rel_decl presence;
514     struct unit_pattern_rel_decl absence;
515     struct reserv_decl reserv;
516     struct insn_reserv_decl insn_reserv;
517   } decl;
518 };
519
520 /* The following structures represent parsed reservation strings.  */
521 enum regexp_mode
522 {
523   rm_unit,
524   rm_reserv,
525   rm_nothing,
526   rm_sequence,
527   rm_repeat,
528   rm_allof,
529   rm_oneof
530 };
531
532 /* Cpu unit in reservation.  */
533 struct unit_regexp
534 {
535   const char *name;
536   unit_decl_t unit_decl;
537 };
538
539 /* Define_reservation in a reservation.  */
540 struct reserv_regexp
541 {
542   const char *name;
543   struct reserv_decl *reserv_decl;
544 };
545
546 /* Absence of reservation (represented by string `nothing').  */
547 struct nothing_regexp
548 {
549   /* This used to be empty but ISO C doesn't allow that.  */
550   char unused;
551 };
552
553 /* Representation of reservations separated by ',' (see file
554    rtl.def).  */
555 struct sequence_regexp
556 {
557   int regexps_num;
558   regexp_t regexps [1];
559 };
560
561 /* Representation of construction `repeat' (see file rtl.def).  */
562 struct repeat_regexp
563 {
564   int repeat_num;
565   regexp_t regexp;
566 };
567
568 /* Representation of reservations separated by '+' (see file
569    rtl.def).  */
570 struct allof_regexp
571 {
572   int regexps_num;
573   regexp_t regexps [1];
574 };
575
576 /* Representation of reservations separated by '|' (see file
577    rtl.def).  */
578 struct oneof_regexp
579 {
580   int regexps_num;
581   regexp_t regexps [1];
582 };
583
584 /* Representation of a reservation string.  */
585 struct regexp
586 {
587   /* What node in the union? */
588   enum regexp_mode mode;
589   pos_t pos;
590   union
591   {
592     struct unit_regexp unit;
593     struct reserv_regexp reserv;
594     struct nothing_regexp nothing;
595     struct sequence_regexp sequence;
596     struct repeat_regexp repeat;
597     struct allof_regexp allof;
598     struct oneof_regexp oneof;
599   } regexp;
600 };
601
602 /* Represents description of pipeline hazard description based on
603    NDFA.  */
604 struct description
605 {
606   int decls_num;
607
608   /* The following fields are defined by checker.  */
609
610   /* The following fields values are correspondingly number of all
611      units, query units, and insns in the description.  */
612   int units_num;
613   int query_units_num;
614   int insns_num;
615   /* The following field value is max length (in cycles) of
616      reservations of insns.  The field value is defined only for
617      correct programs.  */
618   int max_insn_reserv_cycles;
619
620   /* The following fields are defined by automaton generator.  */
621
622   /* The following field value is the first automaton.  */
623   automaton_t first_automaton;
624
625   /* The following field is created by pipeline hazard parser and
626      contains all declarations.  We allocate additional entry for
627      special insn "cycle advancing" which is added by the automaton
628      generator.  */
629   decl_t decls [1];
630 };
631
632
633 /* The following nodes are created in automaton checker.  */
634
635 /* The following nodes represent exclusion set for cpu units.  Each
636    element is accessed through only one excl_list.  */
637 struct unit_set_el
638 {
639   unit_decl_t unit_decl;
640   unit_set_el_t next_unit_set_el;
641 };
642
643 /* The following nodes represent presence or absence pattern for cpu
644    units.  Each element is accessed through only one presence_list or
645    absence_list.  */
646 struct pattern_set_el
647 {
648   /* The number of units in unit_decls.  */
649   int units_num;
650   /* The units forming the pattern.  */
651   struct unit_decl **unit_decls;
652   pattern_set_el_t next_pattern_set_el;
653 };
654
655
656 /* The following nodes are created in automaton generator.  */
657
658
659 /* The following nodes represent presence or absence pattern for cpu
660    units.  Each element is accessed through only one element of
661    unit_presence_set_table or unit_absence_set_table.  */
662 struct pattern_reserv
663 {
664   reserv_sets_t reserv;
665   pattern_reserv_t next_pattern_reserv;
666 };
667
668 /* The following node type describes state automaton.  The state may
669    be deterministic or non-deterministic.  Non-deterministic state has
670    several component states which represent alternative cpu units
671    reservations.  The state also is used for describing a
672    deterministic reservation of automaton insn.  */
673 struct state
674 {
675   /* The following member value is nonzero if there is a transition by
676      cycle advancing.  */
677   int new_cycle_p;
678   /* The following field is list of processor unit reservations on
679      each cycle.  */
680   reserv_sets_t reservs;
681   /* The following field is unique number of given state between other
682      states.  */
683   int unique_num;
684   /* The following field value is automaton to which given state
685      belongs.  */
686   automaton_t automaton;
687   /* The following field value is the first arc output from given
688      state.  */
689   arc_t first_out_arc;
690   unsigned int num_out_arcs;
691   /* The following field is used to form NDFA.  */
692   char it_was_placed_in_stack_for_NDFA_forming;
693   /* The following field is used to form DFA.  */
694   char it_was_placed_in_stack_for_DFA_forming;
695   /* The following field is used to transform NDFA to DFA and DFA
696      minimization.  The field value is not NULL if the state is a
697      compound state.  In this case the value of field `unit_sets_list'
698      is NULL.  All states in the list are in the hash table.  The list
699      is formed through field `next_sorted_alt_state'.  We should
700      support only one level of nesting state.  */
701   alt_state_t component_states;
702   /* The following field is used for passing graph of states.  */
703   int pass_num;
704   /* The list of states belonging to one equivalence class is formed
705      with the aid of the following field.  */
706   state_t next_equiv_class_state;
707   /* The two following fields are used during minimization of a finite
708      state automaton.  */
709   int equiv_class_num_1, equiv_class_num_2;
710   /* The following field is used during minimization of a finite state
711      automaton.  The field value is state corresponding to equivalence
712      class to which given state belongs.  */
713   state_t equiv_class_state;
714   unsigned int *presence_signature;
715   /* The following field value is the order number of given state.
716      The states in final DFA is enumerated with the aid of the
717      following field.  */
718   int order_state_num;
719   /* This member is used for passing states for searching minimal
720      delay time.  */
721   int state_pass_num;
722   /* The following member is used to evaluate min issue delay of insn
723      for a state.  */
724   int min_insn_issue_delay;
725 };
726
727 /* Automaton arc.  */
728 struct arc
729 {
730   /* The following field refers for the state into which given arc
731      enters.  */
732   state_t to_state;
733   /* The following field describes that the insn issue (with cycle
734      advancing for special insn `cycle advancing' and without cycle
735      advancing for others) makes transition from given state to
736      another given state.  */
737   ainsn_t insn;
738   /* The following field value is the next arc output from the same
739      state.  */
740   arc_t next_out_arc;
741   /* List of arcs marked given insn is formed with the following
742      field.  The field is used in transformation NDFA -> DFA.  */
743   arc_t next_arc_marked_by_insn;
744 };
745
746 /* The following node type describes a deterministic alternative in
747    non-deterministic state which characterizes cpu unit reservations
748    of automaton insn or which is part of NDFA.  */
749 struct alt_state
750 {
751   /* The following field is a deterministic state which characterizes
752      unit reservations of the instruction.  */
753   state_t state;
754   /* The following field refers to the next state which characterizes
755      unit reservations of the instruction.  */
756   alt_state_t next_alt_state;
757   /* The following field refers to the next state in sorted list.  */
758   alt_state_t next_sorted_alt_state;
759 };
760
761 /* The following node type describes insn of automaton.  They are
762    labels of FA arcs.  */
763 struct ainsn
764 {
765   /* The following field value is the corresponding insn declaration
766      of description.  */
767   struct insn_reserv_decl *insn_reserv_decl;
768   /* The following field value is the next insn declaration for an
769      automaton.  */
770   ainsn_t next_ainsn;
771   /* The following field is states which characterize automaton unit
772      reservations of the instruction.  The value can be NULL only if it
773      is special insn `cycle advancing'.  */
774   alt_state_t alt_states;
775   /* The following field is sorted list of states which characterize
776      automaton unit reservations of the instruction.  The value can be
777      NULL only if it is special insn `cycle advancing'.  */
778   alt_state_t sorted_alt_states;
779   /* The following field refers the next automaton insn with
780      the same reservations.  */
781   ainsn_t next_same_reservs_insn;
782   /* The following field is flag of the first automaton insn with the
783      same reservations in the declaration list.  Only arcs marked such
784      insn is present in the automaton.  This significantly decreases
785      memory requirements especially when several automata are
786      formed.  */
787   char first_insn_with_same_reservs;
788   /* The following member has nonzero value if there is arc from state of
789      the automaton marked by the ainsn.  */
790   char arc_exists_p;
791   /* Cyclic list of insns of an equivalence class is formed with the
792      aid of the following field.  */
793   ainsn_t next_equiv_class_insn;
794   /* The following field value is nonzero if the insn declaration is
795      the first insn declaration with given equivalence number.  */
796   char first_ainsn_with_given_equivalence_num;
797   /* The following field is number of class of equivalence of insns.
798      It is necessary because many insns may be equivalent with the
799      point of view of pipeline hazards.  */
800   int insn_equiv_class_num;
801   /* The following member value is TRUE if there is an arc in the
802      automaton marked by the insn into another state.  In other
803      words, the insn can change the state of the automaton.  */
804   int important_p;
805 };
806
807 /* The following describes an automaton for PHR.  */
808 struct automaton
809 {
810   /* The following field value is the list of insn declarations for
811      given automaton.  */
812   ainsn_t ainsn_list;
813   /* The following field value is the corresponding automaton
814      declaration.  This field is not NULL only if the automatic
815      partition on automata is not used.  */
816   struct automaton_decl *corresponding_automaton_decl;
817   /* The following field value is the next automaton.  */
818   automaton_t next_automaton;
819   /* The following field is start state of FA.  There are not unit
820      reservations in the state.  */
821   state_t start_state;
822   /* The following field value is number of equivalence classes of
823      insns (see field `insn_equiv_class_num' in
824      `insn_reserv_decl').  */
825   int insn_equiv_classes_num;
826   /* The following field value is number of states of final DFA.  */
827   int achieved_states_num;
828   /* The following field value is the order number (0, 1, ...) of
829      given automaton.  */
830   int automaton_order_num;
831   /* The following fields contain statistics information about
832      building automaton.  */
833   int NDFA_states_num, DFA_states_num;
834   /* The following field value is defined only if minimization of DFA
835      is used.  */
836   int minimal_DFA_states_num;
837   int NDFA_arcs_num, DFA_arcs_num;
838   /* The following field value is defined only if minimization of DFA
839      is used.  */
840   int minimal_DFA_arcs_num;
841   /* The following member refers for two table state x ainsn -> int.
842      ??? Above sentence is incomprehensible.  */
843   state_ainsn_table_t trans_table;
844   /* The following member value is maximal value of min issue delay
845      for insns of the automaton.  */
846   int max_min_delay;
847   /* Usually min issue delay is small and we can place several (2, 4,
848      8) elements in one vector element.  So the compression factor can
849      be 1 (no compression), 2, 4, 8.  */
850   int min_issue_delay_table_compression_factor;
851   /* Total number of locked states in this automaton.  */
852   int locked_states;
853 };
854
855 /* The following is the element of the list of automata.  */
856 struct automata_list_el
857 {
858   /* The automaton itself.  */
859   automaton_t automaton;
860   /* The next automata set element.  */
861   automata_list_el_t next_automata_list_el;
862 };
863
864 /* The following structure describes a table state X ainsn -> int(>= 0).  */
865 struct state_ainsn_table
866 {
867   /* Automaton to which given table belongs.  */
868   automaton_t automaton;
869   /* The following tree vectors for comb vector implementation of the
870      table.  */
871   vla_hwint_t comb_vect;
872   vla_hwint_t check_vect;
873   vla_hwint_t base_vect;
874   /* This is simple implementation of the table.  */
875   vla_hwint_t full_vect;
876   /* Minimal and maximal values of the previous vectors.  */
877   int min_comb_vect_el_value, max_comb_vect_el_value;
878   int min_base_vect_el_value, max_base_vect_el_value;
879 };
880
881 /* Macros to access members of unions.  Use only them for access to
882    union members of declarations and regexps.  */
883
884 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
885
886 #define DECL_UNIT(d) __extension__                                      \
887 (({ __typeof (d) const _decl = (d);                                     \
888      if (_decl->mode != dm_unit)                                        \
889        decl_mode_check_failed (_decl->mode, "dm_unit",                  \
890                                __FILE__, __LINE__, __FUNCTION__);       \
891      &(_decl)->decl.unit; }))
892
893 #define DECL_BYPASS(d) __extension__                                    \
894 (({ __typeof (d) const _decl = (d);                                     \
895      if (_decl->mode != dm_bypass)                                      \
896        decl_mode_check_failed (_decl->mode, "dm_bypass",                \
897                                __FILE__, __LINE__, __FUNCTION__);       \
898      &(_decl)->decl.bypass; }))
899
900 #define DECL_AUTOMATON(d) __extension__                                 \
901 (({ __typeof (d) const _decl = (d);                                     \
902      if (_decl->mode != dm_automaton)                                   \
903        decl_mode_check_failed (_decl->mode, "dm_automaton",             \
904                                __FILE__, __LINE__, __FUNCTION__);       \
905      &(_decl)->decl.automaton; }))
906
907 #define DECL_EXCL(d) __extension__                                      \
908 (({ __typeof (d) const _decl = (d);                                     \
909      if (_decl->mode != dm_excl)                                        \
910        decl_mode_check_failed (_decl->mode, "dm_excl",                  \
911                                __FILE__, __LINE__, __FUNCTION__);       \
912      &(_decl)->decl.excl; }))
913
914 #define DECL_PRESENCE(d) __extension__                                  \
915 (({ __typeof (d) const _decl = (d);                                     \
916      if (_decl->mode != dm_presence)                                    \
917        decl_mode_check_failed (_decl->mode, "dm_presence",              \
918                                __FILE__, __LINE__, __FUNCTION__);       \
919      &(_decl)->decl.presence; }))
920
921 #define DECL_ABSENCE(d) __extension__                                   \
922 (({ __typeof (d) const _decl = (d);                                     \
923      if (_decl->mode != dm_absence)                                     \
924        decl_mode_check_failed (_decl->mode, "dm_absence",               \
925                                __FILE__, __LINE__, __FUNCTION__);       \
926      &(_decl)->decl.absence; }))
927
928 #define DECL_RESERV(d) __extension__                                    \
929 (({ __typeof (d) const _decl = (d);                                     \
930      if (_decl->mode != dm_reserv)                                      \
931        decl_mode_check_failed (_decl->mode, "dm_reserv",                \
932                                __FILE__, __LINE__, __FUNCTION__);       \
933      &(_decl)->decl.reserv; }))
934
935 #define DECL_INSN_RESERV(d) __extension__                               \
936 (({ __typeof (d) const _decl = (d);                                     \
937      if (_decl->mode != dm_insn_reserv)                                 \
938        decl_mode_check_failed (_decl->mode, "dm_insn_reserv",           \
939                                __FILE__, __LINE__, __FUNCTION__);       \
940      &(_decl)->decl.insn_reserv; }))
941
942 static const char *decl_name (enum decl_mode);
943 static void decl_mode_check_failed (enum decl_mode, const char *,
944                                     const char *, int, const char *)
945      ATTRIBUTE_NORETURN;
946
947 /* Return string representation of declaration mode MODE.  */
948 static const char *
949 decl_name (enum decl_mode mode)
950 {
951   static char str [100];
952
953   if (mode == dm_unit)
954     return "dm_unit";
955   else if (mode == dm_bypass)
956     return "dm_bypass";
957   else if (mode == dm_automaton)
958     return "dm_automaton";
959   else if (mode == dm_excl)
960     return "dm_excl";
961   else if (mode == dm_presence)
962     return "dm_presence";
963   else if (mode == dm_absence)
964     return "dm_absence";
965   else if (mode == dm_reserv)
966     return "dm_reserv";
967   else if (mode == dm_insn_reserv)
968     return "dm_insn_reserv";
969   else
970     sprintf (str, "unknown (%d)", (int) mode);
971   return str;
972 }
973
974 /* The function prints message about unexpected declaration and finish
975    the program.  */
976 static void
977 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
978                         const char *file, int line, const char *func)
979 {
980   fprintf
981     (stderr,
982      "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
983      file, line, func, expected_mode_str, decl_name (mode));
984   exit (1);
985 }
986
987
988 #define REGEXP_UNIT(r) __extension__                                    \
989 (({ struct regexp *const _regexp = (r);                                 \
990      if (_regexp->mode != rm_unit)                                      \
991        regexp_mode_check_failed (_regexp->mode, "rm_unit",              \
992                                __FILE__, __LINE__, __FUNCTION__);       \
993      &(_regexp)->regexp.unit; }))
994
995 #define REGEXP_RESERV(r) __extension__                                  \
996 (({ struct regexp *const _regexp = (r);                                 \
997      if (_regexp->mode != rm_reserv)                                    \
998        regexp_mode_check_failed (_regexp->mode, "rm_reserv",            \
999                                __FILE__, __LINE__, __FUNCTION__);       \
1000      &(_regexp)->regexp.reserv; }))
1001
1002 #define REGEXP_SEQUENCE(r) __extension__                                \
1003 (({ struct regexp *const _regexp = (r);                                 \
1004      if (_regexp->mode != rm_sequence)                                  \
1005        regexp_mode_check_failed (_regexp->mode, "rm_sequence",          \
1006                                __FILE__, __LINE__, __FUNCTION__);       \
1007      &(_regexp)->regexp.sequence; }))
1008
1009 #define REGEXP_REPEAT(r) __extension__                                  \
1010 (({ struct regexp *const _regexp = (r);                                 \
1011      if (_regexp->mode != rm_repeat)                                    \
1012        regexp_mode_check_failed (_regexp->mode, "rm_repeat",            \
1013                                __FILE__, __LINE__, __FUNCTION__);       \
1014      &(_regexp)->regexp.repeat; }))
1015
1016 #define REGEXP_ALLOF(r) __extension__                                   \
1017 (({ struct regexp *const _regexp = (r);                                 \
1018      if (_regexp->mode != rm_allof)                                     \
1019        regexp_mode_check_failed (_regexp->mode, "rm_allof",             \
1020                                __FILE__, __LINE__, __FUNCTION__);       \
1021      &(_regexp)->regexp.allof; }))
1022
1023 #define REGEXP_ONEOF(r) __extension__                                   \
1024 (({ struct regexp *const _regexp = (r);                                 \
1025      if (_regexp->mode != rm_oneof)                                     \
1026        regexp_mode_check_failed (_regexp->mode, "rm_oneof",             \
1027                                __FILE__, __LINE__, __FUNCTION__);       \
1028      &(_regexp)->regexp.oneof; }))
1029
1030 static const char *regexp_name (enum regexp_mode);
1031 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1032                                       const char *, int,
1033                                       const char *) ATTRIBUTE_NORETURN;
1034
1035
1036 /* Return string representation of regexp mode MODE.  */
1037 static const char *
1038 regexp_name (enum regexp_mode mode)
1039 {
1040   switch (mode)
1041     {
1042     case rm_unit:
1043       return "rm_unit";
1044     case rm_reserv:
1045       return "rm_reserv";
1046     case rm_nothing:
1047       return "rm_nothing";
1048     case rm_sequence:
1049       return "rm_sequence";
1050     case rm_repeat:
1051       return "rm_repeat";
1052     case rm_allof:
1053       return "rm_allof";
1054     case rm_oneof:
1055       return "rm_oneof";
1056     default:
1057       gcc_unreachable ();
1058     }
1059 }
1060
1061 /* The function prints message about unexpected regexp and finish the
1062    program.  */
1063 static void
1064 regexp_mode_check_failed (enum regexp_mode mode,
1065                           const char *expected_mode_str,
1066                           const char *file, int line, const char *func)
1067 {
1068   fprintf
1069     (stderr,
1070      "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1071      file, line, func, expected_mode_str, regexp_name (mode));
1072   exit (1);
1073 }
1074
1075 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1076
1077 #define DECL_UNIT(d) (&(d)->decl.unit)
1078 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1079 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1080 #define DECL_EXCL(d) (&(d)->decl.excl)
1081 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1082 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1083 #define DECL_RESERV(d) (&(d)->decl.reserv)
1084 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1085
1086 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1087 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1088 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1089 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1090 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1091 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1092
1093 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1094
1095 #define XCREATENODE(T) ((T *) create_node (sizeof (T)))
1096 #define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
1097 #define XCREATENODEVAR(T, S) ((T *) create_node ((S)))
1098
1099 #define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T)))
1100 #define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N)))
1101 #define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S)))
1102
1103 /* Create IR structure (node).  */
1104 static void *
1105 create_node (size_t size)
1106 {
1107   void *result;
1108
1109   obstack_blank (&irp, size);
1110   result = obstack_base (&irp);
1111   obstack_finish (&irp);
1112   /* Default values of members are NULL and zero.  */
1113   memset (result, 0, size);
1114   return result;
1115 }
1116
1117 /* Copy IR structure (node).  */
1118 static void *
1119 copy_node (const void *from, size_t size)
1120 {
1121   void *const result = create_node (size);
1122   memcpy (result, from, size);
1123   return result;
1124 }
1125
1126 /* The function checks that NAME does not contain quotes (`"').  */
1127 static const char *
1128 check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
1129 {
1130   const char *str;
1131
1132   for (str = name; *str != '\0'; str++)
1133     if (*str == '\"')
1134       error ("Name `%s' contains quotes", name);
1135   return name;
1136 }
1137
1138 /* Pointers to all declarations during IR generation are stored in the
1139    following.  */
1140 static VEC(decl_t, heap) *decls;
1141
1142 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1143    string containing the next separated element, taking parentheses
1144    into account if PAR_FLAG has nonzero value.  Advance the pointer to
1145    after the string scanned, or the end-of-string.  Return NULL if at
1146    end of string.  */
1147 static char *
1148 next_sep_el (const char **pstr, int sep, int par_flag)
1149 {
1150   char *out_str;
1151   const char *p;
1152   int pars_num;
1153   int n_spaces;
1154
1155   /* Remove leading whitespaces.  */
1156   while (ISSPACE ((int) **pstr))
1157     (*pstr)++;
1158
1159   if (**pstr == '\0')
1160     return NULL;
1161
1162   n_spaces = 0;
1163   for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1164     {
1165       if (par_flag && *p == '(')
1166         pars_num++;
1167       else if (par_flag && *p == ')')
1168         pars_num--;
1169       else if (pars_num == 0 && *p == sep)
1170         break;
1171       if (pars_num == 0 && ISSPACE ((int) *p))
1172         n_spaces++;
1173       else
1174         {
1175           for (; n_spaces != 0; n_spaces--)
1176             obstack_1grow (&irp, p [-n_spaces]);
1177           obstack_1grow (&irp, *p);
1178         }
1179     }
1180   obstack_1grow (&irp, '\0');
1181   out_str = obstack_base (&irp);
1182   obstack_finish (&irp);
1183
1184   *pstr = p;
1185   if (**pstr == sep)
1186     (*pstr)++;
1187
1188   return out_str;
1189 }
1190
1191 /* Given a string and a separator, return the number of separated
1192    elements in it, taking parentheses into account if PAR_FLAG has
1193    nonzero value.  Return 0 for the null string, -1 if parentheses is
1194    not balanced.  */
1195 static int
1196 n_sep_els (const char *s, int sep, int par_flag)
1197 {
1198   int n;
1199   int pars_num;
1200
1201   if (*s == '\0')
1202     return 0;
1203
1204   for (pars_num = 0, n = 1; *s; s++)
1205     if (par_flag && *s == '(')
1206       pars_num++;
1207     else if (par_flag && *s == ')')
1208       pars_num--;
1209     else if (pars_num == 0 && *s == sep)
1210       n++;
1211
1212   return (pars_num != 0 ? -1 : n);
1213 }
1214
1215 /* Given a string and a separator, return vector of strings which are
1216    elements in the string and number of elements through els_num.
1217    Take parentheses into account if PAREN_P has nonzero value.  The
1218    function also inserts the end marker NULL at the end of vector.
1219    Return 0 for the null string, -1 if parentheses are not balanced.  */
1220 static char **
1221 get_str_vect (const char *str, int *els_num, int sep, int paren_p)
1222 {
1223   int i;
1224   char **vect;
1225   const char **pstr;
1226   char *trail;
1227
1228   *els_num = n_sep_els (str, sep, paren_p);
1229   if (*els_num <= 0)
1230     return NULL;
1231   obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1232   vect = (char **) obstack_base (&irp);
1233   obstack_finish (&irp);
1234   pstr = &str;
1235   for (i = 0; i < *els_num; i++)
1236     vect [i] = next_sep_el (pstr, sep, paren_p);
1237   trail = next_sep_el (pstr, sep, paren_p);
1238   gcc_assert (!trail);
1239   vect [i] = NULL;
1240   return vect;
1241 }
1242
1243 /* Process a DEFINE_CPU_UNIT.
1244
1245    This gives information about a unit contained in CPU.  We fill a
1246    struct unit_decl with information used later by `expand_automata'.  */
1247 static void
1248 gen_cpu_unit (rtx def)
1249 {
1250   decl_t decl;
1251   char **str_cpu_units;
1252   int vect_length;
1253   int i;
1254
1255   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1256   if (str_cpu_units == NULL)
1257     fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1258   for (i = 0; i < vect_length; i++)
1259     {
1260       decl = XCREATENODE (struct decl);
1261       decl->mode = dm_unit;
1262       decl->pos = 0;
1263       DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1264       DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1265       DECL_UNIT (decl)->query_p = 0;
1266       DECL_UNIT (decl)->min_occ_cycle_num = -1;
1267       DECL_UNIT (decl)->in_set_p = 0;
1268       VEC_safe_push (decl_t, heap, decls, decl);
1269     }
1270 }
1271
1272 /* Process a DEFINE_QUERY_CPU_UNIT.
1273
1274    This gives information about a unit contained in CPU.  We fill a
1275    struct unit_decl with information used later by `expand_automata'.  */
1276 static void
1277 gen_query_cpu_unit (rtx def)
1278 {
1279   decl_t decl;
1280   char **str_cpu_units;
1281   int vect_length;
1282   int i;
1283
1284   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
1285                                 FALSE);
1286   if (str_cpu_units == NULL)
1287     fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1288   for (i = 0; i < vect_length; i++)
1289     {
1290       decl = XCREATENODE (struct decl);
1291       decl->mode = dm_unit;
1292       decl->pos = 0;
1293       DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1294       DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1295       DECL_UNIT (decl)->query_p = 1;
1296       VEC_safe_push (decl_t, heap, decls, decl);
1297     }
1298 }
1299
1300 /* Process a DEFINE_BYPASS.
1301
1302    This gives information about a unit contained in the CPU.  We fill
1303    in a struct bypass_decl with information used later by
1304    `expand_automata'.  */
1305 static void
1306 gen_bypass (rtx def)
1307 {
1308   decl_t decl;
1309   char **out_insns;
1310   int out_length;
1311   char **in_insns;
1312   int in_length;
1313   int i, j;
1314
1315   out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
1316   if (out_insns == NULL)
1317     fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1318   in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
1319   if (in_insns == NULL)
1320     fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1321   for (i = 0; i < out_length; i++)
1322     for (j = 0; j < in_length; j++)
1323       {
1324         decl = XCREATENODE (struct decl);
1325         decl->mode = dm_bypass;
1326         decl->pos = 0;
1327         DECL_BYPASS (decl)->latency = XINT (def, 0);
1328         DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1329         DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1330         DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
1331         VEC_safe_push (decl_t, heap, decls, decl);
1332       }
1333 }
1334
1335 /* Process an EXCLUSION_SET.
1336
1337    This gives information about a cpu unit conflicts.  We fill a
1338    struct excl_rel_decl (excl) with information used later by
1339    `expand_automata'.  */
1340 static void
1341 gen_excl_set (rtx def)
1342 {
1343   decl_t decl;
1344   char **first_str_cpu_units;
1345   char **second_str_cpu_units;
1346   int first_vect_length;
1347   int length;
1348   int i;
1349
1350   first_str_cpu_units
1351     = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
1352   if (first_str_cpu_units == NULL)
1353     fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1354   second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
1355                                        FALSE);
1356   if (second_str_cpu_units == NULL)
1357     fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1358   length += first_vect_length;
1359   decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
1360   decl->mode = dm_excl;
1361   decl->pos = 0;
1362   DECL_EXCL (decl)->all_names_num = length;
1363   DECL_EXCL (decl)->first_list_length = first_vect_length;
1364   for (i = 0; i < length; i++)
1365     if (i < first_vect_length)
1366       DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1367     else
1368       DECL_EXCL (decl)->names [i]
1369         = second_str_cpu_units [i - first_vect_length];
1370   VEC_safe_push (decl_t, heap, decls, decl);
1371 }
1372
1373 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1374    FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1375
1376    This gives information about a cpu unit reservation requirements.
1377    We fill a struct unit_pattern_rel_decl with information used later
1378    by `expand_automata'.  */
1379 static void
1380 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1381 {
1382   decl_t decl;
1383   char **str_cpu_units;
1384   char **str_pattern_lists;
1385   char ***str_patterns;
1386   int cpu_units_length;
1387   int length;
1388   int patterns_length;
1389   int i;
1390
1391   str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
1392                                 FALSE);
1393   if (str_cpu_units == NULL)
1394     fatal ((presence_p
1395             ? (final_p
1396                ? "invalid first string `%s' in final_presence_set"
1397                : "invalid first string `%s' in presence_set")
1398             : (final_p
1399                ? "invalid first string `%s' in final_absence_set"
1400                : "invalid first string `%s' in absence_set")),
1401            XSTR (def, 0));
1402   str_pattern_lists = get_str_vect (XSTR (def, 1),
1403                                     &patterns_length, ',', FALSE);
1404   if (str_pattern_lists == NULL)
1405     fatal ((presence_p
1406             ? (final_p
1407                ? "invalid second string `%s' in final_presence_set"
1408                : "invalid second string `%s' in presence_set")
1409             : (final_p
1410                ? "invalid second string `%s' in final_absence_set"
1411                : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1412   str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
1413   for (i = 0; i < patterns_length; i++)
1414     {
1415       str_patterns [i] = get_str_vect (str_pattern_lists [i],
1416                                        &length, ' ', FALSE);
1417       gcc_assert (str_patterns [i]);
1418     }
1419   decl = XCREATENODE (struct decl);
1420   decl->pos = 0;
1421   if (presence_p)
1422     {
1423       decl->mode = dm_presence;
1424       DECL_PRESENCE (decl)->names_num = cpu_units_length;
1425       DECL_PRESENCE (decl)->names = str_cpu_units;
1426       DECL_PRESENCE (decl)->patterns = str_patterns;
1427       DECL_PRESENCE (decl)->patterns_num = patterns_length;
1428       DECL_PRESENCE (decl)->final_p = final_p;
1429     }
1430   else
1431     {
1432       decl->mode = dm_absence;
1433       DECL_ABSENCE (decl)->names_num = cpu_units_length;
1434       DECL_ABSENCE (decl)->names = str_cpu_units;
1435       DECL_ABSENCE (decl)->patterns = str_patterns;
1436       DECL_ABSENCE (decl)->patterns_num = patterns_length;
1437       DECL_ABSENCE (decl)->final_p = final_p;
1438     }
1439   VEC_safe_push (decl_t, heap, decls, decl);
1440 }
1441
1442 /* Process a PRESENCE_SET.
1443
1444     This gives information about a cpu unit reservation requirements.
1445    We fill a struct unit_pattern_rel_decl (presence) with information
1446    used later by `expand_automata'.  */
1447 static void
1448 gen_presence_set (rtx def)
1449 {
1450   gen_presence_absence_set (def, TRUE, FALSE);
1451 }
1452
1453 /* Process a FINAL_PRESENCE_SET.
1454
1455    This gives information about a cpu unit reservation requirements.
1456    We fill a struct unit_pattern_rel_decl (presence) with information
1457    used later by `expand_automata'.  */
1458 static void
1459 gen_final_presence_set (rtx def)
1460 {
1461   gen_presence_absence_set (def, TRUE, TRUE);
1462 }
1463
1464 /* Process an ABSENCE_SET.
1465
1466    This gives information about a cpu unit reservation requirements.
1467    We fill a struct unit_pattern_rel_decl (absence) with information
1468    used later by `expand_automata'.  */
1469 static void
1470 gen_absence_set (rtx def)
1471 {
1472   gen_presence_absence_set (def, FALSE, FALSE);
1473 }
1474
1475 /* Process a FINAL_ABSENCE_SET.
1476
1477    This gives information about a cpu unit reservation requirements.
1478    We fill a struct unit_pattern_rel_decl (absence) with information
1479    used later by `expand_automata'.  */
1480 static void
1481 gen_final_absence_set (rtx def)
1482 {
1483   gen_presence_absence_set (def, FALSE, TRUE);
1484 }
1485
1486 /* Process a DEFINE_AUTOMATON.
1487
1488    This gives information about a finite state automaton used for
1489    recognizing pipeline hazards.  We fill a struct automaton_decl
1490    with information used later by `expand_automata'.  */
1491 static void
1492 gen_automaton (rtx def)
1493 {
1494   decl_t decl;
1495   char **str_automata;
1496   int vect_length;
1497   int i;
1498
1499   str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1500   if (str_automata == NULL)
1501     fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1502   for (i = 0; i < vect_length; i++)
1503     {
1504       decl = XCREATENODE (struct decl);
1505       decl->mode = dm_automaton;
1506       decl->pos = 0;
1507       DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1508       VEC_safe_push (decl_t, heap, decls, decl);
1509     }
1510 }
1511
1512 /* Process an AUTOMATA_OPTION.
1513
1514    This gives information how to generate finite state automaton used
1515    for recognizing pipeline hazards.  */
1516 static void
1517 gen_automata_option (rtx def)
1518 {
1519   if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1520     no_minimization_flag = 1;
1521   else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1522     time_flag = 1;
1523   else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
1524     stats_flag = 1;
1525   else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1526     v_flag = 1;
1527   else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1528     w_flag = 1;
1529   else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1530     ndfa_flag = 1;
1531   else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1532     progress_flag = 1;
1533   else
1534     fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1535 }
1536
1537 /* Name in reservation to denote absence reservation.  */
1538 #define NOTHING_NAME "nothing"
1539
1540 /* The following string contains original reservation string being
1541    parsed.  */
1542 static const char *reserv_str;
1543
1544 /* Parse an element in STR.  */
1545 static regexp_t
1546 gen_regexp_el (const char *str)
1547 {
1548   regexp_t regexp;
1549   char *dstr;
1550   int len;
1551
1552   if (*str == '(')
1553     {
1554       len = strlen (str);
1555       if (str [len - 1] != ')')
1556         fatal ("garbage after ) in reservation `%s'", reserv_str);
1557       dstr = XALLOCAVAR (char, len - 1);
1558       memcpy (dstr, str + 1, len - 2);
1559       dstr [len-2] = '\0';
1560       regexp = gen_regexp_sequence (dstr);
1561     }
1562   else if (strcmp (str, NOTHING_NAME) == 0)
1563     {
1564       regexp = XCREATENODE (struct regexp);
1565       regexp->mode = rm_nothing;
1566     }
1567   else
1568     {
1569       regexp = XCREATENODE (struct regexp);
1570       regexp->mode = rm_unit;
1571       REGEXP_UNIT (regexp)->name = str;
1572     }
1573   return regexp;
1574 }
1575
1576 /* Parse construction `repeat' in STR.  */
1577 static regexp_t
1578 gen_regexp_repeat (const char *str)
1579 {
1580   regexp_t regexp;
1581   regexp_t repeat;
1582   char **repeat_vect;
1583   int els_num;
1584   int i;
1585
1586   repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1587   if (repeat_vect == NULL)
1588     fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1589   if (els_num > 1)
1590     {
1591       regexp = gen_regexp_el (repeat_vect [0]);
1592       for (i = 1; i < els_num; i++)
1593         {
1594           repeat = XCREATENODE (struct regexp);
1595           repeat->mode = rm_repeat;
1596           REGEXP_REPEAT (repeat)->regexp = regexp;
1597           REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
1598           if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
1599             fatal ("repetition `%s' <= 1 in reservation `%s'",
1600                    str, reserv_str);
1601           regexp = repeat;
1602         }
1603       return regexp;
1604     }
1605   else
1606     return gen_regexp_el (repeat_vect[0]);
1607 }
1608
1609 /* Parse reservation STR which possibly contains separator '+'.  */
1610 static regexp_t
1611 gen_regexp_allof (const char *str)
1612 {
1613   regexp_t allof;
1614   char **allof_vect;
1615   int els_num;
1616   int i;
1617
1618   allof_vect = get_str_vect (str, &els_num, '+', TRUE);
1619   if (allof_vect == NULL)
1620     fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1621   if (els_num > 1)
1622     {
1623       allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1624                               + sizeof (regexp_t) * (els_num - 1));
1625       allof->mode = rm_allof;
1626       REGEXP_ALLOF (allof)->regexps_num = els_num;
1627       for (i = 0; i < els_num; i++)
1628         REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
1629       return allof;
1630     }
1631   else
1632     return gen_regexp_repeat (allof_vect[0]);
1633 }
1634
1635 /* Parse reservation STR which possibly contains separator '|'.  */
1636 static regexp_t
1637 gen_regexp_oneof (const char *str)
1638 {
1639   regexp_t oneof;
1640   char **oneof_vect;
1641   int els_num;
1642   int i;
1643
1644   oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
1645   if (oneof_vect == NULL)
1646     fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1647   if (els_num > 1)
1648     {
1649       oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1650                               + sizeof (regexp_t) * (els_num - 1));
1651       oneof->mode = rm_oneof;
1652       REGEXP_ONEOF (oneof)->regexps_num = els_num;
1653       for (i = 0; i < els_num; i++)
1654         REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
1655       return oneof;
1656     }
1657   else
1658     return gen_regexp_allof (oneof_vect[0]);
1659 }
1660
1661 /* Parse reservation STR which possibly contains separator ','.  */
1662 static regexp_t
1663 gen_regexp_sequence (const char *str)
1664 {
1665   regexp_t sequence;
1666   char **sequence_vect;
1667   int els_num;
1668   int i;
1669
1670   sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
1671   if (els_num > 1)
1672     {
1673       sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1674                                  + sizeof (regexp_t) * (els_num - 1));
1675       sequence->mode = rm_sequence;
1676       REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
1677       for (i = 0; i < els_num; i++)
1678         REGEXP_SEQUENCE (sequence)->regexps [i]
1679           = gen_regexp_oneof (sequence_vect [i]);
1680       return sequence;
1681     }
1682   else
1683     return gen_regexp_oneof (sequence_vect[0]);
1684 }
1685
1686 /* Parse construction reservation STR.  */
1687 static regexp_t
1688 gen_regexp (const char *str)
1689 {
1690   reserv_str = str;
1691   return gen_regexp_sequence (str);
1692 }
1693
1694 /* Process a DEFINE_RESERVATION.
1695
1696    This gives information about a reservation of cpu units.  We fill
1697    in a struct reserv_decl with information used later by
1698    `expand_automata'.  */
1699 static void
1700 gen_reserv (rtx def)
1701 {
1702   decl_t decl;
1703
1704   decl = XCREATENODE (struct decl);
1705   decl->mode = dm_reserv;
1706   decl->pos = 0;
1707   DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
1708   DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
1709   VEC_safe_push (decl_t, heap, decls, decl);
1710 }
1711
1712 /* Process a DEFINE_INSN_RESERVATION.
1713
1714    This gives information about the reservation of cpu units by an
1715    insn.  We fill a struct insn_reserv_decl with information used
1716    later by `expand_automata'.  */
1717 static void
1718 gen_insn_reserv (rtx def)
1719 {
1720   decl_t decl;
1721
1722   decl = XCREATENODE (struct decl);
1723   decl->mode = dm_insn_reserv;
1724   decl->pos = 0;
1725   DECL_INSN_RESERV (decl)->name
1726     = check_name (XSTR (def, 0), decl->pos);
1727   DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
1728   DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
1729   DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
1730   VEC_safe_push (decl_t, heap, decls, decl);
1731 }
1732
1733 \f
1734
1735 /* The function evaluates hash value (0..UINT_MAX) of string.  */
1736 static unsigned
1737 string_hash (const char *string)
1738 {
1739   unsigned result, i;
1740
1741   for (result = i = 0;*string++ != '\0'; i++)
1742     result += ((unsigned char) *string << (i % CHAR_BIT));
1743   return result;
1744 }
1745
1746 \f
1747
1748 /* This page contains abstract data `table of automaton declarations'.
1749    Elements of the table is nodes representing automaton declarations.
1750    Key of the table elements is name of given automaton.  Remember
1751    that automaton names have own space.  */
1752
1753 /* The function evaluates hash value of an automaton declaration.  The
1754    function is used by abstract data `hashtab'.  The function returns
1755    hash value (0..UINT_MAX) of given automaton declaration.  */
1756 static hashval_t
1757 automaton_decl_hash (const void *automaton_decl)
1758 {
1759   const_decl_t const decl = (const_decl_t) automaton_decl;
1760
1761   gcc_assert (decl->mode != dm_automaton
1762               || DECL_AUTOMATON (decl)->name);
1763   return string_hash (DECL_AUTOMATON (decl)->name);
1764 }
1765
1766 /* The function tests automaton declarations on equality of their
1767    keys.  The function is used by abstract data `hashtab'.  The
1768    function returns 1 if the declarations have the same key, 0
1769    otherwise.  */
1770 static int
1771 automaton_decl_eq_p (const void* automaton_decl_1,
1772                      const void* automaton_decl_2)
1773 {
1774   const_decl_t const decl1 = (const_decl_t) automaton_decl_1;
1775   const_decl_t const decl2 = (const_decl_t) automaton_decl_2;
1776
1777   gcc_assert (decl1->mode == dm_automaton
1778               && DECL_AUTOMATON (decl1)->name
1779               && decl2->mode == dm_automaton
1780               && DECL_AUTOMATON (decl2)->name);
1781   return strcmp (DECL_AUTOMATON (decl1)->name,
1782                  DECL_AUTOMATON (decl2)->name) == 0;
1783 }
1784
1785 /* The automaton declaration table itself is represented by the
1786    following variable.  */
1787 static htab_t automaton_decl_table;
1788
1789 /* The function inserts automaton declaration into the table.  The
1790    function does nothing if an automaton declaration with the same key
1791    exists already in the table.  The function returns automaton
1792    declaration node in the table with the same key as given automaton
1793    declaration node.  */
1794 static decl_t
1795 insert_automaton_decl (decl_t automaton_decl)
1796 {
1797   void **entry_ptr;
1798
1799   entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
1800   if (*entry_ptr == NULL)
1801     *entry_ptr = (void *) automaton_decl;
1802   return (decl_t) *entry_ptr;
1803 }
1804
1805 /* The following variable value is node representing automaton
1806    declaration.  The node used for searching automaton declaration
1807    with given name.  */
1808 static struct decl work_automaton_decl;
1809
1810 /* The function searches for automaton declaration in the table with
1811    the same key as node representing name of the automaton
1812    declaration.  The function returns node found in the table, NULL if
1813    such node does not exist in the table.  */
1814 static decl_t
1815 find_automaton_decl (const char *name)
1816 {
1817   void *entry;
1818
1819   work_automaton_decl.mode = dm_automaton;
1820   DECL_AUTOMATON (&work_automaton_decl)->name = name;
1821   entry = htab_find (automaton_decl_table, &work_automaton_decl);
1822   return (decl_t) entry;
1823 }
1824
1825 /* The function creates empty automaton declaration table and node
1826    representing automaton declaration and used for searching automaton
1827    declaration with given name.  The function must be called only once
1828    before any work with the automaton declaration table.  */
1829 static void
1830 initiate_automaton_decl_table (void)
1831 {
1832   work_automaton_decl.mode = dm_automaton;
1833   automaton_decl_table = htab_create (10, automaton_decl_hash,
1834                                       automaton_decl_eq_p, (htab_del) 0);
1835 }
1836
1837 /* The function deletes the automaton declaration table.  Only call of
1838    function `initiate_automaton_decl_table' is possible immediately
1839    after this function call.  */
1840 static void
1841 finish_automaton_decl_table (void)
1842 {
1843   htab_delete (automaton_decl_table);
1844 }
1845
1846 \f
1847
1848 /* This page contains abstract data `table of insn declarations'.
1849    Elements of the table is nodes representing insn declarations.  Key
1850    of the table elements is name of given insn (in corresponding
1851    define_insn_reservation).  Remember that insn names have own
1852    space.  */
1853
1854 /* The function evaluates hash value of an insn declaration.  The
1855    function is used by abstract data `hashtab'.  The function returns
1856    hash value (0..UINT_MAX) of given insn declaration.  */
1857 static hashval_t
1858 insn_decl_hash (const void *insn_decl)
1859 {
1860   const_decl_t const decl = (const_decl_t) insn_decl;
1861
1862   gcc_assert (decl->mode == dm_insn_reserv
1863               && DECL_INSN_RESERV (decl)->name);
1864   return string_hash (DECL_INSN_RESERV (decl)->name);
1865 }
1866
1867 /* The function tests insn declarations on equality of their keys.
1868    The function is used by abstract data `hashtab'.  The function
1869    returns 1 if declarations have the same key, 0 otherwise.  */
1870 static int
1871 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
1872 {
1873   const_decl_t const decl1 = (const_decl_t) insn_decl_1;
1874   const_decl_t const decl2 = (const_decl_t) insn_decl_2;
1875
1876   gcc_assert (decl1->mode == dm_insn_reserv
1877               && DECL_INSN_RESERV (decl1)->name
1878               && decl2->mode == dm_insn_reserv
1879               && DECL_INSN_RESERV (decl2)->name);
1880   return strcmp (DECL_INSN_RESERV (decl1)->name,
1881                  DECL_INSN_RESERV (decl2)->name) == 0;
1882 }
1883
1884 /* The insn declaration table itself is represented by the following
1885    variable.  The table does not contain insn reservation
1886    declarations.  */
1887 static htab_t insn_decl_table;
1888
1889 /* The function inserts insn declaration into the table.  The function
1890    does nothing if an insn declaration with the same key exists
1891    already in the table.  The function returns insn declaration node
1892    in the table with the same key as given insn declaration node.  */
1893 static decl_t
1894 insert_insn_decl (decl_t insn_decl)
1895 {
1896   void **entry_ptr;
1897
1898   entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
1899   if (*entry_ptr == NULL)
1900     *entry_ptr = (void *) insn_decl;
1901   return (decl_t) *entry_ptr;
1902 }
1903
1904 /* The following variable value is node representing insn reservation
1905    declaration.  The node used for searching insn reservation
1906    declaration with given name.  */
1907 static struct decl work_insn_decl;
1908
1909 /* The function searches for insn reservation declaration in the table
1910    with the same key as node representing name of the insn reservation
1911    declaration.  The function returns node found in the table, NULL if
1912    such node does not exist in the table.  */
1913 static decl_t
1914 find_insn_decl (const char *name)
1915 {
1916   void *entry;
1917
1918   work_insn_decl.mode = dm_insn_reserv;
1919   DECL_INSN_RESERV (&work_insn_decl)->name = name;
1920   entry = htab_find (insn_decl_table, &work_insn_decl);
1921   return (decl_t) entry;
1922 }
1923
1924 /* The function creates empty insn declaration table and node
1925    representing insn declaration and used for searching insn
1926    declaration with given name.  The function must be called only once
1927    before any work with the insn declaration table.  */
1928 static void
1929 initiate_insn_decl_table (void)
1930 {
1931   work_insn_decl.mode = dm_insn_reserv;
1932   insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
1933                                  (htab_del) 0);
1934 }
1935
1936 /* The function deletes the insn declaration table.  Only call of
1937    function `initiate_insn_decl_table' is possible immediately after
1938    this function call.  */
1939 static void
1940 finish_insn_decl_table (void)
1941 {
1942   htab_delete (insn_decl_table);
1943 }
1944
1945 \f
1946
1947 /* This page contains abstract data `table of declarations'.  Elements
1948    of the table is nodes representing declarations (of units and
1949    reservations).  Key of the table elements is names of given
1950    declarations.  */
1951
1952 /* The function evaluates hash value of a declaration.  The function
1953    is used by abstract data `hashtab'.  The function returns hash
1954    value (0..UINT_MAX) of given declaration.  */
1955 static hashval_t
1956 decl_hash (const void *decl)
1957 {
1958   const_decl_t const d = (const_decl_t) decl;
1959
1960   gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
1961               || (d->mode == dm_reserv && DECL_RESERV (d)->name));
1962   return string_hash (d->mode == dm_unit
1963                       ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
1964 }
1965
1966 /* The function tests declarations on equality of their keys.  The
1967    function is used by abstract data 'hashtab'.  The function
1968    returns 1 if the declarations have the same key, 0 otherwise.  */
1969 static int
1970 decl_eq_p (const void *decl_1, const void *decl_2)
1971 {
1972   const_decl_t const d1 = (const_decl_t) decl_1;
1973   const_decl_t const d2 = (const_decl_t) decl_2;
1974
1975   gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
1976               || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
1977   gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
1978               || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
1979   return strcmp ((d1->mode == dm_unit
1980                   ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
1981                  (d2->mode == dm_unit
1982                   ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
1983 }
1984
1985 /* The declaration table itself is represented by the following
1986    variable.  */
1987 static htab_t decl_table;
1988
1989 /* The function inserts declaration into the table.  The function does
1990    nothing if a declaration with the same key exists already in the
1991    table.  The function returns declaration node in the table with the
1992    same key as given declaration node.  */
1993
1994 static decl_t
1995 insert_decl (decl_t decl)
1996 {
1997   void **entry_ptr;
1998
1999   entry_ptr = htab_find_slot (decl_table, decl, INSERT);
2000   if (*entry_ptr == NULL)
2001     *entry_ptr = (void *) decl;
2002   return (decl_t) *entry_ptr;
2003 }
2004
2005 /* The following variable value is node representing declaration.  The
2006    node used for searching declaration with given name.  */
2007 static struct decl work_decl;
2008
2009 /* The function searches for declaration in the table with the same
2010    key as node representing name of the declaration.  The function
2011    returns node found in the table, NULL if such node does not exist
2012    in the table.  */
2013 static decl_t
2014 find_decl (const char *name)
2015 {
2016   void *entry;
2017
2018   work_decl.mode = dm_unit;
2019   DECL_UNIT (&work_decl)->name = name;
2020   entry = htab_find (decl_table, &work_decl);
2021   return (decl_t) entry;
2022 }
2023
2024 /* The function creates empty declaration table and node representing
2025    declaration and used for searching declaration with given name.
2026    The function must be called only once before any work with the
2027    declaration table.  */
2028 static void
2029 initiate_decl_table (void)
2030 {
2031   work_decl.mode = dm_unit;
2032   decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2033 }
2034
2035 /* The function deletes the declaration table.  Only call of function
2036    `initiate_declaration_table' is possible immediately after this
2037    function call.  */
2038 static void
2039 finish_decl_table (void)
2040 {
2041   htab_delete (decl_table);
2042 }
2043
2044 \f
2045
2046 /* This page contains checker of pipeline hazard description.  */
2047
2048 /* Checking NAMES in an exclusion clause vector and returning formed
2049    unit_set_el_list.  */
2050 static unit_set_el_t
2051 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2052 {
2053   unit_set_el_t el_list;
2054   unit_set_el_t last_el;
2055   unit_set_el_t new_el;
2056   decl_t decl_in_table;
2057   int i;
2058
2059   el_list = NULL;
2060   last_el = NULL;
2061   for (i = 0; i < num; i++)
2062     {
2063       decl_in_table = find_decl (names [i]);
2064       if (decl_in_table == NULL)
2065         error ("unit `%s' in exclusion is not declared", names [i]);
2066       else if (decl_in_table->mode != dm_unit)
2067         error ("`%s' in exclusion is not unit", names [i]);
2068       else
2069         {
2070           new_el = XCREATENODE (struct unit_set_el);
2071           new_el->unit_decl = DECL_UNIT (decl_in_table);
2072           new_el->next_unit_set_el = NULL;
2073           if (last_el == NULL)
2074             el_list = last_el = new_el;
2075           else
2076             {
2077               last_el->next_unit_set_el = new_el;
2078               last_el = last_el->next_unit_set_el;
2079             }
2080         }
2081     }
2082   return el_list;
2083 }
2084
2085 /* The function adds each element from SOURCE_LIST to the exclusion
2086    list of the each element from DEST_LIST.  Checking situation "unit
2087    excludes itself".  */
2088 static void
2089 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2090            pos_t excl_pos ATTRIBUTE_UNUSED)
2091 {
2092   unit_set_el_t dst;
2093   unit_set_el_t src;
2094   unit_set_el_t curr_el;
2095   unit_set_el_t prev_el;
2096   unit_set_el_t copy;
2097
2098   for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2099     for (src = source_list; src != NULL; src = src->next_unit_set_el)
2100       {
2101         if (dst->unit_decl == src->unit_decl)
2102           {
2103             error ("unit `%s' excludes itself", src->unit_decl->name);
2104             continue;
2105           }
2106         if (dst->unit_decl->automaton_name != NULL
2107             && src->unit_decl->automaton_name != NULL
2108             && strcmp (dst->unit_decl->automaton_name,
2109                        src->unit_decl->automaton_name) != 0)
2110           {
2111             error ("units `%s' and `%s' in exclusion set belong to different automata",
2112                    src->unit_decl->name, dst->unit_decl->name);
2113             continue;
2114           }
2115         for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2116              curr_el != NULL;
2117              prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2118           if (curr_el->unit_decl == src->unit_decl)
2119             break;
2120         if (curr_el == NULL)
2121           {
2122             /* Element not found - insert.  */
2123             copy = XCOPYNODE (struct unit_set_el, src);
2124             copy->next_unit_set_el = NULL;
2125             if (prev_el == NULL)
2126               dst->unit_decl->excl_list = copy;
2127             else
2128               prev_el->next_unit_set_el = copy;
2129         }
2130     }
2131 }
2132
2133 /* Checking NAMES in presence/absence clause and returning the
2134    formed unit_set_el_list.  The function is called only after
2135    processing all exclusion sets.  */
2136 static unit_set_el_t
2137 process_presence_absence_names (char **names, int num,
2138                                 pos_t req_pos ATTRIBUTE_UNUSED,
2139                                 int presence_p, int final_p)
2140 {
2141   unit_set_el_t el_list;
2142   unit_set_el_t last_el;
2143   unit_set_el_t new_el;
2144   decl_t decl_in_table;
2145   int i;
2146
2147   el_list = NULL;
2148   last_el = NULL;
2149   for (i = 0; i < num; i++)
2150     {
2151       decl_in_table = find_decl (names [i]);
2152       if (decl_in_table == NULL)
2153         error ((presence_p
2154                 ? (final_p
2155                    ? "unit `%s' in final presence set is not declared"
2156                    : "unit `%s' in presence set is not declared")
2157                 : (final_p
2158                    ? "unit `%s' in final absence set is not declared"
2159                    : "unit `%s' in absence set is not declared")), names [i]);
2160       else if (decl_in_table->mode != dm_unit)
2161         error ((presence_p
2162                 ? (final_p
2163                    ? "`%s' in final presence set is not unit"
2164                    : "`%s' in presence set is not unit")
2165                 : (final_p
2166                    ? "`%s' in final absence set is not unit"
2167                    : "`%s' in absence set is not unit")), names [i]);
2168       else
2169         {
2170           new_el = XCREATENODE (struct unit_set_el);
2171           new_el->unit_decl = DECL_UNIT (decl_in_table);
2172           new_el->next_unit_set_el = NULL;
2173           if (last_el == NULL)
2174             el_list = last_el = new_el;
2175           else
2176             {
2177               last_el->next_unit_set_el = new_el;
2178               last_el = last_el->next_unit_set_el;
2179             }
2180         }
2181     }
2182   return el_list;
2183 }
2184
2185 /* Checking NAMES in patterns of a presence/absence clause and
2186    returning the formed pattern_set_el_list.  The function is called
2187    only after processing all exclusion sets.  */
2188 static pattern_set_el_t
2189 process_presence_absence_patterns (char ***patterns, int num,
2190                                    pos_t req_pos ATTRIBUTE_UNUSED,
2191                                    int presence_p, int final_p)
2192 {
2193   pattern_set_el_t el_list;
2194   pattern_set_el_t last_el;
2195   pattern_set_el_t new_el;
2196   decl_t decl_in_table;
2197   int i, j;
2198
2199   el_list = NULL;
2200   last_el = NULL;
2201   for (i = 0; i < num; i++)
2202     {
2203       for (j = 0; patterns [i] [j] != NULL; j++)
2204         ;
2205       new_el = XCREATENODEVAR (struct pattern_set_el,
2206                                sizeof (struct pattern_set_el)
2207                                + sizeof (struct unit_decl *) * j);
2208       new_el->unit_decls
2209         = (struct unit_decl **) ((char *) new_el
2210                                  + sizeof (struct pattern_set_el));
2211       new_el->next_pattern_set_el = NULL;
2212       if (last_el == NULL)
2213         el_list = last_el = new_el;
2214       else
2215         {
2216           last_el->next_pattern_set_el = new_el;
2217           last_el = last_el->next_pattern_set_el;
2218         }
2219       new_el->units_num = 0;
2220       for (j = 0; patterns [i] [j] != NULL; j++)
2221         {
2222           decl_in_table = find_decl (patterns [i] [j]);
2223           if (decl_in_table == NULL)
2224             error ((presence_p
2225                     ? (final_p
2226                        ? "unit `%s' in final presence set is not declared"
2227                        : "unit `%s' in presence set is not declared")
2228                     : (final_p
2229                        ? "unit `%s' in final absence set is not declared"
2230                        : "unit `%s' in absence set is not declared")),
2231                    patterns [i] [j]);
2232           else if (decl_in_table->mode != dm_unit)
2233             error ((presence_p
2234                     ? (final_p
2235                        ? "`%s' in final presence set is not unit"
2236                        : "`%s' in presence set is not unit")
2237                     : (final_p
2238                        ? "`%s' in final absence set is not unit"
2239                        : "`%s' in absence set is not unit")),
2240                    patterns [i] [j]);
2241           else
2242             {
2243               new_el->unit_decls [new_el->units_num]
2244                 = DECL_UNIT (decl_in_table);
2245               new_el->units_num++;
2246             }
2247         }
2248     }
2249   return el_list;
2250 }
2251
2252 /* The function adds each element from PATTERN_LIST to presence (if
2253    PRESENCE_P) or absence list of the each element from DEST_LIST.
2254    Checking situations "unit requires own absence", and "unit excludes
2255    and requires presence of ...", "unit requires absence and presence
2256    of ...", "units in (final) presence set belong to different
2257    automata", and "units in (final) absence set belong to different
2258    automata".  Remember that we process absence sets only after all
2259    presence sets.  */
2260 static void
2261 add_presence_absence (unit_set_el_t dest_list,
2262                       pattern_set_el_t pattern_list,
2263                       pos_t req_pos ATTRIBUTE_UNUSED,
2264                       int presence_p, int final_p)
2265 {
2266   unit_set_el_t dst;
2267   pattern_set_el_t pat;
2268   struct unit_decl *unit;
2269   unit_set_el_t curr_excl_el;
2270   pattern_set_el_t curr_pat_el;
2271   pattern_set_el_t prev_el;
2272   pattern_set_el_t copy;
2273   int i;
2274   int no_error_flag;
2275
2276   for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2277     for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2278       {
2279         for (i = 0; i < pat->units_num; i++)
2280           {
2281             unit = pat->unit_decls [i];
2282             if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2283               {
2284                 error ("unit `%s' requires own absence", unit->name);
2285                 continue;
2286               }
2287             if (dst->unit_decl->automaton_name != NULL
2288                 && unit->automaton_name != NULL
2289                 && strcmp (dst->unit_decl->automaton_name,
2290                            unit->automaton_name) != 0)
2291               {
2292                 error ((presence_p
2293                         ? (final_p
2294                            ? "units `%s' and `%s' in final presence set belong to different automata"
2295                            : "units `%s' and `%s' in presence set belong to different automata")
2296                         : (final_p
2297                            ? "units `%s' and `%s' in final absence set belong to different automata"
2298                            : "units `%s' and `%s' in absence set belong to different automata")),
2299                        unit->name, dst->unit_decl->name);
2300                 continue;
2301               }
2302             no_error_flag = 1;
2303             if (presence_p)
2304               for (curr_excl_el = dst->unit_decl->excl_list;
2305                    curr_excl_el != NULL;
2306                    curr_excl_el = curr_excl_el->next_unit_set_el)
2307                 {
2308                   if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2309                     {
2310                       if (!w_flag)
2311                         {
2312                           error ("unit `%s' excludes and requires presence of `%s'",
2313                                  dst->unit_decl->name, unit->name);
2314                           no_error_flag = 0;
2315                         }
2316                       else
2317                         warning ("unit `%s' excludes and requires presence of `%s'",
2318                            dst->unit_decl->name, unit->name);
2319                     }
2320                 }
2321             else if (pat->units_num == 1)
2322               for (curr_pat_el = dst->unit_decl->presence_list;
2323                    curr_pat_el != NULL;
2324                    curr_pat_el = curr_pat_el->next_pattern_set_el)
2325                 if (curr_pat_el->units_num == 1
2326                     && unit == curr_pat_el->unit_decls [0])
2327                   {
2328                     if (!w_flag)
2329                       {
2330                         error ("unit `%s' requires absence and presence of `%s'",
2331                                dst->unit_decl->name, unit->name);
2332                         no_error_flag = 0;
2333                       }
2334                     else
2335                       warning ("unit `%s' requires absence and presence of `%s'",
2336                                dst->unit_decl->name, unit->name);
2337                   }
2338             if (no_error_flag)
2339               {
2340                 for (prev_el = (presence_p
2341                                 ? (final_p
2342                                    ? dst->unit_decl->final_presence_list
2343                                    : dst->unit_decl->final_presence_list)
2344                                 : (final_p
2345                                    ? dst->unit_decl->final_absence_list
2346                                    : dst->unit_decl->absence_list));
2347                      prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2348                      prev_el = prev_el->next_pattern_set_el)
2349                   ;
2350                 copy = XCOPYNODE (struct pattern_set_el, pat);
2351                 copy->next_pattern_set_el = NULL;
2352                 if (prev_el == NULL)
2353                   {
2354                     if (presence_p)
2355                       {
2356                         if (final_p)
2357                           dst->unit_decl->final_presence_list = copy;
2358                         else
2359                           dst->unit_decl->presence_list = copy;
2360                       }
2361                     else if (final_p)
2362                       dst->unit_decl->final_absence_list = copy;
2363                     else
2364                       dst->unit_decl->absence_list = copy;
2365                   }
2366                 else
2367                   prev_el->next_pattern_set_el = copy;
2368               }
2369           }
2370       }
2371 }
2372
2373
2374 /* The function inserts BYPASS in the list of bypasses of the
2375    corresponding output insn.  The order of bypasses in the list is
2376    decribed in a comment for member `bypass_list' (see above).  If
2377    there is already the same bypass in the list the function reports
2378    this and does nothing.  */
2379 static void
2380 insert_bypass (struct bypass_decl *bypass)
2381 {
2382   struct bypass_decl *curr, *last;
2383   struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
2384   struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
2385
2386   for (curr = out_insn_reserv->bypass_list, last = NULL;
2387        curr != NULL;
2388        last = curr, curr = curr->next)
2389     if (curr->in_insn_reserv == in_insn_reserv)
2390       {
2391         if ((bypass->bypass_guard_name != NULL
2392              && curr->bypass_guard_name != NULL
2393              && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
2394             || bypass->bypass_guard_name == curr->bypass_guard_name)
2395           {
2396             if (bypass->bypass_guard_name == NULL)
2397               {
2398                 if (!w_flag)
2399                   error ("the same bypass `%s - %s' is already defined",
2400                          bypass->out_insn_name, bypass->in_insn_name);
2401                 else
2402                   warning ("the same bypass `%s - %s' is already defined",
2403                            bypass->out_insn_name, bypass->in_insn_name);
2404               }
2405             else if (!w_flag)
2406               error ("the same bypass `%s - %s' (guard %s) is already defined",
2407                      bypass->out_insn_name, bypass->in_insn_name,
2408                      bypass->bypass_guard_name);
2409             else
2410               warning
2411                 ("the same bypass `%s - %s' (guard %s) is already defined",
2412                  bypass->out_insn_name, bypass->in_insn_name,
2413                  bypass->bypass_guard_name);
2414             return;
2415           }
2416         if (curr->bypass_guard_name == NULL)
2417           break;
2418         if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
2419           {
2420             last = curr;
2421             break;
2422           }
2423
2424       }
2425   if (last == NULL)
2426     {
2427       bypass->next = out_insn_reserv->bypass_list;
2428       out_insn_reserv->bypass_list = bypass;
2429     }
2430   else
2431     {
2432       bypass->next = last->next;
2433       last->next = bypass;
2434     }
2435 }
2436
2437 /* The function processes pipeline description declarations, checks
2438    their correctness, and forms exclusion/presence/absence sets.  */
2439 static void
2440 process_decls (void)
2441 {
2442   decl_t decl;
2443   decl_t automaton_decl;
2444   decl_t decl_in_table;
2445   decl_t out_insn_reserv;
2446   decl_t in_insn_reserv;
2447   int automaton_presence;
2448   int i;
2449
2450   /* Checking repeated automata declarations.  */
2451   automaton_presence = 0;
2452   for (i = 0; i < description->decls_num; i++)
2453     {
2454       decl = description->decls [i];
2455       if (decl->mode == dm_automaton)
2456         {
2457           automaton_presence = 1;
2458           decl_in_table = insert_automaton_decl (decl);
2459           if (decl_in_table != decl)
2460             {
2461               if (!w_flag)
2462                 error ("repeated declaration of automaton `%s'",
2463                        DECL_AUTOMATON (decl)->name);
2464               else
2465                 warning ("repeated declaration of automaton `%s'",
2466                          DECL_AUTOMATON (decl)->name);
2467             }
2468         }
2469     }
2470   /* Checking undeclared automata, repeated declarations (except for
2471      automata) and correctness of their attributes (insn latency times
2472      etc.).  */
2473   for (i = 0; i < description->decls_num; i++)
2474     {
2475       decl = description->decls [i];
2476       if (decl->mode == dm_insn_reserv)
2477         {
2478           if (DECL_INSN_RESERV (decl)->default_latency < 0)
2479             error ("define_insn_reservation `%s' has negative latency time",
2480                    DECL_INSN_RESERV (decl)->name);
2481           DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2482           description->insns_num++;
2483           decl_in_table = insert_insn_decl (decl);
2484           if (decl_in_table != decl)
2485             error ("`%s' is already used as insn reservation name",
2486                    DECL_INSN_RESERV (decl)->name);
2487         }
2488       else if (decl->mode == dm_bypass)
2489         {
2490           if (DECL_BYPASS (decl)->latency < 0)
2491             error ("define_bypass `%s - %s' has negative latency time",
2492                    DECL_BYPASS (decl)->out_insn_name,
2493                    DECL_BYPASS (decl)->in_insn_name);
2494         }
2495       else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2496         {
2497           if (decl->mode == dm_unit)
2498             {
2499               DECL_UNIT (decl)->automaton_decl = NULL;
2500               if (DECL_UNIT (decl)->automaton_name != NULL)
2501                 {
2502                   automaton_decl
2503                     = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2504                   if (automaton_decl == NULL)
2505                     error ("automaton `%s' is not declared",
2506                            DECL_UNIT (decl)->automaton_name);
2507                   else
2508                     {
2509                       DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2510                       DECL_UNIT (decl)->automaton_decl
2511                         = DECL_AUTOMATON (automaton_decl);
2512                     }
2513                 }
2514               else if (automaton_presence)
2515                 error ("define_unit `%s' without automaton when one defined",
2516                        DECL_UNIT (decl)->name);
2517               DECL_UNIT (decl)->unit_num = description->units_num;
2518               description->units_num++;
2519               if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2520                 {
2521                   error ("`%s' is declared as cpu unit", NOTHING_NAME);
2522                   continue;
2523                 }
2524               decl_in_table = find_decl (DECL_UNIT (decl)->name);
2525             }
2526           else
2527             {
2528               if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2529                 {
2530                   error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2531                   continue;
2532                 }
2533               decl_in_table = find_decl (DECL_RESERV (decl)->name);
2534             }
2535           if (decl_in_table == NULL)
2536             decl_in_table = insert_decl (decl);
2537           else
2538             {
2539               if (decl->mode == dm_unit)
2540                 error ("repeated declaration of unit `%s'",
2541                        DECL_UNIT (decl)->name);
2542               else
2543                 error ("repeated declaration of reservation `%s'",
2544                        DECL_RESERV (decl)->name);
2545             }
2546         }
2547     }
2548   /* Check bypasses and form list of bypasses for each (output)
2549      insn.  */
2550   for (i = 0; i < description->decls_num; i++)
2551     {
2552       decl = description->decls [i];
2553       if (decl->mode == dm_bypass)
2554         {
2555           out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2556           in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2557           if (out_insn_reserv == NULL)
2558             error ("there is no insn reservation `%s'",
2559                    DECL_BYPASS (decl)->out_insn_name);
2560           else if (in_insn_reserv == NULL)
2561             error ("there is no insn reservation `%s'",
2562                    DECL_BYPASS (decl)->in_insn_name);
2563           else
2564             {
2565               DECL_BYPASS (decl)->out_insn_reserv
2566                 = DECL_INSN_RESERV (out_insn_reserv);
2567               DECL_BYPASS (decl)->in_insn_reserv
2568                 = DECL_INSN_RESERV (in_insn_reserv);
2569               insert_bypass (DECL_BYPASS (decl));
2570             }
2571         }
2572     }
2573
2574   /* Check exclusion set declarations and form exclusion sets.  */
2575   for (i = 0; i < description->decls_num; i++)
2576     {
2577       decl = description->decls [i];
2578       if (decl->mode == dm_excl)
2579         {
2580           unit_set_el_t unit_set_el_list;
2581           unit_set_el_t unit_set_el_list_2;
2582
2583           unit_set_el_list
2584             = process_excls (DECL_EXCL (decl)->names,
2585                              DECL_EXCL (decl)->first_list_length, decl->pos);
2586           unit_set_el_list_2
2587             = process_excls (&DECL_EXCL (decl)->names
2588                              [DECL_EXCL (decl)->first_list_length],
2589                              DECL_EXCL (decl)->all_names_num
2590                              - DECL_EXCL (decl)->first_list_length,
2591                              decl->pos);
2592           add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2593           add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2594         }
2595     }
2596
2597   /* Check presence set declarations and form presence sets.  */
2598   for (i = 0; i < description->decls_num; i++)
2599     {
2600       decl = description->decls [i];
2601       if (decl->mode == dm_presence)
2602         {
2603           unit_set_el_t unit_set_el_list;
2604           pattern_set_el_t pattern_set_el_list;
2605
2606           unit_set_el_list
2607             = process_presence_absence_names
2608               (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
2609                decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2610           pattern_set_el_list
2611             = process_presence_absence_patterns
2612               (DECL_PRESENCE (decl)->patterns,
2613                DECL_PRESENCE (decl)->patterns_num,
2614                decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2615           add_presence_absence (unit_set_el_list, pattern_set_el_list,
2616                                 decl->pos, TRUE,
2617                                 DECL_PRESENCE (decl)->final_p);
2618         }
2619     }
2620
2621   /* Check absence set declarations and form absence sets.  */
2622   for (i = 0; i < description->decls_num; i++)
2623     {
2624       decl = description->decls [i];
2625       if (decl->mode == dm_absence)
2626         {
2627           unit_set_el_t unit_set_el_list;
2628           pattern_set_el_t pattern_set_el_list;
2629
2630           unit_set_el_list
2631             = process_presence_absence_names
2632               (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
2633                decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2634           pattern_set_el_list
2635             = process_presence_absence_patterns
2636               (DECL_ABSENCE (decl)->patterns,
2637                DECL_ABSENCE (decl)->patterns_num,
2638                decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2639           add_presence_absence (unit_set_el_list, pattern_set_el_list,
2640                                 decl->pos, FALSE,
2641                                 DECL_ABSENCE (decl)->final_p);
2642         }
2643     }
2644 }
2645
2646 /* The following function checks that declared automaton is used.  If
2647    the automaton is not used, the function fixes error/warning.  The
2648    following function must be called only after `process_decls'.  */
2649 static void
2650 check_automaton_usage (void)
2651 {
2652   decl_t decl;
2653   int i;
2654
2655   for (i = 0; i < description->decls_num; i++)
2656     {
2657       decl = description->decls [i];
2658       if (decl->mode == dm_automaton
2659           && !DECL_AUTOMATON (decl)->automaton_is_used)
2660         {
2661           if (!w_flag)
2662             error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
2663           else
2664             warning ("automaton `%s' is not used",
2665                      DECL_AUTOMATON (decl)->name);
2666         }
2667     }
2668 }
2669
2670 /* The following recursive function processes all regexp in order to
2671    fix usage of units or reservations and to fix errors of undeclared
2672    name.  The function may change unit_regexp onto reserv_regexp.
2673    Remember that reserv_regexp does not exist before the function
2674    call.  */
2675 static regexp_t
2676 process_regexp (regexp_t regexp)
2677 {
2678   decl_t decl_in_table;
2679   regexp_t new_regexp;
2680   int i;
2681
2682   switch (regexp->mode)
2683     {
2684     case rm_unit:
2685       decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
2686       if (decl_in_table == NULL)
2687         error ("undeclared unit or reservation `%s'",
2688                REGEXP_UNIT (regexp)->name);
2689       else
2690         switch (decl_in_table->mode)
2691           {
2692           case dm_unit:
2693             DECL_UNIT (decl_in_table)->unit_is_used = 1;
2694             REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
2695             break;
2696
2697           case dm_reserv:
2698             DECL_RESERV (decl_in_table)->reserv_is_used = 1;
2699             new_regexp = XCREATENODE (struct regexp);
2700             new_regexp->mode = rm_reserv;
2701             new_regexp->pos = regexp->pos;
2702             REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
2703             REGEXP_RESERV (new_regexp)->reserv_decl
2704               = DECL_RESERV (decl_in_table);
2705             regexp = new_regexp;
2706             break;
2707
2708           default:
2709             gcc_unreachable ();
2710         }
2711       break;
2712     case rm_sequence:
2713       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2714         REGEXP_SEQUENCE (regexp)->regexps [i]
2715           = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
2716       break;
2717     case rm_allof:
2718       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2719         REGEXP_ALLOF (regexp)->regexps [i]
2720           = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
2721       break;
2722     case rm_oneof:
2723       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2724         REGEXP_ONEOF (regexp)->regexps [i]
2725           = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
2726       break;
2727     case rm_repeat:
2728       REGEXP_REPEAT (regexp)->regexp
2729         = process_regexp (REGEXP_REPEAT (regexp)->regexp);
2730       break;
2731     case rm_nothing:
2732       break;
2733     default:
2734       gcc_unreachable ();
2735     }
2736   return regexp;
2737 }
2738
2739 /* The following function processes regexp of define_reservation and
2740    define_insn_reservation with the aid of function
2741    `process_regexp'.  */
2742 static void
2743 process_regexp_decls (void)
2744 {
2745   decl_t decl;
2746   int i;
2747
2748   for (i = 0; i < description->decls_num; i++)
2749     {
2750       decl = description->decls [i];
2751       if (decl->mode == dm_reserv)
2752         DECL_RESERV (decl)->regexp
2753           = process_regexp (DECL_RESERV (decl)->regexp);
2754       else if (decl->mode == dm_insn_reserv)
2755         DECL_INSN_RESERV (decl)->regexp
2756           = process_regexp (DECL_INSN_RESERV (decl)->regexp);
2757     }
2758 }
2759
2760 /* The following function checks that declared unit is used.  If the
2761    unit is not used, the function fixes errors/warnings.  The
2762    following function must be called only after `process_decls',
2763    `process_regexp_decls'.  */
2764 static void
2765 check_usage (void)
2766 {
2767   decl_t decl;
2768   int i;
2769
2770   for (i = 0; i < description->decls_num; i++)
2771     {
2772       decl = description->decls [i];
2773       if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
2774         {
2775           if (!w_flag)
2776             error ("unit `%s' is not used", DECL_UNIT (decl)->name);
2777           else
2778             warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
2779         }
2780       else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
2781         {
2782           if (!w_flag)
2783             error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
2784           else
2785             warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
2786         }
2787     }
2788 }
2789
2790 /* The following variable value is number of reservation being
2791    processed on loop recognition.  */
2792 static int curr_loop_pass_num;
2793
2794 /* The following recursive function returns nonzero value if REGEXP
2795    contains given decl or reservations in given regexp refers for
2796    given decl.  */
2797 static int
2798 loop_in_regexp (regexp_t regexp, decl_t start_decl)
2799 {
2800   int i;
2801
2802   if (regexp == NULL)
2803     return 0;
2804   switch (regexp->mode)
2805     {
2806       case rm_unit:
2807         return 0;
2808
2809     case rm_reserv:
2810       if (start_decl->mode == dm_reserv
2811           && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
2812         return 1;
2813       else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
2814                == curr_loop_pass_num)
2815         /* declaration has been processed.  */
2816         return 0;
2817       else
2818         {
2819           REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
2820             = curr_loop_pass_num;
2821           return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2822                                  start_decl);
2823         }
2824
2825     case rm_sequence:
2826       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2827         if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
2828           return 1;
2829       return 0;
2830
2831     case rm_allof:
2832       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2833         if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
2834           return 1;
2835       return 0;
2836
2837     case rm_oneof:
2838       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2839         if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
2840           return 1;
2841       return 0;
2842
2843     case rm_repeat:
2844       return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
2845
2846     case rm_nothing:
2847       return 0;
2848
2849     default:
2850       gcc_unreachable ();
2851     }
2852 }
2853
2854 /* The following function fixes errors "cycle in definition ...".  The
2855    function uses function `loop_in_regexp' for that.  */
2856 static void
2857 check_loops_in_regexps (void)
2858 {
2859   decl_t decl;
2860   int i;
2861
2862   for (i = 0; i < description->decls_num; i++)
2863     {
2864       decl = description->decls [i];
2865       if (decl->mode == dm_reserv)
2866         DECL_RESERV (decl)->loop_pass_num = 0;
2867     }
2868   for (i = 0; i < description->decls_num; i++)
2869     {
2870       decl = description->decls [i];
2871       curr_loop_pass_num = i;
2872
2873       if (decl->mode == dm_reserv)
2874           {
2875             DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
2876             if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
2877               {
2878                 gcc_assert (DECL_RESERV (decl)->regexp);
2879                 error ("cycle in definition of reservation `%s'",
2880                        DECL_RESERV (decl)->name);
2881               }
2882           }
2883     }
2884 }
2885
2886 /* The function recursively processes IR of reservation and defines
2887    max and min cycle for reservation of unit.  */
2888 static void
2889 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
2890                        int min_start_cycle, int *max_finish_cycle,
2891                        int *min_finish_cycle)
2892 {
2893   int i;
2894
2895   switch (regexp->mode)
2896     {
2897     case rm_unit:
2898       if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
2899         REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
2900       if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
2901           || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
2902         REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
2903       *max_finish_cycle = max_start_cycle;
2904       *min_finish_cycle = min_start_cycle;
2905       break;
2906
2907     case rm_reserv:
2908       process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2909                              max_start_cycle, min_start_cycle,
2910                              max_finish_cycle, min_finish_cycle);
2911       break;
2912
2913     case rm_repeat:
2914       for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
2915         {
2916           process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
2917                                  max_start_cycle, min_start_cycle,
2918                                  max_finish_cycle, min_finish_cycle);
2919           max_start_cycle = *max_finish_cycle + 1;
2920           min_start_cycle = *min_finish_cycle + 1;
2921         }
2922       break;
2923
2924     case rm_sequence:
2925       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2926         {
2927           process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
2928                                  max_start_cycle, min_start_cycle,
2929                                  max_finish_cycle, min_finish_cycle);
2930           max_start_cycle = *max_finish_cycle + 1;
2931           min_start_cycle = *min_finish_cycle + 1;
2932         }
2933       break;
2934
2935     case rm_allof:
2936       {
2937         int max_cycle = 0;
2938         int min_cycle = 0;
2939
2940         for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2941           {
2942             process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
2943                                    max_start_cycle, min_start_cycle,
2944                                    max_finish_cycle, min_finish_cycle);
2945             if (max_cycle < *max_finish_cycle)
2946               max_cycle = *max_finish_cycle;
2947             if (i == 0 || min_cycle > *min_finish_cycle)
2948               min_cycle = *min_finish_cycle;
2949           }
2950         *max_finish_cycle = max_cycle;
2951         *min_finish_cycle = min_cycle;
2952       }
2953       break;
2954
2955     case rm_oneof:
2956       {
2957         int max_cycle = 0;
2958         int min_cycle = 0;
2959
2960         for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2961           {
2962             process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
2963                                    max_start_cycle, min_start_cycle,
2964                                    max_finish_cycle, min_finish_cycle);
2965             if (max_cycle < *max_finish_cycle)
2966               max_cycle = *max_finish_cycle;
2967             if (i == 0 || min_cycle > *min_finish_cycle)
2968               min_cycle = *min_finish_cycle;
2969           }
2970         *max_finish_cycle = max_cycle;
2971         *min_finish_cycle = min_cycle;
2972       }
2973       break;
2974
2975     case rm_nothing:
2976       *max_finish_cycle = max_start_cycle;
2977       *min_finish_cycle = min_start_cycle;
2978       break;
2979
2980     default:
2981       gcc_unreachable ();
2982     }
2983 }
2984
2985 /* The following function is called only for correct program.  The
2986    function defines max reservation of insns in cycles.  */
2987 static void
2988 evaluate_max_reserv_cycles (void)
2989 {
2990   int max_insn_cycles_num;
2991   int min_insn_cycles_num;
2992   decl_t decl;
2993   int i;
2994
2995   description->max_insn_reserv_cycles = 0;
2996   for (i = 0; i < description->decls_num; i++)
2997     {
2998       decl = description->decls [i];
2999       if (decl->mode == dm_insn_reserv)
3000       {
3001         process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3002                                &max_insn_cycles_num, &min_insn_cycles_num);
3003         if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3004           description->max_insn_reserv_cycles = max_insn_cycles_num;
3005       }
3006     }
3007   description->max_insn_reserv_cycles++;
3008 }
3009
3010 /* The following function calls functions for checking all
3011    description.  */
3012 static void
3013 check_all_description (void)
3014 {
3015   process_decls ();
3016   check_automaton_usage ();
3017   process_regexp_decls ();
3018   check_usage ();
3019   check_loops_in_regexps ();
3020   if (!have_error)
3021     evaluate_max_reserv_cycles ();
3022 }
3023
3024 \f
3025
3026 /* The page contains abstract data `ticker'.  This data is used to
3027    report time of different phases of building automata.  It is
3028    possibly to write a description for which automata will be built
3029    during several minutes even on fast machine.  */
3030
3031 /* The following function creates ticker and makes it active.  */
3032 static ticker_t
3033 create_ticker (void)
3034 {
3035   ticker_t ticker;
3036
3037   ticker.modified_creation_time = get_run_time ();
3038   ticker.incremented_off_time = 0;
3039   return ticker;
3040 }
3041
3042 /* The following function switches off given ticker.  */
3043 static void
3044 ticker_off (ticker_t *ticker)
3045 {
3046   if (ticker->incremented_off_time == 0)
3047     ticker->incremented_off_time = get_run_time () + 1;
3048 }
3049
3050 /* The following function switches on given ticker.  */
3051 static void
3052 ticker_on (ticker_t *ticker)
3053 {
3054   if (ticker->incremented_off_time != 0)
3055     {
3056       ticker->modified_creation_time
3057         += get_run_time () - ticker->incremented_off_time + 1;
3058       ticker->incremented_off_time = 0;
3059     }
3060 }
3061
3062 /* The following function returns current time in milliseconds since
3063    the moment when given ticker was created.  */
3064 static int
3065 active_time (ticker_t ticker)
3066 {
3067   if (ticker.incremented_off_time != 0)
3068     return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3069   else
3070     return get_run_time () - ticker.modified_creation_time;
3071 }
3072
3073 /* The following function returns string representation of active time
3074    of given ticker.  The result is string representation of seconds
3075    with accuracy of 1/100 second.  Only result of the last call of the
3076    function exists.  Therefore the following code is not correct
3077
3078       printf ("parser time: %s\ngeneration time: %s\n",
3079               active_time_string (parser_ticker),
3080               active_time_string (generation_ticker));
3081
3082    Correct code has to be the following
3083
3084       printf ("parser time: %s\n", active_time_string (parser_ticker));
3085       printf ("generation time: %s\n",
3086               active_time_string (generation_ticker));
3087
3088 */
3089 static void
3090 print_active_time (FILE *f, ticker_t ticker)
3091 {
3092   int msecs;
3093
3094   msecs = active_time (ticker);
3095   fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3096 }
3097
3098 \f
3099
3100 /* The following variable value is number of automaton which are
3101    really being created.  This value is defined on the base of
3102    argument of option `-split'.  If the variable has zero value the
3103    number of automata is defined by the constructions `%automaton'.
3104    This case occurs when option `-split' is absent or has zero
3105    argument.  If constructions `define_automaton' is absent only one
3106    automaton is created.  */
3107 static int automata_num;
3108
3109 /* The following variable values are times of
3110        o transformation of regular expressions
3111        o building NDFA (DFA if !ndfa_flag)
3112        o NDFA -> DFA   (simply the same automaton if !ndfa_flag)
3113        o DFA minimization
3114        o building insn equivalence classes
3115        o all previous ones
3116        o code output */
3117 static ticker_t transform_time;
3118 static ticker_t NDFA_time;
3119 static ticker_t NDFA_to_DFA_time;
3120 static ticker_t minimize_time;
3121 static ticker_t equiv_time;
3122 static ticker_t automaton_generation_time;
3123 static ticker_t output_time;
3124
3125 /* The following variable values are times of
3126        all checking
3127        all generation
3128        all pipeline hazard translator work */
3129 static ticker_t check_time;
3130 static ticker_t generation_time;
3131 static ticker_t all_time;
3132
3133 \f
3134
3135 /* Pseudo insn decl which denotes advancing cycle.  */
3136 static decl_t advance_cycle_insn_decl;
3137 static void
3138 add_advance_cycle_insn_decl (void)
3139 {
3140   advance_cycle_insn_decl = XCREATENODE (struct decl);
3141   advance_cycle_insn_decl->mode = dm_insn_reserv;
3142   advance_cycle_insn_decl->pos = no_pos;
3143   DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3144   DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
3145   DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3146     = description->insns_num;
3147   description->decls [description->decls_num] = advance_cycle_insn_decl;
3148   description->decls_num++;
3149   description->insns_num++;
3150 }
3151
3152 \f
3153 /* Abstract data `alternative states' which represents
3154    nondeterministic nature of the description (see comments for
3155    structures alt_state and state).  */
3156
3157 /* List of free states.  */
3158 static alt_state_t first_free_alt_state;
3159
3160 #ifndef NDEBUG
3161 /* The following variables is maximal number of allocated nodes
3162    alt_state.  */
3163 static int allocated_alt_states_num = 0;
3164 #endif
3165
3166 /* The following function returns free node alt_state.  It may be new
3167    allocated node or node freed earlier.  */
3168 static alt_state_t
3169 get_free_alt_state (void)
3170 {
3171   alt_state_t result;
3172
3173   if (first_free_alt_state != NULL)
3174     {
3175       result = first_free_alt_state;
3176       first_free_alt_state = first_free_alt_state->next_alt_state;
3177     }
3178   else
3179     {
3180 #ifndef NDEBUG
3181       allocated_alt_states_num++;
3182 #endif
3183       result = XCREATENODE (struct alt_state);
3184     }
3185   result->state = NULL;
3186   result->next_alt_state = NULL;
3187   result->next_sorted_alt_state = NULL;
3188   return result;
3189 }
3190
3191 /* The function frees node ALT_STATE.  */
3192 static void
3193 free_alt_state (alt_state_t alt_state)
3194 {
3195   if (alt_state == NULL)
3196     return;
3197   alt_state->next_alt_state = first_free_alt_state;
3198   first_free_alt_state = alt_state;
3199 }
3200
3201 /* The function frees list started with node ALT_STATE_LIST.  */
3202 static void
3203 free_alt_states (alt_state_t alt_states_list)
3204 {
3205   alt_state_t curr_alt_state;
3206   alt_state_t next_alt_state;
3207
3208   for (curr_alt_state = alt_states_list;
3209        curr_alt_state != NULL;
3210        curr_alt_state = next_alt_state)
3211     {
3212       next_alt_state = curr_alt_state->next_alt_state;
3213       free_alt_state (curr_alt_state);
3214     }
3215 }
3216
3217 /* The function compares unique numbers of alt states.  */
3218 static int
3219 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3220 {
3221   if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
3222       == (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
3223     return 0;
3224   else if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
3225            < (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
3226     return -1;
3227   else
3228     return 1;
3229 }
3230
3231 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3232    states from the list.  The comparison key is alt state unique
3233    number.  */
3234
3235 static alt_state_t
3236 uniq_sort_alt_states (alt_state_t alt_states_list)
3237 {
3238   alt_state_t curr_alt_state;
3239   VEC(alt_state_t, heap) *alt_states;
3240   size_t i;
3241   size_t prev_unique_state_ind;
3242   alt_state_t result;
3243
3244   if (alt_states_list == 0)
3245     return 0;
3246   if (alt_states_list->next_alt_state == 0)
3247     return alt_states_list;
3248
3249   alt_states = VEC_alloc (alt_state_t, heap, 150);
3250   for (curr_alt_state = alt_states_list;
3251        curr_alt_state != NULL;
3252        curr_alt_state = curr_alt_state->next_alt_state)
3253     VEC_safe_push (alt_state_t, heap, alt_states, curr_alt_state);
3254
3255   VEC_qsort (alt_state_t, alt_states, alt_state_cmp);
3256
3257   prev_unique_state_ind = 0;
3258   for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3259     if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
3260         != VEC_index (alt_state_t, alt_states, i)->state)
3261       {
3262         prev_unique_state_ind++;
3263         VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
3264                      VEC_index (alt_state_t, alt_states, i));
3265       }
3266   VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
3267
3268   for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3269     VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
3270       = VEC_index (alt_state_t, alt_states, i);
3271   VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
3272
3273   result = VEC_index (alt_state_t, alt_states, 0);
3274
3275   VEC_free (alt_state_t, heap, alt_states);
3276   return result;
3277 }
3278
3279 /* The function checks equality of alt state lists.  Remember that the
3280    lists must be already sorted by the previous function.  */
3281 static int
3282 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3283 {
3284   while (alt_states_1 != NULL && alt_states_2 != NULL
3285          && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3286     {
3287       alt_states_1 = alt_states_1->next_sorted_alt_state;
3288       alt_states_2 = alt_states_2->next_sorted_alt_state;
3289     }
3290   return alt_states_1 == alt_states_2;
3291 }
3292
3293 /* Initialization of the abstract data.  */
3294 static void
3295 initiate_alt_states (void)
3296 {
3297   first_free_alt_state = NULL;
3298 }
3299
3300 /* Finishing work with the abstract data.  */
3301 static void
3302 finish_alt_states (void)
3303 {
3304 }
3305
3306 \f
3307
3308 /* The page contains macros for work with bits strings.  We could use
3309    standard gcc bitmap or sbitmap but it would result in difficulties
3310    of building canadian cross.  */
3311
3312 /* Set bit number bitno in the bit string.  The macro is not side
3313    effect proof.  */
3314 #define SET_BIT(bitstring, bitno)                                         \
3315   ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |=           \
3316         (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))
3317
3318 #define CLEAR_BIT(bitstring, bitno)                                       \
3319   ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &=           \
3320         ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)))
3321
3322 /* Test if bit number bitno in the bitstring is set.  The macro is not
3323    side effect proof.  */
3324 #define TEST_BIT(bitstring, bitno)                                        \
3325   ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >>           \
3326         (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
3327
3328 \f
3329
3330 /* This page contains abstract data `state'.  */
3331
3332 /* Maximal length of reservations in cycles (>= 1).  */
3333 static int max_cycles_num;
3334
3335 /* Number of set elements (see type set_el_t) needed for
3336    representation of one cycle reservation.  It is depended on units
3337    number.  */
3338 static int els_in_cycle_reserv;
3339
3340 /* Number of set elements (see type set_el_t) needed for
3341    representation of maximal length reservation.  Deterministic
3342    reservation is stored as set (bit string) of length equal to the
3343    variable value * number of bits in set_el_t.  */
3344 static int els_in_reservs;
3345
3346 /* Array of pointers to unit declarations.  */
3347 static unit_decl_t *units_array;
3348
3349 /* Temporary reservation of maximal length.  */
3350 static reserv_sets_t temp_reserv;
3351
3352 /* The state table itself is represented by the following variable.  */
3353 static htab_t state_table;
3354
3355 /* Linked list of free 'state' structures to be recycled.  The
3356    next_equiv_class_state pointer is borrowed for a free list.  */
3357 static state_t first_free_state;
3358
3359 static int curr_unique_state_num;
3360
3361 #ifndef NDEBUG
3362 /* The following variables is maximal number of allocated nodes
3363    `state'.  */
3364 static int allocated_states_num = 0;
3365 #endif
3366
3367 /* Allocate new reservation set.  */
3368 static reserv_sets_t
3369 alloc_empty_reserv_sets (void)
3370 {
3371   reserv_sets_t result;
3372
3373   obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3374   result = (reserv_sets_t) obstack_base (&irp);
3375   obstack_finish (&irp);
3376   memset (result, 0, els_in_reservs * sizeof (set_el_t));
3377   return result;
3378 }
3379
3380 /* Hash value of reservation set.  */
3381 static unsigned
3382 reserv_sets_hash_value (reserv_sets_t reservs)
3383 {
3384   set_el_t hash_value;
3385   unsigned result;
3386   int reservs_num, i;
3387   set_el_t *reserv_ptr;
3388
3389   hash_value = 0;
3390   reservs_num = els_in_reservs;
3391   reserv_ptr = reservs;
3392   i = 0;
3393   while (reservs_num != 0)
3394     {
3395       reservs_num--;
3396       hash_value += ((*reserv_ptr >> i)
3397                      | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3398       i++;
3399       if (i == sizeof (set_el_t) * CHAR_BIT)
3400         i = 0;
3401       reserv_ptr++;
3402     }
3403   if (sizeof (set_el_t) <= sizeof (unsigned))
3404     return hash_value;
3405   result = 0;
3406   for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3407     {
3408       result += (unsigned) hash_value;
3409       hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3410     }
3411   return result;
3412 }
3413
3414 /* Comparison of given reservation sets.  */
3415 static int
3416 reserv_sets_cmp (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
3417 {
3418   int reservs_num;
3419   const set_el_t *reserv_ptr_1;
3420   const set_el_t *reserv_ptr_2;
3421
3422   gcc_assert (reservs_1 && reservs_2);
3423   reservs_num = els_in_reservs;
3424   reserv_ptr_1 = reservs_1;
3425   reserv_ptr_2 = reservs_2;
3426   while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3427     {
3428       reservs_num--;
3429       reserv_ptr_1++;
3430       reserv_ptr_2++;
3431     }
3432   if (reservs_num == 0)
3433     return 0;
3434   else if (*reserv_ptr_1 < *reserv_ptr_2)
3435     return -1;
3436   else
3437     return 1;
3438 }
3439
3440 /* The function checks equality of the reservation sets.  */
3441 static int
3442 reserv_sets_eq (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
3443 {
3444   return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3445 }
3446
3447 /* Set up in the reservation set that unit with UNIT_NUM is used on
3448    CYCLE_NUM.  */
3449 static void
3450 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3451 {
3452   gcc_assert (cycle_num < max_cycles_num);
3453   SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3454            * sizeof (set_el_t) * CHAR_BIT + unit_num);
3455 }
3456
3457 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3458    used on CYCLE_NUM.  */
3459 static int
3460 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3461 {
3462   gcc_assert (cycle_num < max_cycles_num);
3463   return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3464                    * sizeof (set_el_t) * CHAR_BIT + unit_num);
3465 }
3466
3467 /* The function checks that the reservation sets are intersected,
3468    i.e. there is a unit reservation on a cycle in both reservation
3469    sets.  */
3470 static int
3471 reserv_sets_are_intersected (reserv_sets_t operand_1,
3472                              reserv_sets_t operand_2)
3473 {
3474   set_el_t *el_ptr_1;
3475   set_el_t *el_ptr_2;
3476   set_el_t *cycle_ptr_1;
3477   set_el_t *cycle_ptr_2;
3478
3479   gcc_assert (operand_1 && operand_2);
3480   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3481        el_ptr_1 < operand_1 + els_in_reservs;
3482        el_ptr_1++, el_ptr_2++)
3483     if (*el_ptr_1 & *el_ptr_2)
3484       return 1;
3485   reserv_sets_or (temp_reserv, operand_1, operand_2);
3486   for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3487        cycle_ptr_1 < operand_1 + els_in_reservs;
3488        cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3489     {
3490       for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3491            el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3492            el_ptr_1++, el_ptr_2++)
3493         if (*el_ptr_1 & *el_ptr_2)
3494           return 1;
3495       if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3496         return 1;
3497       if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3498                                                        - operand_2),
3499                                         cycle_ptr_2, TRUE))
3500         return 1;
3501       if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3502         return 1;
3503       if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3504                                        cycle_ptr_2, TRUE))
3505         return 1;
3506     }
3507   return 0;
3508 }
3509
3510 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3511    cpu cycle.  The remaining bits of OPERAND (representing the last
3512    cycle unit reservations) are not changed.  */
3513 static void
3514 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3515 {
3516   int i;
3517
3518   gcc_assert (result && operand && result != operand);
3519   for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3520     result [i - els_in_cycle_reserv] = operand [i];
3521 }
3522
3523 /* OR of the reservation sets.  */
3524 static void
3525 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3526                 reserv_sets_t operand_2)
3527 {
3528   set_el_t *el_ptr_1;
3529   set_el_t *el_ptr_2;
3530   set_el_t *result_set_el_ptr;
3531
3532   gcc_assert (result && operand_1 && operand_2);
3533   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3534        el_ptr_1 < operand_1 + els_in_reservs;
3535        el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3536     *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3537 }
3538
3539 /* AND of the reservation sets.  */
3540 static void
3541 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3542                 reserv_sets_t operand_2)
3543 {
3544   set_el_t *el_ptr_1;
3545   set_el_t *el_ptr_2;
3546   set_el_t *result_set_el_ptr;
3547
3548   gcc_assert (result && operand_1 && operand_2);
3549   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3550        el_ptr_1 < operand_1 + els_in_reservs;
3551        el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3552     *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3553 }
3554
3555 /* The function outputs string representation of units reservation on
3556    cycle START_CYCLE in the reservation set.  The function uses repeat
3557    construction if REPETITION_NUM > 1.  */
3558 static void
3559 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3560                       int repetition_num)
3561 {
3562   int unit_num;
3563   int reserved_units_num;
3564
3565   reserved_units_num = 0;
3566   for (unit_num = 0; unit_num < description->units_num; unit_num++)
3567     if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3568                   * sizeof (set_el_t) * CHAR_BIT + unit_num))
3569       reserved_units_num++;
3570   gcc_assert (repetition_num > 0);
3571   if (repetition_num != 1 && reserved_units_num > 1)
3572     fprintf (f, "(");
3573   reserved_units_num = 0;
3574   for (unit_num = 0;
3575        unit_num < description->units_num;
3576        unit_num++)
3577     if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3578                   * sizeof (set_el_t) * CHAR_BIT + unit_num))
3579       {
3580         if (reserved_units_num != 0)
3581           fprintf (f, "+");
3582         reserved_units_num++;
3583         fprintf (f, "%s", units_array [unit_num]->name);
3584       }
3585   if (reserved_units_num == 0)
3586     fprintf (f, NOTHING_NAME);
3587   gcc_assert (repetition_num > 0);
3588   if (repetition_num != 1 && reserved_units_num > 1)
3589     fprintf (f, ")");
3590   if (repetition_num != 1)
3591     fprintf (f, "*%d", repetition_num);
3592 }
3593
3594 /* The function outputs string representation of units reservation in
3595    the reservation set.  */
3596 static void
3597 output_reserv_sets (FILE *f, reserv_sets_t reservs)
3598 {
3599   int start_cycle = 0;
3600   int cycle;
3601   int repetition_num;
3602
3603   repetition_num = 0;
3604   for (cycle = 0; cycle < max_cycles_num; cycle++)
3605     if (repetition_num == 0)
3606       {
3607         repetition_num++;
3608         start_cycle = cycle;
3609       }
3610     else if (memcmp
3611              ((char *) reservs + start_cycle * els_in_cycle_reserv
3612               * sizeof (set_el_t),
3613               (char *) reservs + cycle * els_in_cycle_reserv
3614               * sizeof (set_el_t),
3615               els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3616       repetition_num++;
3617     else
3618       {
3619         if (start_cycle != 0)
3620           fprintf (f, ", ");
3621         output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3622         repetition_num = 1;
3623         start_cycle = cycle;
3624       }
3625   if (start_cycle < max_cycles_num)
3626     {
3627       if (start_cycle != 0)
3628         fprintf (f, ", ");
3629       output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3630     }
3631 }
3632
3633 /* The following function returns free node state for AUTOMATON.  It
3634    may be new allocated node or node freed earlier.  The function also
3635    allocates reservation set if WITH_RESERVS has nonzero value.  */
3636 static state_t
3637 get_free_state (int with_reservs, automaton_t automaton)
3638 {
3639   state_t result;
3640
3641   gcc_assert (max_cycles_num > 0 && automaton);
3642   if (first_free_state)
3643     {
3644       result = first_free_state;
3645       first_free_state = result->next_equiv_class_state;
3646
3647       result->next_equiv_class_state = NULL;
3648       result->automaton = automaton;
3649       result->first_out_arc = NULL;
3650       result->it_was_placed_in_stack_for_NDFA_forming = 0;
3651       result->it_was_placed_in_stack_for_DFA_forming = 0;
3652       result->component_states = NULL;
3653     }
3654   else
3655     {
3656 #ifndef NDEBUG
3657       allocated_states_num++;
3658 #endif
3659       result = XCREATENODE (struct state);
3660       result->automaton = automaton;
3661       result->first_out_arc = NULL;
3662       result->unique_num = curr_unique_state_num;
3663       curr_unique_state_num++;
3664     }
3665   if (with_reservs)
3666     {
3667       if (result->reservs == NULL)
3668         result->reservs = alloc_empty_reserv_sets ();
3669       else
3670         memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3671     }
3672   return result;
3673 }
3674
3675 /* The function frees node STATE.  */
3676 static void
3677 free_state (state_t state)
3678 {
3679   free_alt_states (state->component_states);
3680   state->next_equiv_class_state = first_free_state;
3681   first_free_state = state;
3682 }
3683
3684 /* Hash value of STATE.  If STATE represents deterministic state it is
3685    simply hash value of the corresponding reservation set.  Otherwise
3686    it is formed from hash values of the component deterministic
3687    states.  One more key is order number of state automaton.  */
3688 static hashval_t
3689 state_hash (const void *state)
3690 {
3691   unsigned int hash_value;
3692   alt_state_t alt_state;
3693
3694   if (((const_state_t) state)->component_states == NULL)
3695     hash_value = reserv_sets_hash_value (((const_state_t) state)->reservs);
3696   else
3697     {
3698       hash_value = 0;
3699       for (alt_state = ((const_state_t) state)->component_states;
3700            alt_state != NULL;
3701            alt_state = alt_state->next_sorted_alt_state)
3702         hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3703                        | (hash_value << CHAR_BIT))
3704                       + alt_state->state->unique_num);
3705     }
3706   hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3707                  | (hash_value << CHAR_BIT))
3708                 + ((const_state_t) state)->automaton->automaton_order_num);
3709   return hash_value;
3710 }
3711
3712 /* Return nonzero value if the states are the same.  */
3713 static int
3714 state_eq_p (const void *state_1, const void *state_2)
3715 {
3716   alt_state_t alt_state_1;
3717   alt_state_t alt_state_2;
3718
3719   if (((const_state_t) state_1)->automaton != ((const_state_t) state_2)->automaton)
3720     return 0;
3721   else if (((const_state_t) state_1)->component_states == NULL
3722            && ((const_state_t) state_2)->component_states == NULL)
3723     return reserv_sets_eq (((const_state_t) state_1)->reservs,
3724                            ((const_state_t) state_2)->reservs);
3725   else if (((const_state_t) state_1)->component_states != NULL
3726            && ((const_state_t) state_2)->component_states != NULL)
3727     {
3728       for (alt_state_1 = ((const_state_t) state_1)->component_states,
3729            alt_state_2 = ((const_state_t) state_2)->component_states;
3730            alt_state_1 != NULL && alt_state_2 != NULL;
3731            alt_state_1 = alt_state_1->next_sorted_alt_state,
3732            alt_state_2 = alt_state_2->next_sorted_alt_state)
3733         /* All state in the list must be already in the hash table.
3734            Also the lists must be sorted.  */
3735         if (alt_state_1->state != alt_state_2->state)
3736           return 0;
3737       return alt_state_1 == alt_state_2;
3738     }
3739   else
3740     return 0;
3741 }
3742
3743 /* Insert STATE into the state table.  */
3744 static state_t
3745 insert_state (state_t state)
3746 {
3747   void **entry_ptr;
3748
3749   entry_ptr = htab_find_slot (state_table, (void *) state, INSERT);
3750   if (*entry_ptr == NULL)
3751     *entry_ptr = (void *) state;
3752   return (state_t) *entry_ptr;
3753 }
3754
3755 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3756    deterministic STATE.  */
3757 static void
3758 set_state_reserv (state_t state, int cycle_num, int unit_num)
3759 {
3760   set_unit_reserv (state->reservs, cycle_num, unit_num);
3761 }
3762
3763 /* Return nonzero value if the deterministic states contains a
3764    reservation of the same cpu unit on the same cpu cycle.  */
3765 static int
3766 intersected_state_reservs_p (state_t state1, state_t state2)
3767 {
3768   gcc_assert (state1->automaton == state2->automaton);
3769   return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3770 }
3771
3772 /* Return deterministic state (inserted into the table) which
3773    representing the automaton state which is union of reservations of
3774    the deterministic states masked by RESERVS.  */
3775 static state_t
3776 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
3777 {
3778   state_t result;
3779   state_t state_in_table;
3780
3781   gcc_assert (state1->automaton == state2->automaton);
3782   result = get_free_state (1, state1->automaton);
3783   reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
3784   reserv_sets_and (result->reservs, result->reservs, reservs);
3785   state_in_table = insert_state (result);
3786   if (result != state_in_table)
3787     {
3788       free_state (result);
3789       result = state_in_table;
3790     }
3791   return result;
3792 }
3793
3794 /* Return deterministic state (inserted into the table) which
3795    represent the automaton state is obtained from deterministic STATE
3796    by advancing cpu cycle and masking by RESERVS.  */
3797 static state_t
3798 state_shift (state_t state, reserv_sets_t reservs)
3799 {
3800   state_t result;
3801   state_t state_in_table;
3802
3803   result = get_free_state (1, state->automaton);
3804   reserv_sets_shift (result->reservs, state->reservs);
3805   reserv_sets_and (result->reservs, result->reservs, reservs);
3806   state_in_table = insert_state (result);
3807   if (result != state_in_table)
3808     {
3809       free_state (result);
3810       result = state_in_table;
3811     }
3812   return result;
3813 }
3814
3815 /* Initialization of the abstract data.  */
3816 static void
3817 initiate_states (void)
3818 {
3819   decl_t decl;
3820   int i;
3821
3822   if (description->units_num)
3823     units_array = XNEWVEC (unit_decl_t, description->units_num);
3824   else
3825     units_array = 0;
3826
3827   for (i = 0; i < description->decls_num; i++)
3828     {
3829       decl = description->decls [i];
3830       if (decl->mode == dm_unit)
3831         units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
3832     }
3833   max_cycles_num = description->max_insn_reserv_cycles;
3834   els_in_cycle_reserv
3835     = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3836        / (sizeof (set_el_t) * CHAR_BIT));
3837   els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3838   curr_unique_state_num = 0;
3839   initiate_alt_states ();
3840   state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3841   temp_reserv = alloc_empty_reserv_sets ();
3842 }
3843
3844 /* Finishing work with the abstract data.  */
3845 static void
3846 finish_states (void)
3847 {
3848   free (units_array);
3849   units_array = 0;
3850   htab_delete (state_table);
3851   first_free_state = NULL;
3852   finish_alt_states ();
3853 }
3854
3855 \f
3856
3857 /* Abstract data `arcs'.  */
3858
3859 /* List of free arcs.  */
3860 static arc_t first_free_arc;
3861
3862 #ifndef NDEBUG
3863 /* The following variables is maximal number of allocated nodes
3864    `arc'.  */
3865 static int allocated_arcs_num = 0;
3866 #endif
3867
3868 /* The function frees node ARC.  */
3869 static void
3870 free_arc (arc_t arc)
3871 {
3872   arc->next_out_arc = first_free_arc;
3873   first_free_arc = arc;
3874 }
3875
3876 /* The function removes and frees ARC staring from FROM_STATE.  */
3877 static void
3878 remove_arc (state_t from_state, arc_t arc)
3879 {
3880   arc_t prev_arc;
3881   arc_t curr_arc;
3882
3883   gcc_assert (arc);
3884   for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3885        curr_arc != NULL;
3886        prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3887     if (curr_arc == arc)
3888       break;
3889   gcc_assert (curr_arc);
3890   if (prev_arc == NULL)
3891     from_state->first_out_arc = arc->next_out_arc;
3892   else
3893     prev_arc->next_out_arc = arc->next_out_arc;
3894   from_state->num_out_arcs--;
3895   free_arc (arc);
3896 }
3897
3898 /* The functions returns arc with given characteristics (or NULL if
3899    the arc does not exist).  */
3900 static arc_t
3901 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
3902 {
3903   arc_t arc;
3904
3905   for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3906     if (arc->to_state == to_state && arc->insn == insn)
3907       return arc;
3908   return NULL;
3909 }
3910
3911 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN.
3912    The function returns added arc (or already existing arc).  */
3913 static arc_t
3914 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
3915 {
3916   arc_t new_arc;
3917
3918   new_arc = find_arc (from_state, to_state, ainsn);
3919   if (new_arc != NULL)
3920     return new_arc;
3921   if (first_free_arc == NULL)
3922     {
3923 #ifndef NDEBUG
3924       allocated_arcs_num++;
3925 #endif
3926       new_arc = XCREATENODE (struct arc);
3927       new_arc->to_state = NULL;
3928       new_arc->insn = NULL;
3929       new_arc->next_out_arc = NULL;
3930     }
3931   else
3932     {
3933       new_arc = first_free_arc;
3934       first_free_arc =  first_free_arc->next_out_arc;
3935     }
3936   new_arc->to_state = to_state;
3937   new_arc->insn = ainsn;
3938   ainsn->arc_exists_p = 1;
3939   new_arc->next_out_arc = from_state->first_out_arc;
3940   from_state->first_out_arc = new_arc;
3941   from_state->num_out_arcs++;
3942   new_arc->next_arc_marked_by_insn = NULL;
3943   return new_arc;
3944 }
3945
3946 /* The function returns the first arc starting from STATE.  */
3947 static arc_t
3948 first_out_arc (const_state_t state)
3949 {
3950   return state->first_out_arc;
3951 }
3952
3953 /* The function returns next out arc after ARC.  */
3954 static arc_t
3955 next_out_arc (arc_t arc)
3956 {
3957   return arc->next_out_arc;
3958 }
3959
3960 /* Initialization of the abstract data.  */
3961 static void
3962 initiate_arcs (void)
3963 {
3964   first_free_arc = NULL;
3965 }
3966
3967 /* Finishing work with the abstract data.  */
3968 static void
3969 finish_arcs (void)
3970 {
3971 }
3972
3973 \f
3974
3975 /* Abstract data `automata lists'.  */
3976
3977 /* List of free states.  */
3978 static automata_list_el_t first_free_automata_list_el;
3979
3980 /* The list being formed.  */
3981 static automata_list_el_t current_automata_list;
3982
3983 /* Hash table of automata lists.  */
3984 static htab_t automata_list_table;
3985
3986 /* The following function returns free automata list el.  It may be
3987    new allocated node or node freed earlier.  */
3988 static automata_list_el_t
3989 get_free_automata_list_el (void)
3990 {
3991   automata_list_el_t result;
3992
3993   if (first_free_automata_list_el != NULL)
3994     {
3995       result = first_free_automata_list_el;
3996       first_free_automata_list_el
3997         = first_free_automata_list_el->next_automata_list_el;
3998     }
3999   else
4000     result = XCREATENODE (struct automata_list_el);
4001   result->automaton = NULL;
4002   result->next_automata_list_el = NULL;
4003   return result;
4004 }
4005
4006 /* The function frees node AUTOMATA_LIST_EL.  */
4007 static void
4008 free_automata_list_el (automata_list_el_t automata_list_el)
4009 {
4010   if (automata_list_el == NULL)
4011     return;
4012   automata_list_el->next_automata_list_el = first_free_automata_list_el;
4013   first_free_automata_list_el = automata_list_el;
4014 }
4015
4016 /* The function frees list AUTOMATA_LIST.  */
4017 static void
4018 free_automata_list (automata_list_el_t automata_list)
4019 {
4020   automata_list_el_t curr_automata_list_el;
4021   automata_list_el_t next_automata_list_el;
4022
4023   for (curr_automata_list_el = automata_list;
4024        curr_automata_list_el != NULL;
4025        curr_automata_list_el = next_automata_list_el)
4026     {
4027       next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4028       free_automata_list_el (curr_automata_list_el);
4029     }
4030 }
4031
4032 /* Hash value of AUTOMATA_LIST.  */
4033 static hashval_t
4034 automata_list_hash (const void *automata_list)
4035 {
4036   unsigned int hash_value;
4037   const_automata_list_el_t curr_automata_list_el;
4038
4039   hash_value = 0;
4040   for (curr_automata_list_el = (const_automata_list_el_t) automata_list;
4041        curr_automata_list_el != NULL;
4042        curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4043     hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4044                    | (hash_value << CHAR_BIT))
4045                   + curr_automata_list_el->automaton->automaton_order_num);
4046   return hash_value;
4047 }
4048
4049 /* Return nonzero value if the automata_lists are the same.  */
4050 static int
4051 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4052 {
4053   const_automata_list_el_t automata_list_el_1;
4054   const_automata_list_el_t automata_list_el_2;
4055
4056   for (automata_list_el_1 = (const_automata_list_el_t) automata_list_1,
4057          automata_list_el_2 = (const_automata_list_el_t) automata_list_2;
4058        automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4059        automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4060          automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4061     if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4062       return 0;
4063   return automata_list_el_1 == automata_list_el_2;
4064 }
4065
4066 /* Initialization of the abstract data.  */
4067 static void
4068 initiate_automata_lists (void)
4069 {
4070   first_free_automata_list_el = NULL;
4071   automata_list_table = htab_create (1500, automata_list_hash,
4072                                      automata_list_eq_p, (htab_del) 0);
4073 }
4074
4075 /* The following function starts new automata list and makes it the
4076    current one.  */
4077 static void
4078 automata_list_start (void)
4079 {
4080   current_automata_list = NULL;
4081 }
4082
4083 /* The following function adds AUTOMATON to the current list.  */
4084 static void
4085 automata_list_add (automaton_t automaton)
4086 {
4087   automata_list_el_t el;
4088
4089   el = get_free_automata_list_el ();
4090   el->automaton = automaton;
4091   el->next_automata_list_el = current_automata_list;
4092   current_automata_list = el;
4093 }
4094
4095 /* The following function finishes forming the current list, inserts
4096    it into the table and returns it.  */
4097 static automata_list_el_t
4098 automata_list_finish (void)
4099 {
4100   void **entry_ptr;
4101
4102   if (current_automata_list == NULL)
4103     return NULL;
4104   entry_ptr = htab_find_slot (automata_list_table,
4105                               (void *) current_automata_list, INSERT);
4106   if (*entry_ptr == NULL)
4107     *entry_ptr = (void *) current_automata_list;
4108   else
4109     free_automata_list (current_automata_list);
4110   current_automata_list = NULL;
4111   return (automata_list_el_t) *entry_ptr;
4112 }
4113
4114 /* Finishing work with the abstract data.  */
4115 static void
4116 finish_automata_lists (void)
4117 {
4118   htab_delete (automata_list_table);
4119 }
4120
4121 \f
4122
4123 /* The page contains abstract data for work with exclusion sets (see
4124    exclusion_set in file rtl.def).  */
4125
4126 /* The following variable refers to an exclusion set returned by
4127    get_excl_set.  This is bit string of length equal to cpu units
4128    number.  If exclusion set for given unit contains 1 for a unit,
4129    then simultaneous reservation of the units is prohibited.  */
4130 static reserv_sets_t excl_set;
4131
4132 /* The array contains exclusion sets for each unit.  */
4133 static reserv_sets_t *unit_excl_set_table;
4134
4135 /* The following function forms the array containing exclusion sets
4136    for each unit.  */
4137 static void
4138 initiate_excl_sets (void)
4139 {
4140   decl_t decl;
4141   reserv_sets_t unit_excl_set;
4142   unit_set_el_t el;
4143   int i;
4144
4145   obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4146   excl_set = (reserv_sets_t) obstack_base (&irp);
4147   obstack_finish (&irp);
4148   obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4149   unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4150   obstack_finish (&irp);
4151   /* Evaluate unit exclusion sets.  */
4152   for (i = 0; i < description->decls_num; i++)
4153     {
4154       decl = description->decls [i];
4155       if (decl->mode == dm_unit)
4156         {
4157           obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4158           unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4159           obstack_finish (&irp);
4160           memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4161           for (el = DECL_UNIT (decl)->excl_list;
4162                el != NULL;
4163                el = el->next_unit_set_el)
4164             {
4165               SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4166               el->unit_decl->in_set_p = TRUE;
4167             }
4168           unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4169         }
4170     }
4171 }
4172
4173 /* The function sets up and return EXCL_SET which is union of
4174    exclusion sets for each unit in IN_SET.  */
4175 static reserv_sets_t
4176 get_excl_set (reserv_sets_t in_set)
4177 {
4178   int el;
4179   unsigned int i;
4180   int start_unit_num;
4181   int unit_num;
4182
4183   memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4184   for (el = 0; el < els_in_cycle_reserv; el++)
4185     if (in_set[el])
4186       for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4187         if ((in_set[el] >> i) & 1)
4188           {
4189             start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
4190             if (start_unit_num >= description->units_num)
4191               return excl_set;
4192             for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4193               {
4194                 excl_set [unit_num]
4195                   |= unit_excl_set_table [start_unit_num] [unit_num];
4196               }
4197           }
4198   return excl_set;
4199 }
4200
4201 \f
4202
4203 /* The page contains abstract data for work with presence/absence
4204    pattern sets (see presence_set/absence_set in file rtl.def).  */
4205
4206 /* The following arrays contain correspondingly presence, final
4207    presence, absence, and final absence patterns for each unit.  */
4208 static pattern_reserv_t *unit_presence_set_table;
4209 static pattern_reserv_t *unit_final_presence_set_table;
4210 static pattern_reserv_t *unit_absence_set_table;
4211 static pattern_reserv_t *unit_final_absence_set_table;
4212
4213 /* The following function forms list of reservation sets for given
4214    PATTERN_LIST.  */
4215 static pattern_reserv_t
4216 form_reserv_sets_list (pattern_set_el_t pattern_list)
4217 {
4218   pattern_set_el_t el;
4219   pattern_reserv_t first, curr, prev;
4220   int i;
4221
4222   prev = first = NULL;
4223   for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4224     {
4225       curr = XCREATENODE (struct pattern_reserv);
4226       curr->reserv = alloc_empty_reserv_sets ();
4227       curr->next_pattern_reserv = NULL;
4228       for (i = 0; i < el->units_num; i++)
4229         {
4230           SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4231           el->unit_decls [i]->in_set_p = TRUE;
4232         }
4233       if (prev != NULL)
4234         prev->next_pattern_reserv = curr;
4235       else
4236         first = curr;
4237       prev = curr;
4238     }
4239   return first;
4240 }
4241
4242  /* The following function forms the array containing presence and
4243    absence pattern sets for each unit.  */
4244 static void
4245 initiate_presence_absence_pattern_sets (void)
4246 {
4247   decl_t decl;
4248   int i;
4249
4250   obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4251   unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4252   obstack_finish (&irp);
4253   obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4254   unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4255   obstack_finish (&irp);
4256   obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4257   unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4258   obstack_finish (&irp);
4259   obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4260   unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4261   obstack_finish (&irp);
4262   /* Evaluate unit presence/absence sets.  */
4263   for (i = 0; i < description->decls_num; i++)
4264     {
4265       decl = description->decls [i];
4266       if (decl->mode == dm_unit)
4267         {
4268           unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4269             = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4270           unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4271             = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4272           unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4273             = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4274           unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4275             = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4276         }
4277     }
4278 }
4279
4280 /* The function checks that CHECKED_SET satisfies all presence pattern
4281    sets for units in ORIGINAL_SET.  The function returns TRUE if it
4282    is ok.  */
4283 static int
4284 check_presence_pattern_sets (reserv_sets_t checked_set,
4285                              reserv_sets_t original_set,
4286                              int final_p)
4287 {
4288   int el;
4289   unsigned int i;
4290   int start_unit_num;
4291   int unit_num;
4292   int presence_p;
4293   pattern_reserv_t pat_reserv;
4294
4295   for (el = 0; el < els_in_cycle_reserv; el++)
4296     if (original_set[el])
4297       for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4298         if ((original_set[el] >> i) & 1)
4299           {
4300             start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
4301             if (start_unit_num >= description->units_num)
4302               break;
4303             if ((final_p
4304                  && unit_final_presence_set_table [start_unit_num] == NULL)
4305                 || (!final_p
4306                     && unit_presence_set_table [start_unit_num] == NULL))
4307               continue;
4308             presence_p = FALSE;
4309             for (pat_reserv = (final_p
4310                                ? unit_final_presence_set_table [start_unit_num]
4311                                : unit_presence_set_table [start_unit_num]);
4312                  pat_reserv != NULL;
4313                  pat_reserv = pat_reserv->next_pattern_reserv)
4314               {
4315                 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4316                   if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4317                       != pat_reserv->reserv [unit_num])
4318                     break;
4319                 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4320               }
4321             if (!presence_p)
4322               return FALSE;
4323           }
4324   return TRUE;
4325 }
4326
4327 /* The function checks that CHECKED_SET satisfies all absence pattern
4328    sets for units in ORIGINAL_SET.  The function returns TRUE if it
4329    is ok.  */
4330 static int
4331 check_absence_pattern_sets (reserv_sets_t checked_set,
4332                             reserv_sets_t original_set,
4333                             int final_p)
4334 {
4335   int el;
4336   unsigned int i;
4337   int start_unit_num;
4338   int unit_num;
4339   pattern_reserv_t pat_reserv;
4340
4341   for (el = 0; el < els_in_cycle_reserv; el++)
4342     if (original_set[el])
4343       for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4344         if ((original_set[el] >> i) & 1)
4345           {
4346             start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
4347             if (start_unit_num >= description->units_num)
4348               break;
4349             for (pat_reserv = (final_p
4350                                ? unit_final_absence_set_table [start_unit_num]
4351                                : unit_absence_set_table [start_unit_num]);
4352                  pat_reserv != NULL;
4353                  pat_reserv = pat_reserv->next_pattern_reserv)
4354               {
4355                 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4356                   if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4357                       != pat_reserv->reserv [unit_num]
4358                       && pat_reserv->reserv [unit_num])
4359                     break;
4360                 if (unit_num >= els_in_cycle_reserv)
4361                   return FALSE;
4362               }
4363           }
4364   return TRUE;
4365 }
4366
4367 \f
4368
4369 /* This page contains code for transformation of original reservations
4370    described in .md file.  The main goal of transformations is
4371    simplifying reservation and lifting up all `|' on the top of IR
4372    reservation representation.  */
4373
4374
4375 /* The following function makes copy of IR representation of
4376    reservation.  The function also substitutes all reservations
4377    defined by define_reservation by corresponding value during making
4378    the copy.  */
4379 static regexp_t
4380 copy_insn_regexp (regexp_t regexp)
4381 {
4382   regexp_t  result;
4383   int i;
4384
4385   switch (regexp->mode)
4386     {
4387     case rm_reserv:
4388       result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4389       break;
4390
4391     case rm_unit:
4392       result = XCOPYNODE (struct regexp, regexp);
4393       break;
4394
4395     case rm_repeat:
4396       result = XCOPYNODE (struct regexp, regexp);
4397       REGEXP_REPEAT (result)->regexp
4398         = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4399       break;
4400
4401     case rm_sequence:
4402       result = XCOPYNODEVAR (struct regexp, regexp,
4403                              sizeof (struct regexp) + sizeof (regexp_t)
4404                              * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4405       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4406         REGEXP_SEQUENCE (result)->regexps [i]
4407           = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4408       break;
4409
4410     case rm_allof:
4411       result = XCOPYNODEVAR (struct regexp, regexp,
4412                              sizeof (struct regexp) + sizeof (regexp_t)
4413                              * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4414       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4415         REGEXP_ALLOF (result)->regexps [i]
4416           = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4417       break;
4418
4419     case rm_oneof:
4420       result = XCOPYNODEVAR (struct regexp, regexp,
4421                              sizeof (struct regexp) + sizeof (regexp_t)
4422                              * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4423       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4424         REGEXP_ONEOF (result)->regexps [i]
4425           = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4426       break;
4427
4428     case rm_nothing:
4429       result = XCOPYNODE (struct regexp, regexp);
4430       break;
4431
4432     default:
4433       gcc_unreachable ();
4434     }
4435   return result;
4436 }
4437
4438 /* The following variable is set up 1 if a transformation has been
4439    applied.  */
4440 static int regexp_transformed_p;
4441
4442 /* The function makes transformation
4443    A*N -> A, A, ...  */
4444 static regexp_t
4445 transform_1 (regexp_t regexp)
4446 {
4447   int i;
4448   int repeat_num;
4449   regexp_t operand;
4450   pos_t pos;
4451
4452   if (regexp->mode == rm_repeat)
4453     {
4454       repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4455       gcc_assert (repeat_num > 1);
4456       operand = REGEXP_REPEAT (regexp)->regexp;
4457       pos = regexp->mode;
4458       regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4459                                + sizeof (regexp_t) * (repeat_num - 1));
4460       regexp->mode = rm_sequence;
4461       regexp->pos = pos;
4462       REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4463       for (i = 0; i < repeat_num; i++)
4464         REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4465       regexp_transformed_p = 1;
4466     }
4467   return regexp;
4468 }
4469
4470 /* The function makes transformations
4471    ...,(A,B,...),C,... -> ...,A,B,...,C,...
4472    ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4473    ...|(A|B|...)|C|... -> ...|A|B|...|C|...  */
4474 static regexp_t
4475 transform_2 (regexp_t regexp)
4476 {
4477   if (regexp->mode == rm_sequence)
4478     {
4479       regexp_t sequence = NULL;
4480       regexp_t result;
4481       int sequence_index = 0;
4482       int i, j;
4483
4484       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4485         if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4486           {
4487             sequence_index = i;
4488             sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4489             break;
4490           }
4491       if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4492         {
4493           gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4494                       && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4495           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4496                                    + sizeof (regexp_t)
4497                                    * (REGEXP_SEQUENCE (regexp)->regexps_num
4498                                       + REGEXP_SEQUENCE (sequence)->regexps_num
4499                                       - 2));
4500           result->mode = rm_sequence;
4501           result->pos = regexp->pos;
4502           REGEXP_SEQUENCE (result)->regexps_num
4503             = (REGEXP_SEQUENCE (regexp)->regexps_num
4504                + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4505           for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4506             if (i < sequence_index)
4507               REGEXP_SEQUENCE (result)->regexps [i]
4508                 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4509             else if (i > sequence_index)
4510               REGEXP_SEQUENCE (result)->regexps
4511                 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4512                 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4513             else
4514               for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4515                 REGEXP_SEQUENCE (result)->regexps [i + j]
4516                   = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4517           regexp_transformed_p = 1;
4518           regexp = result;
4519         }
4520     }
4521   else if (regexp->mode == rm_allof)
4522     {
4523       regexp_t allof = NULL;
4524       regexp_t result;
4525       int allof_index = 0;
4526       int i, j;
4527
4528       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4529         if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4530           {
4531             allof_index = i;
4532             allof = REGEXP_ALLOF (regexp)->regexps [i];
4533             break;
4534           }
4535       if (i < REGEXP_ALLOF (regexp)->regexps_num)
4536         {
4537           gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4538                       && REGEXP_ALLOF (regexp)->regexps_num > 1);
4539           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4540                                    + sizeof (regexp_t)
4541                                    * (REGEXP_ALLOF (regexp)->regexps_num
4542                                       + REGEXP_ALLOF (allof)->regexps_num - 2));
4543           result->mode = rm_allof;
4544           result->pos = regexp->pos;
4545           REGEXP_ALLOF (result)->regexps_num
4546             = (REGEXP_ALLOF (regexp)->regexps_num
4547                + REGEXP_ALLOF (allof)->regexps_num - 1);
4548           for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4549             if (i < allof_index)
4550               REGEXP_ALLOF (result)->regexps [i]
4551                 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4552             else if (i > allof_index)
4553               REGEXP_ALLOF (result)->regexps
4554                 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4555                 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4556             else
4557               for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4558                 REGEXP_ALLOF (result)->regexps [i + j]
4559                   = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4560           regexp_transformed_p = 1;
4561           regexp = result;
4562         }
4563     }
4564   else if (regexp->mode == rm_oneof)
4565     {
4566       regexp_t oneof = NULL;
4567       regexp_t result;
4568       int oneof_index = 0;
4569       int i, j;
4570
4571       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4572         if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4573           {
4574             oneof_index = i;
4575             oneof = REGEXP_ONEOF (regexp)->regexps [i];
4576             break;
4577           }
4578       if (i < REGEXP_ONEOF (regexp)->regexps_num)
4579         {
4580           gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4581                       && REGEXP_ONEOF (regexp)->regexps_num > 1);
4582           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4583                                    + sizeof (regexp_t)
4584                                    * (REGEXP_ONEOF (regexp)->regexps_num
4585                                       + REGEXP_ONEOF (oneof)->regexps_num - 2));
4586           result->mode = rm_oneof;
4587           result->pos = regexp->pos;
4588           REGEXP_ONEOF (result)->regexps_num
4589             = (REGEXP_ONEOF (regexp)->regexps_num
4590                + REGEXP_ONEOF (oneof)->regexps_num - 1);
4591           for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4592             if (i < oneof_index)
4593               REGEXP_ONEOF (result)->regexps [i]
4594                 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4595             else if (i > oneof_index)
4596               REGEXP_ONEOF (result)->regexps
4597                 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
4598                 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4599             else
4600               for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
4601                 REGEXP_ONEOF (result)->regexps [i + j]
4602                   = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
4603           regexp_transformed_p = 1;
4604           regexp = result;
4605         }
4606     }
4607   return regexp;
4608 }
4609
4610 /* The function makes transformations
4611    ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4612    ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4613    ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4614    ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),...  */
4615 static regexp_t
4616 transform_3 (regexp_t regexp)
4617 {
4618   if (regexp->mode == rm_sequence)
4619     {
4620       regexp_t oneof = NULL;
4621       int oneof_index = 0;
4622       regexp_t result;
4623       regexp_t sequence;
4624       int i, j;
4625
4626       for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4627         if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
4628           {
4629             oneof_index = i;
4630             oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
4631             break;
4632           }
4633       if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4634         {
4635           gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4636                       && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4637           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4638                                    + sizeof (regexp_t)
4639                                    * (REGEXP_ONEOF (oneof)->regexps_num - 1));
4640           result->mode = rm_oneof;
4641           result->pos = regexp->pos;
4642           REGEXP_ONEOF (result)->regexps_num
4643             = REGEXP_ONEOF (oneof)->regexps_num;
4644           for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
4645             {
4646               sequence
4647                 = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4648                                   + sizeof (regexp_t)
4649                                   * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4650               sequence->mode = rm_sequence;
4651               sequence->pos = regexp->pos;
4652               REGEXP_SEQUENCE (sequence)->regexps_num
4653                 = REGEXP_SEQUENCE (regexp)->regexps_num;
4654               REGEXP_ONEOF (result)->regexps [i] = sequence;
4655               for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4656                 if (j != oneof_index)
4657                   REGEXP_SEQUENCE (sequence)->regexps [j]
4658                     = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
4659                 else
4660                   REGEXP_SEQUENCE (sequence)->regexps [j]
4661                     = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
4662             }
4663           regexp_transformed_p = 1;
4664           regexp = result;
4665         }
4666     }
4667   else if (regexp->mode == rm_allof)
4668     {
4669       regexp_t oneof = NULL;
4670       regexp_t seq;
4671       int oneof_index = 0;
4672       int max_seq_length, allof_length;
4673       regexp_t result;
4674       regexp_t allof = NULL;
4675       regexp_t allof_op = NULL;
4676       int i, j;
4677
4678       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4679         if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
4680           {
4681             oneof_index = i;
4682             oneof = REGEXP_ALLOF (regexp)->regexps [i];
4683             break;
4684           }
4685       if (i < REGEXP_ALLOF (regexp)->regexps_num)
4686         {
4687           gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4688                       && REGEXP_ALLOF (regexp)->regexps_num > 1);
4689           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4690                                    + sizeof (regexp_t)
4691                                    * (REGEXP_ONEOF (oneof)->regexps_num - 1));
4692           result->mode = rm_oneof;
4693           result->pos = regexp->pos;
4694           REGEXP_ONEOF (result)->regexps_num
4695             = REGEXP_ONEOF (oneof)->regexps_num;
4696           for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
4697             {
4698               allof
4699                 = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4700                                   + sizeof (regexp_t)
4701                                   * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4702               allof->mode = rm_allof;
4703               allof->pos = regexp->pos;
4704               REGEXP_ALLOF (allof)->regexps_num
4705                 = REGEXP_ALLOF (regexp)->regexps_num;
4706               REGEXP_ONEOF (result)->regexps [i] = allof;
4707               for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4708                 if (j != oneof_index)
4709                   REGEXP_ALLOF (allof)->regexps [j]
4710                     = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
4711                 else
4712                   REGEXP_ALLOF (allof)->regexps [j]
4713                     = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
4714             }
4715           regexp_transformed_p = 1;
4716           regexp = result;
4717         }
4718       max_seq_length = 0;
4719       if (regexp->mode == rm_allof)
4720         for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4721           {
4722             switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
4723               {
4724               case rm_sequence:
4725                 seq = REGEXP_ALLOF (regexp)->regexps [i];
4726                 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
4727                   max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
4728                 break;
4729
4730               case rm_unit:
4731               case rm_nothing:
4732                 break;
4733
4734               default:
4735                 max_seq_length = 0;
4736                 goto break_for;
4737               }
4738           }
4739     break_for:
4740       if (max_seq_length != 0)
4741         {
4742           gcc_assert (max_seq_length != 1
4743                       && REGEXP_ALLOF (regexp)->regexps_num > 1);
4744           result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4745                                    + sizeof (regexp_t) * (max_seq_length - 1));
4746           result->mode = rm_sequence;
4747           result->pos = regexp->pos;
4748           REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
4749           for (i = 0; i < max_seq_length; i++)
4750             {
4751               allof_length = 0;
4752               for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
4753                 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
4754                   {
4755                   case rm_sequence:
4756                     if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4757                                               ->regexps [j])->regexps_num))
4758                       {
4759                         allof_op
4760                           = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4761                                               ->regexps [j])
4762                              ->regexps [i]);
4763                         allof_length++;
4764                       }
4765                     break;
4766                   case rm_unit:
4767                   case rm_nothing:
4768                     if (i == 0)
4769                       {
4770                         allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4771                         allof_length++;
4772                       }
4773                     break;
4774                   default:
4775                     break;
4776                   }
4777
4778               if (allof_length == 1)
4779                 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
4780               else
4781                 {
4782                   allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4783                                           + sizeof (regexp_t)
4784                                           * (allof_length - 1));
4785                   allof->mode = rm_allof;
4786                   allof->pos = regexp->pos;
4787                   REGEXP_ALLOF (allof)->regexps_num = allof_length;
4788                   REGEXP_SEQUENCE (result)->regexps [i] = allof;
4789                   allof_length = 0;
4790                   for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
4791                     if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
4792                         && (i <
4793                             (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4794                                               ->regexps [j])->regexps_num)))
4795                       {
4796                         allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4797                                                      ->regexps [j])
4798                                     ->regexps [i]);
4799                         REGEXP_ALLOF (allof)->regexps [allof_length]
4800                           = allof_op;
4801                         allof_length++;
4802                       }
4803                     else if (i == 0
4804                              && (REGEXP_ALLOF (regexp)->regexps [j]->mode
4805                                  == rm_unit
4806                                  || (REGEXP_ALLOF (regexp)->regexps [j]->mode
4807                                      == rm_nothing)))
4808                       {
4809                         allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4810                         REGEXP_ALLOF (allof)->regexps [allof_length]
4811                           = allof_op;
4812                         allof_length++;
4813                       }
4814                 }
4815             }
4816           regexp_transformed_p = 1;
4817           regexp = result;
4818         }
4819     }
4820   return regexp;
4821 }
4822
4823 /* The function traverses IR of reservation and applies transformations
4824    implemented by FUNC.  */
4825 static regexp_t
4826 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
4827 {
4828   int i;
4829
4830   switch (regexp->mode)
4831     {
4832     case rm_sequence:
4833       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4834         REGEXP_SEQUENCE (regexp)->regexps [i]
4835           = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
4836                                    func);
4837       break;
4838
4839     case rm_allof:
4840       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4841         REGEXP_ALLOF (regexp)->regexps [i]
4842           = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
4843       break;
4844
4845     case rm_oneof:
4846       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4847         REGEXP_ONEOF (regexp)->regexps [i]
4848           = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
4849       break;
4850
4851     case rm_repeat:
4852       REGEXP_REPEAT (regexp)->regexp
4853         = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
4854       break;
4855
4856     case rm_nothing:
4857     case rm_unit:
4858       break;
4859
4860     default:
4861       gcc_unreachable ();
4862     }
4863   return (*func) (regexp);
4864 }
4865
4866 /* The function applies all transformations for IR representation of
4867    reservation REGEXP.  */
4868 static regexp_t
4869 transform_regexp (regexp_t regexp)
4870 {
4871   regexp = regexp_transform_func (regexp, transform_1);
4872   do
4873     {
4874       regexp_transformed_p = 0;
4875       regexp = regexp_transform_func (regexp, transform_2);
4876       regexp = regexp_transform_func (regexp, transform_3);
4877     }
4878   while (regexp_transformed_p);
4879   return regexp;
4880 }
4881
4882 /* The function applies all transformations for reservations of all
4883    insn declarations.  */
4884 static void
4885 transform_insn_regexps (void)
4886 {
4887   decl_t decl;
4888   int i;
4889
4890   transform_time = create_ticker ();
4891   add_advance_cycle_insn_decl ();
4892   if (progress_flag)
4893     fprintf (stderr, "Reservation transformation...");
4894   for (i = 0; i < description->decls_num; i++)
4895     {
4896       decl = description->decls [i];
4897       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4898         DECL_INSN_RESERV (decl)->transformed_regexp
4899           = transform_regexp (copy_insn_regexp
4900                               (DECL_INSN_RESERV (decl)->regexp));
4901     }
4902   if (progress_flag)
4903     fprintf (stderr, "done\n");
4904   ticker_off (&transform_time);
4905 }
4906
4907 \f
4908
4909 /* The following variable value is TRUE if the first annotated message
4910    about units to automata distribution has been output.  */
4911 static int annotation_message_reported_p;
4912
4913 /* The vector contains all decls which are automata.  */
4914 static VEC(decl_t, heap) *automaton_decls;
4915
4916 /* The following structure describes usage of a unit in a reservation.  */
4917 struct unit_usage
4918 {
4919   unit_decl_t unit_decl;
4920   /* The following forms a list of units used on the same cycle in the
4921      same alternative.  The list is ordered by the correspdoning unit
4922      declarations and there is no unit declaration duplication in the
4923      list.  */
4924   struct unit_usage *next;
4925 };
4926 typedef struct unit_usage *unit_usage_t;
4927
4928 DEF_VEC_P(unit_usage_t);
4929 DEF_VEC_ALLOC_P(unit_usage_t, heap);
4930
4931 /* Obstack for unit_usage structures.  */
4932 static struct obstack unit_usages;
4933
4934 /* VLA for representation of array of pointers to unit usage
4935    structures.  There is an element for each combination of
4936    (alternative number, cycle).  Unit usages on given cycle in
4937    alternative with given number are referred through element with
4938    index equals to the cycle * number of all alternatives in the
4939    regexp + the alternative number.  */
4940 static VEC(unit_usage_t, heap) *cycle_alt_unit_usages;
4941
4942 /* The following function creates the structure unit_usage for UNIT on
4943    CYCLE in REGEXP alternative with ALT_NUM.  The structure is made
4944    accessed through cycle_alt_unit_usages.  */
4945 static void
4946 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
4947                       int alt_num)
4948 {
4949   size_t length;
4950   unit_decl_t unit_decl;
4951   unit_usage_t unit_usage_ptr, curr, prev;
4952   int index;
4953
4954   gcc_assert (regexp && regexp->mode == rm_oneof
4955               && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
4956   unit_decl = REGEXP_UNIT (unit)->unit_decl;
4957
4958   length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
4959   while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
4960     VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0);
4961
4962   index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
4963   prev = NULL;
4964   for (curr = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
4965        curr != NULL;
4966        prev = curr, curr = curr->next)
4967     if (curr->unit_decl >= unit_decl)
4968       break;
4969   if (curr != NULL && curr->unit_decl == unit_decl)
4970     return;
4971   obstack_blank (&unit_usages, sizeof (struct unit_usage));
4972   unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
4973   obstack_finish (&unit_usages);
4974   unit_usage_ptr->unit_decl = unit_decl;
4975   unit_decl->last_distribution_check_cycle = -1; /* undefined */
4976   unit_usage_ptr->next = curr;
4977   if (prev == NULL)
4978     VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
4979   else
4980     prev->next = unit_usage_ptr;
4981 }
4982
4983 /* Return true if unit UNIT_DECL is present on the LIST.  */
4984 static bool
4985 unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl)
4986 {
4987   while (list != NULL)
4988     {
4989       if (list->unit_decl == unit_decl)
4990         return true;
4991       list = list->next;
4992     }
4993   return false;
4994 }
4995
4996 /* The function returns true if reservations of alternatives ALT1 and
4997    ALT2 are equal after excluding reservations of units of
4998    EXCLUDED_AUTOMATON_DECL.  */
4999 static bool
5000 equal_alternatives_p (int alt1, int alt2, int n_alts,
5001                       struct automaton_decl *excluded_automaton_decl)
5002 {
5003   int i;
5004   unit_usage_t list1, list2;
5005
5006   for (i = 0;
5007        i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
5008        i += n_alts)
5009     {
5010       for (list1 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt1),
5011              list2 = VEC_index (unit_usage_t, cycle_alt_unit_usages, i + alt2);;
5012            list1 = list1->next, list2 = list2->next)
5013         {
5014           while (list1 != NULL
5015                  && list1->unit_decl->automaton_decl == excluded_automaton_decl)
5016             list1 = list1->next;
5017           while (list2 != NULL
5018                  && list2->unit_decl->automaton_decl == excluded_automaton_decl)
5019             list2 = list2->next;
5020           if (list1 == NULL || list2 == NULL)
5021             {
5022               if (list1 != list2)
5023                 return false;
5024               else
5025                 break;
5026             }
5027           if (list1->unit_decl != list2->unit_decl)
5028             return false;
5029         }
5030     }
5031   return true;
5032 }
5033
5034 DEF_VEC_I(int);
5035 DEF_VEC_ALLOC_I(int, heap);
5036
5037 /* The function processes given REGEXP to find units with the wrong
5038    distribution.  */
5039 static void
5040 check_regexp_units_distribution (const char *insn_reserv_name,
5041                                  regexp_t regexp)
5042 {
5043   int i, j, k, cycle, start, n_alts, alt, alt2;
5044   bool annotation_reservation_message_reported_p;
5045   regexp_t seq, allof, unit;
5046   struct unit_usage *unit_usage_ptr;
5047   VEC(int, heap) *marked;
5048
5049   if (regexp == NULL || regexp->mode != rm_oneof)
5050     return;
5051   /* Store all unit usages in the regexp:  */
5052   obstack_init (&unit_usages);
5053   cycle_alt_unit_usages = VEC_alloc (unit_usage_t, heap, 10);
5054
5055   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5056     {
5057       seq = REGEXP_ONEOF (regexp)->regexps [i];
5058       switch (seq->mode)
5059         {
5060         case rm_sequence:
5061           for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5062             {
5063               allof = REGEXP_SEQUENCE (seq)->regexps [j];
5064               switch (allof->mode)
5065                 {
5066                 case rm_allof:
5067                   for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5068                     {
5069                       unit = REGEXP_ALLOF (allof)->regexps [k];
5070                       if (unit->mode == rm_unit)
5071                         store_alt_unit_usage (regexp, unit, j, i);
5072                       else
5073                         gcc_assert (unit->mode == rm_nothing);
5074                     }
5075                   break;
5076
5077                 case rm_unit:
5078                   store_alt_unit_usage (regexp, allof, j, i);
5079                   break;
5080
5081                 case rm_nothing:
5082                   break;
5083
5084                 default:
5085                   gcc_unreachable ();
5086                 }
5087             }
5088           break;
5089
5090         case rm_allof:
5091           for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5092             {
5093               unit = REGEXP_ALLOF (seq)->regexps [k];
5094               switch (unit->mode)
5095                 {
5096                 case rm_unit:
5097                   store_alt_unit_usage (regexp, unit, 0, i);
5098                   break;
5099
5100                 case rm_nothing:
5101                   break;
5102
5103                 default:
5104                   gcc_unreachable ();
5105                 }
5106             }
5107           break;
5108
5109         case rm_unit:
5110           store_alt_unit_usage (regexp, seq, 0, i);
5111           break;
5112
5113         case rm_nothing:
5114           break;
5115
5116         default:
5117           gcc_unreachable ();
5118         }
5119     }
5120   /* Check distribution:  */
5121   for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
5122     for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
5123          unit_usage_ptr != NULL;
5124          unit_usage_ptr = unit_usage_ptr->next)
5125       unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
5126   n_alts = REGEXP_ONEOF (regexp)->regexps_num;
5127   marked = VEC_alloc (int, heap, n_alts);
5128   for (i = 0; i < n_alts; i++)
5129     VEC_safe_push (int, heap, marked, 0);
5130   annotation_reservation_message_reported_p = false;
5131   for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
5132     {
5133       cycle = i / n_alts;
5134       start = cycle * n_alts;
5135       for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
5136            unit_usage_ptr != NULL;
5137            unit_usage_ptr = unit_usage_ptr->next)
5138         {
5139           if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle)
5140             continue;
5141           unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5142           for (alt = 0; alt < n_alts; alt++)
5143             if (! unit_present_on_list_p (VEC_index (unit_usage_t,
5144                                                      cycle_alt_unit_usages,
5145                                                      start + alt),
5146                                           unit_usage_ptr->unit_decl))
5147               break;
5148           if (alt >= n_alts)
5149             continue;
5150           memset (VEC_address (int, marked), 0, n_alts * sizeof (int));
5151           for (alt = 0; alt < n_alts; alt++)
5152             {
5153               if (! unit_present_on_list_p (VEC_index (unit_usage_t,
5154                                                        cycle_alt_unit_usages,
5155                                                        start + alt),
5156                                             unit_usage_ptr->unit_decl))
5157                 continue;
5158               for (j = 0;
5159                    j < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages);
5160                    j++)
5161                 {
5162                   alt2 = j % n_alts;
5163                   if (! unit_present_on_list_p
5164                         (VEC_index (unit_usage_t, cycle_alt_unit_usages,
5165                                     start + alt2),
5166                          unit_usage_ptr->unit_decl)
5167                       && equal_alternatives_p (alt, alt2, n_alts,
5168                                                unit_usage_ptr
5169                                                ->unit_decl->automaton_decl))
5170                     {
5171                       VEC_replace (int, marked, alt, 1);
5172                       VEC_replace (int, marked, alt2, 1);
5173                     }
5174                 }
5175             }
5176           for (alt = 0; alt < n_alts && VEC_index (int, marked, alt); alt++)
5177             ;
5178           if (alt < n_alts && 0)
5179             {
5180               if (! annotation_message_reported_p)
5181                 {
5182                   fprintf (stderr, "\n");
5183                   error ("The following units do not satisfy units-automata distribution rule");
5184                   error ("(Unit presence on one alt and its absence on other alt\n");
5185                   error (" result in different other automata reservations)");
5186                   annotation_message_reported_p = TRUE;
5187                 }
5188               if (! annotation_reservation_message_reported_p)
5189                 {
5190                   error ("Reserv %s:", insn_reserv_name);
5191                   annotation_reservation_message_reported_p = true;
5192                 }
5193               error ("  Unit %s, cycle %d, alt %d, another alt %d",
5194                      unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt);
5195             }
5196         }
5197     }
5198   VEC_free (int, heap, marked);
5199   VEC_free (unit_usage_t, heap, cycle_alt_unit_usages);
5200   obstack_free (&unit_usages, NULL);
5201 }
5202
5203 /* The function finds units which violates units to automata
5204    distribution rule.  If the units exist, report about them.  */
5205 static void
5206 check_unit_distributions_to_automata (void)
5207 {
5208   decl_t decl;
5209   int i;
5210
5211   if (progress_flag)
5212     fprintf (stderr, "Check unit distributions to automata...");
5213   automaton_decls = NULL;
5214   for (i = 0; i < description->decls_num; i++)
5215     {
5216       decl = description->decls [i];
5217       if (decl->mode == dm_automaton)
5218         VEC_safe_push (decl_t, heap, automaton_decls, decl);
5219     }
5220   if (VEC_length (decl_t, automaton_decls) > 1)
5221     {
5222       annotation_message_reported_p = FALSE;
5223       for (i = 0; i < description->decls_num; i++)
5224         {
5225           decl = description->decls [i];
5226           if (decl->mode == dm_insn_reserv)
5227             check_regexp_units_distribution
5228               (DECL_INSN_RESERV (decl)->name,
5229                DECL_INSN_RESERV (decl)->transformed_regexp);
5230         }
5231     }
5232   VEC_free (decl_t, heap, automaton_decls);
5233   if (progress_flag)
5234     fprintf (stderr, "done\n");
5235 }
5236
5237 \f
5238
5239 /* The page contains code for building alt_states (see comments for
5240    IR) describing all possible insns reservations of an automaton.  */
5241
5242 /* Current state being formed for which the current alt_state
5243    refers.  */
5244 static state_t state_being_formed;
5245
5246 /* Current alt_state being formed.  */
5247 static alt_state_t alt_state_being_formed;
5248
5249 /* This recursive function processes `,' and units in reservation
5250    REGEXP for forming alt_states of AUTOMATON.  It is believed that
5251    CURR_CYCLE is start cycle of all reservation REGEXP.  */
5252 static int
5253 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5254                                 int curr_cycle)
5255 {
5256   int i;
5257
5258   if (regexp == NULL)
5259     return curr_cycle;
5260
5261   switch (regexp->mode)
5262     {
5263     case rm_unit:
5264       if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5265           == automaton->automaton_order_num)
5266         set_state_reserv (state_being_formed, curr_cycle,
5267                           REGEXP_UNIT (regexp)->unit_decl->unit_num);
5268       return curr_cycle;
5269
5270     case rm_sequence:
5271       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5272         curr_cycle
5273           = process_seq_for_forming_states
5274             (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5275       return curr_cycle;
5276
5277     case rm_allof:
5278       {
5279         int finish_cycle = 0;
5280         int cycle;
5281
5282         for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5283           {
5284             cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5285                                                     ->regexps [i],
5286                                                     automaton, curr_cycle);
5287             if (finish_cycle < cycle)
5288               finish_cycle = cycle;
5289           }
5290         return finish_cycle;
5291       }
5292
5293     case rm_nothing:
5294       return curr_cycle;
5295
5296     default:
5297       gcc_unreachable ();
5298     }
5299 }
5300
5301 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5302    inserts alt_state into the table.  */
5303 static void
5304 finish_forming_alt_state (alt_state_t alt_state,
5305                           automaton_t automaton ATTRIBUTE_UNUSED)
5306 {
5307   state_t state_in_table;
5308   state_t corresponding_state;
5309
5310   corresponding_state = alt_state->state;
5311   state_in_table = insert_state (corresponding_state);
5312   if (state_in_table != corresponding_state)
5313     {
5314       free_state (corresponding_state);
5315       alt_state->state = state_in_table;
5316     }
5317 }
5318
5319 /* The following variable value is current automaton insn for whose
5320    reservation the alt states are created.  */
5321 static ainsn_t curr_ainsn;
5322
5323 /* This recursive function processes `|' in reservation REGEXP for
5324    forming alt_states of AUTOMATON.  List of the alt states should
5325    have the same order as in the description.  */
5326 static void
5327 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5328                                  int inside_oneof_p)
5329 {
5330   int i;
5331
5332   if (regexp->mode != rm_oneof)
5333     {
5334       alt_state_being_formed = get_free_alt_state ();
5335       state_being_formed = get_free_state (1, automaton);
5336       alt_state_being_formed->state = state_being_formed;
5337       /* We inserts in reverse order but we process alternatives also
5338          in reverse order.  So we have the same order of alternative
5339          as in the description.  */
5340       alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5341       curr_ainsn->alt_states = alt_state_being_formed;
5342       (void) process_seq_for_forming_states (regexp, automaton, 0);
5343       finish_forming_alt_state (alt_state_being_formed, automaton);
5344     }
5345   else
5346     {
5347       gcc_assert (!inside_oneof_p);
5348       /* We processes it in reverse order to get list with the same
5349          order as in the description.  See also the previous
5350          commentary.  */
5351       for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5352         process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5353                                          automaton, 1);
5354     }
5355 }
5356
5357 /* Create nodes alt_state for all AUTOMATON insns.  */
5358 static void
5359 create_alt_states (automaton_t automaton)
5360 {
5361   struct insn_reserv_decl *reserv_decl;
5362
5363   for (curr_ainsn = automaton->ainsn_list;
5364        curr_ainsn != NULL;
5365        curr_ainsn = curr_ainsn->next_ainsn)
5366     {
5367       reserv_decl = curr_ainsn->insn_reserv_decl;
5368       if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5369         {
5370           curr_ainsn->alt_states = NULL;
5371           process_alts_for_forming_states (reserv_decl->transformed_regexp,
5372                                            automaton, 0);
5373           curr_ainsn->sorted_alt_states
5374             = uniq_sort_alt_states (curr_ainsn->alt_states);
5375         }
5376     }
5377 }
5378
5379 \f
5380
5381 /* The page contains major code for building DFA(s) for fast pipeline
5382    hazards recognition.  */
5383
5384 /* The function forms list of ainsns of AUTOMATON with the same
5385    reservation.  */
5386
5387 static void
5388 form_ainsn_with_same_reservs (automaton_t automaton)
5389 {
5390   ainsn_t curr_ainsn;
5391   size_t i;
5392   VEC(ainsn_t, heap) *last_insns = VEC_alloc (ainsn_t, heap, 150);
5393
5394   for (curr_ainsn = automaton->ainsn_list;
5395        curr_ainsn != NULL;
5396        curr_ainsn = curr_ainsn->next_ainsn)
5397     if (curr_ainsn->insn_reserv_decl
5398         == DECL_INSN_RESERV (advance_cycle_insn_decl))
5399       {
5400         curr_ainsn->next_same_reservs_insn = NULL;
5401         curr_ainsn->first_insn_with_same_reservs = 1;
5402       }
5403     else
5404       {
5405         for (i = 0; i < VEC_length (ainsn_t, last_insns); i++)
5406           if (alt_states_eq
5407               (curr_ainsn->sorted_alt_states,
5408                VEC_index (ainsn_t, last_insns, i)->sorted_alt_states))
5409             break;
5410         curr_ainsn->next_same_reservs_insn = NULL;
5411         if (i < VEC_length (ainsn_t, last_insns))
5412           {
5413             curr_ainsn->first_insn_with_same_reservs = 0;
5414             VEC_index (ainsn_t, last_insns, i)->next_same_reservs_insn
5415               = curr_ainsn;
5416             VEC_replace (ainsn_t, last_insns, i, curr_ainsn);
5417           }
5418         else
5419           {
5420             VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn);
5421             curr_ainsn->first_insn_with_same_reservs = 1;
5422           }
5423       }
5424   VEC_free (ainsn_t, heap, last_insns);
5425 }
5426
5427 /* Forming unit reservations which can affect creating the automaton
5428    states achieved from a given state.  It permits to build smaller
5429    automata in many cases.  We would have the same automata after
5430    the minimization without such optimization, but the automaton
5431    right after the building could be huge.  So in other words, usage
5432    of reservs_matter means some minimization during building the
5433    automaton.  */
5434 static reserv_sets_t
5435 form_reservs_matter (automaton_t automaton)
5436 {
5437   int cycle, unit;
5438   reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5439
5440   for (cycle = 0; cycle < max_cycles_num; cycle++)
5441     for (unit = 0; unit < description->units_num; unit++)
5442       if (units_array [unit]->automaton_decl
5443           == automaton->corresponding_automaton_decl
5444           && (cycle >= units_array [unit]->min_occ_cycle_num
5445               /* We can not remove queried unit from reservations.  */
5446               || units_array [unit]->query_p
5447               /* We can not remove units which are used
5448                  `exclusion_set', `presence_set',
5449                  `final_presence_set', `absence_set', and
5450                  `final_absence_set'.  */
5451               || units_array [unit]->in_set_p))
5452         set_unit_reserv (reservs_matter, cycle, unit);
5453   return reservs_matter;
5454 }
5455
5456 /* The following function creates all states of nondeterministic AUTOMATON.  */
5457 static void
5458 make_automaton (automaton_t automaton)
5459 {
5460   ainsn_t ainsn;
5461   struct insn_reserv_decl *insn_reserv_decl;
5462   alt_state_t alt_state;
5463   state_t state;
5464   state_t start_state;
5465   state_t state2;
5466   ainsn_t advance_cycle_ainsn;
5467   arc_t added_arc;
5468   VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150);
5469   int states_n;
5470   reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5471
5472   /* Create the start state (empty state).  */
5473   start_state = insert_state (get_free_state (1, automaton));
5474   automaton->start_state = start_state;
5475   start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5476   VEC_safe_push (state_t, heap, state_stack, start_state);
5477   states_n = 1;
5478   while (VEC_length (state_t, state_stack) != 0)
5479     {
5480       state = VEC_pop (state_t, state_stack);
5481       advance_cycle_ainsn = NULL;
5482       for (ainsn = automaton->ainsn_list;
5483            ainsn != NULL;
5484            ainsn = ainsn->next_ainsn)
5485         if (ainsn->first_insn_with_same_reservs)
5486           {
5487             insn_reserv_decl = ainsn->insn_reserv_decl;
5488             if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5489               {
5490                 /* We process alt_states in the same order as they are
5491                    present in the description.  */
5492                 added_arc = NULL;
5493                 for (alt_state = ainsn->alt_states;
5494                      alt_state != NULL;
5495                      alt_state = alt_state->next_alt_state)
5496                   {
5497                     state2 = alt_state->state;
5498                     if (!intersected_state_reservs_p (state, state2))
5499                       {
5500                         state2 = states_union (state, state2, reservs_matter);
5501                         if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5502                           {
5503                             state2->it_was_placed_in_stack_for_NDFA_forming
5504                               = 1;
5505                             VEC_safe_push (state_t, heap, state_stack, state2);
5506                             states_n++;
5507                             if (progress_flag && states_n % 100 == 0)
5508                               fprintf (stderr, ".");
5509                           }
5510                         added_arc = add_arc (state, state2, ainsn);
5511                         if (!ndfa_flag)
5512                           break;
5513                       }
5514                   }
5515                 if (!ndfa_flag && added_arc != NULL)
5516                   {
5517                     for (alt_state = ainsn->alt_states;
5518                          alt_state != NULL;
5519                          alt_state = alt_state->next_alt_state)
5520                       state2 = alt_state->state;
5521                   }
5522               }
5523             else
5524               advance_cycle_ainsn = ainsn;
5525           }
5526       /* Add transition to advance cycle.  */
5527       state2 = state_shift (state, reservs_matter);
5528       if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5529         {
5530           state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5531           VEC_safe_push (state_t, heap, state_stack, state2);
5532           states_n++;
5533           if (progress_flag && states_n % 100 == 0)
5534             fprintf (stderr, ".");
5535         }
5536       gcc_assert (advance_cycle_ainsn);
5537       add_arc (state, state2, advance_cycle_ainsn);
5538     }
5539   VEC_free (state_t, heap, state_stack);
5540 }
5541
5542 /* Form lists of all arcs of STATE marked by the same ainsn.  */
5543 static void
5544 form_arcs_marked_by_insn (state_t state)
5545 {
5546   decl_t decl;
5547   arc_t arc;
5548   int i;
5549
5550   for (i = 0; i < description->decls_num; i++)
5551     {
5552       decl = description->decls [i];
5553       if (decl->mode == dm_insn_reserv)
5554         DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5555     }
5556   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5557     {
5558       gcc_assert (arc->insn);
5559       arc->next_arc_marked_by_insn
5560         = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5561       arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5562     }
5563 }
5564
5565 /* The function creates composed state (see comments for IR) from
5566    ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5567    same insn.  If the composed state is not in STATE_STACK yet, it is
5568    pushed into STATE_STACK.  */
5569
5570 static int
5571 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5572                        VEC(state_t, heap) **state_stack)
5573 {
5574   state_t state;
5575   alt_state_t alt_state, curr_alt_state;
5576   alt_state_t new_alt_state;
5577   arc_t curr_arc;
5578   arc_t next_arc;
5579   state_t state_in_table;
5580   state_t temp_state;
5581   alt_state_t canonical_alt_states_list;
5582   int alts_number;
5583   int new_state_p = 0;
5584
5585   if (arcs_marked_by_insn == NULL)
5586     return new_state_p;
5587   if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5588     state = arcs_marked_by_insn->to_state;
5589   else
5590     {
5591       gcc_assert (ndfa_flag);
5592       /* Create composed state.  */
5593       state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5594       curr_alt_state = NULL;
5595       for (curr_arc = arcs_marked_by_insn;
5596            curr_arc != NULL;
5597            curr_arc = curr_arc->next_arc_marked_by_insn)
5598         if (curr_arc->to_state->component_states == NULL)
5599           {
5600             new_alt_state = get_free_alt_state ();
5601             new_alt_state->next_alt_state = curr_alt_state;
5602             new_alt_state->state = curr_arc->to_state;
5603             curr_alt_state = new_alt_state;
5604           }
5605         else
5606           for (alt_state = curr_arc->to_state->component_states;
5607                alt_state != NULL;
5608                alt_state = alt_state->next_sorted_alt_state)
5609             {
5610               new_alt_state = get_free_alt_state ();
5611               new_alt_state->next_alt_state = curr_alt_state;
5612               new_alt_state->state = alt_state->state;
5613               gcc_assert (!alt_state->state->component_states);
5614               curr_alt_state = new_alt_state;
5615             }
5616       /* There are not identical sets in the alt state list.  */
5617       canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5618       if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5619         {
5620           temp_state = state;
5621           state = canonical_alt_states_list->state;
5622           free_state (temp_state);
5623         }
5624       else
5625         {
5626           state->component_states = canonical_alt_states_list;
5627           state_in_table = insert_state (state);
5628           if (state_in_table != state)
5629             {
5630               gcc_assert
5631                 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5632               free_state (state);
5633               state = state_in_table;
5634             }
5635           else
5636             {
5637               gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5638               new_state_p = 1;
5639               for (curr_alt_state = state->component_states;
5640                    curr_alt_state != NULL;
5641                    curr_alt_state = curr_alt_state->next_sorted_alt_state)
5642                 for (curr_arc = first_out_arc (curr_alt_state->state);
5643                      curr_arc != NULL;
5644                      curr_arc = next_out_arc (curr_arc))
5645                   add_arc (state, curr_arc->to_state, curr_arc->insn);
5646             }
5647           arcs_marked_by_insn->to_state = state;
5648           for (alts_number = 0,
5649                curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5650                curr_arc != NULL;
5651                curr_arc = next_arc)
5652             {
5653               next_arc = curr_arc->next_arc_marked_by_insn;
5654               remove_arc (original_state, curr_arc);
5655               alts_number++;
5656             }
5657         }
5658     }
5659   if (!state->it_was_placed_in_stack_for_DFA_forming)
5660     {
5661       state->it_was_placed_in_stack_for_DFA_forming = 1;
5662       VEC_safe_push (state_t, heap, *state_stack, state);
5663     }
5664   return new_state_p;
5665 }
5666
5667 /* The function transforms nondeterministic AUTOMATON into
5668    deterministic.  */
5669
5670 static void
5671 NDFA_to_DFA (automaton_t automaton)
5672 {
5673   state_t start_state;
5674   state_t state;
5675   decl_t decl;
5676   VEC(state_t, heap) *state_stack;
5677   int i;
5678   int states_n;
5679
5680   state_stack = VEC_alloc (state_t, heap, 0);
5681
5682   /* Create the start state (empty state).  */
5683   start_state = automaton->start_state;
5684   start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5685   VEC_safe_push (state_t, heap, state_stack, start_state);
5686   states_n = 1;
5687   while (VEC_length (state_t, state_stack) != 0)
5688     {
5689       state = VEC_pop (state_t, state_stack);
5690       form_arcs_marked_by_insn (state);
5691       for (i = 0; i < description->decls_num; i++)
5692         {
5693           decl = description->decls [i];
5694           if (decl->mode == dm_insn_reserv
5695               && create_composed_state
5696                  (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5697                   &state_stack))
5698             {
5699               states_n++;
5700               if (progress_flag && states_n % 100 == 0)
5701                 fprintf (stderr, ".");
5702             }
5703         }
5704     }
5705   VEC_free (state_t, heap, state_stack);
5706 }
5707
5708 /* The following variable value is current number (1, 2, ...) of passing
5709    graph of states.  */
5710 static int curr_state_graph_pass_num;
5711
5712 /* This recursive function passes all states achieved from START_STATE
5713    and applies APPLIED_FUNC to them.  */
5714 static void
5715 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
5716 {
5717   arc_t arc;
5718
5719   if (start_state->pass_num == curr_state_graph_pass_num)
5720     return;
5721   start_state->pass_num = curr_state_graph_pass_num;
5722   (*applied_func) (start_state);
5723   for (arc = first_out_arc (start_state);
5724        arc != NULL;
5725        arc = next_out_arc (arc))
5726     pass_state_graph (arc->to_state, applied_func);
5727 }
5728
5729 /* This recursive function passes all states of AUTOMATON and applies
5730    APPLIED_FUNC to them.  */
5731 static void
5732 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
5733 {
5734   curr_state_graph_pass_num++;
5735   pass_state_graph (automaton->start_state, applied_func);
5736 }
5737
5738 /* The function initializes code for passing of all states.  */
5739 static void
5740 initiate_pass_states (void)
5741 {
5742   curr_state_graph_pass_num = 0;
5743 }
5744
5745 /* The following vla is used for storing pointers to all achieved
5746    states.  */
5747 static VEC(state_t, heap) *all_achieved_states;
5748
5749 /* This function is called by function pass_states to add an achieved
5750    STATE.  */
5751 static void
5752 add_achieved_state (state_t state)
5753 {
5754   VEC_safe_push (state_t, heap, all_achieved_states, state);
5755 }
5756
5757 /* The function sets up equivalence numbers of insns which mark all
5758    out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5759    nonzero value) or by equiv_class_num_2 of the destination state.
5760    The function returns number of out arcs of STATE.  */
5761 static void
5762 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
5763 {
5764   arc_t arc;
5765
5766   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5767     {
5768       gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
5769       arc->insn->insn_reserv_decl->equiv_class_num
5770         = (odd_iteration_flag
5771            ? arc->to_state->equiv_class_num_1
5772            : arc->to_state->equiv_class_num_2);
5773       gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
5774     }
5775 }
5776
5777 /* The function clears equivalence numbers and alt_states in all insns
5778    which mark all out arcs of STATE.  */
5779 static void
5780 clear_arc_insns_equiv_num (state_t state)
5781 {
5782   arc_t arc;
5783
5784   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5785     arc->insn->insn_reserv_decl->equiv_class_num = 0;
5786 }
5787
5788
5789 /* The following function returns TRUE if STATE reserves the unit with
5790    UNIT_NUM on the first cycle.  */
5791 static int
5792 first_cycle_unit_presence (state_t state, int unit_num)
5793 {
5794   alt_state_t alt_state;
5795
5796   if (state->component_states == NULL)
5797     return test_unit_reserv (state->reservs, 0, unit_num);
5798   else
5799     {
5800       for (alt_state = state->component_states;
5801            alt_state != NULL;
5802            alt_state = alt_state->next_sorted_alt_state)
5803         if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
5804           return true;
5805     }
5806   return false;
5807 }
5808
5809 /* This fills in the presence_signature[] member of STATE.  */
5810 static void
5811 cache_presence (state_t state)
5812 {
5813   int i, num = 0;
5814   unsigned int sz;
5815   sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5816         / (sizeof (int) * CHAR_BIT);
5817
5818   state->presence_signature = XCREATENODEVEC (unsigned int, sz);
5819   for (i = 0; i < description->units_num; i++)
5820     if (units_array [i]->query_p)
5821       {
5822         int presence1_p = first_cycle_unit_presence (state, i);
5823         state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
5824           |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
5825         num++;
5826       }
5827 }
5828
5829 /* The function returns nonzero value if STATE is not equivalent to
5830    ANOTHER_STATE from the same current partition on equivalence
5831    classes.  Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
5832    output arcs.  Iteration of making equivalence partition is defined
5833    by ODD_ITERATION_FLAG.  */
5834 static int
5835 state_is_differed (state_t state, state_t another_state,
5836                    int odd_iteration_flag)
5837 {
5838   arc_t arc;
5839   unsigned int sz, si;
5840
5841   gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
5842
5843   sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5844         / (sizeof (int) * CHAR_BIT);
5845
5846   for (si = 0; si < sz; si++)
5847     gcc_assert (state->presence_signature[si]
5848                 == another_state->presence_signature[si]);
5849
5850   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5851     {
5852       if ((odd_iteration_flag
5853            ? arc->to_state->equiv_class_num_1
5854            : arc->to_state->equiv_class_num_2)
5855           != arc->insn->insn_reserv_decl->equiv_class_num)
5856         return 1;
5857     }
5858
5859   return 0;
5860 }
5861
5862 /* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2
5863    and return -1, 0 or 1.  This function can be used as predicate for
5864    qsort().  It requires the member presence_signature[] of both
5865    states be filled.  */
5866 static int
5867 compare_states_for_equiv (const void *state_ptr_1,
5868                           const void *state_ptr_2)
5869 {
5870   const_state_t const s1 = *(const_state_t const*)state_ptr_1;
5871   const_state_t const s2 = *(const_state_t const*)state_ptr_2;
5872   unsigned int sz, si;
5873   if (s1->num_out_arcs < s2->num_out_arcs)
5874     return -1;
5875   else if (s1->num_out_arcs > s2->num_out_arcs)
5876     return 1;
5877
5878   sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5879         / (sizeof (int) * CHAR_BIT);
5880
5881   for (si = 0; si < sz; si++)
5882     if (s1->presence_signature[si] < s2->presence_signature[si])
5883       return -1;
5884     else if (s1->presence_signature[si] > s2->presence_signature[si])
5885       return 1;
5886   return 0;
5887 }
5888
5889 /* The function makes initial partition of STATES on equivalent
5890    classes and saves it into *CLASSES.  This function requires the input
5891    to be sorted via compare_states_for_equiv().  */
5892 static int
5893 init_equiv_class (VEC(state_t, heap) *states, VEC (state_t, heap) **classes)
5894 {
5895   size_t i;
5896   state_t prev = 0;
5897   int class_num = 1;
5898
5899   *classes = VEC_alloc (state_t, heap, 150);
5900   for (i = 0; i < VEC_length (state_t, states); i++)
5901     {
5902       state_t state = VEC_index (state_t, states, i);
5903       if (prev)
5904         {
5905           if (compare_states_for_equiv (&prev, &state) != 0)
5906             {
5907               VEC_safe_push (state_t, heap, *classes, prev);
5908               class_num++;
5909               prev = NULL;
5910             }
5911         }
5912       state->equiv_class_num_1 = class_num;
5913       state->next_equiv_class_state = prev;
5914       prev = state;
5915     }
5916   if (prev)
5917     VEC_safe_push (state_t, heap, *classes, prev);
5918   return class_num;
5919 }
5920
5921 /* The function copies pointers to equivalent states from vla FROM
5922    into vla TO.  */
5923 static void
5924 copy_equiv_class (VEC(state_t, heap) **to, VEC(state_t, heap) *from)
5925 {
5926   VEC_free (state_t, heap, *to);
5927   *to = VEC_copy (state_t, heap, from);
5928 }
5929
5930 /* The function processes equivalence class given by its first state,
5931    FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG.  If there
5932    are not equivalent states, the function partitions the class
5933    removing nonequivalent states and placing them in
5934    *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5935    assigns it to the state equivalence number.  If the class has been
5936    partitioned, the function returns nonzero value.  */
5937 static int
5938 partition_equiv_class (state_t first_state, int odd_iteration_flag,
5939                        VEC(state_t, heap) **next_iteration_classes,
5940                        int *new_equiv_class_num_ptr)
5941 {
5942   state_t new_equiv_class;
5943   int partition_p;
5944   state_t curr_state;
5945   state_t prev_state;
5946   state_t next_state;
5947
5948   partition_p = 0;
5949
5950   while (first_state != NULL)
5951     {
5952       new_equiv_class = NULL;
5953       if (first_state->next_equiv_class_state != NULL)
5954         {
5955           /* There are more one states in the class equivalence.  */
5956           set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
5957           for (prev_state = first_state,
5958                  curr_state = first_state->next_equiv_class_state;
5959                curr_state != NULL;
5960                curr_state = next_state)
5961             {
5962               next_state = curr_state->next_equiv_class_state;
5963               if (state_is_differed (curr_state, first_state,
5964                                      odd_iteration_flag))
5965                 {
5966                   /* Remove curr state from the class equivalence.  */
5967                   prev_state->next_equiv_class_state = next_state;
5968                   /* Add curr state to the new class equivalence.  */
5969                   curr_state->next_equiv_class_state = new_equiv_class;
5970                   if (new_equiv_class == NULL)
5971                     (*new_equiv_class_num_ptr)++;
5972                   if (odd_iteration_flag)
5973                     curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5974                   else
5975                     curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5976                   new_equiv_class = curr_state;
5977                   partition_p = 1;
5978                 }
5979               else
5980                 prev_state = curr_state;
5981             }
5982           clear_arc_insns_equiv_num (first_state);
5983         }
5984       if (new_equiv_class != NULL)
5985         VEC_safe_push (state_t, heap, *next_iteration_classes, new_equiv_class);
5986       first_state = new_equiv_class;
5987     }
5988   return partition_p;
5989 }
5990
5991 /* The function finds equivalent states of AUTOMATON.  */
5992 static void
5993 evaluate_equiv_classes (automaton_t automaton,
5994                         VEC(state_t, heap) **equiv_classes)
5995 {
5996   int new_equiv_class_num;
5997   int odd_iteration_flag;
5998   int finish_flag;
5999   VEC (state_t, heap) *next_iteration_classes;
6000   size_t i;
6001
6002   all_achieved_states = VEC_alloc (state_t, heap, 1500);
6003   pass_states (automaton, add_achieved_state);
6004   pass_states (automaton, cache_presence);
6005   VEC_qsort (state_t, all_achieved_states, compare_states_for_equiv);
6006
6007   odd_iteration_flag = 0;
6008   new_equiv_class_num = init_equiv_class (all_achieved_states,
6009                                           &next_iteration_classes);
6010
6011   do
6012     {
6013       odd_iteration_flag = !odd_iteration_flag;
6014       finish_flag = 1;
6015       copy_equiv_class (equiv_classes, next_iteration_classes);
6016
6017       /* Transfer equiv numbers for the next iteration.  */
6018       for (i = 0; i < VEC_length (state_t, all_achieved_states); i++)
6019         if (odd_iteration_flag)
6020           VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2
6021             = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1;
6022         else
6023           VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1
6024             = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2;
6025
6026       for (i = 0; i < VEC_length (state_t, *equiv_classes); i++)
6027         if (partition_equiv_class (VEC_index (state_t, *equiv_classes, i),
6028                                    odd_iteration_flag,
6029                                    &next_iteration_classes,
6030                                    &new_equiv_class_num))
6031           finish_flag = 0;
6032     }
6033   while (!finish_flag);
6034   VEC_free (state_t, heap, next_iteration_classes);
6035   VEC_free (state_t, heap, all_achieved_states);
6036 }
6037
6038 /* The function merges equivalent states of AUTOMATON.  */
6039 static void
6040 merge_states (automaton_t automaton, VEC(state_t, heap) *equiv_classes)
6041 {
6042   state_t curr_state;
6043   state_t new_state;
6044   state_t first_class_state;
6045   alt_state_t alt_states;
6046   alt_state_t alt_state, new_alt_state;
6047   arc_t curr_arc;
6048   arc_t next_arc;
6049   size_t i;
6050
6051   /* Create states corresponding to equivalence classes containing two
6052      or more states.  */
6053   for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
6054     {
6055       curr_state = VEC_index (state_t, equiv_classes, i);
6056       if (curr_state->next_equiv_class_state != NULL)
6057         {
6058           /* There are more one states in the class equivalence.  */
6059           /* Create new compound state.  */
6060           new_state = get_free_state (0, automaton);
6061           alt_states = NULL;
6062           first_class_state = curr_state;
6063           for (curr_state = first_class_state;
6064                curr_state != NULL;
6065                curr_state = curr_state->next_equiv_class_state)
6066             {
6067               curr_state->equiv_class_state = new_state;
6068               if (curr_state->component_states == NULL)
6069                 {
6070                   new_alt_state = get_free_alt_state ();
6071                   new_alt_state->state = curr_state;
6072                   new_alt_state->next_alt_state = alt_states;
6073                   alt_states = new_alt_state;
6074                 }
6075               else
6076                 for (alt_state = curr_state->component_states;
6077                      alt_state != NULL;
6078                      alt_state = alt_state->next_sorted_alt_state)
6079                   {
6080                     new_alt_state = get_free_alt_state ();
6081                     new_alt_state->state = alt_state->state;
6082                     new_alt_state->next_alt_state = alt_states;
6083                     alt_states = new_alt_state;
6084                   }
6085             }
6086           /* Its is important that alt states were sorted before and
6087              after merging to have the same querying results.  */
6088           new_state->component_states = uniq_sort_alt_states (alt_states);
6089         }
6090       else
6091         curr_state->equiv_class_state = curr_state;
6092     }
6093
6094   for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
6095     {
6096       curr_state = VEC_index (state_t, equiv_classes, i);
6097       if (curr_state->next_equiv_class_state != NULL)
6098         {
6099           first_class_state = curr_state;
6100           /* Create new arcs output from the state corresponding to
6101              equiv class.  */
6102           for (curr_arc = first_out_arc (first_class_state);
6103                curr_arc != NULL;
6104                curr_arc = next_out_arc (curr_arc))
6105             add_arc (first_class_state->equiv_class_state,
6106                      curr_arc->to_state->equiv_class_state,
6107                      curr_arc->insn);
6108           /* Delete output arcs from states of given class equivalence.  */
6109           for (curr_state = first_class_state;
6110                curr_state != NULL;
6111                curr_state = curr_state->next_equiv_class_state)
6112             {
6113               if (automaton->start_state == curr_state)
6114                 automaton->start_state = curr_state->equiv_class_state;
6115               /* Delete the state and its output arcs.  */
6116               for (curr_arc = first_out_arc (curr_state);
6117                    curr_arc != NULL;
6118                    curr_arc = next_arc)
6119                 {
6120                   next_arc = next_out_arc (curr_arc);
6121                   free_arc (curr_arc);
6122                 }
6123             }
6124         }
6125       else
6126         {
6127           /* Change `to_state' of arcs output from the state of given
6128              equivalence class.  */
6129           for (curr_arc = first_out_arc (curr_state);
6130                curr_arc != NULL;
6131                curr_arc = next_out_arc (curr_arc))
6132             curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6133         }
6134     }
6135 }
6136
6137 /* The function sets up new_cycle_p for states if there is arc to the
6138    state marked by advance_cycle_insn_decl.  */
6139 static void
6140 set_new_cycle_flags (state_t state)
6141 {
6142   arc_t arc;
6143
6144   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6145     if (arc->insn->insn_reserv_decl
6146         == DECL_INSN_RESERV (advance_cycle_insn_decl))
6147       arc->to_state->new_cycle_p = 1;
6148 }
6149
6150 /* The top level function for minimization of deterministic
6151    AUTOMATON.  */
6152 static void
6153 minimize_DFA (automaton_t automaton)
6154 {
6155   VEC(state_t, heap) *equiv_classes = 0;
6156
6157   evaluate_equiv_classes (automaton, &equiv_classes);
6158   merge_states (automaton, equiv_classes);
6159   pass_states (automaton, set_new_cycle_flags);
6160
6161   VEC_free (state_t, heap, equiv_classes);
6162 }
6163
6164 /* Values of two variables are counted number of states and arcs in an
6165    automaton.  */
6166 static int curr_counted_states_num;
6167 static int curr_counted_arcs_num;
6168
6169 /* The function is called by function `pass_states' to count states
6170    and arcs of an automaton.  */
6171 static void
6172 incr_states_and_arcs_nums (state_t state)
6173 {
6174   arc_t arc;
6175
6176   curr_counted_states_num++;
6177   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6178     curr_counted_arcs_num++;
6179 }
6180
6181 /* The function counts states and arcs of AUTOMATON.  */
6182 static void
6183 count_states_and_arcs (automaton_t automaton, int *states_num,
6184                        int *arcs_num)
6185 {
6186   curr_counted_states_num = 0;
6187   curr_counted_arcs_num = 0;
6188   pass_states (automaton, incr_states_and_arcs_nums);
6189   *states_num = curr_counted_states_num;
6190   *arcs_num = curr_counted_arcs_num;
6191 }
6192
6193 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6194    recognition after checking and simplifying IR of the
6195    description.  */
6196 static void
6197 build_automaton (automaton_t automaton)
6198 {
6199   int states_num;
6200   int arcs_num;
6201
6202   ticker_on (&NDFA_time);
6203   if (progress_flag)
6204     {
6205       if (automaton->corresponding_automaton_decl == NULL)
6206         fprintf (stderr, "Create anonymous automaton");
6207       else
6208         fprintf (stderr, "Create automaton `%s'",
6209                  automaton->corresponding_automaton_decl->name);
6210       fprintf (stderr, " (1 dot is 100 new states):");
6211     }
6212   make_automaton (automaton);
6213   if (progress_flag)
6214     fprintf (stderr, " done\n");
6215   ticker_off (&NDFA_time);
6216   count_states_and_arcs (automaton, &states_num, &arcs_num);
6217   automaton->NDFA_states_num = states_num;
6218   automaton->NDFA_arcs_num = arcs_num;
6219   ticker_on (&NDFA_to_DFA_time);
6220   if (progress_flag)
6221     {
6222       if (automaton->corresponding_automaton_decl == NULL)
6223         fprintf (stderr, "Make anonymous DFA");
6224       else
6225         fprintf (stderr, "Make DFA `%s'",
6226                  automaton->corresponding_automaton_decl->name);
6227       fprintf (stderr, " (1 dot is 100 new states):");
6228     }
6229   NDFA_to_DFA (automaton);
6230   if (progress_flag)
6231     fprintf (stderr, " done\n");
6232   ticker_off (&NDFA_to_DFA_time);
6233   count_states_and_arcs (automaton, &states_num, &arcs_num);
6234   automaton->DFA_states_num = states_num;
6235   automaton->DFA_arcs_num = arcs_num;
6236   if (!no_minimization_flag)
6237     {
6238       ticker_on (&minimize_time);
6239       if (progress_flag)
6240         {
6241           if (automaton->corresponding_automaton_decl == NULL)
6242             fprintf (stderr, "Minimize anonymous DFA...");
6243           else
6244             fprintf (stderr, "Minimize DFA `%s'...",
6245                      automaton->corresponding_automaton_decl->name);
6246         }
6247       minimize_DFA (automaton);
6248       if (progress_flag)
6249         fprintf (stderr, "done\n");
6250       ticker_off (&minimize_time);
6251       count_states_and_arcs (automaton, &states_num, &arcs_num);
6252       automaton->minimal_DFA_states_num = states_num;
6253       automaton->minimal_DFA_arcs_num = arcs_num;
6254     }
6255 }
6256
6257 \f
6258
6259 /* The page contains code for enumeration  of all states of an automaton.  */
6260
6261 /* Variable used for enumeration of all states of an automaton.  Its
6262    value is current number of automaton states.  */
6263 static int curr_state_order_num;
6264
6265 /* The function is called by function `pass_states' for enumerating
6266    states.  */
6267 static void
6268 set_order_state_num (state_t state)
6269 {
6270   state->order_state_num = curr_state_order_num;
6271   curr_state_order_num++;
6272 }
6273
6274 /* The function enumerates all states of AUTOMATON.  */
6275 static void
6276 enumerate_states (automaton_t automaton)
6277 {
6278   curr_state_order_num = 0;
6279   pass_states (automaton, set_order_state_num);
6280   automaton->achieved_states_num = curr_state_order_num;
6281 }
6282
6283 \f
6284
6285 /* The page contains code for finding equivalent automaton insns
6286    (ainsns).  */
6287
6288 /* The function inserts AINSN into cyclic list
6289    CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns.  */
6290 static ainsn_t
6291 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6292                                ainsn_t cyclic_equiv_class_insn_list)
6293 {
6294   if (cyclic_equiv_class_insn_list == NULL)
6295     ainsn->next_equiv_class_insn = ainsn;
6296   else
6297     {
6298       ainsn->next_equiv_class_insn
6299         = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6300       cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6301     }
6302   return ainsn;
6303 }
6304
6305 /* The function deletes equiv_class_insn into cyclic list of
6306    equivalent ainsns.  */
6307 static void
6308 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6309 {
6310   ainsn_t curr_equiv_class_insn;
6311   ainsn_t prev_equiv_class_insn;
6312
6313   prev_equiv_class_insn = equiv_class_insn;
6314   for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6315        curr_equiv_class_insn != equiv_class_insn;
6316        curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6317     prev_equiv_class_insn = curr_equiv_class_insn;
6318   if (prev_equiv_class_insn != equiv_class_insn)
6319     prev_equiv_class_insn->next_equiv_class_insn
6320       = equiv_class_insn->next_equiv_class_insn;
6321 }
6322
6323 /* The function processes AINSN of a state in order to find equivalent
6324    ainsns.  INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6325    state.  */
6326 static void
6327 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6328 {
6329   ainsn_t next_insn;
6330   ainsn_t curr_insn;
6331   ainsn_t cyclic_insn_list;
6332   arc_t arc;
6333
6334   gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6335   curr_insn = ainsn;
6336   /* New class of ainsns which are not equivalent to given ainsn.  */
6337   cyclic_insn_list = NULL;
6338   do
6339     {
6340       next_insn = curr_insn->next_equiv_class_insn;
6341       arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6342       if (arc == NULL
6343           || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6344               != arc->to_state))
6345         {
6346           delete_ainsn_from_equiv_class (curr_insn);
6347           cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6348                                                             cyclic_insn_list);
6349         }
6350       curr_insn = next_insn;
6351     }
6352   while (curr_insn != ainsn);
6353 }
6354
6355 /* The function processes STATE in order to find equivalent ainsns.  */
6356 static void
6357 process_state_for_insn_equiv_partition (state_t state)
6358 {
6359   arc_t arc;
6360   arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
6361
6362   /* Process insns of the arcs.  */
6363   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6364     insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6365   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6366     process_insn_equiv_class (arc->insn, insn_arcs_array);
6367
6368   free (insn_arcs_array);
6369 }
6370
6371 /* The function searches for equivalent ainsns of AUTOMATON.  */
6372 static void
6373 set_insn_equiv_classes (automaton_t automaton)
6374 {
6375   ainsn_t ainsn;
6376   ainsn_t first_insn;
6377   ainsn_t curr_insn;
6378   ainsn_t cyclic_insn_list;
6379   ainsn_t insn_with_same_reservs;
6380   int equiv_classes_num;
6381
6382   /* All insns are included in one equivalence class.  */
6383   cyclic_insn_list = NULL;
6384   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6385     if (ainsn->first_insn_with_same_reservs)
6386       cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6387                                                         cyclic_insn_list);
6388   /* Process insns in order to make equivalence partition.  */
6389   pass_states (automaton, process_state_for_insn_equiv_partition);
6390   /* Enumerate equiv classes.  */
6391   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6392     /* Set undefined value.  */
6393     ainsn->insn_equiv_class_num = -1;
6394   equiv_classes_num = 0;
6395   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6396     if (ainsn->insn_equiv_class_num < 0)
6397       {
6398         first_insn = ainsn;
6399         gcc_assert (first_insn->first_insn_with_same_reservs);
6400         first_insn->first_ainsn_with_given_equivalence_num = 1;
6401         curr_insn = first_insn;
6402         do
6403           {
6404             for (insn_with_same_reservs = curr_insn;
6405                  insn_with_same_reservs != NULL;
6406                  insn_with_same_reservs
6407                    = insn_with_same_reservs->next_same_reservs_insn)
6408               insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6409             curr_insn = curr_insn->next_equiv_class_insn;
6410           }
6411         while (curr_insn != first_insn);
6412         equiv_classes_num++;
6413       }
6414   automaton->insn_equiv_classes_num = equiv_classes_num;
6415 }
6416
6417 \f
6418
6419 /* This page contains code for creating DFA(s) and calls functions
6420    building them.  */
6421
6422
6423 /* The following value is used to prevent floating point overflow for
6424    estimating an automaton bound.  The value should be less DBL_MAX on
6425    the host machine.  We use here approximate minimum of maximal
6426    double floating point value required by ANSI C standard.  It
6427    will work for non ANSI sun compiler too.  */
6428
6429 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND  1.0E37
6430
6431 /* The function estimate size of the single DFA used by PHR (pipeline
6432    hazards recognizer).  */
6433 static double
6434 estimate_one_automaton_bound (void)
6435 {
6436   decl_t decl;
6437   double one_automaton_estimation_bound;
6438   double root_value;
6439   int i;
6440
6441   one_automaton_estimation_bound = 1.0;
6442   for (i = 0; i < description->decls_num; i++)
6443     {
6444       decl = description->decls [i];
6445       if (decl->mode == dm_unit)
6446         {
6447           root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6448                                  - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6449                             / automata_num);
6450           if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6451               > one_automaton_estimation_bound)
6452             one_automaton_estimation_bound *= root_value;
6453         }
6454     }
6455   return one_automaton_estimation_bound;
6456 }
6457
6458 /* The function compares unit declarations according to their maximal
6459    cycle in reservations.  */
6460 static int
6461 compare_max_occ_cycle_nums (const void *unit_decl_1,
6462                             const void *unit_decl_2)
6463 {
6464   if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
6465       < (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
6466     return 1;
6467   else if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
6468            == (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
6469     return 0;
6470   else
6471     return -1;
6472 }
6473
6474 /* The function makes heuristic assigning automata to units.  Actually
6475    efficacy of the algorithm has been checked yet??? */
6476
6477 static void
6478 units_to_automata_heuristic_distr (void)
6479 {
6480   double estimation_bound;
6481   int automaton_num;
6482   int rest_units_num;
6483   double bound_value;
6484   unit_decl_t *unit_decls;
6485   int i, j;
6486
6487   if (description->units_num == 0)
6488     return;
6489   estimation_bound = estimate_one_automaton_bound ();
6490   unit_decls = XNEWVEC (unit_decl_t, description->units_num);
6491
6492   for (i = 0, j = 0; i < description->decls_num; i++)
6493     if (description->decls[i]->mode == dm_unit)
6494       unit_decls[j++] = DECL_UNIT (description->decls[i]);
6495   gcc_assert (j == description->units_num);
6496
6497   qsort (unit_decls, description->units_num,
6498          sizeof (unit_decl_t), compare_max_occ_cycle_nums);
6499
6500   automaton_num = 0;
6501   bound_value = unit_decls[0]->max_occ_cycle_num;
6502   unit_decls[0]->corresponding_automaton_num = automaton_num;
6503
6504   for (i = 1; i < description->units_num; i++)
6505     {
6506       rest_units_num = description->units_num - i + 1;
6507       gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6508       if (automaton_num < automata_num - 1
6509           && ((automata_num - automaton_num - 1 == rest_units_num)
6510               || (bound_value
6511                   > (estimation_bound
6512                      / unit_decls[i]->max_occ_cycle_num))))
6513         {
6514           bound_value = unit_decls[i]->max_occ_cycle_num;
6515           automaton_num++;
6516         }
6517       else
6518         bound_value *= unit_decls[i]->max_occ_cycle_num;
6519       unit_decls[i]->corresponding_automaton_num = automaton_num;
6520     }
6521   gcc_assert (automaton_num == automata_num - 1);
6522   free (unit_decls);
6523 }
6524
6525 /* The functions creates automaton insns for each automata.  Automaton
6526    insn is simply insn for given automaton which makes reservation
6527    only of units of the automaton.  */
6528 static ainsn_t
6529 create_ainsns (void)
6530 {
6531   decl_t decl;
6532   ainsn_t first_ainsn;
6533   ainsn_t curr_ainsn;
6534   ainsn_t prev_ainsn;
6535   int i;
6536
6537   first_ainsn = NULL;
6538   prev_ainsn = NULL;
6539   for (i = 0; i < description->decls_num; i++)
6540     {
6541       decl = description->decls [i];
6542       if (decl->mode == dm_insn_reserv)
6543         {
6544           curr_ainsn = XCREATENODE (struct ainsn);
6545           curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6546           curr_ainsn->important_p = FALSE;
6547           curr_ainsn->next_ainsn = NULL;
6548           if (prev_ainsn == NULL)
6549             first_ainsn = curr_ainsn;
6550           else
6551             prev_ainsn->next_ainsn = curr_ainsn;
6552           prev_ainsn = curr_ainsn;
6553         }
6554     }
6555   return first_ainsn;
6556 }
6557
6558 /* The function assigns automata to units according to constructions
6559    `define_automaton' in the description.  */
6560 static void
6561 units_to_automata_distr (void)
6562 {
6563   decl_t decl;
6564   int i;
6565
6566   for (i = 0; i < description->decls_num; i++)
6567     {
6568       decl = description->decls [i];
6569       if (decl->mode == dm_unit)
6570         {
6571           if (DECL_UNIT (decl)->automaton_decl == NULL
6572               || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6573                   == NULL))
6574             /* Distribute to the first automaton.  */
6575             DECL_UNIT (decl)->corresponding_automaton_num = 0;
6576           else
6577             DECL_UNIT (decl)->corresponding_automaton_num
6578               = (DECL_UNIT (decl)->automaton_decl
6579                  ->corresponding_automaton->automaton_order_num);
6580         }
6581     }
6582 }
6583
6584 /* The function creates DFA(s) for fast pipeline hazards recognition
6585    after checking and simplifying IR of the description.  */
6586 static void
6587 create_automata (void)
6588 {
6589   automaton_t curr_automaton;
6590   automaton_t prev_automaton;
6591   decl_t decl;
6592   int curr_automaton_num;
6593   int i;
6594
6595   if (automata_num != 0)
6596     {
6597       units_to_automata_heuristic_distr ();
6598       for (prev_automaton = NULL, curr_automaton_num = 0;
6599            curr_automaton_num < automata_num;
6600            curr_automaton_num++, prev_automaton = curr_automaton)
6601         {
6602           curr_automaton = XCREATENODE (struct automaton);
6603           curr_automaton->ainsn_list = create_ainsns ();
6604           curr_automaton->corresponding_automaton_decl = NULL;
6605           curr_automaton->next_automaton = NULL;
6606           curr_automaton->automaton_order_num = curr_automaton_num;
6607           if (prev_automaton == NULL)
6608             description->first_automaton = curr_automaton;
6609           else
6610             prev_automaton->next_automaton = curr_automaton;
6611         }
6612     }
6613   else
6614     {
6615       curr_automaton_num = 0;
6616       prev_automaton = NULL;
6617       for (i = 0; i < description->decls_num; i++)
6618         {
6619           decl = description->decls [i];
6620           if (decl->mode == dm_automaton
6621               && DECL_AUTOMATON (decl)->automaton_is_used)
6622             {
6623               curr_automaton = XCREATENODE (struct automaton);
6624               curr_automaton->ainsn_list = create_ainsns ();
6625               curr_automaton->corresponding_automaton_decl
6626                 = DECL_AUTOMATON (decl);
6627               curr_automaton->next_automaton = NULL;
6628               DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6629               curr_automaton->automaton_order_num = curr_automaton_num;
6630               if (prev_automaton == NULL)
6631                 description->first_automaton = curr_automaton;
6632               else
6633                 prev_automaton->next_automaton = curr_automaton;
6634               curr_automaton_num++;
6635               prev_automaton = curr_automaton;
6636             }
6637         }
6638       if (curr_automaton_num == 0)
6639         {
6640           curr_automaton = XCREATENODE (struct automaton);
6641           curr_automaton->ainsn_list = create_ainsns ();
6642           curr_automaton->corresponding_automaton_decl = NULL;
6643           curr_automaton->next_automaton = NULL;
6644           description->first_automaton = curr_automaton;
6645         }
6646       units_to_automata_distr ();
6647     }
6648   NDFA_time = create_ticker ();
6649   ticker_off (&NDFA_time);
6650   NDFA_to_DFA_time = create_ticker ();
6651   ticker_off (&NDFA_to_DFA_time);
6652   minimize_time = create_ticker ();
6653   ticker_off (&minimize_time);
6654   equiv_time = create_ticker ();
6655   ticker_off (&equiv_time);
6656   for (curr_automaton = description->first_automaton;
6657        curr_automaton != NULL;
6658        curr_automaton = curr_automaton->next_automaton)
6659     {
6660       if (progress_flag)
6661         {
6662           if (curr_automaton->corresponding_automaton_decl == NULL)
6663             fprintf (stderr, "Prepare anonymous automaton creation ... ");
6664           else
6665             fprintf (stderr, "Prepare automaton `%s' creation...",
6666                      curr_automaton->corresponding_automaton_decl->name);
6667         }
6668       create_alt_states (curr_automaton);
6669       form_ainsn_with_same_reservs (curr_automaton);
6670       if (progress_flag)
6671         fprintf (stderr, "done\n");
6672       build_automaton (curr_automaton);
6673       enumerate_states (curr_automaton);
6674       ticker_on (&equiv_time);
6675       set_insn_equiv_classes (curr_automaton);
6676       ticker_off (&equiv_time);
6677     }
6678 }
6679
6680 \f
6681
6682 /* This page contains code for forming string representation of
6683    regexp.  The representation is formed on IR obstack.  So you should
6684    not work with IR obstack between regexp_representation and
6685    finish_regexp_representation calls.  */
6686
6687 /* This recursive function forms string representation of regexp
6688    (without tailing '\0').  */
6689 static void
6690 form_regexp (regexp_t regexp)
6691 {
6692   int i;
6693
6694   switch (regexp->mode)
6695     {
6696     case rm_unit: case rm_reserv:
6697       {
6698         const char *name = (regexp->mode == rm_unit
6699                             ? REGEXP_UNIT (regexp)->name
6700                             : REGEXP_RESERV (regexp)->name);
6701
6702         obstack_grow (&irp, name, strlen (name));
6703         break;
6704       }
6705
6706     case rm_sequence:
6707       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6708         {
6709           if (i != 0)
6710             obstack_1grow (&irp, ',');
6711           form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6712         }
6713       break;
6714
6715     case rm_allof:
6716       obstack_1grow (&irp, '(');
6717       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6718         {
6719           if (i != 0)
6720             obstack_1grow (&irp, '+');
6721           if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6722               || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6723             obstack_1grow (&irp, '(');
6724           form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6725           if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6726               || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6727             obstack_1grow (&irp, ')');
6728         }
6729       obstack_1grow (&irp, ')');
6730       break;
6731
6732     case rm_oneof:
6733       for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6734         {
6735           if (i != 0)
6736             obstack_1grow (&irp, '|');
6737           if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6738             obstack_1grow (&irp, '(');
6739           form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6740           if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6741           obstack_1grow (&irp, ')');
6742         }
6743       break;
6744
6745     case rm_repeat:
6746       {
6747         char digits [30];
6748
6749         if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6750             || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6751             || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6752           obstack_1grow (&irp, '(');
6753         form_regexp (REGEXP_REPEAT (regexp)->regexp);
6754         if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6755             || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6756             || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6757           obstack_1grow (&irp, ')');
6758         sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6759         obstack_grow (&irp, digits, strlen (digits));
6760         break;
6761       }
6762
6763     case rm_nothing:
6764       obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6765       break;
6766
6767     default:
6768       gcc_unreachable ();
6769     }
6770 }
6771
6772 /* The function returns string representation of REGEXP on IR
6773    obstack.  */
6774 static const char *
6775 regexp_representation (regexp_t regexp)
6776 {
6777   form_regexp (regexp);
6778   obstack_1grow (&irp, '\0');
6779   return obstack_base (&irp);
6780 }
6781
6782 /* The function frees memory allocated for last formed string
6783    representation of regexp.  */
6784 static void
6785 finish_regexp_representation (void)
6786 {
6787   int length = obstack_object_size (&irp);
6788
6789   obstack_blank_fast (&irp, -length);
6790 }
6791
6792 \f
6793
6794 /* This page contains code for output PHR (pipeline hazards recognizer).  */
6795
6796 /* The function outputs minimal C type which is sufficient for
6797    representation numbers in range min_range_value and
6798    max_range_value.  Because host machine and build machine may be
6799    different, we use here minimal values required by ANSI C standard
6800    instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc.  This is a good
6801    approximation.  */
6802
6803 static void
6804 output_range_type (FILE *f, long int min_range_value,
6805                    long int max_range_value)
6806 {
6807   if (min_range_value >= 0 && max_range_value <= 255)
6808     fprintf (f, "unsigned char");
6809   else if (min_range_value >= -127 && max_range_value <= 127)
6810     fprintf (f, "signed char");
6811   else if (min_range_value >= 0 && max_range_value <= 65535)
6812     fprintf (f, "unsigned short");
6813   else if (min_range_value >= -32767 && max_range_value <= 32767)
6814     fprintf (f, "short");
6815   else
6816     fprintf (f, "int");
6817 }
6818
6819 /* The function outputs all initialization values of VECT.  */
6820 static void
6821 output_vect (vla_hwint_t vect)
6822 {
6823   int els_on_line;
6824   size_t vect_length = VEC_length (vect_el_t, vect);
6825   size_t i;
6826
6827   els_on_line = 1;
6828   if (vect_length == 0)
6829     fputs ("0 /* This is dummy el because the vect is empty */", output_file);
6830   else
6831     for (i = 0; i < vect_length; i++)
6832       {
6833         fprintf (output_file, "%5ld", (long) VEC_index (vect_el_t, vect, i));
6834         if (els_on_line == 10)
6835           {
6836             els_on_line = 0;
6837             fputs (",\n", output_file);
6838           }
6839         else if (i < vect_length-1)
6840           fputs (", ", output_file);
6841         els_on_line++;
6842       }
6843 }
6844
6845 /* The following is name of the structure which represents DFA(s) for
6846    PHR.  */
6847 #define CHIP_NAME "DFA_chip"
6848
6849 /* The following is name of member which represents state of a DFA for
6850    PHR.  */
6851 static void
6852 output_chip_member_name (FILE *f, automaton_t automaton)
6853 {
6854   if (automaton->corresponding_automaton_decl == NULL)
6855     fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6856   else
6857     fprintf (f, "%s_automaton_state",
6858              automaton->corresponding_automaton_decl->name);
6859 }
6860
6861 /* The following is name of temporary variable which stores state of a
6862    DFA for PHR.  */
6863 static void
6864 output_temp_chip_member_name (FILE *f, automaton_t automaton)
6865 {
6866   fprintf (f, "_");
6867   output_chip_member_name (f, automaton);
6868 }
6869
6870 /* This is name of macro value which is code of pseudo_insn
6871    representing advancing cpu cycle.  Its value is used as internal
6872    code unknown insn.  */
6873 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6874
6875 /* Output name of translate vector for given automaton.  */
6876 static void
6877 output_translate_vect_name (FILE *f, automaton_t automaton)
6878 {
6879   if (automaton->corresponding_automaton_decl == NULL)
6880     fprintf (f, "translate_%d", automaton->automaton_order_num);
6881   else
6882     fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6883 }
6884
6885 /* Output name for simple transition table representation.  */
6886 static void
6887 output_trans_full_vect_name (FILE *f, automaton_t automaton)
6888 {
6889   if (automaton->corresponding_automaton_decl == NULL)
6890     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6891   else
6892     fprintf (f, "%s_transitions",
6893              automaton->corresponding_automaton_decl->name);
6894 }
6895
6896 /* Output name of comb vector of the transition table for given
6897    automaton.  */
6898 static void
6899 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
6900 {
6901   if (automaton->corresponding_automaton_decl == NULL)
6902     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6903   else
6904     fprintf (f, "%s_transitions",
6905              automaton->corresponding_automaton_decl->name);
6906 }
6907
6908 /* Output name of check vector of the transition table for given
6909    automaton.  */
6910 static void
6911 output_trans_check_vect_name (FILE *f, automaton_t automaton)
6912 {
6913   if (automaton->corresponding_automaton_decl == NULL)
6914     fprintf (f, "check_%d", automaton->automaton_order_num);
6915   else
6916     fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6917 }
6918
6919 /* Output name of base vector of the transition table for given
6920    automaton.  */
6921 static void
6922 output_trans_base_vect_name (FILE *f, automaton_t automaton)
6923 {
6924   if (automaton->corresponding_automaton_decl == NULL)
6925     fprintf (f, "base_%d", automaton->automaton_order_num);
6926   else
6927     fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6928 }
6929
6930 /* Output name of simple min issue delay table representation.  */
6931 static void
6932 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
6933 {
6934   if (automaton->corresponding_automaton_decl == NULL)
6935     fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6936   else
6937     fprintf (f, "%s_min_issue_delay",
6938              automaton->corresponding_automaton_decl->name);
6939 }
6940
6941 /* Output name of deadlock vector for given automaton.  */
6942 static void
6943 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
6944 {
6945   if (automaton->corresponding_automaton_decl == NULL)
6946     fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6947   else
6948     fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6949 }
6950
6951 /* Output name of reserved units table for AUTOMATON into file F.  */
6952 static void
6953 output_reserved_units_table_name (FILE *f, automaton_t automaton)
6954 {
6955   if (automaton->corresponding_automaton_decl == NULL)
6956     fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6957   else
6958     fprintf (f, "%s_reserved_units",
6959              automaton->corresponding_automaton_decl->name);
6960 }
6961
6962 /* Name of the PHR interface macro.  */
6963 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6964
6965 /* Names of an internal functions: */
6966 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6967
6968 /* This is external type of DFA(s) state.  */
6969 #define STATE_TYPE_NAME "state_t"
6970
6971 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6972
6973 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6974
6975 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6976
6977 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6978
6979 /* Name of cache of insn dfa codes.  */
6980 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6981
6982 /* Name of length of cache of insn dfa codes.  */
6983 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6984
6985 /* Names of the PHR interface functions: */
6986 #define SIZE_FUNC_NAME "state_size"
6987
6988 #define TRANSITION_FUNC_NAME "state_transition"
6989
6990 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6991
6992 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6993
6994 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6995
6996 #define RESET_FUNC_NAME "state_reset"
6997
6998 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6999
7000 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7001
7002 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7003
7004 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7005
7006 #define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p"
7007
7008 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME  "dfa_clean_insn_cache"
7009
7010 #define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
7011
7012 #define DFA_START_FUNC_NAME  "dfa_start"
7013
7014 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7015
7016 /* Names of parameters of the PHR interface functions.  */
7017 #define STATE_NAME "state"
7018
7019 #define INSN_PARAMETER_NAME "insn"
7020
7021 #define INSN2_PARAMETER_NAME "insn2"
7022
7023 #define CHIP_PARAMETER_NAME "chip"
7024
7025 #define FILE_PARAMETER_NAME "f"
7026
7027 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7028
7029 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7030
7031 /* Names of the variables whose values are internal insn code of rtx
7032    insn.  */
7033 #define INTERNAL_INSN_CODE_NAME "insn_code"
7034
7035 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7036
7037 /* Names of temporary variables in some functions.  */
7038 #define TEMPORARY_VARIABLE_NAME "temp"
7039
7040 #define I_VARIABLE_NAME "i"
7041
7042 /* Name of result variable in some functions.  */
7043 #define RESULT_VARIABLE_NAME "res"
7044
7045 /* Name of function (attribute) to translate insn into internal insn
7046    code.  */
7047 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7048
7049 /* Name of function (attribute) to translate insn into internal insn
7050    code with caching.  */
7051 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7052
7053 /* Output C type which is used for representation of codes of states
7054    of AUTOMATON.  */
7055 static void
7056 output_state_member_type (FILE *f, automaton_t automaton)
7057 {
7058   output_range_type (f, 0, automaton->achieved_states_num);
7059 }
7060
7061 /* Output definition of the structure representing current DFA(s)
7062    state(s).  */
7063 static void
7064 output_chip_definitions (void)
7065 {
7066   automaton_t automaton;
7067
7068   fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7069   for (automaton = description->first_automaton;
7070        automaton != NULL;
7071        automaton = automaton->next_automaton)
7072     {
7073       fprintf (output_file, "  ");
7074       output_state_member_type (output_file, automaton);
7075       fprintf (output_file, " ");
7076       output_chip_member_name (output_file, automaton);
7077       fprintf (output_file, ";\n");
7078     }
7079   fprintf (output_file, "};\n\n");
7080 #if 0
7081   fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7082 #endif
7083 }
7084
7085
7086 /* The function outputs translate vector of internal insn code into
7087    insn equivalence class number.  The equivalence class number is
7088    used to access to table and vectors representing DFA(s).  */
7089 static void
7090 output_translate_vect (automaton_t automaton)
7091 {
7092   ainsn_t ainsn;
7093   int insn_value;
7094   vla_hwint_t translate_vect;
7095
7096   translate_vect = VEC_alloc (vect_el_t, heap, description->insns_num);
7097
7098   for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7099     /* Undefined value */
7100     VEC_quick_push (vect_el_t, translate_vect,
7101                     automaton->insn_equiv_classes_num);
7102
7103   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7104     VEC_replace (vect_el_t, translate_vect,
7105                  ainsn->insn_reserv_decl->insn_num,
7106                  ainsn->insn_equiv_class_num);
7107
7108   fprintf (output_file,
7109            "/* Vector translating external insn codes to internal ones.*/\n");
7110   fprintf (output_file, "static const ");
7111   output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7112   fprintf (output_file, " ");
7113   output_translate_vect_name (output_file, automaton);
7114   fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7115   output_vect (translate_vect);
7116   fprintf (output_file, "};\n\n");
7117   VEC_free (vect_el_t, heap, translate_vect);
7118 }
7119
7120 /* The value in a table state x ainsn -> something which represents
7121    undefined value.  */
7122 static int undefined_vect_el_value;
7123
7124 /* The following function returns nonzero value if the best
7125    representation of the table is comb vector.  */
7126 static int
7127 comb_vect_p (state_ainsn_table_t tab)
7128 {
7129   return  (2 * VEC_length (vect_el_t, tab->full_vect)
7130            > 5 * VEC_length (vect_el_t, tab->comb_vect));
7131 }
7132
7133 /* The following function creates new table for AUTOMATON.  */
7134 static state_ainsn_table_t
7135 create_state_ainsn_table (automaton_t automaton)
7136 {
7137   state_ainsn_table_t tab;
7138   int full_vect_length;
7139   int i;
7140
7141   tab = XCREATENODE (struct state_ainsn_table);
7142   tab->automaton = automaton;
7143
7144   tab->comb_vect  = VEC_alloc (vect_el_t, heap, 10000);
7145   tab->check_vect = VEC_alloc (vect_el_t, heap, 10000);
7146
7147   tab->base_vect  = 0;
7148   VEC_safe_grow (vect_el_t, heap, tab->base_vect,
7149                  automaton->achieved_states_num);
7150
7151   full_vect_length = (automaton->insn_equiv_classes_num
7152                       * automaton->achieved_states_num);
7153   tab->full_vect  = VEC_alloc (vect_el_t, heap, full_vect_length);
7154   for (i = 0; i < full_vect_length; i++)
7155     VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
7156
7157   tab->min_base_vect_el_value = 0;
7158   tab->max_base_vect_el_value = 0;
7159   tab->min_comb_vect_el_value = 0;
7160   tab->max_comb_vect_el_value = 0;
7161   return tab;
7162 }
7163
7164 /* The following function outputs the best C representation of the
7165    table TAB of given TABLE_NAME.  */
7166 static void
7167 output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
7168                           void (*output_full_vect_name_func) (FILE *, automaton_t),
7169                           void (*output_comb_vect_name_func) (FILE *, automaton_t),
7170                           void (*output_check_vect_name_func) (FILE *, automaton_t),
7171                           void (*output_base_vect_name_func) (FILE *, automaton_t))
7172 {
7173   if (!comb_vect_p (tab))
7174     {
7175       fprintf (output_file, "/* Vector for %s.  */\n", table_name);
7176       fprintf (output_file, "static const ");
7177       output_range_type (output_file, tab->min_comb_vect_el_value,
7178                          tab->max_comb_vect_el_value);
7179       fprintf (output_file, " ");
7180       (*output_full_vect_name_func) (output_file, tab->automaton);
7181       fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7182       output_vect (tab->full_vect);
7183       fprintf (output_file, "};\n\n");
7184     }
7185   else
7186     {
7187       fprintf (output_file, "/* Comb vector for %s.  */\n", table_name);
7188       fprintf (output_file, "static const ");
7189       output_range_type (output_file, tab->min_comb_vect_el_value,
7190                          tab->max_comb_vect_el_value);
7191       fprintf (output_file, " ");
7192       (*output_comb_vect_name_func) (output_file, tab->automaton);
7193       fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7194       output_vect (tab->comb_vect);
7195       fprintf (output_file, "};\n\n");
7196       fprintf (output_file, "/* Check vector for %s.  */\n", table_name);
7197       fprintf (output_file, "static const ");
7198       output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7199       fprintf (output_file, " ");
7200       (*output_check_vect_name_func) (output_file, tab->automaton);
7201       fprintf (output_file, "[] = {\n");
7202       output_vect (tab->check_vect);
7203       fprintf (output_file, "};\n\n");
7204       fprintf (output_file, "/* Base vector for %s.  */\n", table_name);
7205       fprintf (output_file, "static const ");
7206       output_range_type (output_file, tab->min_base_vect_el_value,
7207                          tab->max_base_vect_el_value);
7208       fprintf (output_file, " ");
7209       (*output_base_vect_name_func) (output_file, tab->automaton);
7210       fprintf (output_file, "[] = {\n");
7211       output_vect (tab->base_vect);
7212       fprintf (output_file, "};\n\n");
7213     }
7214 }
7215
7216 /* The following function adds vector VECT to table TAB as its line
7217    with number VECT_NUM.  */
7218 static void
7219 add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
7220 {
7221   int vect_length;
7222   size_t real_vect_length;
7223   int comb_vect_index;
7224   int comb_vect_els_num;
7225   int vect_index;
7226   int first_unempty_vect_index;
7227   int additional_els_num;
7228   int no_state_value;
7229   vect_el_t vect_el;
7230   int i;
7231   unsigned long vect_mask, comb_vect_mask;
7232
7233   vect_length = VEC_length (vect_el_t, vect);
7234   gcc_assert (vect_length);
7235   gcc_assert (VEC_last (vect_el_t, vect) != undefined_vect_el_value);
7236   real_vect_length = tab->automaton->insn_equiv_classes_num;
7237   /* Form full vector in the table: */
7238   {
7239     size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
7240     if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
7241       VEC_safe_grow (vect_el_t, heap, tab->full_vect,
7242                      full_base + vect_length);
7243     for (i = 0; i < vect_length; i++)
7244       VEC_replace (vect_el_t, tab->full_vect, full_base + i,
7245                    VEC_index (vect_el_t, vect, i));
7246   }
7247   /* Form comb vector in the table: */
7248   gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7249               == VEC_length (vect_el_t, tab->check_vect));
7250
7251   comb_vect_els_num = VEC_length (vect_el_t, tab->comb_vect);
7252   for (first_unempty_vect_index = 0;
7253        first_unempty_vect_index < vect_length;
7254        first_unempty_vect_index++)
7255     if (VEC_index (vect_el_t, vect, first_unempty_vect_index)
7256         != undefined_vect_el_value)
7257       break;
7258
7259   /* Search for the place in comb vect for the inserted vect.  */
7260
7261   /* Slow case.  */
7262   if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7263     {
7264       for (comb_vect_index = 0;
7265            comb_vect_index < comb_vect_els_num;
7266            comb_vect_index++)
7267         {
7268           for (vect_index = first_unempty_vect_index;
7269                vect_index < vect_length
7270                && vect_index + comb_vect_index < comb_vect_els_num;
7271                vect_index++)
7272             if (VEC_index (vect_el_t, vect, vect_index)
7273                 != undefined_vect_el_value
7274                 && (VEC_index (vect_el_t, tab->comb_vect,
7275                                vect_index + comb_vect_index)
7276                     != undefined_vect_el_value))
7277               break;
7278           if (vect_index >= vect_length
7279               || vect_index + comb_vect_index >= comb_vect_els_num)
7280             break;
7281         }
7282       goto found;
7283     }
7284
7285   /* Fast case.  */
7286   vect_mask = 0;
7287   for (vect_index = first_unempty_vect_index;
7288        vect_index < vect_length;
7289        vect_index++)
7290     {
7291       vect_mask = vect_mask << 1;
7292       if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
7293         vect_mask |= 1;
7294     }
7295
7296   /* Search for the place in comb vect for the inserted vect.  */
7297   comb_vect_index = 0;
7298   if (comb_vect_els_num == 0)
7299     goto found;
7300
7301   comb_vect_mask = 0;
7302   for (vect_index = first_unempty_vect_index;
7303        vect_index < vect_length && vect_index < comb_vect_els_num;
7304        vect_index++)
7305     {
7306       comb_vect_mask <<= 1;
7307       if (vect_index + comb_vect_index < comb_vect_els_num
7308           && VEC_index (vect_el_t, tab->comb_vect, vect_index + comb_vect_index)
7309              != undefined_vect_el_value)
7310         comb_vect_mask |= 1;
7311     }
7312   if ((vect_mask & comb_vect_mask) == 0)
7313     goto found;
7314
7315   for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7316        comb_vect_index++, i++)
7317     {
7318       comb_vect_mask = (comb_vect_mask << 1) | 1;
7319       comb_vect_mask ^= (VEC_index (vect_el_t, tab->comb_vect, i)
7320                          == undefined_vect_el_value);
7321       if ((vect_mask & comb_vect_mask) == 0)
7322         goto found;
7323     }
7324   for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7325     {
7326       comb_vect_mask <<= 1;
7327       if ((vect_mask & comb_vect_mask) == 0)
7328         goto found;
7329     }
7330
7331  found:
7332   /* Slot was found.  */
7333   additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7334   if (additional_els_num < 0)
7335     additional_els_num = 0;
7336   /* Expand comb and check vectors.  */
7337   vect_el = undefined_vect_el_value;
7338   no_state_value = tab->automaton->achieved_states_num;
7339   while (additional_els_num > 0)
7340     {
7341       VEC_safe_push (vect_el_t, heap, tab->comb_vect, vect_el);
7342       VEC_safe_push (vect_el_t, heap, tab->check_vect, no_state_value);
7343       additional_els_num--;
7344     }
7345   gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7346               >= comb_vect_index + real_vect_length);
7347   /* Fill comb and check vectors.  */
7348   for (vect_index = 0; vect_index < vect_length; vect_index++)
7349     if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
7350       {
7351         vect_el_t x = VEC_index (vect_el_t, vect, vect_index);
7352         gcc_assert (VEC_index (vect_el_t, tab->comb_vect,
7353                                comb_vect_index + vect_index)
7354                     == undefined_vect_el_value);
7355         gcc_assert (x >= 0);
7356         if (tab->max_comb_vect_el_value < x)
7357           tab->max_comb_vect_el_value = x;
7358         if (tab->min_comb_vect_el_value > x)
7359           tab->min_comb_vect_el_value = x;
7360         VEC_replace (vect_el_t, tab->comb_vect,
7361                      comb_vect_index + vect_index, x);
7362         VEC_replace (vect_el_t, tab->check_vect,
7363                      comb_vect_index + vect_index, vect_num);
7364       }
7365   if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7366     tab->max_comb_vect_el_value = undefined_vect_el_value;
7367   if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7368     tab->min_comb_vect_el_value = undefined_vect_el_value;
7369   if (tab->max_base_vect_el_value < comb_vect_index)
7370     tab->max_base_vect_el_value = comb_vect_index;
7371   if (tab->min_base_vect_el_value > comb_vect_index)
7372     tab->min_base_vect_el_value = comb_vect_index;
7373
7374   VEC_replace (vect_el_t, tab->base_vect, vect_num, comb_vect_index);
7375 }
7376
7377 /* Return number of out arcs of STATE.  */
7378 static int
7379 out_state_arcs_num (const_state_t state)
7380 {
7381   int result;
7382   arc_t arc;
7383
7384   result = 0;
7385   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7386     {
7387       gcc_assert (arc->insn);
7388       if (arc->insn->first_ainsn_with_given_equivalence_num)
7389         result++;
7390     }
7391   return result;
7392 }
7393
7394 /* Compare number of possible transitions from the states.  */
7395 static int
7396 compare_transition_els_num (const void *state_ptr_1,
7397                             const void *state_ptr_2)
7398 {
7399   const int transition_els_num_1
7400     = out_state_arcs_num (*(const_state_t const*) state_ptr_1);
7401   const int transition_els_num_2
7402     = out_state_arcs_num (*(const_state_t const*) state_ptr_2);
7403
7404   if (transition_els_num_1 < transition_els_num_2)
7405     return 1;
7406   else if (transition_els_num_1 == transition_els_num_2)
7407     return 0;
7408   else
7409     return -1;
7410 }
7411
7412 /* The function adds element EL_VALUE to vector VECT for a table state
7413    x AINSN.  */
7414 static void
7415 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7416 {
7417   int equiv_class_num;
7418   int vect_index;
7419
7420   gcc_assert (ainsn);
7421   equiv_class_num = ainsn->insn_equiv_class_num;
7422   for (vect_index = VEC_length (vect_el_t, *vect);
7423        vect_index <= equiv_class_num;
7424        vect_index++)
7425     VEC_safe_push (vect_el_t, heap, *vect, undefined_vect_el_value);
7426   VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
7427 }
7428
7429 /* This is for forming vector of states of an automaton.  */
7430 static VEC(state_t, heap) *output_states_vect;
7431
7432 /* The function is called by function pass_states.  The function adds
7433    STATE to `output_states_vect'.  */
7434 static void
7435 add_states_vect_el (state_t state)
7436 {
7437   VEC_safe_push (state_t, heap, output_states_vect, state);
7438 }
7439
7440 /* Form and output vectors (comb, check, base or full vector)
7441    representing transition table of AUTOMATON.  */
7442 static void
7443 output_trans_table (automaton_t automaton)
7444 {
7445   size_t i;
7446   arc_t arc;
7447   vla_hwint_t transition_vect = 0;
7448
7449   undefined_vect_el_value = automaton->achieved_states_num;
7450   automaton->trans_table = create_state_ainsn_table (automaton);
7451   /* Create vect of pointers to states ordered by num of transitions
7452      from the state (state with the maximum num is the first).  */
7453   output_states_vect = 0;
7454   pass_states (automaton, add_states_vect_el);
7455   VEC_qsort (state_t, output_states_vect, compare_transition_els_num);
7456
7457   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7458     {
7459       VEC_truncate (vect_el_t, transition_vect, 0);
7460       for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
7461            arc != NULL;
7462            arc = next_out_arc (arc))
7463         {
7464           gcc_assert (arc->insn);
7465           if (arc->insn->first_ainsn_with_given_equivalence_num)
7466             add_vect_el (&transition_vect, arc->insn,
7467                          arc->to_state->order_state_num);
7468         }
7469       add_vect (automaton->trans_table,
7470                 VEC_index (state_t, output_states_vect, i)->order_state_num,
7471                 transition_vect);
7472     }
7473   output_state_ainsn_table
7474     (automaton->trans_table, "state transitions",
7475      output_trans_full_vect_name, output_trans_comb_vect_name,
7476      output_trans_check_vect_name, output_trans_base_vect_name);
7477
7478   VEC_free (state_t, heap, output_states_vect);
7479   VEC_free (vect_el_t, heap, transition_vect);
7480 }
7481
7482 /* Form and output vectors representing minimal issue delay table of
7483    AUTOMATON.  The table is state x ainsn -> minimal issue delay of
7484    the ainsn.  */
7485 static void
7486 output_min_issue_delay_table (automaton_t automaton)
7487 {
7488   vla_hwint_t min_issue_delay_vect;
7489   vla_hwint_t compressed_min_issue_delay_vect;
7490   ainsn_t ainsn;
7491   size_t i;
7492   size_t min_issue_delay_len, compressed_min_issue_delay_len;
7493   size_t cfactor;
7494   int changed;
7495
7496   /* Create vect of pointers to states ordered by num of transitions
7497      from the state (state with the maximum num is the first).  */
7498   output_states_vect = 0;
7499   pass_states (automaton, add_states_vect_el);
7500
7501   min_issue_delay_len = (VEC_length (state_t, output_states_vect)
7502                          * automaton->insn_equiv_classes_num);
7503   min_issue_delay_vect = VEC_alloc (vect_el_t, heap, min_issue_delay_len);
7504   for (i = 0; i < min_issue_delay_len; i++)
7505     VEC_quick_push (vect_el_t, min_issue_delay_vect, -1);
7506
7507   automaton->max_min_delay = 0;
7508
7509   do
7510     {
7511       size_t state_no;
7512
7513       changed = 0;
7514
7515       for (state_no = 0; state_no < VEC_length (state_t, output_states_vect);
7516            state_no++)
7517         {
7518           state_t s = VEC_index (state_t, output_states_vect, state_no);
7519           arc_t arc;
7520
7521           for (arc = first_out_arc (s); arc; arc = next_out_arc (arc))
7522             {
7523               int k;
7524
7525               size_t asn = s->order_state_num
7526                            * automaton->insn_equiv_classes_num
7527                            + arc->insn->insn_equiv_class_num;
7528
7529               if (VEC_index (vect_el_t, min_issue_delay_vect, asn))
7530                 {
7531                   VEC_replace (vect_el_t, min_issue_delay_vect, asn, 0);
7532                   changed = 1;
7533                 }
7534
7535               for (k = 0; k < automaton->insn_equiv_classes_num; k++)
7536                 {
7537                   size_t n0, n1;
7538                   vect_el_t delay0, delay1;
7539
7540                   n0 = s->order_state_num
7541                        * automaton->insn_equiv_classes_num
7542                        + k;
7543                   n1 = arc->to_state->order_state_num
7544                        * automaton->insn_equiv_classes_num
7545                        + k;
7546                   delay0 = VEC_index (vect_el_t, min_issue_delay_vect, n0);
7547                   delay1 = VEC_index (vect_el_t, min_issue_delay_vect, n1);
7548                   if (delay1 != -1)
7549                     {
7550                       if (arc->insn->insn_reserv_decl
7551                           == DECL_INSN_RESERV (advance_cycle_insn_decl))
7552                         delay1++;
7553                       if (delay1 < delay0 || delay0 == -1)
7554                         {
7555                           VEC_replace (vect_el_t, min_issue_delay_vect, n0, delay1);
7556                           changed = 1;
7557                         }
7558                     }
7559                 }
7560             }
7561         }
7562     }
7563   while (changed);
7564
7565   automaton->max_min_delay = 0;
7566
7567   for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn)
7568     if (ainsn->first_ainsn_with_given_equivalence_num)
7569       {
7570         for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7571           {
7572             state_t s = VEC_index (state_t, output_states_vect, i);
7573             size_t np = s->order_state_num
7574                         * automaton->insn_equiv_classes_num
7575                         + ainsn->insn_equiv_class_num;
7576             vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, np);
7577
7578             if (automaton->max_min_delay < x)
7579               automaton->max_min_delay = x;
7580             if (x == -1)
7581               VEC_replace (vect_el_t, min_issue_delay_vect, np, 0);
7582           }
7583       }
7584
7585   fprintf (output_file, "/* Vector of min issue delay of insns.  */\n");
7586   fprintf (output_file, "static const ");
7587   output_range_type (output_file, 0, automaton->max_min_delay);
7588   fprintf (output_file, " ");
7589   output_min_issue_delay_vect_name (output_file, automaton);
7590   fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7591   /* Compress the vector.  */
7592   if (automaton->max_min_delay < 2)
7593     cfactor = 8;
7594   else if (automaton->max_min_delay < 4)
7595     cfactor = 4;
7596   else if (automaton->max_min_delay < 16)
7597     cfactor = 2;
7598   else
7599     cfactor = 1;
7600   automaton->min_issue_delay_table_compression_factor = cfactor;
7601
7602   compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
7603   compressed_min_issue_delay_vect
7604     = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len);
7605
7606   for (i = 0; i < compressed_min_issue_delay_len; i++)
7607     VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
7608
7609   for (i = 0; i < min_issue_delay_len; i++)
7610     {
7611       size_t ci = i / cfactor;
7612       vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, i);
7613       vect_el_t cx = VEC_index (vect_el_t, compressed_min_issue_delay_vect, ci);
7614
7615       cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
7616       VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx);
7617     }
7618   output_vect (compressed_min_issue_delay_vect);
7619   fprintf (output_file, "};\n\n");
7620   VEC_free (state_t, heap, output_states_vect);
7621   VEC_free (vect_el_t, heap, min_issue_delay_vect);
7622   VEC_free (vect_el_t, heap, compressed_min_issue_delay_vect);
7623 }
7624
7625 /* Form and output vector representing the locked states of
7626    AUTOMATON.  */
7627 static void
7628 output_dead_lock_vect (automaton_t automaton)
7629 {
7630   size_t i;
7631   arc_t arc;
7632   vla_hwint_t dead_lock_vect = 0;
7633
7634   /* Create vect of pointers to states ordered by num of
7635      transitions from the state (state with the maximum num is the
7636      first).  */
7637   automaton->locked_states = 0;
7638   output_states_vect = 0;
7639   pass_states (automaton, add_states_vect_el);
7640
7641   VEC_safe_grow (vect_el_t, heap, dead_lock_vect,
7642                  VEC_length (state_t, output_states_vect));
7643   for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7644     {
7645       state_t s = VEC_index (state_t, output_states_vect, i);
7646       arc = first_out_arc (s);
7647       gcc_assert (arc);
7648       if (next_out_arc (arc) == NULL
7649           && (arc->insn->insn_reserv_decl
7650               == DECL_INSN_RESERV (advance_cycle_insn_decl)))
7651         {
7652           VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 1);
7653           automaton->locked_states++;
7654         }
7655       else
7656         VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 0);
7657     }
7658   if (automaton->locked_states == 0)
7659     return;
7660
7661   fprintf (output_file, "/* Vector for locked state flags.  */\n");
7662   fprintf (output_file, "static const ");
7663   output_range_type (output_file, 0, 1);
7664   fprintf (output_file, " ");
7665   output_dead_lock_vect_name (output_file, automaton);
7666   fprintf (output_file, "[] = {\n");
7667   output_vect (dead_lock_vect);
7668   fprintf (output_file, "};\n\n");
7669   VEC_free (state_t, heap, output_states_vect);
7670   VEC_free (vect_el_t, heap, dead_lock_vect);
7671 }
7672
7673 /* Form and output vector representing reserved units of the states of
7674    AUTOMATON.  */
7675 static void
7676 output_reserved_units_table (automaton_t automaton)
7677 {
7678   vla_hwint_t reserved_units_table = 0;
7679   int state_byte_size;
7680   int reserved_units_size;
7681   size_t n;
7682   int i;
7683
7684   if (description->query_units_num == 0)
7685     return;
7686
7687   /* Create vect of pointers to states.  */
7688   output_states_vect = 0;
7689   pass_states (automaton, add_states_vect_el);
7690   /* Create vector.  */
7691   state_byte_size = (description->query_units_num + 7) / 8;
7692   reserved_units_size = (VEC_length (state_t, output_states_vect)
7693                          * state_byte_size);
7694
7695   reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size);
7696
7697   for (i = 0; i < reserved_units_size; i++)
7698     VEC_quick_push (vect_el_t, reserved_units_table, 0);
7699   for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
7700     {
7701       state_t s = VEC_index (state_t, output_states_vect, n);
7702       for (i = 0; i < description->units_num; i++)
7703         if (units_array [i]->query_p
7704             && first_cycle_unit_presence (s, i))
7705           {
7706             int ri = (s->order_state_num * state_byte_size
7707                       + units_array [i]->query_num / 8);
7708             vect_el_t x = VEC_index (vect_el_t, reserved_units_table, ri);
7709
7710             x += 1 << (units_array [i]->query_num % 8);
7711             VEC_replace (vect_el_t, reserved_units_table, ri, x);
7712           }
7713     }
7714   fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
7715   fprintf (output_file, "/* Vector for reserved units of states.  */\n");
7716   fprintf (output_file, "static const ");
7717   output_range_type (output_file, 0, 255);
7718   fprintf (output_file, " ");
7719   output_reserved_units_table_name (output_file, automaton);
7720   fprintf (output_file, "[] = {\n");
7721   output_vect (reserved_units_table);
7722   fprintf (output_file, "};\n#endif /* #if %s */\n\n",
7723            CPU_UNITS_QUERY_MACRO_NAME);
7724
7725   VEC_free (state_t, heap, output_states_vect);
7726   VEC_free (vect_el_t, heap, reserved_units_table);
7727 }
7728
7729 /* The function outputs all tables representing DFA(s) used for fast
7730    pipeline hazards recognition.  */
7731 static void
7732 output_tables (void)
7733 {
7734   automaton_t automaton;
7735
7736   for (automaton = description->first_automaton;
7737        automaton != NULL;
7738        automaton = automaton->next_automaton)
7739     {
7740       output_translate_vect (automaton);
7741       output_trans_table (automaton);
7742       output_min_issue_delay_table (automaton);
7743       output_dead_lock_vect (automaton);
7744       output_reserved_units_table (automaton);
7745     }
7746   fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7747            DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
7748 }
7749
7750 /* The function outputs definition and value of PHR interface variable
7751    `max_insn_queue_index'.  Its value is not less than maximal queue
7752    length needed for the insn scheduler.  */
7753 static void
7754 output_max_insn_queue_index_def (void)
7755 {
7756   int i, max, latency;
7757   decl_t decl;
7758
7759   max = description->max_insn_reserv_cycles;
7760   for (i = 0; i < description->decls_num; i++)
7761     {
7762       decl = description->decls [i];
7763       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
7764         {
7765           latency = DECL_INSN_RESERV (decl)->default_latency;
7766           if (latency > max)
7767             max = latency;
7768         }
7769       else if (decl->mode == dm_bypass)
7770         {
7771           latency = DECL_BYPASS (decl)->latency;
7772           if (latency > max)
7773             max = latency;
7774         }
7775     }
7776   for (i = 0; (1 << i) <= max; i++)
7777     ;
7778   gcc_assert (i >= 0);
7779   fprintf (output_file, "\nconst int max_insn_queue_index = %d;\n\n",
7780            (1 << i) - 1);
7781 }
7782
7783 /* The function outputs switch cases for insn reservations using
7784    function *output_automata_list_code.  */
7785 static void
7786 output_insn_code_cases (void (*output_automata_list_code)
7787                         (automata_list_el_t))
7788 {
7789   decl_t decl, decl2;
7790   int i, j;
7791
7792   for (i = 0; i < description->decls_num; i++)
7793     {
7794       decl = description->decls [i];
7795       if (decl->mode == dm_insn_reserv)
7796         DECL_INSN_RESERV (decl)->processed_p = FALSE;
7797     }
7798   for (i = 0; i < description->decls_num; i++)
7799     {
7800       decl = description->decls [i];
7801       if (decl->mode == dm_insn_reserv
7802           && !DECL_INSN_RESERV (decl)->processed_p)
7803         {
7804           for (j = i; j < description->decls_num; j++)
7805             {
7806               decl2 = description->decls [j];
7807               if (decl2->mode == dm_insn_reserv
7808                   && (DECL_INSN_RESERV (decl2)->important_automata_list
7809                       == DECL_INSN_RESERV (decl)->important_automata_list))
7810                 {
7811                   DECL_INSN_RESERV (decl2)->processed_p = TRUE;
7812                   fprintf (output_file, "    case %d: /* %s */\n",
7813                            DECL_INSN_RESERV (decl2)->insn_num,
7814                            DECL_INSN_RESERV (decl2)->name);
7815                 }
7816             }
7817           (*output_automata_list_code)
7818             (DECL_INSN_RESERV (decl)->important_automata_list);
7819         }
7820     }
7821 }
7822
7823
7824 /* The function outputs a code for evaluation of a minimal delay of
7825    issue of insns which have reservations in given AUTOMATA_LIST.  */
7826 static void
7827 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
7828 {
7829   automata_list_el_t el;
7830   automaton_t automaton;
7831
7832   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7833     {
7834       automaton = el->automaton;
7835       fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);
7836       output_min_issue_delay_vect_name (output_file, automaton);
7837       fprintf (output_file,
7838                (automaton->min_issue_delay_table_compression_factor != 1
7839                 ? " [(" : " ["));
7840       output_translate_vect_name (output_file, automaton);
7841       fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7842       fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7843       output_chip_member_name (output_file, automaton);
7844       fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7845       if (automaton->min_issue_delay_table_compression_factor == 1)
7846         fprintf (output_file, "];\n");
7847       else
7848         {
7849           fprintf (output_file, ") / %d];\n",
7850                    automaton->min_issue_delay_table_compression_factor);
7851           fprintf (output_file, "      %s = (%s >> (8 - ((",
7852                    TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7853           output_translate_vect_name (output_file, automaton);
7854           fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7855           fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7856           output_chip_member_name (output_file, automaton);
7857           fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num);
7858           fprintf
7859             (output_file, " %% %d + 1) * %d)) & %d;\n",
7860              automaton->min_issue_delay_table_compression_factor,
7861              8 / automaton->min_issue_delay_table_compression_factor,
7862              (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7863              - 1);
7864         }
7865       if (el == automata_list)
7866         fprintf (output_file, "      %s = %s;\n",
7867                  RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7868       else
7869         {
7870           fprintf (output_file, "      if (%s > %s)\n",
7871                    TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7872           fprintf (output_file, "        %s = %s;\n",
7873                    RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7874         }
7875     }
7876   fprintf (output_file, "      break;\n\n");
7877 }
7878
7879 /* Output function `internal_min_issue_delay'.  */
7880 static void
7881 output_internal_min_issue_delay_func (void)
7882 {
7883   fprintf (output_file,
7884            "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
7885            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7886            CHIP_NAME, CHIP_PARAMETER_NAME);
7887   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s = -1;\n",
7888            TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7889   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
7890   output_insn_code_cases (output_automata_list_min_issue_delay_code);
7891   fprintf (output_file,
7892            "\n    default:\n      %s = -1;\n      break;\n    }\n",
7893            RESULT_VARIABLE_NAME);
7894   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
7895   fprintf (output_file, "}\n\n");
7896 }
7897
7898 /* The function outputs a code changing state after issue of insns
7899    which have reservations in given AUTOMATA_LIST.  */
7900 static void
7901 output_automata_list_transition_code (automata_list_el_t automata_list)
7902 {
7903   automata_list_el_t el, next_el;
7904
7905   fprintf (output_file, "      {\n");
7906   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7907     for (el = automata_list;; el = next_el)
7908       {
7909         next_el = el->next_automata_list_el;
7910         if (next_el == NULL)
7911           break;
7912         fprintf (output_file, "        ");
7913         output_state_member_type (output_file, el->automaton);
7914         fprintf (output_file, " ");
7915         output_temp_chip_member_name (output_file, el->automaton);
7916         fprintf (output_file, ";\n");
7917       }
7918   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7919     if (comb_vect_p (el->automaton->trans_table))
7920       {
7921         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
7922         output_trans_base_vect_name (output_file, el->automaton);
7923         fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7924         output_chip_member_name (output_file, el->automaton);
7925         fprintf (output_file, "] + ");
7926         output_translate_vect_name (output_file, el->automaton);
7927         fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7928         fprintf (output_file, "        if (");
7929         output_trans_check_vect_name (output_file, el->automaton);
7930         fprintf (output_file, " [%s] != %s->",
7931                  TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7932         output_chip_member_name (output_file, el->automaton);
7933         fprintf (output_file, ")\n");
7934         fprintf (output_file, "          return %s (%s, %s);\n",
7935                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7936                  CHIP_PARAMETER_NAME);
7937         fprintf (output_file, "        else\n");
7938         fprintf (output_file, "          ");
7939         if (el->next_automata_list_el != NULL)
7940           output_temp_chip_member_name (output_file, el->automaton);
7941         else
7942           {
7943             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7944             output_chip_member_name (output_file, el->automaton);
7945           }
7946         fprintf (output_file, " = ");
7947         output_trans_comb_vect_name (output_file, el->automaton);
7948         fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7949       }
7950     else
7951       {
7952         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
7953         output_trans_full_vect_name (output_file, el->automaton);
7954         fprintf (output_file, " [");
7955         output_translate_vect_name (output_file, el->automaton);
7956         fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7957         fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7958         output_chip_member_name (output_file, el->automaton);
7959         fprintf (output_file, " * %d];\n",
7960                  el->automaton->insn_equiv_classes_num);
7961         fprintf (output_file, "        if (%s >= %d)\n",
7962                  TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7963         fprintf (output_file, "          return %s (%s, %s);\n",
7964                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7965                  CHIP_PARAMETER_NAME);
7966         fprintf (output_file, "        else\n          ");
7967         if (el->next_automata_list_el != NULL)
7968           output_temp_chip_member_name (output_file, el->automaton);
7969         else
7970           {
7971             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7972             output_chip_member_name (output_file, el->automaton);
7973           }
7974         fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7975       }
7976   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7977     for (el = automata_list;; el = next_el)
7978       {
7979         next_el = el->next_automata_list_el;
7980         if (next_el == NULL)
7981           break;
7982         fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);
7983         output_chip_member_name (output_file, el->automaton);
7984         fprintf (output_file, " = ");
7985         output_temp_chip_member_name (output_file, el->automaton);
7986         fprintf (output_file, ";\n");
7987       }
7988   fprintf (output_file, "        return -1;\n");
7989   fprintf (output_file, "      }\n");
7990 }
7991
7992 /* Output function `internal_state_transition'.  */
7993 static void
7994 output_internal_trans_func (void)
7995 {
7996   fprintf (output_file,
7997            "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
7998            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7999            CHIP_NAME, CHIP_PARAMETER_NAME);
8000   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8001   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8002   output_insn_code_cases (output_automata_list_transition_code);
8003   fprintf (output_file, "\n    default:\n      return -1;\n    }\n");
8004   fprintf (output_file, "}\n\n");
8005 }
8006
8007 /* Output code
8008
8009   if (insn != 0)
8010     {
8011       insn_code = dfa_insn_code (insn);
8012       if (insn_code > DFA__ADVANCE_CYCLE)
8013         return code;
8014     }
8015   else
8016     insn_code = DFA__ADVANCE_CYCLE;
8017
8018   where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8019   code denotes CODE.  */
8020 static void
8021 output_internal_insn_code_evaluation (const char *insn_name,
8022                                       const char *insn_code_name,
8023                                       int code)
8024 {
8025   fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);
8026   fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,
8027            DFA_INSN_CODE_FUNC_NAME, insn_name);
8028   fprintf (output_file, "      if (%s > %s)\n        return %d;\n",
8029            insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8030   fprintf (output_file, "    }\n  else\n    %s = %s;\n\n",
8031            insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8032 }
8033
8034
8035 /* This function outputs `dfa_insn_code' and its helper function
8036    `dfa_insn_code_enlarge'.  */
8037 static void
8038 output_dfa_insn_code_func (void)
8039 {
8040   /* Emacs c-mode gets really confused if there's a { or } in column 0
8041      inside a string, so don't do that.  */
8042   fprintf (output_file, "\
8043 static void\n\
8044 dfa_insn_code_enlarge (int uid)\n\
8045 {\n\
8046   int i = %s;\n\
8047   %s = 2 * uid;\n\
8048   %s = XRESIZEVEC (int, %s,\n\
8049                  %s);\n\
8050   for (; i < %s; i++)\n\
8051     %s[i] = -1;\n}\n\n",
8052            DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8053            DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8054            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8055            DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8056            DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8057            DFA_INSN_CODES_VARIABLE_NAME);
8058   fprintf (output_file, "\
8059 static inline int\n%s (rtx %s)\n\
8060 {\n\
8061   int uid = INSN_UID (%s);\n\
8062   int %s;\n\n",
8063            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8064            INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8065
8066   fprintf (output_file,
8067            "  if (uid >= %s)\n    dfa_insn_code_enlarge (uid);\n\n",
8068            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8069   fprintf (output_file, "  %s = %s[uid];\n",
8070            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8071   fprintf (output_file, "\
8072   if (%s < 0)\n\
8073     {\n\
8074       %s = %s (%s);\n\
8075       %s[uid] = %s;\n\
8076     }\n",
8077            INTERNAL_INSN_CODE_NAME,
8078            INTERNAL_INSN_CODE_NAME,
8079            INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8080            DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8081   fprintf (output_file, "  return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8082 }
8083
8084 /* The function outputs PHR interface function `state_transition'.  */
8085 static void
8086 output_trans_func (void)
8087 {
8088   fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8089            TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8090            INSN_PARAMETER_NAME);
8091   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8092   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8093                                         INTERNAL_INSN_CODE_NAME, -1);
8094   fprintf (output_file, "  return %s (%s, (struct %s *) %s);\n}\n\n",
8095            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
8096 }
8097
8098 /* Output function `min_issue_delay'.  */
8099 static void
8100 output_min_issue_delay_func (void)
8101 {
8102   fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8103            MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8104            INSN_PARAMETER_NAME);
8105   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8106   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8107   fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8108            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8109   fprintf (output_file, "      if (%s > %s)\n        return 0;\n",
8110            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8111   fprintf (output_file, "    }\n  else\n    %s = %s;\n",
8112            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8113   fprintf (output_file, "\n  return %s (%s, (struct %s *) %s);\n",
8114            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8115            CHIP_NAME, STATE_NAME);
8116   fprintf (output_file, "}\n\n");
8117 }
8118
8119 /* Output function `internal_dead_lock'.  */
8120 static void
8121 output_internal_dead_lock_func (void)
8122 {
8123   automaton_t automaton;
8124
8125   fprintf (output_file, "static int\n%s (struct %s *ARG_UNUSED (%s))\n",
8126            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8127   fprintf (output_file, "{\n");
8128   for (automaton = description->first_automaton;
8129        automaton != NULL;
8130        automaton = automaton->next_automaton)
8131     if (automaton->locked_states)
8132       {
8133         fprintf (output_file, "  if (");
8134         output_dead_lock_vect_name (output_file, automaton);
8135         fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8136         output_chip_member_name (output_file, automaton);
8137         fprintf (output_file, "])\n    return 1/* TRUE */;\n");
8138       }
8139   fprintf (output_file, "  return 0/* FALSE */;\n}\n\n");
8140 }
8141
8142 /* The function outputs PHR interface function `state_dead_lock_p'.  */
8143 static void
8144 output_dead_lock_func (void)
8145 {
8146   fprintf (output_file, "int\n%s (%s %s)\n",
8147            DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8148   fprintf (output_file, "{\n  return %s ((struct %s *) %s);\n}\n\n",
8149            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME);
8150 }
8151
8152 /* Output function `internal_reset'.  */
8153 static void
8154 output_internal_reset_func (void)
8155 {
8156   fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8157            INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8158   fprintf (output_file, "{\n  memset (%s, 0, sizeof (struct %s));\n}\n\n",
8159            CHIP_PARAMETER_NAME, CHIP_NAME);
8160 }
8161
8162 /* The function outputs PHR interface function `state_size'.  */
8163 static void
8164 output_size_func (void)
8165 {
8166   fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8167   fprintf (output_file, "{\n  return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8168 }
8169
8170 /* The function outputs PHR interface function `state_reset'.  */
8171 static void
8172 output_reset_func (void)
8173 {
8174   fprintf (output_file, "void\n%s (%s %s)\n",
8175            RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8176   fprintf (output_file, "{\n  %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8177            CHIP_NAME, STATE_NAME);
8178 }
8179
8180 /* Output function `min_insn_conflict_delay'.  */
8181 static void
8182 output_min_insn_conflict_delay_func (void)
8183 {
8184   fprintf (output_file,
8185            "int\n%s (%s %s, rtx %s, rtx %s)\n",
8186            MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8187            STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8188   fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s, transition;\n",
8189            CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8190            INTERNAL_INSN2_CODE_NAME);
8191   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8192                                         INTERNAL_INSN_CODE_NAME, 0);
8193   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8194                                         INTERNAL_INSN2_CODE_NAME, 0);
8195   fprintf (output_file, "  memcpy (&%s, %s, sizeof (%s));\n",
8196            CHIP_NAME, STATE_NAME, CHIP_NAME);
8197   fprintf (output_file, "  %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8198   fprintf (output_file, "  transition = %s (%s, &%s);\n",
8199            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8200   fprintf (output_file, "  gcc_assert (transition <= 0);\n");
8201   fprintf (output_file, "  return %s (%s, &%s);\n",
8202            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8203            CHIP_NAME);
8204   fprintf (output_file, "}\n\n");
8205 }
8206
8207 /* Output the array holding default latency values.  These are used in
8208    insn_latency and maximal_insn_latency function implementations.  */
8209 static void
8210 output_default_latencies (void)
8211 {
8212   int i, j, col;
8213   decl_t decl;
8214   const char *tabletype = "unsigned char";
8215
8216   /* Find the smallest integer type that can hold all the default
8217      latency values.  */
8218   for (i = 0; i < description->decls_num; i++)
8219     if (description->decls[i]->mode == dm_insn_reserv)
8220       {
8221         decl = description->decls[i];
8222         if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8223             && tabletype[0] != 'i')  /* Don't shrink it.  */
8224           tabletype = "unsigned short";
8225         if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8226           tabletype = "int";
8227       }
8228
8229   fprintf (output_file, "  static const %s default_latencies[] =\n    {",
8230            tabletype);
8231
8232   for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8233     if (description->decls[i]->mode == dm_insn_reserv
8234         && description->decls[i] != advance_cycle_insn_decl)
8235       {
8236         if ((col = (col+1) % 8) == 0)
8237           fputs ("\n     ", output_file);
8238         decl = description->decls[i];
8239         gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8240         fprintf (output_file, "% 4d,",
8241                  DECL_INSN_RESERV (decl)->default_latency);
8242       }
8243   gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8244   fputs ("\n    };\n", output_file);
8245 }
8246
8247 /* Output function `internal_insn_latency'.  */
8248 static void
8249 output_internal_insn_latency_func (void)
8250 {
8251   int i;
8252   decl_t decl;
8253   struct bypass_decl *bypass;
8254
8255   fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8256            INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8257            INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8258            INSN2_PARAMETER_NAME);
8259   fprintf (output_file, "{\n");
8260
8261   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8262     {
8263       fputs ("  return 0;\n}\n\n", output_file);
8264       return;
8265     }
8266
8267   fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",
8268            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8269            INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8270
8271   fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8272   for (i = 0; i < description->decls_num; i++)
8273     if (description->decls[i]->mode == dm_insn_reserv
8274         && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8275       {
8276         decl = description->decls [i];
8277         fprintf (output_file,
8278                  "    case %d:\n      switch (%s)\n        {\n",
8279                  DECL_INSN_RESERV (decl)->insn_num,
8280                  INTERNAL_INSN2_CODE_NAME);
8281         for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8282              bypass != NULL;
8283              bypass = bypass->next)
8284           {
8285             gcc_assert (bypass->in_insn_reserv->insn_num
8286                         != (DECL_INSN_RESERV
8287                             (advance_cycle_insn_decl)->insn_num));
8288             fprintf (output_file, "        case %d:\n",
8289                      bypass->in_insn_reserv->insn_num);
8290             for (;;)
8291               {
8292                 if (bypass->bypass_guard_name == NULL)
8293                   {
8294                     gcc_assert (bypass->next == NULL
8295                                 || (bypass->in_insn_reserv
8296                                     != bypass->next->in_insn_reserv));
8297                     fprintf (output_file, "          return %d;\n",
8298                              bypass->latency);
8299                   }
8300                 else
8301                   {
8302                     fprintf (output_file,
8303                              "          if (%s (%s, %s))\n",
8304                              bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8305                              INSN2_PARAMETER_NAME);
8306                     fprintf (output_file, "            return %d;\n",
8307                              bypass->latency);
8308                   }
8309                 if (bypass->next == NULL
8310                     || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
8311                   break;
8312                 bypass = bypass->next;
8313               }
8314             if (bypass->bypass_guard_name != NULL)
8315               fprintf (output_file, "          break;\n");
8316           }
8317         fputs ("        }\n      break;\n", output_file);
8318       }
8319
8320   fprintf (output_file, "    }\n  return default_latencies[%s];\n}\n\n",
8321            INTERNAL_INSN_CODE_NAME);
8322 }
8323
8324 /* Output function `internal_maximum_insn_latency'.  */
8325 static void
8326 output_internal_maximal_insn_latency_func (void)
8327 {
8328   decl_t decl;
8329   struct bypass_decl *bypass;
8330   int i;
8331   int max;
8332
8333   fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8334            "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
8335            INSN_PARAMETER_NAME);
8336   fprintf (output_file, "{\n");
8337
8338   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8339     {
8340       fputs ("  return 0;\n}\n\n", output_file);
8341       return;
8342     }
8343
8344   fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8345   for (i = 0; i < description->decls_num; i++)
8346     if (description->decls[i]->mode == dm_insn_reserv
8347         && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8348       {
8349         decl = description->decls [i];
8350         max = DECL_INSN_RESERV (decl)->default_latency;
8351         fprintf (output_file,
8352                  "    case %d: {",
8353                  DECL_INSN_RESERV (decl)->insn_num);
8354         for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8355              bypass != NULL;
8356              bypass = bypass->next)
8357           {
8358             if (bypass->latency > max)
8359               max = bypass->latency;
8360           }
8361         fprintf (output_file, " return %d; }\n      break;\n", max);
8362       }
8363
8364   fprintf (output_file, "    }\n  return default_latencies[%s];\n}\n\n",
8365            INTERNAL_INSN_CODE_NAME);
8366 }
8367
8368 /* The function outputs PHR interface function `insn_latency'.  */
8369 static void
8370 output_insn_latency_func (void)
8371 {
8372   fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8373            INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8374   fprintf (output_file, "{\n  int %s, %s;\n",
8375            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8376   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8377                                         INTERNAL_INSN_CODE_NAME, 0);
8378   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8379                                         INTERNAL_INSN2_CODE_NAME, 0);
8380   fprintf (output_file, "  return %s (%s, %s, %s, %s);\n}\n\n",
8381            INTERNAL_INSN_LATENCY_FUNC_NAME,
8382            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8383            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8384 }
8385
8386 /* The function outputs PHR interface function `maximal_insn_latency'.  */
8387 static void
8388 output_maximal_insn_latency_func (void)
8389 {
8390   fprintf (output_file, "int\n%s (rtx %s)\n",
8391            "maximal_insn_latency", INSN_PARAMETER_NAME);
8392   fprintf (output_file, "{\n  int %s;\n",
8393            INTERNAL_INSN_CODE_NAME);
8394   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8395                                         INTERNAL_INSN_CODE_NAME, 0);
8396   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8397            "internal_maximal_insn_latency",
8398            INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
8399 }
8400
8401 /* The function outputs PHR interface function `print_reservation'.  */
8402 static void
8403 output_print_reservation_func (void)
8404 {
8405   decl_t decl;
8406   int i, j;
8407
8408   fprintf (output_file,
8409            "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8410            PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8411            INSN_PARAMETER_NAME);
8412
8413   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8414     {
8415       fprintf (output_file, "  fputs (\"%s\", %s);\n}\n\n",
8416                NOTHING_NAME, FILE_PARAMETER_NAME);
8417       return;
8418     }
8419
8420
8421   fputs ("  static const char *const reservation_names[] =\n    {",
8422          output_file);
8423
8424   for (i = 0, j = 0; i < description->decls_num; i++)
8425     {
8426       decl = description->decls [i];
8427       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8428         {
8429           gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8430           j++;
8431
8432           fprintf (output_file, "\n      \"%s\",",
8433                    regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8434           finish_regexp_representation ();
8435         }
8436     }
8437   gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8438
8439   fprintf (output_file, "\n      \"%s\"\n    };\n  int %s;\n\n",
8440            NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8441
8442   fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",
8443            INSN_PARAMETER_NAME,
8444            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8445   fprintf (output_file, "  else\n\
8446     {\n\
8447       %s = %s (%s);\n\
8448       if (%s > %s)\n\
8449         %s = %s;\n\
8450     }\n",
8451            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8452                INSN_PARAMETER_NAME,
8453            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8454            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8455
8456   fprintf (output_file, "  fputs (reservation_names[%s], %s);\n}\n\n",
8457            INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8458 }
8459
8460 /* The following function is used to sort unit declaration by their
8461    names.  */
8462 static int
8463 units_cmp (const void *unit1, const void *unit2)
8464 {
8465   const_unit_decl_t const u1 = *(const_unit_decl_t const*) unit1;
8466   const_unit_decl_t const u2 = *(const_unit_decl_t const*) unit2;
8467
8468   return strcmp (u1->name, u2->name);
8469 }
8470
8471 /* The following macro value is name of struct containing unit name
8472    and unit code.  */
8473 #define NAME_CODE_STRUCT_NAME  "name_code"
8474
8475 /* The following macro value is name of table of struct name_code.  */
8476 #define NAME_CODE_TABLE_NAME   "name_code_table"
8477
8478 /* The following macro values are member names for struct name_code.  */
8479 #define NAME_MEMBER_NAME       "name"
8480 #define CODE_MEMBER_NAME       "code"
8481
8482 /* The following macro values are local variable names for function
8483    `get_cpu_unit_code'.  */
8484 #define CMP_VARIABLE_NAME      "cmp"
8485 #define LOW_VARIABLE_NAME      "l"
8486 #define MIDDLE_VARIABLE_NAME   "m"
8487 #define HIGH_VARIABLE_NAME     "h"
8488
8489 /* The following function outputs function to obtain internal cpu unit
8490    code by the cpu unit name.  */
8491 static void
8492 output_get_cpu_unit_code_func (void)
8493 {
8494   int i;
8495   unit_decl_t *units;
8496
8497   fprintf (output_file, "int\n%s (const char *%s)\n",
8498            GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
8499   fprintf (output_file, "{\n  struct %s {const char *%s; int %s;};\n",
8500            NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8501   fprintf (output_file, "  int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8502            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8503   fprintf (output_file, "  static struct %s %s [] =\n    {\n",
8504            NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8505   units = XNEWVEC (unit_decl_t, description->units_num);
8506   memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8507   qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8508   for (i = 0; i < description->units_num; i++)
8509     if (units [i]->query_p)
8510       fprintf (output_file, "      {\"%s\", %d},\n",
8511                units[i]->name, units[i]->query_num);
8512   fprintf (output_file, "    };\n\n");
8513   fprintf (output_file, "  /* The following is binary search: */\n");
8514   fprintf (output_file, "  %s = 0;\n", LOW_VARIABLE_NAME);
8515   fprintf (output_file, "  %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8516            HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8517   fprintf (output_file, "  while (%s <= %s)\n    {\n",
8518            LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8519   fprintf (output_file, "      %s = (%s + %s) / 2;\n",
8520            MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8521   fprintf (output_file, "      %s = strcmp (%s, %s [%s].%s);\n",
8522            CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8523            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8524   fprintf (output_file, "      if (%s < 0)\n", CMP_VARIABLE_NAME);
8525   fprintf (output_file, "        %s = %s - 1;\n",
8526            HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8527   fprintf (output_file, "      else if (%s > 0)\n", CMP_VARIABLE_NAME);
8528   fprintf (output_file, "        %s = %s + 1;\n",
8529            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8530   fprintf (output_file, "      else\n");
8531   fprintf (output_file, "        return %s [%s].%s;\n    }\n",
8532            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8533   fprintf (output_file, "  return -1;\n}\n\n");
8534   free (units);
8535 }
8536
8537 /* The following function outputs function to check reservation of cpu
8538    unit (its internal code will be passed as the function argument) in
8539    given cpu state.  */
8540 static void
8541 output_cpu_unit_reservation_p (void)
8542 {
8543   automaton_t automaton;
8544
8545   fprintf (output_file, "int\n%s (%s %s, int %s)\n",
8546            CPU_UNIT_RESERVATION_P_FUNC_NAME,
8547            STATE_TYPE_NAME, STATE_NAME,
8548            CPU_CODE_PARAMETER_NAME);
8549   fprintf (output_file, "{\n  gcc_assert (%s >= 0 && %s < %d);\n",
8550            CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8551            description->query_units_num);
8552   if (description->query_units_num > 0)
8553     for (automaton = description->first_automaton;
8554          automaton != NULL;
8555          automaton = automaton->next_automaton)
8556       {
8557         fprintf (output_file, "  if ((");
8558         output_reserved_units_table_name (output_file, automaton);
8559         fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8560         output_chip_member_name (output_file, automaton);
8561         fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8562                  (description->query_units_num + 7) / 8,
8563                  CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8564         fprintf (output_file, "    return 1;\n");
8565       }
8566   fprintf (output_file, "  return 0;\n}\n\n");
8567 }
8568
8569 /* The following function outputs a function to check if insn
8570    has a dfa reservation.  */
8571 static void
8572 output_insn_has_dfa_reservation_p (void)
8573 {
8574   fprintf (output_file,
8575            "bool\n%s (rtx %s ATTRIBUTE_UNUSED)\n{\n",
8576            INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
8577            INSN_PARAMETER_NAME);
8578
8579   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8580     {
8581       fprintf (output_file, "  return false;\n}\n\n");
8582       return;
8583     }
8584
8585   fprintf (output_file, "  int %s;\n\n", INTERNAL_INSN_CODE_NAME);
8586
8587   fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",
8588            INSN_PARAMETER_NAME,
8589            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8590   fprintf (output_file, "  else\n\
8591     {\n\
8592       %s = %s (%s);\n\
8593       if (%s > %s)\n\
8594         %s = %s;\n\
8595     }\n\n",
8596            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8597                INSN_PARAMETER_NAME,
8598            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8599            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8600
8601   fprintf (output_file, "  return %s != %s;\n}\n\n",
8602            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8603 }
8604
8605 /* The function outputs PHR interface functions `dfa_clean_insn_cache'
8606    and 'dfa_clear_single_insn_cache'.  */
8607 static void
8608 output_dfa_clean_insn_cache_func (void)
8609 {
8610   fprintf (output_file,
8611            "void\n%s (void)\n{\n  int %s;\n\n",
8612            DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
8613   fprintf (output_file,
8614            "  for (%s = 0; %s < %s; %s++)\n    %s [%s] = -1;\n}\n\n",
8615            I_VARIABLE_NAME, I_VARIABLE_NAME,
8616            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8617            DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8618
8619   fprintf (output_file,
8620            "void\n%s (rtx %s)\n{\n  int %s;\n\n",
8621            DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
8622            I_VARIABLE_NAME);
8623   fprintf (output_file,
8624            "  %s = INSN_UID (%s);\n  if (%s < %s)\n    %s [%s] = -1;\n}\n\n",
8625            I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME,
8626            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8627            I_VARIABLE_NAME);
8628 }
8629
8630 /* The function outputs PHR interface function `dfa_start'.  */
8631 static void
8632 output_dfa_start_func (void)
8633 {
8634   fprintf (output_file,
8635            "void\n%s (void)\n{\n  %s = get_max_uid ();\n",
8636            DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8637   fprintf (output_file, "  %s = XNEWVEC (int, %s);\n",
8638            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8639   fprintf (output_file, "  %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8640 }
8641
8642 /* The function outputs PHR interface function `dfa_finish'.  */
8643 static void
8644 output_dfa_finish_func (void)
8645 {
8646   fprintf (output_file, "void\n%s (void)\n{\n  free (%s);\n}\n\n",
8647            DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8648 }
8649
8650 \f
8651
8652 /* The page contains code for output description file (readable
8653    representation of original description and generated DFA(s).  */
8654
8655 /* The function outputs string representation of IR reservation.  */
8656 static void
8657 output_regexp (regexp_t regexp)
8658 {
8659   fprintf (output_description_file, "%s", regexp_representation (regexp));
8660   finish_regexp_representation ();
8661 }
8662
8663 /* Output names of units in LIST separated by comma.  */
8664 static void
8665 output_unit_set_el_list (unit_set_el_t list)
8666 {
8667   unit_set_el_t el;
8668
8669   for (el = list; el != NULL; el = el->next_unit_set_el)
8670     {
8671       if (el != list)
8672         fprintf (output_description_file, ", ");
8673       fprintf (output_description_file, "%s", el->unit_decl->name);
8674     }
8675 }
8676
8677 /* Output patterns in LIST separated by comma.  */
8678 static void
8679 output_pattern_set_el_list (pattern_set_el_t list)
8680 {
8681   pattern_set_el_t el;
8682   int i;
8683
8684   for (el = list; el != NULL; el = el->next_pattern_set_el)
8685     {
8686       if (el != list)
8687         fprintf (output_description_file, ", ");
8688       for (i = 0; i < el->units_num; i++)
8689         fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
8690                  el->unit_decls [i]->name);
8691     }
8692 }
8693
8694 /* The function outputs string representation of IR define_reservation
8695    and define_insn_reservation.  */
8696 static void
8697 output_description (void)
8698 {
8699   decl_t decl;
8700   int i;
8701
8702   for (i = 0; i < description->decls_num; i++)
8703     {
8704       decl = description->decls [i];
8705       if (decl->mode == dm_unit)
8706         {
8707           if (DECL_UNIT (decl)->excl_list != NULL)
8708             {
8709               fprintf (output_description_file, "unit %s exclusion_set: ",
8710                        DECL_UNIT (decl)->name);
8711               output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
8712               fprintf (output_description_file, "\n");
8713             }
8714           if (DECL_UNIT (decl)->presence_list != NULL)
8715             {
8716               fprintf (output_description_file, "unit %s presence_set: ",
8717                        DECL_UNIT (decl)->name);
8718               output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
8719               fprintf (output_description_file, "\n");
8720             }
8721           if (DECL_UNIT (decl)->final_presence_list != NULL)
8722             {
8723               fprintf (output_description_file, "unit %s final_presence_set: ",
8724                        DECL_UNIT (decl)->name);
8725               output_pattern_set_el_list
8726                 (DECL_UNIT (decl)->final_presence_list);
8727               fprintf (output_description_file, "\n");
8728             }
8729           if (DECL_UNIT (decl)->absence_list != NULL)
8730             {
8731               fprintf (output_description_file, "unit %s absence_set: ",
8732                        DECL_UNIT (decl)->name);
8733               output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
8734               fprintf (output_description_file, "\n");
8735             }
8736           if (DECL_UNIT (decl)->final_absence_list != NULL)
8737             {
8738               fprintf (output_description_file, "unit %s final_absence_set: ",
8739                        DECL_UNIT (decl)->name);
8740               output_pattern_set_el_list
8741                 (DECL_UNIT (decl)->final_absence_list);
8742               fprintf (output_description_file, "\n");
8743             }
8744         }
8745     }
8746   fprintf (output_description_file, "\n");
8747   for (i = 0; i < description->decls_num; i++)
8748     {
8749       decl = description->decls [i];
8750       if (decl->mode == dm_reserv)
8751         {
8752           fprintf (output_description_file, "reservation %s: ",
8753                    DECL_RESERV (decl)->name);
8754           output_regexp (DECL_RESERV (decl)->regexp);
8755           fprintf (output_description_file, "\n");
8756         }
8757       else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8758         {
8759           fprintf (output_description_file, "insn reservation %s ",
8760                    DECL_INSN_RESERV (decl)->name);
8761           print_rtl (output_description_file,
8762                      DECL_INSN_RESERV (decl)->condexp);
8763           fprintf (output_description_file, ": ");
8764           output_regexp (DECL_INSN_RESERV (decl)->regexp);
8765           fprintf (output_description_file, "\n");
8766         }
8767       else if (decl->mode == dm_bypass)
8768         fprintf (output_description_file, "bypass %d %s %s\n",
8769                  DECL_BYPASS (decl)->latency,
8770                  DECL_BYPASS (decl)->out_insn_name,
8771                  DECL_BYPASS (decl)->in_insn_name);
8772     }
8773   fprintf (output_description_file, "\n\f\n");
8774 }
8775
8776 /* The function outputs name of AUTOMATON.  */
8777 static void
8778 output_automaton_name (FILE *f, automaton_t automaton)
8779 {
8780   if (automaton->corresponding_automaton_decl == NULL)
8781     fprintf (f, "#%d", automaton->automaton_order_num);
8782   else
8783     fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8784 }
8785
8786 /* Maximal length of line for pretty printing into description
8787    file.  */
8788 #define MAX_LINE_LENGTH 70
8789
8790 /* The function outputs units name belonging to AUTOMATON.  */
8791 static void
8792 output_automaton_units (automaton_t automaton)
8793 {
8794   decl_t decl;
8795   const char *name;
8796   int curr_line_length;
8797   int there_is_an_automaton_unit;
8798   int i;
8799
8800   fprintf (output_description_file, "\n  Corresponding units:\n");
8801   fprintf (output_description_file, "    ");
8802   curr_line_length = 4;
8803   there_is_an_automaton_unit = 0;
8804   for (i = 0; i < description->decls_num; i++)
8805     {
8806       decl = description->decls [i];
8807       if (decl->mode == dm_unit
8808           && (DECL_UNIT (decl)->corresponding_automaton_num
8809               == automaton->automaton_order_num))
8810         {
8811           there_is_an_automaton_unit = 1;
8812           name = DECL_UNIT (decl)->name;
8813           if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8814             {
8815               curr_line_length = strlen (name) + 4;
8816               fprintf (output_description_file, "\n    ");
8817             }
8818           else
8819             {
8820               curr_line_length += strlen (name) + 1;
8821               fprintf (output_description_file, " ");
8822             }
8823           fprintf (output_description_file, "%s", name);
8824         }
8825     }
8826   if (!there_is_an_automaton_unit)
8827     fprintf (output_description_file, "<None>");
8828   fprintf (output_description_file, "\n\n");
8829 }
8830
8831 /* The following variable is used for forming array of all possible cpu unit
8832    reservations described by the current DFA state.  */
8833 static VEC(reserv_sets_t, heap) *state_reservs;
8834
8835 /* The function forms `state_reservs' for STATE.  */
8836 static void
8837 add_state_reservs (state_t state)
8838 {
8839   alt_state_t curr_alt_state;
8840
8841   if (state->component_states != NULL)
8842     for (curr_alt_state = state->component_states;
8843          curr_alt_state != NULL;
8844          curr_alt_state = curr_alt_state->next_sorted_alt_state)
8845       add_state_reservs (curr_alt_state->state);
8846   else
8847     VEC_safe_push (reserv_sets_t, heap, state_reservs, state->reservs);
8848 }
8849
8850 /* The function outputs readable representation of all out arcs of
8851    STATE.  */
8852 static void
8853 output_state_arcs (state_t state)
8854 {
8855   arc_t arc;
8856   ainsn_t ainsn;
8857   const char *insn_name;
8858   int curr_line_length;
8859
8860   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8861     {
8862       ainsn = arc->insn;
8863       gcc_assert (ainsn->first_insn_with_same_reservs);
8864       fprintf (output_description_file, "    ");
8865       curr_line_length = 7;
8866       fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8867       do
8868         {
8869           insn_name = ainsn->insn_reserv_decl->name;
8870           if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8871             {
8872               if (ainsn != arc->insn)
8873                 {
8874                   fprintf (output_description_file, ",\n      ");
8875                   curr_line_length = strlen (insn_name) + 6;
8876                 }
8877               else
8878                 curr_line_length += strlen (insn_name);
8879             }
8880           else
8881             {
8882               curr_line_length += strlen (insn_name);
8883               if (ainsn != arc->insn)
8884                 {
8885                   curr_line_length += 2;
8886                   fprintf (output_description_file, ", ");
8887                 }
8888             }
8889           fprintf (output_description_file, "%s", insn_name);
8890           ainsn = ainsn->next_same_reservs_insn;
8891         }
8892       while (ainsn != NULL);
8893       fprintf (output_description_file, "    %d \n",
8894                arc->to_state->order_state_num);
8895     }
8896   fprintf (output_description_file, "\n");
8897 }
8898
8899 /* The following function is used for sorting possible cpu unit
8900    reservation of a DFA state.  */
8901 static int
8902 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
8903 {
8904   return reserv_sets_cmp (*(const_reserv_sets_t const*) reservs_ptr_1,
8905                           *(const_reserv_sets_t const*) reservs_ptr_2);
8906 }
8907
8908 /* The following function is used for sorting possible cpu unit
8909    reservation of a DFA state.  */
8910 static void
8911 remove_state_duplicate_reservs (void)
8912 {
8913   size_t i, j;
8914
8915   for (i = 1, j = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
8916     if (reserv_sets_cmp (VEC_index (reserv_sets_t, state_reservs, j),
8917                          VEC_index (reserv_sets_t, state_reservs, i)))
8918       {
8919         j++;
8920         VEC_replace (reserv_sets_t, state_reservs, j,
8921                      VEC_index (reserv_sets_t, state_reservs, i));
8922       }
8923   VEC_truncate (reserv_sets_t, state_reservs, j + 1);
8924 }
8925
8926 /* The following function output readable representation of DFA(s)
8927    state used for fast recognition of pipeline hazards.  State is
8928    described by possible (current and scheduled) cpu unit
8929    reservations.  */
8930 static void
8931 output_state (state_t state)
8932 {
8933   size_t i;
8934
8935   state_reservs = 0;
8936
8937   fprintf (output_description_file, "  State #%d", state->order_state_num);
8938   fprintf (output_description_file,
8939            state->new_cycle_p ? " (new cycle)\n" : "\n");
8940   add_state_reservs (state);
8941   VEC_qsort (reserv_sets_t, state_reservs, state_reservs_cmp);
8942   remove_state_duplicate_reservs ();
8943   for (i = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
8944     {
8945       fprintf (output_description_file, "    ");
8946       output_reserv_sets (output_description_file,
8947                           VEC_index (reserv_sets_t, state_reservs, i));
8948       fprintf (output_description_file, "\n");
8949     }
8950   fprintf (output_description_file, "\n");
8951   output_state_arcs (state);
8952   VEC_free (reserv_sets_t, heap, state_reservs);
8953 }
8954
8955 /* The following function output readable representation of
8956    DFAs used for fast recognition of pipeline hazards.  */
8957 static void
8958 output_automaton_descriptions (void)
8959 {
8960   automaton_t automaton;
8961
8962   for (automaton = description->first_automaton;
8963        automaton != NULL;
8964        automaton = automaton->next_automaton)
8965     {
8966       fprintf (output_description_file, "\nAutomaton ");
8967       output_automaton_name (output_description_file, automaton);
8968       fprintf (output_description_file, "\n");
8969       output_automaton_units (automaton);
8970       pass_states (automaton, output_state);
8971     }
8972 }
8973
8974 \f
8975
8976 /* The page contains top level function for generation DFA(s) used for
8977    PHR.  */
8978
8979 /* The function outputs statistics about work of different phases of
8980    DFA generator.  */
8981 static void
8982 output_statistics (FILE *f)
8983 {
8984   automaton_t automaton;
8985   int states_num;
8986 #ifndef NDEBUG
8987   int transition_comb_vect_els = 0;
8988   int transition_full_vect_els = 0;
8989   int min_issue_delay_vect_els = 0;
8990   int locked_states = 0;
8991 #endif
8992
8993   for (automaton = description->first_automaton;
8994        automaton != NULL;
8995        automaton = automaton->next_automaton)
8996     {
8997       fprintf (f, "\nAutomaton ");
8998       output_automaton_name (f, automaton);
8999       fprintf (f, "\n    %5d NDFA states,          %5d NDFA arcs\n",
9000                automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9001       fprintf (f, "    %5d DFA states,           %5d DFA arcs\n",
9002                automaton->DFA_states_num, automaton->DFA_arcs_num);
9003       states_num = automaton->DFA_states_num;
9004       if (!no_minimization_flag)
9005         {
9006           fprintf (f, "    %5d minimal DFA states,   %5d minimal DFA arcs\n",
9007                    automaton->minimal_DFA_states_num,
9008                    automaton->minimal_DFA_arcs_num);
9009           states_num = automaton->minimal_DFA_states_num;
9010         }
9011       fprintf (f, "    %5d all insns      %5d insn equivalence classes\n",
9012                description->insns_num, automaton->insn_equiv_classes_num);
9013       fprintf (f, "    %d locked states\n", automaton->locked_states);
9014 #ifndef NDEBUG
9015       fprintf
9016         (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9017          (long) VEC_length (vect_el_t, automaton->trans_table->comb_vect),
9018          (long) VEC_length (vect_el_t, automaton->trans_table->full_vect),
9019          (comb_vect_p (automaton->trans_table)
9020           ? "use comb vect" : "use simple vect"));
9021       fprintf
9022         (f, "%5ld min delay table els, compression factor %d\n",
9023          (long) states_num * automaton->insn_equiv_classes_num,
9024          automaton->min_issue_delay_table_compression_factor);
9025       transition_comb_vect_els
9026         += VEC_length (vect_el_t, automaton->trans_table->comb_vect);
9027       transition_full_vect_els
9028         += VEC_length (vect_el_t, automaton->trans_table->full_vect);
9029       min_issue_delay_vect_els
9030         += states_num * automaton->insn_equiv_classes_num;
9031       locked_states
9032         += automaton->locked_states;
9033 #endif
9034     }
9035 #ifndef NDEBUG
9036   fprintf (f, "\n%5d all allocated states,     %5d all allocated arcs\n",
9037            allocated_states_num, allocated_arcs_num);
9038   fprintf (f, "%5d all allocated alternative states\n",
9039            allocated_alt_states_num);
9040   fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9041            transition_comb_vect_els, transition_full_vect_els);
9042   fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9043   fprintf (f, "%5d all locked states\n", locked_states);
9044 #endif
9045 }
9046
9047 /* The function output times of work of different phases of DFA
9048    generator.  */
9049 static void
9050 output_time_statistics (FILE *f)
9051 {
9052   fprintf (f, "\n  transformation: ");
9053   print_active_time (f, transform_time);
9054   fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9055   print_active_time (f, NDFA_time);
9056   if (ndfa_flag)
9057     {
9058       fprintf (f, ", NDFA -> DFA: ");
9059       print_active_time (f, NDFA_to_DFA_time);
9060     }
9061   fprintf (f, "\n  DFA minimization: ");
9062   print_active_time (f, minimize_time);
9063   fprintf (f, ", making insn equivalence: ");
9064   print_active_time (f, equiv_time);
9065   fprintf (f, "\n all automaton generation: ");
9066   print_active_time (f, automaton_generation_time);
9067   fprintf (f, ", output: ");
9068   print_active_time (f, output_time);
9069   fprintf (f, "\n");
9070 }
9071
9072 /* The function generates DFA (deterministic finite state automaton)
9073    for fast recognition of pipeline hazards.  No errors during
9074    checking must be fixed before this function call.  */
9075 static void
9076 generate (void)
9077 {
9078   automata_num = split_argument;
9079   if (description->units_num < automata_num)
9080     automata_num = description->units_num;
9081   initiate_states ();
9082   initiate_arcs ();
9083   initiate_automata_lists ();
9084   initiate_pass_states ();
9085   initiate_excl_sets ();
9086   initiate_presence_absence_pattern_sets ();
9087   automaton_generation_time = create_ticker ();
9088   create_automata ();
9089   ticker_off (&automaton_generation_time);
9090 }
9091
9092 \f
9093
9094 /* This page mainly contains top level functions of pipeline hazards
9095    description translator.  */
9096
9097 /* The following macro value is suffix of name of description file of
9098    pipeline hazards description translator.  */
9099 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9100
9101 /* The function returns suffix of given file name.  The returned
9102    string can not be changed.  */
9103 static const char *
9104 file_name_suffix (const char *file_name)
9105 {
9106   const char *last_period;
9107
9108   for (last_period = NULL; *file_name != '\0'; file_name++)
9109     if (*file_name == '.')
9110       last_period = file_name;
9111   return (last_period == NULL ? file_name : last_period);
9112 }
9113
9114 /* The function returns base name of given file name, i.e. pointer to
9115    first char after last `/' (or `\' for WIN32) in given file name,
9116    given file name itself if the directory name is absent.  The
9117    returned string can not be changed.  */
9118 static const char *
9119 base_file_name (const char *file_name)
9120 {
9121   int directory_name_length;
9122
9123   directory_name_length = strlen (file_name);
9124 #ifdef WIN32
9125   while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9126          && file_name[directory_name_length] != '\\')
9127 #else
9128   while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9129 #endif
9130     directory_name_length--;
9131   return file_name + directory_name_length + 1;
9132 }
9133
9134 /* The following is top level function to initialize the work of
9135    pipeline hazards description translator.  */
9136 static void
9137 initiate_automaton_gen (int argc, char **argv)
9138 {
9139   const char *base_name;
9140   int i;
9141
9142   ndfa_flag = 0;
9143   split_argument = 0;  /* default value */
9144   no_minimization_flag = 0;
9145   time_flag = 0;
9146   stats_flag = 0;
9147   v_flag = 0;
9148   w_flag = 0;
9149   progress_flag = 0;
9150   for (i = 2; i < argc; i++)
9151     if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9152       no_minimization_flag = 1;
9153     else if (strcmp (argv [i], TIME_OPTION) == 0)
9154       time_flag = 1;
9155     else if (strcmp (argv [i], STATS_OPTION) == 0)
9156       stats_flag = 1;
9157     else if (strcmp (argv [i], V_OPTION) == 0)
9158       v_flag = 1;
9159     else if (strcmp (argv [i], W_OPTION) == 0)
9160       w_flag = 1;
9161     else if (strcmp (argv [i], NDFA_OPTION) == 0)
9162       ndfa_flag = 1;
9163     else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9164       progress_flag = 1;
9165     else if (strcmp (argv [i], "-split") == 0)
9166       {
9167         if (i + 1 >= argc)
9168           fatal ("-split has no argument.");
9169         fatal ("option `-split' has not been implemented yet\n");
9170         /* split_argument = atoi (argument_vect [i + 1]); */
9171       }
9172
9173   /* Initialize IR storage.  */
9174   obstack_init (&irp);
9175   initiate_automaton_decl_table ();
9176   initiate_insn_decl_table ();
9177   initiate_decl_table ();
9178   output_file = stdout;
9179   output_description_file = NULL;
9180   base_name = base_file_name (argv[1]);
9181   obstack_grow (&irp, base_name,
9182                 strlen (base_name) - strlen (file_name_suffix (base_name)));
9183   obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9184                 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9185   obstack_1grow (&irp, '\0');
9186   output_description_file_name = obstack_base (&irp);
9187   obstack_finish (&irp);
9188 }
9189
9190 /* The following function checks existence at least one arc marked by
9191    each insn.  */
9192 static void
9193 check_automata_insn_issues (void)
9194 {
9195   automaton_t automaton;
9196   ainsn_t ainsn, reserv_ainsn;
9197
9198   for (automaton = description->first_automaton;
9199        automaton != NULL;
9200        automaton = automaton->next_automaton)
9201     {
9202       for (ainsn = automaton->ainsn_list;
9203            ainsn != NULL;
9204            ainsn = ainsn->next_ainsn)
9205         if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9206           {
9207             for (reserv_ainsn = ainsn;
9208                  reserv_ainsn != NULL;
9209                  reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9210               if (automaton->corresponding_automaton_decl != NULL)
9211                 {
9212                   if (!w_flag)
9213                     error ("Automaton `%s': Insn `%s' will never be issued",
9214                            automaton->corresponding_automaton_decl->name,
9215                            reserv_ainsn->insn_reserv_decl->name);
9216                   else
9217                     warning ("Automaton `%s': Insn `%s' will never be issued",
9218                              automaton->corresponding_automaton_decl->name,
9219                              reserv_ainsn->insn_reserv_decl->name);
9220                 }
9221               else
9222                 {
9223                   if (!w_flag)
9224                     error ("Insn `%s' will never be issued",
9225                            reserv_ainsn->insn_reserv_decl->name);
9226                   else
9227                     warning ("Insn `%s' will never be issued",
9228                              reserv_ainsn->insn_reserv_decl->name);
9229                 }
9230           }
9231     }
9232 }
9233
9234 /* The following vla is used for storing pointers to all achieved
9235    states.  */
9236 static VEC(state_t, heap) *automaton_states;
9237
9238 /* This function is called by function pass_states to add an achieved
9239    STATE.  */
9240 static void
9241 add_automaton_state (state_t state)
9242 {
9243   VEC_safe_push (state_t, heap, automaton_states, state);
9244 }
9245
9246 /* The following function forms list of important automata (whose
9247    states may be changed after the insn issue) for each insn.  */
9248 static void
9249 form_important_insn_automata_lists (void)
9250 {
9251   automaton_t automaton;
9252   decl_t decl;
9253   ainsn_t ainsn;
9254   arc_t arc;
9255   int i;
9256   size_t n;
9257
9258   automaton_states = 0;
9259   /* Mark important ainsns.  */
9260   for (automaton = description->first_automaton;
9261        automaton != NULL;
9262        automaton = automaton->next_automaton)
9263     {
9264       VEC_truncate (state_t, automaton_states, 0);
9265       pass_states (automaton, add_automaton_state);
9266       for (n = 0; n < VEC_length (state_t, automaton_states); n++)
9267         {
9268           state_t s = VEC_index (state_t, automaton_states, n);
9269           for (arc = first_out_arc (s);
9270                arc != NULL;
9271                arc = next_out_arc (arc))
9272             if (arc->to_state != s)
9273               {
9274                 gcc_assert (arc->insn->first_insn_with_same_reservs);
9275                 for (ainsn = arc->insn;
9276                      ainsn != NULL;
9277                      ainsn = ainsn->next_same_reservs_insn)
9278                   ainsn->important_p = TRUE;
9279               }
9280         }
9281     }
9282   VEC_free (state_t, heap, automaton_states);
9283
9284   /* Create automata sets for the insns.  */
9285   for (i = 0; i < description->decls_num; i++)
9286     {
9287       decl = description->decls [i];
9288       if (decl->mode == dm_insn_reserv)
9289         {
9290           automata_list_start ();
9291           for (automaton = description->first_automaton;
9292                automaton != NULL;
9293                automaton = automaton->next_automaton)
9294             for (ainsn = automaton->ainsn_list;
9295                  ainsn != NULL;
9296                  ainsn = ainsn->next_ainsn)
9297               if (ainsn->important_p
9298                   && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9299                 {
9300                   automata_list_add (automaton);
9301                   break;
9302                 }
9303           DECL_INSN_RESERV (decl)->important_automata_list
9304             = automata_list_finish ();
9305         }
9306     }
9307 }
9308
9309
9310 /* The following is top level function to generate automat(a,on) for
9311    fast recognition of pipeline hazards.  */
9312 static void
9313 expand_automata (void)
9314 {
9315   int i;
9316
9317   description = XCREATENODEVAR (struct description,
9318                                 sizeof (struct description)
9319                                 /* One entry for cycle advancing insn.  */
9320                                 + sizeof (decl_t) * VEC_length (decl_t, decls));
9321   description->decls_num = VEC_length (decl_t, decls);
9322   description->query_units_num = 0;
9323   for (i = 0; i < description->decls_num; i++)
9324     {
9325       description->decls [i] = VEC_index (decl_t, decls, i);
9326       if (description->decls [i]->mode == dm_unit
9327           && DECL_UNIT (description->decls [i])->query_p)
9328         DECL_UNIT (description->decls [i])->query_num
9329           = description->query_units_num++;
9330     }
9331   all_time = create_ticker ();
9332   check_time = create_ticker ();
9333   if (progress_flag)
9334     fprintf (stderr, "Check description...");
9335   check_all_description ();
9336   if (progress_flag)
9337     fprintf (stderr, "done\n");
9338   ticker_off (&check_time);
9339   generation_time = create_ticker ();
9340   if (!have_error)
9341     {
9342       transform_insn_regexps ();
9343       check_unit_distributions_to_automata ();
9344     }
9345   if (!have_error)
9346     {
9347       generate ();
9348       check_automata_insn_issues ();
9349     }
9350   if (!have_error)
9351     {
9352       form_important_insn_automata_lists ();
9353     }
9354   ticker_off (&generation_time);
9355 }
9356
9357 /* The following is top level function to output PHR and to finish
9358    work with pipeline description translator.  */
9359 static void
9360 write_automata (void)
9361 {
9362   output_time = create_ticker ();
9363   if (progress_flag)
9364     fprintf (stderr, "Forming and outputting automata tables...");
9365   output_tables ();
9366   if (progress_flag)
9367     {
9368       fprintf (stderr, "done\n");
9369       fprintf (stderr, "Output functions to work with automata...");
9370     }
9371   output_chip_definitions ();
9372   output_max_insn_queue_index_def ();
9373   output_internal_min_issue_delay_func ();
9374   output_internal_trans_func ();
9375   /* Cache of insn dfa codes: */
9376   fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9377   fprintf (output_file, "\nstatic int %s;\n\n",
9378            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9379   output_dfa_insn_code_func ();
9380   output_trans_func ();
9381   output_min_issue_delay_func ();
9382   output_internal_dead_lock_func ();
9383   output_dead_lock_func ();
9384   output_size_func ();
9385   output_internal_reset_func ();
9386   output_reset_func ();
9387   output_min_insn_conflict_delay_func ();
9388   output_default_latencies ();
9389   output_internal_insn_latency_func ();
9390   output_insn_latency_func ();
9391   output_internal_maximal_insn_latency_func ();
9392   output_maximal_insn_latency_func ();
9393   output_print_reservation_func ();
9394   /* Output function get_cpu_unit_code.  */
9395   fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9396   output_get_cpu_unit_code_func ();
9397   output_cpu_unit_reservation_p ();
9398   output_insn_has_dfa_reservation_p ();
9399   fprintf (output_file, "\n#endif /* #if %s */\n\n",
9400            CPU_UNITS_QUERY_MACRO_NAME);
9401   output_dfa_clean_insn_cache_func ();
9402   output_dfa_start_func ();
9403   output_dfa_finish_func ();
9404   if (progress_flag)
9405     fprintf (stderr, "done\n");
9406   if (v_flag)
9407     {
9408       output_description_file = fopen (output_description_file_name, "w");
9409       if (output_description_file == NULL)
9410         {
9411           perror (output_description_file_name);
9412           exit (FATAL_EXIT_CODE);
9413         }
9414       if (progress_flag)
9415         fprintf (stderr, "Output automata description...");
9416       output_description ();
9417       output_automaton_descriptions ();
9418       if (progress_flag)
9419         fprintf (stderr, "done\n");
9420       output_statistics (output_description_file);
9421     }
9422   if (stats_flag)
9423     output_statistics (stderr);
9424   ticker_off (&output_time);
9425   if (time_flag)
9426     output_time_statistics (stderr);
9427   finish_states ();
9428   finish_arcs ();
9429   finish_automata_lists ();
9430   if (time_flag)
9431     {
9432       fprintf (stderr, "Summary:\n");
9433       fprintf (stderr, "  check time ");
9434       print_active_time (stderr, check_time);
9435       fprintf (stderr, ", generation time ");
9436       print_active_time (stderr, generation_time);
9437       fprintf (stderr, ", all time ");
9438       print_active_time (stderr, all_time);
9439       fprintf (stderr, "\n");
9440     }
9441   /* Finish all work.  */
9442   if (output_description_file != NULL)
9443     {
9444       fflush (output_description_file);
9445       if (ferror (stdout) != 0)
9446         fatal ("Error in writing DFA description file %s: %s",
9447                output_description_file_name, xstrerror (errno));
9448       fclose (output_description_file);
9449     }
9450   finish_automaton_decl_table ();
9451   finish_insn_decl_table ();
9452   finish_decl_table ();
9453   obstack_free (&irp, NULL);
9454   if (have_error && output_description_file != NULL)
9455     remove (output_description_file_name);
9456 }
9457
9458 int
9459 main (int argc, char **argv)
9460 {
9461   rtx desc;
9462
9463   progname = "genautomata";
9464
9465   if (!init_rtx_reader_args (argc, argv))
9466     return (FATAL_EXIT_CODE);
9467
9468   initiate_automaton_gen (argc, argv);
9469   while (1)
9470     {
9471       int lineno;
9472       int insn_code_number;
9473
9474       desc = read_md_rtx (&lineno, &insn_code_number);
9475       if (desc == NULL)
9476         break;
9477
9478       switch (GET_CODE (desc))
9479         {
9480         case DEFINE_CPU_UNIT:
9481           gen_cpu_unit (desc);
9482           break;
9483
9484         case DEFINE_QUERY_CPU_UNIT:
9485           gen_query_cpu_unit (desc);
9486           break;
9487
9488         case DEFINE_BYPASS:
9489           gen_bypass (desc);
9490           break;
9491
9492         case EXCLUSION_SET:
9493           gen_excl_set (desc);
9494           break;
9495
9496         case PRESENCE_SET:
9497           gen_presence_set (desc);
9498           break;
9499
9500         case FINAL_PRESENCE_SET:
9501           gen_final_presence_set (desc);
9502           break;
9503
9504         case ABSENCE_SET:
9505           gen_absence_set (desc);
9506           break;
9507
9508         case FINAL_ABSENCE_SET:
9509           gen_final_absence_set (desc);
9510           break;
9511
9512         case DEFINE_AUTOMATON:
9513           gen_automaton (desc);
9514           break;
9515
9516         case AUTOMATA_OPTION:
9517           gen_automata_option (desc);
9518           break;
9519
9520         case DEFINE_RESERVATION:
9521           gen_reserv (desc);
9522           break;
9523
9524         case DEFINE_INSN_RESERVATION:
9525           gen_insn_reserv (desc);
9526           break;
9527
9528         default:
9529           break;
9530         }
9531     }
9532
9533   if (have_error)
9534     return FATAL_EXIT_CODE;
9535
9536   if (VEC_length (decl_t, decls) > 0)
9537     {
9538       expand_automata ();
9539       if (!have_error)
9540         {
9541           puts ("/* Generated automatically by the program `genautomata'\n"
9542                 "   from the machine description file `md'.  */\n\n"
9543                 "#include \"config.h\"\n"
9544                 "#include \"system.h\"\n"
9545                 "#include \"coretypes.h\"\n"
9546                 "#include \"tm.h\"\n"
9547                 "#include \"rtl.h\"\n"
9548                 "#include \"tm_p.h\"\n"
9549                 "#include \"insn-config.h\"\n"
9550                 "#include \"recog.h\"\n"
9551                 "#include \"regs.h\"\n"
9552                 "#include \"output.h\"\n"
9553                 "#include \"insn-attr.h\"\n"
9554                 "#include \"diagnostic-core.h\"\n"
9555                 "#include \"flags.h\"\n"
9556                 "#include \"function.h\"\n"
9557                 "#include \"emit-rtl.h\"\n");
9558                  /* FIXME: emit-rtl.h can go away once crtl is in rtl.h.  */
9559
9560           write_automata ();
9561         }
9562     }
9563   else
9564     {
9565       puts ("/* Generated automatically by the program `genautomata'\n"
9566             "   from the machine description file `md'.  */\n\n"
9567             "/* There is no automaton, but ISO C forbids empty\n"
9568             "   translation units, so include a header file with some\n"
9569             "   declarations, and its pre-requisite header file.  */\n"
9570             "#include \"config.h\"\n"
9571             "#include \"system.h\"\n");
9572     }
9573
9574   fflush (stdout);
9575   return (ferror (stdout) != 0 || have_error
9576           ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9577 }