OSDN Git Service

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