1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
3 Free Software Foundation, Inc.
5 Written by Vladimir Makarov <vmakarov@redhat.com>
7 This file is part of GCC.
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 2, or (at your option) any
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
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 1. Detecting pipeline structural hazards quickly. T. Proebsting,
27 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
28 Principles of Programming Languages, pages 280--286, 1994.
30 This article is a good start point to understand usage of finite
31 state automata for pipeline hazard recognizers. But I'd
32 recommend the 2nd article for more deep understanding.
34 2. Efficient Instruction Scheduling Using Finite State Automata:
35 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
36 article about usage of finite state automata for pipeline hazard
39 The current implementation is different from the 2nd article in the
42 1. New operator `|' (alternative) is permitted in functional unit
43 reservation which can be treated deterministically and
44 non-deterministically.
46 2. Possibility of usage of nondeterministic automata too.
48 3. Possibility to query functional unit reservations for given
51 4. Several constructions to describe impossible reservations
52 (`exclusion_set', `presence_set', `final_presence_set',
53 `absence_set', and `final_absence_set').
55 5. No reverse automata are generated. Trace instruction scheduling
56 requires this. It can be easily added in the future if we
59 6. Union of automaton states are not generated yet. It is planned
60 to be implemented. Such feature is needed to make more accurate
61 interlock insn scheduling to get state describing functional
62 unit reservation in a joint CFG point. */
64 /* This file code processes constructions of machine description file
65 which describes automaton used for recognition of processor pipeline
66 hazards by insn scheduler and can be used for other tasks (such as
69 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
70 `gen_bypass', `gen_excl_set', `gen_presence_set',
71 `gen_final_presence_set', `gen_absence_set',
72 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
73 `gen_reserv', `gen_insn_reserv' are called from file
74 `genattrtab.c'. They transform RTL constructions describing
75 automata in .md file into internal representation convenient for
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
82 o checking correctness of the automaton pipeline description
83 (major function is `check_all_description').
85 o generating automaton (automata) from the description (major
86 function is `make_automaton').
88 o optional transformation of nondeterministic finite state
89 automata into deterministic ones if the alternative operator
90 `|' is treated nondeterministically in the description (major
91 function is NDFA_to_DFA).
93 o optional minimization of the finite state automata by merging
94 equivalent automaton states (major function is `minimize_DFA').
96 o forming tables (some as comb vectors) and attributes
97 representing the automata (functions output_..._table).
99 Function `write_automata' outputs the created finite state
100 automaton as different tables and functions which works with the
101 automata to inquire automaton state and to change its state. These
102 function are used by gcc instruction scheduler and may be some
107 #include "coretypes.h"
112 #include "gensupport.h"
122 /* Positions in machine description file. Now they are not used. But
123 they could be used in the future for better diagnostic messages. */
126 /* The following is element of vector of current (and planned in the
127 future) functional unit reservations. */
128 typedef unsigned HOST_WIDE_INT set_el_t;
130 /* Reservations of function units are represented by value of the following
132 typedef set_el_t *reserv_sets_t;
134 /* The following structure describes a ticker. */
137 /* The following member value is time of the ticker creation with
138 taking into account time when the ticker is off. Active time of
139 the ticker is current time minus the value. */
140 int modified_creation_time;
141 /* The following member value is time (incremented by one) when the
142 ticker was off. Zero value means that now the ticker is on. */
143 int incremented_off_time;
146 /* The ticker is represented by the following type. */
147 typedef struct ticker ticker_t;
149 /* The following type describes elements of output vectors. */
150 typedef HOST_WIDE_INT vect_el_t;
152 /* Forward declaration of structures of internal representation of
153 pipeline description based on NDFA. */
158 struct automaton_decl;
159 struct unit_pattern_rel_decl;
161 struct insn_reserv_decl;
164 struct result_regexp;
165 struct reserv_regexp;
166 struct nothing_regexp;
167 struct sequence_regexp;
168 struct repeat_regexp;
174 struct pattern_set_el;
175 struct pattern_reserv;
181 struct state_ainsn_table;
183 /* The following typedefs are for brevity. */
184 typedef struct unit_decl *unit_decl_t;
185 typedef struct decl *decl_t;
186 typedef struct regexp *regexp_t;
187 typedef struct unit_set_el *unit_set_el_t;
188 typedef struct pattern_set_el *pattern_set_el_t;
189 typedef struct pattern_reserv *pattern_reserv_t;
190 typedef struct alt_state *alt_state_t;
191 typedef struct state *state_t;
192 typedef struct arc *arc_t;
193 typedef struct ainsn *ainsn_t;
194 typedef struct automaton *automaton_t;
195 typedef struct automata_list_el *automata_list_el_t;
196 typedef struct state_ainsn_table *state_ainsn_table_t;
198 /* Undefined position. */
199 static pos_t no_pos = 0;
201 /* All IR is stored in the following obstack. */
202 static struct obstack irp;
205 /* Declare vector types for various data structures: */
207 DEF_VEC_P(alt_state_t);
208 DEF_VEC_ALLOC_P(alt_state_t,heap);
210 DEF_VEC_ALLOC_P(ainsn_t,heap);
212 DEF_VEC_ALLOC_P(state_t,heap);
214 DEF_VEC_ALLOC_P(decl_t,heap);
215 DEF_VEC_P(reserv_sets_t);
216 DEF_VEC_ALLOC_P(reserv_sets_t,heap);
218 DEF_VEC_I(vect_el_t);
219 DEF_VEC_ALLOC_I(vect_el_t, heap);
220 typedef VEC(vect_el_t,heap) *vla_hwint_t;
222 /* Forward declarations of functions used before their definitions, only. */
223 static regexp_t gen_regexp_sequence (const char *);
224 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
226 static reserv_sets_t get_excl_set (reserv_sets_t);
227 static int check_presence_pattern_sets (reserv_sets_t,
229 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
231 static arc_t first_out_arc (state_t);
232 static arc_t next_out_arc (arc_t);
236 /* Options with the following names can be set up in automata_option
237 construction. Because the strings occur more one time we use the
240 #define NO_MINIMIZATION_OPTION "-no-minimization"
241 #define TIME_OPTION "-time"
242 #define STATS_OPTION "-stats"
243 #define V_OPTION "-v"
244 #define W_OPTION "-w"
245 #define NDFA_OPTION "-ndfa"
246 #define PROGRESS_OPTION "-progress"
248 /* The following flags are set up by function `initiate_automaton_gen'. */
250 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
251 static int ndfa_flag;
253 /* Do not make minimization of DFA (`-no-minimization'). */
254 static int no_minimization_flag;
256 /* Value of this variable is number of automata being generated. The
257 actual number of automata may be less this value if there is not
258 sufficient number of units. This value is defined by argument of
259 option `-split' or by constructions automaton if the value is zero
260 (it is default value of the argument). */
261 static int split_argument;
263 /* Flag of output time statistics (`-time'). */
264 static int time_flag;
266 /* Flag of automata statistics (`-stats'). */
267 static int stats_flag;
269 /* Flag of creation of description file which contains description of
270 result automaton and statistics information (`-v'). */
273 /* Flag of output of a progress bar showing how many states were
274 generated so far for automaton being processed (`-progress'). */
275 static int progress_flag;
277 /* Flag of generating warning instead of error for non-critical errors
282 /* Output file for pipeline hazard recognizer (PHR) being generated.
283 The value is NULL if the file is not defined. */
284 static FILE *output_file;
286 /* Description file of PHR. The value is NULL if the file is not
288 static FILE *output_description_file;
290 /* PHR description file name. */
291 static char *output_description_file_name;
293 /* Value of the following variable is node representing description
294 being processed. This is start point of IR. */
295 static struct description *description;
299 /* This page contains description of IR structure (nodes). */
313 /* This describes define_cpu_unit and define_query_cpu_unit (see file
318 /* NULL if the automaton name is absent. */
319 const char *automaton_name;
320 /* If the following value is not zero, the cpu unit reservation is
321 described in define_query_cpu_unit. */
324 /* The following fields are defined by checker. */
326 /* The following field value is nonzero if the unit is used in an
330 /* The following field value is order number (0, 1, ...) of given
333 /* The following field value is corresponding declaration of
334 automaton which was given in description. If the field value is
335 NULL then automaton in the unit declaration was absent. */
336 struct automaton_decl *automaton_decl;
337 /* The following field value is maximal cycle number (1, ...) on
338 which given unit occurs in insns. Zero value means that given
339 unit is not used in insns. */
340 int max_occ_cycle_num;
341 /* The following field value is minimal cycle number (0, ...) on
342 which given unit occurs in insns. -1 value means that given
343 unit is not used in insns. */
344 int min_occ_cycle_num;
345 /* The following list contains units which conflict with given
347 unit_set_el_t excl_list;
348 /* The following list contains patterns which are required to
349 reservation of given unit. */
350 pattern_set_el_t presence_list;
351 pattern_set_el_t final_presence_list;
352 /* The following list contains patterns which should be not present
353 in reservation for given unit. */
354 pattern_set_el_t absence_list;
355 pattern_set_el_t final_absence_list;
356 /* The following is used only when `query_p' has nonzero value.
357 This is query number for the unit. */
359 /* The following is the last cycle on which the unit was checked for
360 correct distributions of units to automata in a regexp. */
361 int last_distribution_check_cycle;
363 /* The following fields are defined by automaton generator. */
365 /* The following field value is number of the automaton to which
366 given unit belongs. */
367 int corresponding_automaton_num;
368 /* If the following value is not zero, the cpu unit is present in a
369 `exclusion_set' or in right part of a `presence_set',
370 `final_presence_set', `absence_set', and
371 `final_absence_set'define_query_cpu_unit. */
375 /* This describes define_bypass (see file rtl.def). */
379 const char *out_insn_name;
380 const char *in_insn_name;
381 const char *bypass_guard_name;
383 /* The following fields are defined by checker. */
385 /* output and input insns of given bypass. */
386 struct insn_reserv_decl *out_insn_reserv;
387 struct insn_reserv_decl *in_insn_reserv;
388 /* The next bypass for given output insn. */
389 struct bypass_decl *next;
392 /* This describes define_automaton (see file rtl.def). */
393 struct automaton_decl
397 /* The following fields are defined by automaton generator. */
399 /* The following field value is nonzero if the automaton is used in
400 an regexp definition. */
401 char automaton_is_used;
403 /* The following fields are defined by checker. */
405 /* The following field value is the corresponding automaton. This
406 field is not NULL only if the automaton is present in unit
407 declarations and the automatic partition on automata is not
409 automaton_t corresponding_automaton;
412 /* This describes exclusion relations: exclusion_set (see file
417 int first_list_length;
421 /* This describes unit relations: [final_]presence_set or
422 [final_]absence_set (see file rtl.def). */
423 struct unit_pattern_rel_decl
432 /* This describes define_reservation (see file rtl.def). */
438 /* The following fields are defined by checker. */
440 /* The following field value is nonzero if the unit is used in an
443 /* The following field is used to check up cycle in expression
448 /* This describes define_insn_reservation (see file rtl.def). */
449 struct insn_reserv_decl
456 /* The following fields are defined by checker. */
458 /* The following field value is order number (0, 1, ...) of given
461 /* The following field value is list of bypasses in which given insn
463 struct bypass_decl *bypass_list;
465 /* The following fields are defined by automaton generator. */
467 /* The following field is the insn regexp transformed that
468 the regexp has not optional regexp, repetition regexp, and an
469 reservation name (i.e. reservation identifiers are changed by the
470 corresponding regexp) and all alternations are the topest level
471 of the regexp. The value can be NULL only if it is special
472 insn `cycle advancing'. */
473 regexp_t transformed_regexp;
474 /* The following field value is list of arcs marked given
475 insn. The field is used in transformation NDFA -> DFA. */
476 arc_t arcs_marked_by_insn;
477 /* The two following fields are used during minimization of a finite state
479 /* The field value is number of equivalence class of state into
480 which arc marked by given insn enters from a state (fixed during
481 an automaton minimization). */
483 /* The following member value is the list to automata which can be
484 changed by the insn issue. */
485 automata_list_el_t important_automata_list;
486 /* The following member is used to process insn once for output. */
490 /* This contains a declaration mentioned above. */
493 /* What node in the union? */
498 struct unit_decl unit;
499 struct bypass_decl bypass;
500 struct automaton_decl automaton;
501 struct excl_rel_decl excl;
502 struct unit_pattern_rel_decl presence;
503 struct unit_pattern_rel_decl absence;
504 struct reserv_decl reserv;
505 struct insn_reserv_decl insn_reserv;
509 /* The following structures represent parsed reservation strings. */
521 /* Cpu unit in reservation. */
525 unit_decl_t unit_decl;
528 /* Define_reservation in a reservation. */
532 struct reserv_decl *reserv_decl;
535 /* Absence of reservation (represented by string `nothing'). */
536 struct nothing_regexp
538 /* This used to be empty but ISO C doesn't allow that. */
542 /* Representation of reservations separated by ',' (see file
544 struct sequence_regexp
547 regexp_t regexps [1];
550 /* Representation of construction `repeat' (see file rtl.def). */
557 /* Representation of reservations separated by '+' (see file
562 regexp_t regexps [1];
565 /* Representation of reservations separated by '|' (see file
570 regexp_t regexps [1];
573 /* Representation of a reservation string. */
576 /* What node in the union? */
577 enum regexp_mode mode;
581 struct unit_regexp unit;
582 struct reserv_regexp reserv;
583 struct nothing_regexp nothing;
584 struct sequence_regexp sequence;
585 struct repeat_regexp repeat;
586 struct allof_regexp allof;
587 struct oneof_regexp oneof;
591 /* Represents description of pipeline hazard description based on
597 /* The following fields are defined by checker. */
599 /* The following fields values are correspondingly number of all
600 units, query units, and insns in the description. */
604 /* The following field value is max length (in cycles) of
605 reservations of insns. The field value is defined only for
607 int max_insn_reserv_cycles;
609 /* The following fields are defined by automaton generator. */
611 /* The following field value is the first automaton. */
612 automaton_t first_automaton;
614 /* The following field is created by pipeline hazard parser and
615 contains all declarations. We allocate additional entry for
616 special insn "cycle advancing" which is added by the automaton
622 /* The following nodes are created in automaton checker. */
624 /* The following nodes represent exclusion set for cpu units. Each
625 element is accessed through only one excl_list. */
628 unit_decl_t unit_decl;
629 unit_set_el_t next_unit_set_el;
632 /* The following nodes represent presence or absence pattern for cpu
633 units. Each element is accessed through only one presence_list or
635 struct pattern_set_el
637 /* The number of units in unit_decls. */
639 /* The units forming the pattern. */
640 struct unit_decl **unit_decls;
641 pattern_set_el_t next_pattern_set_el;
645 /* The following nodes are created in automaton generator. */
648 /* The following nodes represent presence or absence pattern for cpu
649 units. Each element is accessed through only one element of
650 unit_presence_set_table or unit_absence_set_table. */
651 struct pattern_reserv
653 reserv_sets_t reserv;
654 pattern_reserv_t next_pattern_reserv;
657 /* The following node type describes state automaton. The state may
658 be deterministic or non-deterministic. Non-deterministic state has
659 several component states which represent alternative cpu units
660 reservations. The state also is used for describing a
661 deterministic reservation of automaton insn. */
664 /* The following member value is nonzero if there is a transition by
667 /* The following field is list of processor unit reservations on
669 reserv_sets_t reservs;
670 /* The following field is unique number of given state between other
673 /* The following field value is automaton to which given state
675 automaton_t automaton;
676 /* The following field value is the first arc output from given
679 unsigned int num_out_arcs;
680 /* The following field is used to form NDFA. */
681 char it_was_placed_in_stack_for_NDFA_forming;
682 /* The following field is used to form DFA. */
683 char it_was_placed_in_stack_for_DFA_forming;
684 /* The following field is used to transform NDFA to DFA and DFA
685 minimization. The field value is not NULL if the state is a
686 compound state. In this case the value of field `unit_sets_list'
687 is NULL. All states in the list are in the hash table. The list
688 is formed through field `next_sorted_alt_state'. We should
689 support only one level of nesting state. */
690 alt_state_t component_states;
691 /* The following field is used for passing graph of states. */
693 /* The list of states belonging to one equivalence class is formed
694 with the aid of the following field. */
695 state_t next_equiv_class_state;
696 /* The two following fields are used during minimization of a finite
698 int equiv_class_num_1, equiv_class_num_2;
699 /* The following field is used during minimization of a finite state
700 automaton. The field value is state corresponding to equivalence
701 class to which given state belongs. */
702 state_t equiv_class_state;
703 unsigned int *presence_signature;
704 /* The following field value is the order number of given state.
705 The states in final DFA is enumerated with the aid of the
708 /* This member is used for passing states for searching minimal
711 /* The following member is used to evaluate min issue delay of insn
713 int min_insn_issue_delay;
719 /* The following field refers for the state into which given arc
722 /* The following field describes that the insn issue (with cycle
723 advancing for special insn `cycle advancing' and without cycle
724 advancing for others) makes transition from given state to
725 another given state. */
727 /* The following field value is the next arc output from the same
730 /* List of arcs marked given insn is formed with the following
731 field. The field is used in transformation NDFA -> DFA. */
732 arc_t next_arc_marked_by_insn;
735 /* The following node type describes a deterministic alternative in
736 non-deterministic state which characterizes cpu unit reservations
737 of automaton insn or which is part of NDFA. */
740 /* The following field is a deterministic state which characterizes
741 unit reservations of the instruction. */
743 /* The following field refers to the next state which characterizes
744 unit reservations of the instruction. */
745 alt_state_t next_alt_state;
746 /* The following field refers to the next state in sorted list. */
747 alt_state_t next_sorted_alt_state;
750 /* The following node type describes insn of automaton. They are
751 labels of FA arcs. */
754 /* The following field value is the corresponding insn declaration
756 struct insn_reserv_decl *insn_reserv_decl;
757 /* The following field value is the next insn declaration for an
760 /* The following field is states which characterize automaton unit
761 reservations of the instruction. The value can be NULL only if it
762 is special insn `cycle advancing'. */
763 alt_state_t alt_states;
764 /* The following field is sorted list of states which characterize
765 automaton unit reservations of the instruction. The value can be
766 NULL only if it is special insn `cycle advancing'. */
767 alt_state_t sorted_alt_states;
768 /* The following field refers the next automaton insn with
769 the same reservations. */
770 ainsn_t next_same_reservs_insn;
771 /* The following field is flag of the first automaton insn with the
772 same reservations in the declaration list. Only arcs marked such
773 insn is present in the automaton. This significantly decreases
774 memory requirements especially when several automata are
776 char first_insn_with_same_reservs;
777 /* The following member has nonzero value if there is arc from state of
778 the automaton marked by the ainsn. */
780 /* Cyclic list of insns of an equivalence class is formed with the
781 aid of the following field. */
782 ainsn_t next_equiv_class_insn;
783 /* The following field value is nonzero if the insn declaration is
784 the first insn declaration with given equivalence number. */
785 char first_ainsn_with_given_equivalence_num;
786 /* The following field is number of class of equivalence of insns.
787 It is necessary because many insns may be equivalent with the
788 point of view of pipeline hazards. */
789 int insn_equiv_class_num;
790 /* The following member value is TRUE if there is an arc in the
791 automaton marked by the insn into another state. In other
792 words, the insn can change the state of the automaton. */
796 /* The following describes an automaton for PHR. */
799 /* The following field value is the list of insn declarations for
802 /* The following field value is the corresponding automaton
803 declaration. This field is not NULL only if the automatic
804 partition on automata is not used. */
805 struct automaton_decl *corresponding_automaton_decl;
806 /* The following field value is the next automaton. */
807 automaton_t next_automaton;
808 /* The following field is start state of FA. There are not unit
809 reservations in the state. */
811 /* The following field value is number of equivalence classes of
812 insns (see field `insn_equiv_class_num' in
813 `insn_reserv_decl'). */
814 int insn_equiv_classes_num;
815 /* The following field value is number of states of final DFA. */
816 int achieved_states_num;
817 /* The following field value is the order number (0, 1, ...) of
819 int automaton_order_num;
820 /* The following fields contain statistics information about
821 building automaton. */
822 int NDFA_states_num, DFA_states_num;
823 /* The following field value is defined only if minimization of DFA
825 int minimal_DFA_states_num;
826 int NDFA_arcs_num, DFA_arcs_num;
827 /* The following field value is defined only if minimization of DFA
829 int minimal_DFA_arcs_num;
830 /* The following member refers for two table state x ainsn -> int.
831 ??? Above sentence is incomprehensible. */
832 state_ainsn_table_t trans_table;
833 /* The following member value is maximal value of min issue delay
834 for insns of the automaton. */
836 /* Usually min issue delay is small and we can place several (2, 4,
837 8) elements in one vector element. So the compression factor can
838 be 1 (no compression), 2, 4, 8. */
839 int min_issue_delay_table_compression_factor;
840 /* Total number of locked states in this automaton. */
844 /* The following is the element of the list of automata. */
845 struct automata_list_el
847 /* The automaton itself. */
848 automaton_t automaton;
849 /* The next automata set element. */
850 automata_list_el_t next_automata_list_el;
853 /* The following structure describes a table state X ainsn -> int(>= 0). */
854 struct state_ainsn_table
856 /* Automaton to which given table belongs. */
857 automaton_t automaton;
858 /* The following tree vectors for comb vector implementation of the
860 vla_hwint_t comb_vect;
861 vla_hwint_t check_vect;
862 vla_hwint_t base_vect;
863 /* This is simple implementation of the table. */
864 vla_hwint_t full_vect;
865 /* Minimal and maximal values of the previous vectors. */
866 int min_comb_vect_el_value, max_comb_vect_el_value;
867 int min_base_vect_el_value, max_base_vect_el_value;
870 /* Macros to access members of unions. Use only them for access to
871 union members of declarations and regexps. */
873 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
875 #define DECL_UNIT(d) __extension__ \
876 (({ struct decl *const _decl = (d); \
877 if (_decl->mode != dm_unit) \
878 decl_mode_check_failed (_decl->mode, "dm_unit", \
879 __FILE__, __LINE__, __FUNCTION__); \
880 &(_decl)->decl.unit; }))
882 #define DECL_BYPASS(d) __extension__ \
883 (({ struct decl *const _decl = (d); \
884 if (_decl->mode != dm_bypass) \
885 decl_mode_check_failed (_decl->mode, "dm_bypass", \
886 __FILE__, __LINE__, __FUNCTION__); \
887 &(_decl)->decl.bypass; }))
889 #define DECL_AUTOMATON(d) __extension__ \
890 (({ struct decl *const _decl = (d); \
891 if (_decl->mode != dm_automaton) \
892 decl_mode_check_failed (_decl->mode, "dm_automaton", \
893 __FILE__, __LINE__, __FUNCTION__); \
894 &(_decl)->decl.automaton; }))
896 #define DECL_EXCL(d) __extension__ \
897 (({ struct decl *const _decl = (d); \
898 if (_decl->mode != dm_excl) \
899 decl_mode_check_failed (_decl->mode, "dm_excl", \
900 __FILE__, __LINE__, __FUNCTION__); \
901 &(_decl)->decl.excl; }))
903 #define DECL_PRESENCE(d) __extension__ \
904 (({ struct decl *const _decl = (d); \
905 if (_decl->mode != dm_presence) \
906 decl_mode_check_failed (_decl->mode, "dm_presence", \
907 __FILE__, __LINE__, __FUNCTION__); \
908 &(_decl)->decl.presence; }))
910 #define DECL_ABSENCE(d) __extension__ \
911 (({ struct decl *const _decl = (d); \
912 if (_decl->mode != dm_absence) \
913 decl_mode_check_failed (_decl->mode, "dm_absence", \
914 __FILE__, __LINE__, __FUNCTION__); \
915 &(_decl)->decl.absence; }))
917 #define DECL_RESERV(d) __extension__ \
918 (({ struct decl *const _decl = (d); \
919 if (_decl->mode != dm_reserv) \
920 decl_mode_check_failed (_decl->mode, "dm_reserv", \
921 __FILE__, __LINE__, __FUNCTION__); \
922 &(_decl)->decl.reserv; }))
924 #define DECL_INSN_RESERV(d) __extension__ \
925 (({ struct decl *const _decl = (d); \
926 if (_decl->mode != dm_insn_reserv) \
927 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
928 __FILE__, __LINE__, __FUNCTION__); \
929 &(_decl)->decl.insn_reserv; }))
931 static const char *decl_name (enum decl_mode);
932 static void decl_mode_check_failed (enum decl_mode, const char *,
933 const char *, int, const char *)
936 /* Return string representation of declaration mode MODE. */
938 decl_name (enum decl_mode mode)
940 static char str [100];
944 else if (mode == dm_bypass)
946 else if (mode == dm_automaton)
947 return "dm_automaton";
948 else if (mode == dm_excl)
950 else if (mode == dm_presence)
951 return "dm_presence";
952 else if (mode == dm_absence)
954 else if (mode == dm_reserv)
956 else if (mode == dm_insn_reserv)
957 return "dm_insn_reserv";
959 sprintf (str, "unknown (%d)", (int) mode);
963 /* The function prints message about unexpected declaration and finish
966 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
967 const char *file, int line, const char *func)
971 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
972 file, line, func, expected_mode_str, decl_name (mode));
977 #define REGEXP_UNIT(r) __extension__ \
978 (({ struct regexp *const _regexp = (r); \
979 if (_regexp->mode != rm_unit) \
980 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
981 __FILE__, __LINE__, __FUNCTION__); \
982 &(_regexp)->regexp.unit; }))
984 #define REGEXP_RESERV(r) __extension__ \
985 (({ struct regexp *const _regexp = (r); \
986 if (_regexp->mode != rm_reserv) \
987 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
988 __FILE__, __LINE__, __FUNCTION__); \
989 &(_regexp)->regexp.reserv; }))
991 #define REGEXP_SEQUENCE(r) __extension__ \
992 (({ struct regexp *const _regexp = (r); \
993 if (_regexp->mode != rm_sequence) \
994 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
995 __FILE__, __LINE__, __FUNCTION__); \
996 &(_regexp)->regexp.sequence; }))
998 #define REGEXP_REPEAT(r) __extension__ \
999 (({ struct regexp *const _regexp = (r); \
1000 if (_regexp->mode != rm_repeat) \
1001 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1002 __FILE__, __LINE__, __FUNCTION__); \
1003 &(_regexp)->regexp.repeat; }))
1005 #define REGEXP_ALLOF(r) __extension__ \
1006 (({ struct regexp *const _regexp = (r); \
1007 if (_regexp->mode != rm_allof) \
1008 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1009 __FILE__, __LINE__, __FUNCTION__); \
1010 &(_regexp)->regexp.allof; }))
1012 #define REGEXP_ONEOF(r) __extension__ \
1013 (({ struct regexp *const _regexp = (r); \
1014 if (_regexp->mode != rm_oneof) \
1015 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1016 __FILE__, __LINE__, __FUNCTION__); \
1017 &(_regexp)->regexp.oneof; }))
1019 static const char *regexp_name (enum regexp_mode);
1020 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1022 const char *) ATTRIBUTE_NORETURN;
1025 /* Return string representation of regexp mode MODE. */
1027 regexp_name (enum regexp_mode mode)
1036 return "rm_nothing";
1038 return "rm_sequence";
1050 /* The function prints message about unexpected regexp and finish the
1053 regexp_mode_check_failed (enum regexp_mode mode,
1054 const char *expected_mode_str,
1055 const char *file, int line, const char *func)
1059 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1060 file, line, func, expected_mode_str, regexp_name (mode));
1064 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1066 #define DECL_UNIT(d) (&(d)->decl.unit)
1067 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1068 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1069 #define DECL_EXCL(d) (&(d)->decl.excl)
1070 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1071 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1072 #define DECL_RESERV(d) (&(d)->decl.reserv)
1073 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1075 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1076 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1077 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1078 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1079 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1080 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1082 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1084 /* Create IR structure (node). */
1086 create_node (size_t size)
1090 obstack_blank (&irp, size);
1091 result = obstack_base (&irp);
1092 obstack_finish (&irp);
1093 /* Default values of members are NULL and zero. */
1094 memset (result, 0, size);
1098 /* Copy IR structure (node). */
1100 copy_node (const void *from, size_t size)
1102 void *const result = create_node (size);
1103 memcpy (result, from, size);
1107 /* The function checks that NAME does not contain quotes (`"'). */
1109 check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
1113 for (str = name; *str != '\0'; str++)
1115 error ("Name `%s' contains quotes", name);
1119 /* Pointers to all declarations during IR generation are stored in the
1121 static VEC(decl_t,heap) *decls;
1123 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1124 string containing the next separated element, taking parentheses
1125 into account if PAR_FLAG has nonzero value. Advance the pointer to
1126 after the string scanned, or the end-of-string. Return NULL if at
1129 next_sep_el (const char **pstr, int sep, int par_flag)
1136 /* Remove leading whitespaces. */
1137 while (ISSPACE ((int) **pstr))
1144 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1146 if (par_flag && *p == '(')
1148 else if (par_flag && *p == ')')
1150 else if (pars_num == 0 && *p == sep)
1152 if (pars_num == 0 && ISSPACE ((int) *p))
1156 for (; n_spaces != 0; n_spaces--)
1157 obstack_1grow (&irp, p [-n_spaces]);
1158 obstack_1grow (&irp, *p);
1161 obstack_1grow (&irp, '\0');
1162 out_str = obstack_base (&irp);
1163 obstack_finish (&irp);
1172 /* Given a string and a separator, return the number of separated
1173 elements in it, taking parentheses into account if PAR_FLAG has
1174 nonzero value. Return 0 for the null string, -1 if parentheses is
1177 n_sep_els (const char *s, int sep, int par_flag)
1185 for (pars_num = 0, n = 1; *s; s++)
1186 if (par_flag && *s == '(')
1188 else if (par_flag && *s == ')')
1190 else if (pars_num == 0 && *s == sep)
1193 return (pars_num != 0 ? -1 : n);
1196 /* Given a string and a separator, return vector of strings which are
1197 elements in the string and number of elements through els_num.
1198 Take parentheses into account if PAREN_P has nonzero value. The
1199 function also inserts the end marker NULL at the end of vector.
1200 Return 0 for the null string, -1 if parentheses are not balanced. */
1202 get_str_vect (const char *str, int *els_num, int sep, int paren_p)
1209 *els_num = n_sep_els (str, sep, paren_p);
1212 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1213 vect = (char **) obstack_base (&irp);
1214 obstack_finish (&irp);
1216 for (i = 0; i < *els_num; i++)
1217 vect [i] = next_sep_el (pstr, sep, paren_p);
1218 trail = next_sep_el (pstr, sep, paren_p);
1219 gcc_assert (!trail);
1224 /* Process a DEFINE_CPU_UNIT.
1226 This gives information about a unit contained in CPU. We fill a
1227 struct unit_decl with information used later by `expand_automata'. */
1229 gen_cpu_unit (rtx def)
1232 char **str_cpu_units;
1236 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1237 if (str_cpu_units == NULL)
1238 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1239 for (i = 0; i < vect_length; i++)
1241 decl = create_node (sizeof (struct decl));
1242 decl->mode = dm_unit;
1244 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1245 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1246 DECL_UNIT (decl)->query_p = 0;
1247 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1248 DECL_UNIT (decl)->in_set_p = 0;
1249 VEC_safe_push (decl_t,heap, decls, decl);
1253 /* Process a DEFINE_QUERY_CPU_UNIT.
1255 This gives information about a unit contained in CPU. We fill a
1256 struct unit_decl with information used later by `expand_automata'. */
1258 gen_query_cpu_unit (rtx def)
1261 char **str_cpu_units;
1265 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
1267 if (str_cpu_units == NULL)
1268 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1269 for (i = 0; i < vect_length; i++)
1271 decl = create_node (sizeof (struct decl));
1272 decl->mode = dm_unit;
1274 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1275 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1276 DECL_UNIT (decl)->query_p = 1;
1277 VEC_safe_push (decl_t,heap, decls, decl);
1281 /* Process a DEFINE_BYPASS.
1283 This gives information about a unit contained in the CPU. We fill
1284 in a struct bypass_decl with information used later by
1285 `expand_automata'. */
1287 gen_bypass (rtx def)
1296 out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
1297 if (out_insns == NULL)
1298 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1299 in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
1300 if (in_insns == NULL)
1301 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1302 for (i = 0; i < out_length; i++)
1303 for (j = 0; j < in_length; j++)
1305 decl = create_node (sizeof (struct decl));
1306 decl->mode = dm_bypass;
1308 DECL_BYPASS (decl)->latency = XINT (def, 0);
1309 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1310 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1311 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
1312 VEC_safe_push (decl_t,heap, decls, decl);
1316 /* Process an EXCLUSION_SET.
1318 This gives information about a cpu unit conflicts. We fill a
1319 struct excl_rel_decl (excl) with information used later by
1320 `expand_automata'. */
1322 gen_excl_set (rtx def)
1325 char **first_str_cpu_units;
1326 char **second_str_cpu_units;
1327 int first_vect_length;
1332 = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
1333 if (first_str_cpu_units == NULL)
1334 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1335 second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
1337 if (second_str_cpu_units == NULL)
1338 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1339 length += first_vect_length;
1340 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1341 decl->mode = dm_excl;
1343 DECL_EXCL (decl)->all_names_num = length;
1344 DECL_EXCL (decl)->first_list_length = first_vect_length;
1345 for (i = 0; i < length; i++)
1346 if (i < first_vect_length)
1347 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1349 DECL_EXCL (decl)->names [i]
1350 = second_str_cpu_units [i - first_vect_length];
1351 VEC_safe_push (decl_t,heap, decls, decl);
1354 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1355 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1357 This gives information about a cpu unit reservation requirements.
1358 We fill a struct unit_pattern_rel_decl with information used later
1359 by `expand_automata'. */
1361 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1364 char **str_cpu_units;
1365 char **str_pattern_lists;
1366 char ***str_patterns;
1367 int cpu_units_length;
1369 int patterns_length;
1372 str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
1374 if (str_cpu_units == NULL)
1377 ? "invalid first string `%s' in final_presence_set"
1378 : "invalid first string `%s' in presence_set")
1380 ? "invalid first string `%s' in final_absence_set"
1381 : "invalid first string `%s' in absence_set")),
1383 str_pattern_lists = get_str_vect (XSTR (def, 1),
1384 &patterns_length, ',', FALSE);
1385 if (str_pattern_lists == NULL)
1388 ? "invalid second string `%s' in final_presence_set"
1389 : "invalid second string `%s' in presence_set")
1391 ? "invalid second string `%s' in final_absence_set"
1392 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1393 str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
1394 for (i = 0; i < patterns_length; i++)
1396 str_patterns [i] = get_str_vect (str_pattern_lists [i],
1397 &length, ' ', FALSE);
1398 gcc_assert (str_patterns [i]);
1400 decl = create_node (sizeof (struct decl));
1404 decl->mode = dm_presence;
1405 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1406 DECL_PRESENCE (decl)->names = str_cpu_units;
1407 DECL_PRESENCE (decl)->patterns = str_patterns;
1408 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1409 DECL_PRESENCE (decl)->final_p = final_p;
1413 decl->mode = dm_absence;
1414 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1415 DECL_ABSENCE (decl)->names = str_cpu_units;
1416 DECL_ABSENCE (decl)->patterns = str_patterns;
1417 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1418 DECL_ABSENCE (decl)->final_p = final_p;
1420 VEC_safe_push (decl_t,heap, decls, decl);
1423 /* Process a PRESENCE_SET.
1425 This gives information about a cpu unit reservation requirements.
1426 We fill a struct unit_pattern_rel_decl (presence) with information
1427 used later by `expand_automata'. */
1429 gen_presence_set (rtx def)
1431 gen_presence_absence_set (def, TRUE, FALSE);
1434 /* Process a FINAL_PRESENCE_SET.
1436 This gives information about a cpu unit reservation requirements.
1437 We fill a struct unit_pattern_rel_decl (presence) with information
1438 used later by `expand_automata'. */
1440 gen_final_presence_set (rtx def)
1442 gen_presence_absence_set (def, TRUE, TRUE);
1445 /* Process an ABSENCE_SET.
1447 This gives information about a cpu unit reservation requirements.
1448 We fill a struct unit_pattern_rel_decl (absence) with information
1449 used later by `expand_automata'. */
1451 gen_absence_set (rtx def)
1453 gen_presence_absence_set (def, FALSE, FALSE);
1456 /* Process a FINAL_ABSENCE_SET.
1458 This gives information about a cpu unit reservation requirements.
1459 We fill a struct unit_pattern_rel_decl (absence) with information
1460 used later by `expand_automata'. */
1462 gen_final_absence_set (rtx def)
1464 gen_presence_absence_set (def, FALSE, TRUE);
1467 /* Process a DEFINE_AUTOMATON.
1469 This gives information about a finite state automaton used for
1470 recognizing pipeline hazards. We fill a struct automaton_decl
1471 with information used later by `expand_automata'. */
1473 gen_automaton (rtx def)
1476 char **str_automata;
1480 str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1481 if (str_automata == NULL)
1482 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1483 for (i = 0; i < vect_length; i++)
1485 decl = create_node (sizeof (struct decl));
1486 decl->mode = dm_automaton;
1488 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1489 VEC_safe_push (decl_t,heap, decls, decl);
1493 /* Process an AUTOMATA_OPTION.
1495 This gives information how to generate finite state automaton used
1496 for recognizing pipeline hazards. */
1498 gen_automata_option (rtx def)
1500 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1501 no_minimization_flag = 1;
1502 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1504 else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
1506 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1508 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1510 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1512 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1515 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1518 /* Name in reservation to denote absence reservation. */
1519 #define NOTHING_NAME "nothing"
1521 /* The following string contains original reservation string being
1523 static const char *reserv_str;
1525 /* Parse an element in STR. */
1527 gen_regexp_el (const char *str)
1536 if (str [len - 1] != ')')
1537 fatal ("garbage after ) in reservation `%s'", reserv_str);
1538 dstr = alloca (len - 1);
1539 memcpy (dstr, str + 1, len - 2);
1540 dstr [len-2] = '\0';
1541 regexp = gen_regexp_sequence (dstr);
1543 else if (strcmp (str, NOTHING_NAME) == 0)
1545 regexp = create_node (sizeof (struct decl));
1546 regexp->mode = rm_nothing;
1550 regexp = create_node (sizeof (struct decl));
1551 regexp->mode = rm_unit;
1552 REGEXP_UNIT (regexp)->name = str;
1557 /* Parse construction `repeat' in STR. */
1559 gen_regexp_repeat (const char *str)
1567 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1568 if (repeat_vect == NULL)
1569 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1572 regexp = gen_regexp_el (repeat_vect [0]);
1573 for (i = 1; i < els_num; i++)
1575 repeat = create_node (sizeof (struct regexp));
1576 repeat->mode = rm_repeat;
1577 REGEXP_REPEAT (repeat)->regexp = regexp;
1578 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
1579 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
1580 fatal ("repetition `%s' <= 1 in reservation `%s'",
1587 return gen_regexp_el (str);
1590 /* Parse reservation STR which possibly contains separator '+'. */
1592 gen_regexp_allof (const char *str)
1599 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
1600 if (allof_vect == NULL)
1601 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1604 allof = create_node (sizeof (struct regexp)
1605 + sizeof (regexp_t) * (els_num - 1));
1606 allof->mode = rm_allof;
1607 REGEXP_ALLOF (allof)->regexps_num = els_num;
1608 for (i = 0; i < els_num; i++)
1609 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
1613 return gen_regexp_repeat (str);
1616 /* Parse reservation STR which possibly contains separator '|'. */
1618 gen_regexp_oneof (const char *str)
1625 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
1626 if (oneof_vect == NULL)
1627 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1630 oneof = create_node (sizeof (struct regexp)
1631 + sizeof (regexp_t) * (els_num - 1));
1632 oneof->mode = rm_oneof;
1633 REGEXP_ONEOF (oneof)->regexps_num = els_num;
1634 for (i = 0; i < els_num; i++)
1635 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
1639 return gen_regexp_allof (str);
1642 /* Parse reservation STR which possibly contains separator ','. */
1644 gen_regexp_sequence (const char *str)
1647 char **sequence_vect;
1651 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
1654 sequence = create_node (sizeof (struct regexp)
1655 + sizeof (regexp_t) * (els_num - 1));
1656 sequence->mode = rm_sequence;
1657 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
1658 for (i = 0; i < els_num; i++)
1659 REGEXP_SEQUENCE (sequence)->regexps [i]
1660 = gen_regexp_oneof (sequence_vect [i]);
1664 return gen_regexp_oneof (str);
1667 /* Parse construction reservation STR. */
1669 gen_regexp (const char *str)
1672 return gen_regexp_sequence (str);;
1675 /* Process a DEFINE_RESERVATION.
1677 This gives information about a reservation of cpu units. We fill
1678 in a struct reserv_decl with information used later by
1679 `expand_automata'. */
1681 gen_reserv (rtx def)
1685 decl = create_node (sizeof (struct decl));
1686 decl->mode = dm_reserv;
1688 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
1689 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
1690 VEC_safe_push (decl_t,heap, decls, decl);
1693 /* Process a DEFINE_INSN_RESERVATION.
1695 This gives information about the reservation of cpu units by an
1696 insn. We fill a struct insn_reserv_decl with information used
1697 later by `expand_automata'. */
1699 gen_insn_reserv (rtx def)
1703 decl = create_node (sizeof (struct decl));
1704 decl->mode = dm_insn_reserv;
1706 DECL_INSN_RESERV (decl)->name
1707 = check_name (XSTR (def, 0), decl->pos);
1708 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
1709 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
1710 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
1711 VEC_safe_push (decl_t,heap, decls, decl);
1716 /* The function evaluates hash value (0..UINT_MAX) of string. */
1718 string_hash (const char *string)
1722 for (result = i = 0;*string++ != '\0'; i++)
1723 result += ((unsigned char) *string << (i % CHAR_BIT));
1729 /* This page contains abstract data `table of automaton declarations'.
1730 Elements of the table is nodes representing automaton declarations.
1731 Key of the table elements is name of given automaton. Remember
1732 that automaton names have own space. */
1734 /* The function evaluates hash value of an automaton declaration. The
1735 function is used by abstract data `hashtab'. The function returns
1736 hash value (0..UINT_MAX) of given automaton declaration. */
1738 automaton_decl_hash (const void *automaton_decl)
1740 const decl_t decl = (decl_t) automaton_decl;
1742 gcc_assert (decl->mode != dm_automaton
1743 || DECL_AUTOMATON (decl)->name);
1744 return string_hash (DECL_AUTOMATON (decl)->name);
1747 /* The function tests automaton declarations on equality of their
1748 keys. The function is used by abstract data `hashtab'. The
1749 function returns 1 if the declarations have the same key, 0
1752 automaton_decl_eq_p (const void* automaton_decl_1,
1753 const void* automaton_decl_2)
1755 const decl_t decl1 = (decl_t) automaton_decl_1;
1756 const decl_t decl2 = (decl_t) automaton_decl_2;
1758 gcc_assert (decl1->mode == dm_automaton
1759 && DECL_AUTOMATON (decl1)->name
1760 && decl2->mode == dm_automaton
1761 && DECL_AUTOMATON (decl2)->name);
1762 return strcmp (DECL_AUTOMATON (decl1)->name,
1763 DECL_AUTOMATON (decl2)->name) == 0;
1766 /* The automaton declaration table itself is represented by the
1767 following variable. */
1768 static htab_t automaton_decl_table;
1770 /* The function inserts automaton declaration into the table. The
1771 function does nothing if an automaton declaration with the same key
1772 exists already in the table. The function returns automaton
1773 declaration node in the table with the same key as given automaton
1774 declaration node. */
1776 insert_automaton_decl (decl_t automaton_decl)
1780 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
1781 if (*entry_ptr == NULL)
1782 *entry_ptr = (void *) automaton_decl;
1783 return (decl_t) *entry_ptr;
1786 /* The following variable value is node representing automaton
1787 declaration. The node used for searching automaton declaration
1789 static struct decl work_automaton_decl;
1791 /* The function searches for automaton declaration in the table with
1792 the same key as node representing name of the automaton
1793 declaration. The function returns node found in the table, NULL if
1794 such node does not exist in the table. */
1796 find_automaton_decl (const char *name)
1800 work_automaton_decl.mode = dm_automaton;
1801 DECL_AUTOMATON (&work_automaton_decl)->name = name;
1802 entry = htab_find (automaton_decl_table, &work_automaton_decl);
1803 return (decl_t) entry;
1806 /* The function creates empty automaton declaration table and node
1807 representing automaton declaration and used for searching automaton
1808 declaration with given name. The function must be called only once
1809 before any work with the automaton declaration table. */
1811 initiate_automaton_decl_table (void)
1813 work_automaton_decl.mode = dm_automaton;
1814 automaton_decl_table = htab_create (10, automaton_decl_hash,
1815 automaton_decl_eq_p, (htab_del) 0);
1818 /* The function deletes the automaton declaration table. Only call of
1819 function `initiate_automaton_decl_table' is possible immediately
1820 after this function call. */
1822 finish_automaton_decl_table (void)
1824 htab_delete (automaton_decl_table);
1829 /* This page contains abstract data `table of insn declarations'.
1830 Elements of the table is nodes representing insn declarations. Key
1831 of the table elements is name of given insn (in corresponding
1832 define_insn_reservation). Remember that insn names have own
1835 /* The function evaluates hash value of an insn declaration. The
1836 function is used by abstract data `hashtab'. The function returns
1837 hash value (0..UINT_MAX) of given insn declaration. */
1839 insn_decl_hash (const void *insn_decl)
1841 const decl_t decl = (decl_t) insn_decl;
1843 gcc_assert (decl->mode == dm_insn_reserv
1844 && DECL_INSN_RESERV (decl)->name);
1845 return string_hash (DECL_INSN_RESERV (decl)->name);
1848 /* The function tests insn declarations on equality of their keys.
1849 The function is used by abstract data `hashtab'. The function
1850 returns 1 if declarations have the same key, 0 otherwise. */
1852 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
1854 const decl_t decl1 = (decl_t) insn_decl_1;
1855 const decl_t decl2 = (decl_t) insn_decl_2;
1857 gcc_assert (decl1->mode == dm_insn_reserv
1858 && DECL_INSN_RESERV (decl1)->name
1859 && decl2->mode == dm_insn_reserv
1860 && DECL_INSN_RESERV (decl2)->name);
1861 return strcmp (DECL_INSN_RESERV (decl1)->name,
1862 DECL_INSN_RESERV (decl2)->name) == 0;
1865 /* The insn declaration table itself is represented by the following
1866 variable. The table does not contain insn reservation
1868 static htab_t insn_decl_table;
1870 /* The function inserts insn declaration into the table. The function
1871 does nothing if an insn declaration with the same key exists
1872 already in the table. The function returns insn declaration node
1873 in the table with the same key as given insn declaration node. */
1875 insert_insn_decl (decl_t insn_decl)
1879 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
1880 if (*entry_ptr == NULL)
1881 *entry_ptr = (void *) insn_decl;
1882 return (decl_t) *entry_ptr;
1885 /* The following variable value is node representing insn reservation
1886 declaration. The node used for searching insn reservation
1887 declaration with given name. */
1888 static struct decl work_insn_decl;
1890 /* The function searches for insn reservation declaration in the table
1891 with the same key as node representing name of the insn reservation
1892 declaration. The function returns node found in the table, NULL if
1893 such node does not exist in the table. */
1895 find_insn_decl (const char *name)
1899 work_insn_decl.mode = dm_insn_reserv;
1900 DECL_INSN_RESERV (&work_insn_decl)->name = name;
1901 entry = htab_find (insn_decl_table, &work_insn_decl);
1902 return (decl_t) entry;
1905 /* The function creates empty insn declaration table and node
1906 representing insn declaration and used for searching insn
1907 declaration with given name. The function must be called only once
1908 before any work with the insn declaration table. */
1910 initiate_insn_decl_table (void)
1912 work_insn_decl.mode = dm_insn_reserv;
1913 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
1917 /* The function deletes the insn declaration table. Only call of
1918 function `initiate_insn_decl_table' is possible immediately after
1919 this function call. */
1921 finish_insn_decl_table (void)
1923 htab_delete (insn_decl_table);
1928 /* This page contains abstract data `table of declarations'. Elements
1929 of the table is nodes representing declarations (of units and
1930 reservations). Key of the table elements is names of given
1933 /* The function evaluates hash value of a declaration. The function
1934 is used by abstract data `hashtab'. The function returns hash
1935 value (0..UINT_MAX) of given declaration. */
1937 decl_hash (const void *decl)
1939 const decl_t d = (const decl_t) decl;
1941 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
1942 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
1943 return string_hash (d->mode == dm_unit
1944 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
1947 /* The function tests declarations on equality of their keys. The
1948 function is used by abstract data 'hashtab'. The function
1949 returns 1 if the declarations have the same key, 0 otherwise. */
1951 decl_eq_p (const void *decl_1, const void *decl_2)
1953 const decl_t d1 = (const decl_t) decl_1;
1954 const decl_t d2 = (const decl_t) decl_2;
1956 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
1957 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
1958 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
1959 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
1960 return strcmp ((d1->mode == dm_unit
1961 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
1962 (d2->mode == dm_unit
1963 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
1966 /* The declaration table itself is represented by the following
1968 static htab_t decl_table;
1970 /* The function inserts declaration into the table. The function does
1971 nothing if a declaration with the same key exists already in the
1972 table. The function returns declaration node in the table with the
1973 same key as given declaration node. */
1976 insert_decl (decl_t decl)
1980 entry_ptr = htab_find_slot (decl_table, decl, 1);
1981 if (*entry_ptr == NULL)
1982 *entry_ptr = (void *) decl;
1983 return (decl_t) *entry_ptr;
1986 /* The following variable value is node representing declaration. The
1987 node used for searching declaration with given name. */
1988 static struct decl work_decl;
1990 /* The function searches for declaration in the table with the same
1991 key as node representing name of the declaration. The function
1992 returns node found in the table, NULL if such node does not exist
1995 find_decl (const char *name)
1999 work_decl.mode = dm_unit;
2000 DECL_UNIT (&work_decl)->name = name;
2001 entry = htab_find (decl_table, &work_decl);
2002 return (decl_t) entry;
2005 /* The function creates empty declaration table and node representing
2006 declaration and used for searching declaration with given name.
2007 The function must be called only once before any work with the
2008 declaration table. */
2010 initiate_decl_table (void)
2012 work_decl.mode = dm_unit;
2013 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2016 /* The function deletes the declaration table. Only call of function
2017 `initiate_declaration_table' is possible immediately after this
2020 finish_decl_table (void)
2022 htab_delete (decl_table);
2027 /* This page contains checker of pipeline hazard description. */
2029 /* Checking NAMES in an exclusion clause vector and returning formed
2030 unit_set_el_list. */
2031 static unit_set_el_t
2032 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2034 unit_set_el_t el_list;
2035 unit_set_el_t last_el;
2036 unit_set_el_t new_el;
2037 decl_t decl_in_table;
2042 for (i = 0; i < num; i++)
2044 decl_in_table = find_decl (names [i]);
2045 if (decl_in_table == NULL)
2046 error ("unit `%s' in exclusion is not declared", names [i]);
2047 else if (decl_in_table->mode != dm_unit)
2048 error ("`%s' in exclusion is not unit", names [i]);
2051 new_el = create_node (sizeof (struct unit_set_el));
2052 new_el->unit_decl = DECL_UNIT (decl_in_table);
2053 new_el->next_unit_set_el = NULL;
2054 if (last_el == NULL)
2055 el_list = last_el = new_el;
2058 last_el->next_unit_set_el = new_el;
2059 last_el = last_el->next_unit_set_el;
2066 /* The function adds each element from SOURCE_LIST to the exclusion
2067 list of the each element from DEST_LIST. Checking situation "unit
2068 excludes itself". */
2070 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2071 pos_t excl_pos ATTRIBUTE_UNUSED)
2075 unit_set_el_t curr_el;
2076 unit_set_el_t prev_el;
2079 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2080 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2082 if (dst->unit_decl == src->unit_decl)
2084 error ("unit `%s' excludes itself", src->unit_decl->name);
2087 if (dst->unit_decl->automaton_name != NULL
2088 && src->unit_decl->automaton_name != NULL
2089 && strcmp (dst->unit_decl->automaton_name,
2090 src->unit_decl->automaton_name) != 0)
2092 error ("units `%s' and `%s' in exclusion set belong to different automata",
2093 src->unit_decl->name, dst->unit_decl->name);
2096 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2098 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2099 if (curr_el->unit_decl == src->unit_decl)
2101 if (curr_el == NULL)
2103 /* Element not found - insert. */
2104 copy = copy_node (src, sizeof (*src));
2105 copy->next_unit_set_el = NULL;
2106 if (prev_el == NULL)
2107 dst->unit_decl->excl_list = copy;
2109 prev_el->next_unit_set_el = copy;
2114 /* Checking NAMES in presence/absence clause and returning the
2115 formed unit_set_el_list. The function is called only after
2116 processing all exclusion sets. */
2117 static unit_set_el_t
2118 process_presence_absence_names (char **names, int num,
2119 pos_t req_pos ATTRIBUTE_UNUSED,
2120 int presence_p, int final_p)
2122 unit_set_el_t el_list;
2123 unit_set_el_t last_el;
2124 unit_set_el_t new_el;
2125 decl_t decl_in_table;
2130 for (i = 0; i < num; i++)
2132 decl_in_table = find_decl (names [i]);
2133 if (decl_in_table == NULL)
2136 ? "unit `%s' in final presence set is not declared"
2137 : "unit `%s' in presence set is not declared")
2139 ? "unit `%s' in final absence set is not declared"
2140 : "unit `%s' in absence set is not declared")), names [i]);
2141 else if (decl_in_table->mode != dm_unit)
2144 ? "`%s' in final presence set is not unit"
2145 : "`%s' in presence set is not unit")
2147 ? "`%s' in final absence set is not unit"
2148 : "`%s' in absence set is not unit")), names [i]);
2151 new_el = create_node (sizeof (struct unit_set_el));
2152 new_el->unit_decl = DECL_UNIT (decl_in_table);
2153 new_el->next_unit_set_el = NULL;
2154 if (last_el == NULL)
2155 el_list = last_el = new_el;
2158 last_el->next_unit_set_el = new_el;
2159 last_el = last_el->next_unit_set_el;
2166 /* Checking NAMES in patterns of a presence/absence clause and
2167 returning the formed pattern_set_el_list. The function is called
2168 only after processing all exclusion sets. */
2169 static pattern_set_el_t
2170 process_presence_absence_patterns (char ***patterns, int num,
2171 pos_t req_pos ATTRIBUTE_UNUSED,
2172 int presence_p, int final_p)
2174 pattern_set_el_t el_list;
2175 pattern_set_el_t last_el;
2176 pattern_set_el_t new_el;
2177 decl_t decl_in_table;
2182 for (i = 0; i < num; i++)
2184 for (j = 0; patterns [i] [j] != NULL; j++)
2186 new_el = create_node (sizeof (struct pattern_set_el)
2187 + sizeof (struct unit_decl *) * j);
2189 = (struct unit_decl **) ((char *) new_el
2190 + sizeof (struct pattern_set_el));
2191 new_el->next_pattern_set_el = NULL;
2192 if (last_el == NULL)
2193 el_list = last_el = new_el;
2196 last_el->next_pattern_set_el = new_el;
2197 last_el = last_el->next_pattern_set_el;
2199 new_el->units_num = 0;
2200 for (j = 0; patterns [i] [j] != NULL; j++)
2202 decl_in_table = find_decl (patterns [i] [j]);
2203 if (decl_in_table == NULL)
2206 ? "unit `%s' in final presence set is not declared"
2207 : "unit `%s' in presence set is not declared")
2209 ? "unit `%s' in final absence set is not declared"
2210 : "unit `%s' in absence set is not declared")),
2212 else if (decl_in_table->mode != dm_unit)
2215 ? "`%s' in final presence set is not unit"
2216 : "`%s' in presence set is not unit")
2218 ? "`%s' in final absence set is not unit"
2219 : "`%s' in absence set is not unit")),
2223 new_el->unit_decls [new_el->units_num]
2224 = DECL_UNIT (decl_in_table);
2225 new_el->units_num++;
2232 /* The function adds each element from PATTERN_LIST to presence (if
2233 PRESENCE_P) or absence list of the each element from DEST_LIST.
2234 Checking situations "unit requires own absence", and "unit excludes
2235 and requires presence of ...", "unit requires absence and presence
2236 of ...", "units in (final) presence set belong to different
2237 automata", and "units in (final) absence set belong to different
2238 automata". Remember that we process absence sets only after all
2241 add_presence_absence (unit_set_el_t dest_list,
2242 pattern_set_el_t pattern_list,
2243 pos_t req_pos ATTRIBUTE_UNUSED,
2244 int presence_p, int final_p)
2247 pattern_set_el_t pat;
2248 struct unit_decl *unit;
2249 unit_set_el_t curr_excl_el;
2250 pattern_set_el_t curr_pat_el;
2251 pattern_set_el_t prev_el;
2252 pattern_set_el_t copy;
2256 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2257 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2259 for (i = 0; i < pat->units_num; i++)
2261 unit = pat->unit_decls [i];
2262 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2264 error ("unit `%s' requires own absence", unit->name);
2267 if (dst->unit_decl->automaton_name != NULL
2268 && unit->automaton_name != NULL
2269 && strcmp (dst->unit_decl->automaton_name,
2270 unit->automaton_name) != 0)
2274 ? "units `%s' and `%s' in final presence set belong to different automata"
2275 : "units `%s' and `%s' in presence set belong to different automata")
2277 ? "units `%s' and `%s' in final absence set belong to different automata"
2278 : "units `%s' and `%s' in absence set belong to different automata")),
2279 unit->name, dst->unit_decl->name);
2284 for (curr_excl_el = dst->unit_decl->excl_list;
2285 curr_excl_el != NULL;
2286 curr_excl_el = curr_excl_el->next_unit_set_el)
2288 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2292 error ("unit `%s' excludes and requires presence of `%s'",
2293 dst->unit_decl->name, unit->name);
2298 (0, "unit `%s' excludes and requires presence of `%s'",
2299 dst->unit_decl->name, unit->name);
2302 else if (pat->units_num == 1)
2303 for (curr_pat_el = dst->unit_decl->presence_list;
2304 curr_pat_el != NULL;
2305 curr_pat_el = curr_pat_el->next_pattern_set_el)
2306 if (curr_pat_el->units_num == 1
2307 && unit == curr_pat_el->unit_decls [0])
2312 ("unit `%s' requires absence and presence of `%s'",
2313 dst->unit_decl->name, unit->name);
2318 (0, "unit `%s' requires absence and presence of `%s'",
2319 dst->unit_decl->name, unit->name);
2323 for (prev_el = (presence_p
2325 ? dst->unit_decl->final_presence_list
2326 : dst->unit_decl->final_presence_list)
2328 ? dst->unit_decl->final_absence_list
2329 : dst->unit_decl->absence_list));
2330 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2331 prev_el = prev_el->next_pattern_set_el)
2333 copy = copy_node (pat, sizeof (*pat));
2334 copy->next_pattern_set_el = NULL;
2335 if (prev_el == NULL)
2340 dst->unit_decl->final_presence_list = copy;
2342 dst->unit_decl->presence_list = copy;
2345 dst->unit_decl->final_absence_list = copy;
2347 dst->unit_decl->absence_list = copy;
2350 prev_el->next_pattern_set_el = copy;
2357 /* The function searches for bypass with given IN_INSN_RESERV in given
2359 static struct bypass_decl *
2360 find_bypass (struct bypass_decl *bypass_list,
2361 struct insn_reserv_decl *in_insn_reserv)
2363 struct bypass_decl *bypass;
2365 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2366 if (bypass->in_insn_reserv == in_insn_reserv)
2371 /* The function processes pipeline description declarations, checks
2372 their correctness, and forms exclusion/presence/absence sets. */
2374 process_decls (void)
2377 decl_t automaton_decl;
2378 decl_t decl_in_table;
2379 decl_t out_insn_reserv;
2380 decl_t in_insn_reserv;
2381 struct bypass_decl *bypass;
2382 int automaton_presence;
2385 /* Checking repeated automata declarations. */
2386 automaton_presence = 0;
2387 for (i = 0; i < description->decls_num; i++)
2389 decl = description->decls [i];
2390 if (decl->mode == dm_automaton)
2392 automaton_presence = 1;
2393 decl_in_table = insert_automaton_decl (decl);
2394 if (decl_in_table != decl)
2397 error ("repeated declaration of automaton `%s'",
2398 DECL_AUTOMATON (decl)->name);
2400 warning (0, "repeated declaration of automaton `%s'",
2401 DECL_AUTOMATON (decl)->name);
2405 /* Checking undeclared automata, repeated declarations (except for
2406 automata) and correctness of their attributes (insn latency times
2408 for (i = 0; i < description->decls_num; i++)
2410 decl = description->decls [i];
2411 if (decl->mode == dm_insn_reserv)
2413 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2414 error ("define_insn_reservation `%s' has negative latency time",
2415 DECL_INSN_RESERV (decl)->name);
2416 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2417 description->insns_num++;
2418 decl_in_table = insert_insn_decl (decl);
2419 if (decl_in_table != decl)
2420 error ("`%s' is already used as insn reservation name",
2421 DECL_INSN_RESERV (decl)->name);
2423 else if (decl->mode == dm_bypass)
2425 if (DECL_BYPASS (decl)->latency < 0)
2426 error ("define_bypass `%s - %s' has negative latency time",
2427 DECL_BYPASS (decl)->out_insn_name,
2428 DECL_BYPASS (decl)->in_insn_name);
2430 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2432 if (decl->mode == dm_unit)
2434 DECL_UNIT (decl)->automaton_decl = NULL;
2435 if (DECL_UNIT (decl)->automaton_name != NULL)
2438 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2439 if (automaton_decl == NULL)
2440 error ("automaton `%s' is not declared",
2441 DECL_UNIT (decl)->automaton_name);
2444 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2445 DECL_UNIT (decl)->automaton_decl
2446 = DECL_AUTOMATON (automaton_decl);
2449 else if (automaton_presence)
2450 error ("define_unit `%s' without automaton when one defined",
2451 DECL_UNIT (decl)->name);
2452 DECL_UNIT (decl)->unit_num = description->units_num;
2453 description->units_num++;
2454 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2456 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2459 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2463 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2465 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2468 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2470 if (decl_in_table == NULL)
2471 decl_in_table = insert_decl (decl);
2474 if (decl->mode == dm_unit)
2475 error ("repeated declaration of unit `%s'",
2476 DECL_UNIT (decl)->name);
2478 error ("repeated declaration of reservation `%s'",
2479 DECL_RESERV (decl)->name);
2483 /* Check bypasses and form list of bypasses for each (output)
2485 for (i = 0; i < description->decls_num; i++)
2487 decl = description->decls [i];
2488 if (decl->mode == dm_bypass)
2490 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2491 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2492 if (out_insn_reserv == NULL)
2493 error ("there is no insn reservation `%s'",
2494 DECL_BYPASS (decl)->out_insn_name);
2495 else if (in_insn_reserv == NULL)
2496 error ("there is no insn reservation `%s'",
2497 DECL_BYPASS (decl)->in_insn_name);
2500 DECL_BYPASS (decl)->out_insn_reserv
2501 = DECL_INSN_RESERV (out_insn_reserv);
2502 DECL_BYPASS (decl)->in_insn_reserv
2503 = DECL_INSN_RESERV (in_insn_reserv);
2505 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2506 DECL_BYPASS (decl)->in_insn_reserv);
2509 if (DECL_BYPASS (decl)->latency == bypass->latency)
2513 ("the same bypass `%s - %s' is already defined",
2514 DECL_BYPASS (decl)->out_insn_name,
2515 DECL_BYPASS (decl)->in_insn_name);
2518 (0, "the same bypass `%s - %s' is already defined",
2519 DECL_BYPASS (decl)->out_insn_name,
2520 DECL_BYPASS (decl)->in_insn_name);
2523 error ("bypass `%s - %s' is already defined",
2524 DECL_BYPASS (decl)->out_insn_name,
2525 DECL_BYPASS (decl)->in_insn_name);
2529 DECL_BYPASS (decl)->next
2530 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2531 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2532 = DECL_BYPASS (decl);
2538 /* Check exclusion set declarations and form exclusion sets. */
2539 for (i = 0; i < description->decls_num; i++)
2541 decl = description->decls [i];
2542 if (decl->mode == dm_excl)
2544 unit_set_el_t unit_set_el_list;
2545 unit_set_el_t unit_set_el_list_2;
2548 = process_excls (DECL_EXCL (decl)->names,
2549 DECL_EXCL (decl)->first_list_length, decl->pos);
2551 = process_excls (&DECL_EXCL (decl)->names
2552 [DECL_EXCL (decl)->first_list_length],
2553 DECL_EXCL (decl)->all_names_num
2554 - DECL_EXCL (decl)->first_list_length,
2556 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2557 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2561 /* Check presence set declarations and form presence sets. */
2562 for (i = 0; i < description->decls_num; i++)
2564 decl = description->decls [i];
2565 if (decl->mode == dm_presence)
2567 unit_set_el_t unit_set_el_list;
2568 pattern_set_el_t pattern_set_el_list;
2571 = process_presence_absence_names
2572 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
2573 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2575 = process_presence_absence_patterns
2576 (DECL_PRESENCE (decl)->patterns,
2577 DECL_PRESENCE (decl)->patterns_num,
2578 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2579 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2581 DECL_PRESENCE (decl)->final_p);
2585 /* Check absence set declarations and form absence sets. */
2586 for (i = 0; i < description->decls_num; i++)
2588 decl = description->decls [i];
2589 if (decl->mode == dm_absence)
2591 unit_set_el_t unit_set_el_list;
2592 pattern_set_el_t pattern_set_el_list;
2595 = process_presence_absence_names
2596 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
2597 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2599 = process_presence_absence_patterns
2600 (DECL_ABSENCE (decl)->patterns,
2601 DECL_ABSENCE (decl)->patterns_num,
2602 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2603 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2605 DECL_ABSENCE (decl)->final_p);
2610 /* The following function checks that declared automaton is used. If
2611 the automaton is not used, the function fixes error/warning. The
2612 following function must be called only after `process_decls'. */
2614 check_automaton_usage (void)
2619 for (i = 0; i < description->decls_num; i++)
2621 decl = description->decls [i];
2622 if (decl->mode == dm_automaton
2623 && !DECL_AUTOMATON (decl)->automaton_is_used)
2626 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
2628 warning (0, "automaton `%s' is not used",
2629 DECL_AUTOMATON (decl)->name);
2634 /* The following recursive function processes all regexp in order to
2635 fix usage of units or reservations and to fix errors of undeclared
2636 name. The function may change unit_regexp onto reserv_regexp.
2637 Remember that reserv_regexp does not exist before the function
2640 process_regexp (regexp_t regexp)
2642 decl_t decl_in_table;
2643 regexp_t new_regexp;
2646 switch (regexp->mode)
2649 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
2650 if (decl_in_table == NULL)
2651 error ("undeclared unit or reservation `%s'",
2652 REGEXP_UNIT (regexp)->name);
2654 switch (decl_in_table->mode)
2657 DECL_UNIT (decl_in_table)->unit_is_used = 1;
2658 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
2662 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
2663 new_regexp = create_node (sizeof (struct regexp));
2664 new_regexp->mode = rm_reserv;
2665 new_regexp->pos = regexp->pos;
2666 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
2667 REGEXP_RESERV (new_regexp)->reserv_decl
2668 = DECL_RESERV (decl_in_table);
2669 regexp = new_regexp;
2677 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2678 REGEXP_SEQUENCE (regexp)->regexps [i]
2679 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
2682 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2683 REGEXP_ALLOF (regexp)->regexps [i]
2684 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
2687 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2688 REGEXP_ONEOF (regexp)->regexps [i]
2689 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
2692 REGEXP_REPEAT (regexp)->regexp
2693 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
2703 /* The following function processes regexp of define_reservation and
2704 define_insn_reservation with the aid of function
2705 `process_regexp'. */
2707 process_regexp_decls (void)
2712 for (i = 0; i < description->decls_num; i++)
2714 decl = description->decls [i];
2715 if (decl->mode == dm_reserv)
2716 DECL_RESERV (decl)->regexp
2717 = process_regexp (DECL_RESERV (decl)->regexp);
2718 else if (decl->mode == dm_insn_reserv)
2719 DECL_INSN_RESERV (decl)->regexp
2720 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
2724 /* The following function checks that declared unit is used. If the
2725 unit is not used, the function fixes errors/warnings. The
2726 following function must be called only after `process_decls',
2727 `process_regexp_decls'. */
2734 for (i = 0; i < description->decls_num; i++)
2736 decl = description->decls [i];
2737 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
2740 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
2742 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
2744 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
2747 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
2749 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
2754 /* The following variable value is number of reservation being
2755 processed on loop recognition. */
2756 static int curr_loop_pass_num;
2758 /* The following recursive function returns nonzero value if REGEXP
2759 contains given decl or reservations in given regexp refers for
2762 loop_in_regexp (regexp_t regexp, decl_t start_decl)
2768 switch (regexp->mode)
2774 if (start_decl->mode == dm_reserv
2775 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
2777 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
2778 == curr_loop_pass_num)
2779 /* declaration has been processed. */
2783 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
2784 = curr_loop_pass_num;
2785 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2790 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2791 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
2796 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2797 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
2802 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2803 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
2808 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
2818 /* The following function fixes errors "cycle in definition ...". The
2819 function uses function `loop_in_regexp' for that. */
2821 check_loops_in_regexps (void)
2826 for (i = 0; i < description->decls_num; i++)
2828 decl = description->decls [i];
2829 if (decl->mode == dm_reserv)
2830 DECL_RESERV (decl)->loop_pass_num = 0;
2832 for (i = 0; i < description->decls_num; i++)
2834 decl = description->decls [i];
2835 curr_loop_pass_num = i;
2837 if (decl->mode == dm_reserv)
2839 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
2840 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
2842 gcc_assert (DECL_RESERV (decl)->regexp);
2843 error ("cycle in definition of reservation `%s'",
2844 DECL_RESERV (decl)->name);
2850 /* The function recursively processes IR of reservation and defines
2851 max and min cycle for reservation of unit. */
2853 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
2854 int min_start_cycle, int *max_finish_cycle,
2855 int *min_finish_cycle)
2859 switch (regexp->mode)
2862 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
2863 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
2864 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
2865 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
2866 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
2867 *max_finish_cycle = max_start_cycle;
2868 *min_finish_cycle = min_start_cycle;
2872 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2873 max_start_cycle, min_start_cycle,
2874 max_finish_cycle, min_finish_cycle);
2878 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
2880 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
2881 max_start_cycle, min_start_cycle,
2882 max_finish_cycle, min_finish_cycle);
2883 max_start_cycle = *max_finish_cycle + 1;
2884 min_start_cycle = *min_finish_cycle + 1;
2889 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2891 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
2892 max_start_cycle, min_start_cycle,
2893 max_finish_cycle, min_finish_cycle);
2894 max_start_cycle = *max_finish_cycle + 1;
2895 min_start_cycle = *min_finish_cycle + 1;
2904 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2906 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
2907 max_start_cycle, min_start_cycle,
2908 max_finish_cycle, min_finish_cycle);
2909 if (max_cycle < *max_finish_cycle)
2910 max_cycle = *max_finish_cycle;
2911 if (i == 0 || min_cycle > *min_finish_cycle)
2912 min_cycle = *min_finish_cycle;
2914 *max_finish_cycle = max_cycle;
2915 *min_finish_cycle = min_cycle;
2924 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2926 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
2927 max_start_cycle, min_start_cycle,
2928 max_finish_cycle, min_finish_cycle);
2929 if (max_cycle < *max_finish_cycle)
2930 max_cycle = *max_finish_cycle;
2931 if (i == 0 || min_cycle > *min_finish_cycle)
2932 min_cycle = *min_finish_cycle;
2934 *max_finish_cycle = max_cycle;
2935 *min_finish_cycle = min_cycle;
2940 *max_finish_cycle = max_start_cycle;
2941 *min_finish_cycle = min_start_cycle;
2949 /* The following function is called only for correct program. The
2950 function defines max reservation of insns in cycles. */
2952 evaluate_max_reserv_cycles (void)
2954 int max_insn_cycles_num;
2955 int min_insn_cycles_num;
2959 description->max_insn_reserv_cycles = 0;
2960 for (i = 0; i < description->decls_num; i++)
2962 decl = description->decls [i];
2963 if (decl->mode == dm_insn_reserv)
2965 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
2966 &max_insn_cycles_num, &min_insn_cycles_num);
2967 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
2968 description->max_insn_reserv_cycles = max_insn_cycles_num;
2971 description->max_insn_reserv_cycles++;
2974 /* The following function calls functions for checking all
2977 check_all_description (void)
2980 check_automaton_usage ();
2981 process_regexp_decls ();
2983 check_loops_in_regexps ();
2985 evaluate_max_reserv_cycles ();
2990 /* The page contains abstract data `ticker'. This data is used to
2991 report time of different phases of building automata. It is
2992 possibly to write a description for which automata will be built
2993 during several minutes even on fast machine. */
2995 /* The following function creates ticker and makes it active. */
2997 create_ticker (void)
3001 ticker.modified_creation_time = get_run_time ();
3002 ticker.incremented_off_time = 0;
3006 /* The following function switches off given ticker. */
3008 ticker_off (ticker_t *ticker)
3010 if (ticker->incremented_off_time == 0)
3011 ticker->incremented_off_time = get_run_time () + 1;
3014 /* The following function switches on given ticker. */
3016 ticker_on (ticker_t *ticker)
3018 if (ticker->incremented_off_time != 0)
3020 ticker->modified_creation_time
3021 += get_run_time () - ticker->incremented_off_time + 1;
3022 ticker->incremented_off_time = 0;
3026 /* The following function returns current time in milliseconds since
3027 the moment when given ticker was created. */
3029 active_time (ticker_t ticker)
3031 if (ticker.incremented_off_time != 0)
3032 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3034 return get_run_time () - ticker.modified_creation_time;
3037 /* The following function returns string representation of active time
3038 of given ticker. The result is string representation of seconds
3039 with accuracy of 1/100 second. Only result of the last call of the
3040 function exists. Therefore the following code is not correct
3042 printf ("parser time: %s\ngeneration time: %s\n",
3043 active_time_string (parser_ticker),
3044 active_time_string (generation_ticker));
3046 Correct code has to be the following
3048 printf ("parser time: %s\n", active_time_string (parser_ticker));
3049 printf ("generation time: %s\n",
3050 active_time_string (generation_ticker));
3054 print_active_time (FILE *f, ticker_t ticker)
3058 msecs = active_time (ticker);
3059 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3064 /* The following variable value is number of automaton which are
3065 really being created. This value is defined on the base of
3066 argument of option `-split'. If the variable has zero value the
3067 number of automata is defined by the constructions `%automaton'.
3068 This case occurs when option `-split' is absent or has zero
3069 argument. If constructions `define_automaton' is absent only one
3070 automaton is created. */
3071 static int automata_num;
3073 /* The following variable values are times of
3074 o transformation of regular expressions
3075 o building NDFA (DFA if !ndfa_flag)
3076 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3078 o building insn equivalence classes
3081 static ticker_t transform_time;
3082 static ticker_t NDFA_time;
3083 static ticker_t NDFA_to_DFA_time;
3084 static ticker_t minimize_time;
3085 static ticker_t equiv_time;
3086 static ticker_t automaton_generation_time;
3087 static ticker_t output_time;
3089 /* The following variable values are times of
3092 all pipeline hazard translator work */
3093 static ticker_t check_time;
3094 static ticker_t generation_time;
3095 static ticker_t all_time;
3099 /* Pseudo insn decl which denotes advancing cycle. */
3100 static decl_t advance_cycle_insn_decl;
3102 add_advance_cycle_insn_decl (void)
3104 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3105 advance_cycle_insn_decl->mode = dm_insn_reserv;
3106 advance_cycle_insn_decl->pos = no_pos;
3107 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3108 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
3109 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3110 = description->insns_num;
3111 description->decls [description->decls_num] = advance_cycle_insn_decl;
3112 description->decls_num++;
3113 description->insns_num++;
3117 /* Abstract data `alternative states' which represents
3118 nondeterministic nature of the description (see comments for
3119 structures alt_state and state). */
3121 /* List of free states. */
3122 static alt_state_t first_free_alt_state;
3125 /* The following variables is maximal number of allocated nodes
3127 static int allocated_alt_states_num = 0;
3130 /* The following function returns free node alt_state. It may be new
3131 allocated node or node freed earlier. */
3133 get_free_alt_state (void)
3137 if (first_free_alt_state != NULL)
3139 result = first_free_alt_state;
3140 first_free_alt_state = first_free_alt_state->next_alt_state;
3145 allocated_alt_states_num++;
3147 result = create_node (sizeof (struct alt_state));
3149 result->state = NULL;
3150 result->next_alt_state = NULL;
3151 result->next_sorted_alt_state = NULL;
3155 /* The function frees node ALT_STATE. */
3157 free_alt_state (alt_state_t alt_state)
3159 if (alt_state == NULL)
3161 alt_state->next_alt_state = first_free_alt_state;
3162 first_free_alt_state = alt_state;
3165 /* The function frees list started with node ALT_STATE_LIST. */
3167 free_alt_states (alt_state_t alt_states_list)
3169 alt_state_t curr_alt_state;
3170 alt_state_t next_alt_state;
3172 for (curr_alt_state = alt_states_list;
3173 curr_alt_state != NULL;
3174 curr_alt_state = next_alt_state)
3176 next_alt_state = curr_alt_state->next_alt_state;
3177 free_alt_state (curr_alt_state);
3181 /* The function compares unique numbers of alt states. */
3183 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3185 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3186 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3188 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3189 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3195 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3196 states from the list. The comparison key is alt state unique
3200 uniq_sort_alt_states (alt_state_t alt_states_list)
3202 alt_state_t curr_alt_state;
3203 VEC(alt_state_t,heap) *alt_states;
3205 size_t prev_unique_state_ind;
3208 if (alt_states_list == 0)
3210 if (alt_states_list->next_alt_state == 0)
3211 return alt_states_list;
3213 alt_states = VEC_alloc (alt_state_t,heap, 150);
3214 for (curr_alt_state = alt_states_list;
3215 curr_alt_state != NULL;
3216 curr_alt_state = curr_alt_state->next_alt_state)
3217 VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
3219 qsort (VEC_address (alt_state_t, alt_states),
3220 VEC_length (alt_state_t, alt_states),
3221 sizeof (alt_state_t), alt_state_cmp);
3223 prev_unique_state_ind = 0;
3224 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3225 if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
3226 != VEC_index (alt_state_t, alt_states, i)->state)
3228 prev_unique_state_ind++;
3229 VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
3230 VEC_index (alt_state_t, alt_states, i));
3232 VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
3234 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3235 VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
3236 = VEC_index (alt_state_t, alt_states, i);
3237 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
3239 result = VEC_index (alt_state_t, alt_states, 0);
3241 VEC_free (alt_state_t,heap, alt_states);
3245 /* The function checks equality of alt state lists. Remember that the
3246 lists must be already sorted by the previous function. */
3248 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3250 while (alt_states_1 != NULL && alt_states_2 != NULL
3251 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3253 alt_states_1 = alt_states_1->next_sorted_alt_state;
3254 alt_states_2 = alt_states_2->next_sorted_alt_state;
3256 return alt_states_1 == alt_states_2;
3259 /* Initialization of the abstract data. */
3261 initiate_alt_states (void)
3263 first_free_alt_state = NULL;
3266 /* Finishing work with the abstract data. */
3268 finish_alt_states (void)
3274 /* The page contains macros for work with bits strings. We could use
3275 standard gcc bitmap or sbitmap but it would result in difficulties
3276 of building canadian cross. */
3278 /* Set bit number bitno in the bit string. The macro is not side
3280 #define SET_BIT(bitstring, bitno) \
3281 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3283 #define CLEAR_BIT(bitstring, bitno) \
3284 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3286 /* Test if bit number bitno in the bitstring is set. The macro is not
3287 side effect proof. */
3288 #define TEST_BIT(bitstring, bitno) \
3289 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3293 /* This page contains abstract data `state'. */
3295 /* Maximal length of reservations in cycles (>= 1). */
3296 static int max_cycles_num;
3298 /* Number of set elements (see type set_el_t) needed for
3299 representation of one cycle reservation. It is depended on units
3301 static int els_in_cycle_reserv;
3303 /* Number of set elements (see type set_el_t) needed for
3304 representation of maximal length reservation. Deterministic
3305 reservation is stored as set (bit string) of length equal to the
3306 variable value * number of bits in set_el_t. */
3307 static int els_in_reservs;
3309 /* Array of pointers to unit declarations. */
3310 static unit_decl_t *units_array;
3312 /* Temporary reservation of maximal length. */
3313 static reserv_sets_t temp_reserv;
3315 /* The state table itself is represented by the following variable. */
3316 static htab_t state_table;
3318 /* Linked list of free 'state' structures to be recycled. The
3319 next_equiv_class_state pointer is borrowed for a free list. */
3320 static state_t first_free_state;
3322 static int curr_unique_state_num;
3325 /* The following variables is maximal number of allocated nodes
3327 static int allocated_states_num = 0;
3330 /* Allocate new reservation set. */
3331 static reserv_sets_t
3332 alloc_empty_reserv_sets (void)
3334 reserv_sets_t result;
3336 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3337 result = (reserv_sets_t) obstack_base (&irp);
3338 obstack_finish (&irp);
3339 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3343 /* Hash value of reservation set. */
3345 reserv_sets_hash_value (reserv_sets_t reservs)
3347 set_el_t hash_value;
3350 set_el_t *reserv_ptr;
3353 reservs_num = els_in_reservs;
3354 reserv_ptr = reservs;
3356 while (reservs_num != 0)
3359 hash_value += ((*reserv_ptr >> i)
3360 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3362 if (i == sizeof (set_el_t) * CHAR_BIT)
3366 if (sizeof (set_el_t) <= sizeof (unsigned))
3369 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3371 result += (unsigned) hash_value;
3372 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3377 /* Comparison of given reservation sets. */
3379 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3382 set_el_t *reserv_ptr_1;
3383 set_el_t *reserv_ptr_2;
3385 gcc_assert (reservs_1 && reservs_2);
3386 reservs_num = els_in_reservs;
3387 reserv_ptr_1 = reservs_1;
3388 reserv_ptr_2 = reservs_2;
3389 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3395 if (reservs_num == 0)
3397 else if (*reserv_ptr_1 < *reserv_ptr_2)
3403 /* The function checks equality of the reservation sets. */
3405 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3407 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3410 /* Set up in the reservation set that unit with UNIT_NUM is used on
3413 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3415 gcc_assert (cycle_num < max_cycles_num);
3416 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3417 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3420 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3421 used on CYCLE_NUM. */
3423 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3425 gcc_assert (cycle_num < max_cycles_num);
3426 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3427 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3430 /* The function checks that the reservation sets are intersected,
3431 i.e. there is a unit reservation on a cycle in both reservation
3434 reserv_sets_are_intersected (reserv_sets_t operand_1,
3435 reserv_sets_t operand_2)
3439 set_el_t *cycle_ptr_1;
3440 set_el_t *cycle_ptr_2;
3442 gcc_assert (operand_1 && operand_2);
3443 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3444 el_ptr_1 < operand_1 + els_in_reservs;
3445 el_ptr_1++, el_ptr_2++)
3446 if (*el_ptr_1 & *el_ptr_2)
3448 reserv_sets_or (temp_reserv, operand_1, operand_2);
3449 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3450 cycle_ptr_1 < operand_1 + els_in_reservs;
3451 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3453 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3454 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3455 el_ptr_1++, el_ptr_2++)
3456 if (*el_ptr_1 & *el_ptr_2)
3458 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3460 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3464 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3466 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3473 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3474 cpu cycle. The remaining bits of OPERAND (representing the last
3475 cycle unit reservations) are not changed. */
3477 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3481 gcc_assert (result && operand && result != operand);
3482 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3483 result [i - els_in_cycle_reserv] = operand [i];
3486 /* OR of the reservation sets. */
3488 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3489 reserv_sets_t operand_2)
3493 set_el_t *result_set_el_ptr;
3495 gcc_assert (result && operand_1 && operand_2);
3496 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3497 el_ptr_1 < operand_1 + els_in_reservs;
3498 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3499 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3502 /* AND of the reservation sets. */
3504 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3505 reserv_sets_t operand_2)
3509 set_el_t *result_set_el_ptr;
3511 gcc_assert (result && operand_1 && operand_2);
3512 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3513 el_ptr_1 < operand_1 + els_in_reservs;
3514 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3515 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3518 /* The function outputs string representation of units reservation on
3519 cycle START_CYCLE in the reservation set. The function uses repeat
3520 construction if REPETITION_NUM > 1. */
3522 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3526 int reserved_units_num;
3528 reserved_units_num = 0;
3529 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3530 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3531 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3532 reserved_units_num++;
3533 gcc_assert (repetition_num > 0);
3534 if (repetition_num != 1 && reserved_units_num > 1)
3536 reserved_units_num = 0;
3538 unit_num < description->units_num;
3540 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3541 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3543 if (reserved_units_num != 0)
3545 reserved_units_num++;
3546 fprintf (f, "%s", units_array [unit_num]->name);
3548 if (reserved_units_num == 0)
3549 fprintf (f, NOTHING_NAME);
3550 gcc_assert (repetition_num > 0);
3551 if (repetition_num != 1 && reserved_units_num > 1)
3553 if (repetition_num != 1)
3554 fprintf (f, "*%d", repetition_num);
3557 /* The function outputs string representation of units reservation in
3558 the reservation set. */
3560 output_reserv_sets (FILE *f, reserv_sets_t reservs)
3562 int start_cycle = 0;
3567 for (cycle = 0; cycle < max_cycles_num; cycle++)
3568 if (repetition_num == 0)
3571 start_cycle = cycle;
3574 ((char *) reservs + start_cycle * els_in_cycle_reserv
3575 * sizeof (set_el_t),
3576 (char *) reservs + cycle * els_in_cycle_reserv
3577 * sizeof (set_el_t),
3578 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3582 if (start_cycle != 0)
3584 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3586 start_cycle = cycle;
3588 if (start_cycle < max_cycles_num)
3590 if (start_cycle != 0)
3592 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3596 /* The following function returns free node state for AUTOMATON. It
3597 may be new allocated node or node freed earlier. The function also
3598 allocates reservation set if WITH_RESERVS has nonzero value. */
3600 get_free_state (int with_reservs, automaton_t automaton)
3604 gcc_assert (max_cycles_num > 0 && automaton);
3605 if (first_free_state)
3607 result = first_free_state;
3608 first_free_state = result->next_equiv_class_state;
3610 result->next_equiv_class_state = NULL;
3611 result->automaton = automaton;
3612 result->first_out_arc = NULL;
3613 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3614 result->it_was_placed_in_stack_for_DFA_forming = 0;
3615 result->component_states = NULL;
3620 allocated_states_num++;
3622 result = create_node (sizeof (struct state));
3623 result->automaton = automaton;
3624 result->first_out_arc = NULL;
3625 result->unique_num = curr_unique_state_num;
3626 curr_unique_state_num++;
3630 if (result->reservs == NULL)
3631 result->reservs = alloc_empty_reserv_sets ();
3633 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3638 /* The function frees node STATE. */
3640 free_state (state_t state)
3642 free_alt_states (state->component_states);
3643 state->next_equiv_class_state = first_free_state;
3644 first_free_state = state;
3647 /* Hash value of STATE. If STATE represents deterministic state it is
3648 simply hash value of the corresponding reservation set. Otherwise
3649 it is formed from hash values of the component deterministic
3650 states. One more key is order number of state automaton. */
3652 state_hash (const void *state)
3654 unsigned int hash_value;
3655 alt_state_t alt_state;
3657 if (((state_t) state)->component_states == NULL)
3658 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
3662 for (alt_state = ((state_t) state)->component_states;
3664 alt_state = alt_state->next_sorted_alt_state)
3665 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3666 | (hash_value << CHAR_BIT))
3667 + alt_state->state->unique_num);
3669 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3670 | (hash_value << CHAR_BIT))
3671 + ((state_t) state)->automaton->automaton_order_num);
3675 /* Return nonzero value if the states are the same. */
3677 state_eq_p (const void *state_1, const void *state_2)
3679 alt_state_t alt_state_1;
3680 alt_state_t alt_state_2;
3682 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
3684 else if (((state_t) state_1)->component_states == NULL
3685 && ((state_t) state_2)->component_states == NULL)
3686 return reserv_sets_eq (((state_t) state_1)->reservs,
3687 ((state_t) state_2)->reservs);
3688 else if (((state_t) state_1)->component_states != NULL
3689 && ((state_t) state_2)->component_states != NULL)
3691 for (alt_state_1 = ((state_t) state_1)->component_states,
3692 alt_state_2 = ((state_t) state_2)->component_states;
3693 alt_state_1 != NULL && alt_state_2 != NULL;
3694 alt_state_1 = alt_state_1->next_sorted_alt_state,
3695 alt_state_2 = alt_state_2->next_sorted_alt_state)
3696 /* All state in the list must be already in the hash table.
3697 Also the lists must be sorted. */
3698 if (alt_state_1->state != alt_state_2->state)
3700 return alt_state_1 == alt_state_2;
3706 /* Insert STATE into the state table. */
3708 insert_state (state_t state)
3712 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
3713 if (*entry_ptr == NULL)
3714 *entry_ptr = (void *) state;
3715 return (state_t) *entry_ptr;
3718 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3719 deterministic STATE. */
3721 set_state_reserv (state_t state, int cycle_num, int unit_num)
3723 set_unit_reserv (state->reservs, cycle_num, unit_num);
3726 /* Return nonzero value if the deterministic states contains a
3727 reservation of the same cpu unit on the same cpu cycle. */
3729 intersected_state_reservs_p (state_t state1, state_t state2)
3731 gcc_assert (state1->automaton == state2->automaton);
3732 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3735 /* Return deterministic state (inserted into the table) which
3736 representing the automaton state which is union of reservations of
3737 the deterministic states masked by RESERVS. */
3739 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
3742 state_t state_in_table;
3744 gcc_assert (state1->automaton == state2->automaton);
3745 result = get_free_state (1, state1->automaton);
3746 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
3747 reserv_sets_and (result->reservs, result->reservs, reservs);
3748 state_in_table = insert_state (result);
3749 if (result != state_in_table)
3751 free_state (result);
3752 result = state_in_table;
3757 /* Return deterministic state (inserted into the table) which
3758 represent the automaton state is obtained from deterministic STATE
3759 by advancing cpu cycle and masking by RESERVS. */
3761 state_shift (state_t state, reserv_sets_t reservs)
3764 state_t state_in_table;
3766 result = get_free_state (1, state->automaton);
3767 reserv_sets_shift (result->reservs, state->reservs);
3768 reserv_sets_and (result->reservs, result->reservs, reservs);
3769 state_in_table = insert_state (result);
3770 if (result != state_in_table)
3772 free_state (result);
3773 result = state_in_table;
3778 /* Initialization of the abstract data. */
3780 initiate_states (void)
3785 if (description->units_num)
3786 units_array = XNEWVEC (unit_decl_t, description->units_num);
3790 for (i = 0; i < description->decls_num; i++)
3792 decl = description->decls [i];
3793 if (decl->mode == dm_unit)
3794 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
3796 max_cycles_num = description->max_insn_reserv_cycles;
3798 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3799 / (sizeof (set_el_t) * CHAR_BIT));
3800 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3801 curr_unique_state_num = 0;
3802 initiate_alt_states ();
3803 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3804 temp_reserv = alloc_empty_reserv_sets ();
3807 /* Finishing work with the abstract data. */
3809 finish_states (void)
3813 htab_delete (state_table);
3814 first_free_state = NULL;
3815 finish_alt_states ();
3820 /* Abstract data `arcs'. */
3822 /* List of free arcs. */
3823 static arc_t first_free_arc;
3826 /* The following variables is maximal number of allocated nodes
3828 static int allocated_arcs_num = 0;
3831 /* The function frees node ARC. */
3833 free_arc (arc_t arc)
3835 arc->next_out_arc = first_free_arc;
3836 first_free_arc = arc;
3839 /* The function removes and frees ARC staring from FROM_STATE. */
3841 remove_arc (state_t from_state, arc_t arc)
3847 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3849 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3850 if (curr_arc == arc)
3852 gcc_assert (curr_arc);
3853 if (prev_arc == NULL)
3854 from_state->first_out_arc = arc->next_out_arc;
3856 prev_arc->next_out_arc = arc->next_out_arc;
3857 from_state->num_out_arcs--;
3861 /* The functions returns arc with given characteristics (or NULL if
3862 the arc does not exist). */
3864 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
3868 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3869 if (arc->to_state == to_state && arc->insn == insn)
3874 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN.
3875 The function returns added arc (or already existing arc). */
3877 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
3881 new_arc = find_arc (from_state, to_state, ainsn);
3882 if (new_arc != NULL)
3884 if (first_free_arc == NULL)
3887 allocated_arcs_num++;
3889 new_arc = create_node (sizeof (struct arc));
3890 new_arc->to_state = NULL;
3891 new_arc->insn = NULL;
3892 new_arc->next_out_arc = NULL;
3896 new_arc = first_free_arc;
3897 first_free_arc = first_free_arc->next_out_arc;
3899 new_arc->to_state = to_state;
3900 new_arc->insn = ainsn;
3901 ainsn->arc_exists_p = 1;
3902 new_arc->next_out_arc = from_state->first_out_arc;
3903 from_state->first_out_arc = new_arc;
3904 from_state->num_out_arcs++;
3905 new_arc->next_arc_marked_by_insn = NULL;
3909 /* The function returns the first arc starting from STATE. */
3911 first_out_arc (state_t state)
3913 return state->first_out_arc;
3916 /* The function returns next out arc after ARC. */
3918 next_out_arc (arc_t arc)
3920 return arc->next_out_arc;
3923 /* Initialization of the abstract data. */
3925 initiate_arcs (void)
3927 first_free_arc = NULL;
3930 /* Finishing work with the abstract data. */
3938 /* Abstract data `automata lists'. */
3940 /* List of free states. */
3941 static automata_list_el_t first_free_automata_list_el;
3943 /* The list being formed. */
3944 static automata_list_el_t current_automata_list;
3946 /* Hash table of automata lists. */
3947 static htab_t automata_list_table;
3949 /* The following function returns free automata list el. It may be
3950 new allocated node or node freed earlier. */
3951 static automata_list_el_t
3952 get_free_automata_list_el (void)
3954 automata_list_el_t result;
3956 if (first_free_automata_list_el != NULL)
3958 result = first_free_automata_list_el;
3959 first_free_automata_list_el
3960 = first_free_automata_list_el->next_automata_list_el;
3963 result = create_node (sizeof (struct automata_list_el));
3964 result->automaton = NULL;
3965 result->next_automata_list_el = NULL;
3969 /* The function frees node AUTOMATA_LIST_EL. */
3971 free_automata_list_el (automata_list_el_t automata_list_el)
3973 if (automata_list_el == NULL)
3975 automata_list_el->next_automata_list_el = first_free_automata_list_el;
3976 first_free_automata_list_el = automata_list_el;
3979 /* The function frees list AUTOMATA_LIST. */
3981 free_automata_list (automata_list_el_t automata_list)
3983 automata_list_el_t curr_automata_list_el;
3984 automata_list_el_t next_automata_list_el;
3986 for (curr_automata_list_el = automata_list;
3987 curr_automata_list_el != NULL;
3988 curr_automata_list_el = next_automata_list_el)
3990 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
3991 free_automata_list_el (curr_automata_list_el);
3995 /* Hash value of AUTOMATA_LIST. */
3997 automata_list_hash (const void *automata_list)
3999 unsigned int hash_value;
4000 automata_list_el_t curr_automata_list_el;
4003 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4004 curr_automata_list_el != NULL;
4005 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4006 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4007 | (hash_value << CHAR_BIT))
4008 + curr_automata_list_el->automaton->automaton_order_num);
4012 /* Return nonzero value if the automata_lists are the same. */
4014 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4016 automata_list_el_t automata_list_el_1;
4017 automata_list_el_t automata_list_el_2;
4019 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4020 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4021 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4022 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4023 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4024 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4026 return automata_list_el_1 == automata_list_el_2;
4029 /* Initialization of the abstract data. */
4031 initiate_automata_lists (void)
4033 first_free_automata_list_el = NULL;
4034 automata_list_table = htab_create (1500, automata_list_hash,
4035 automata_list_eq_p, (htab_del) 0);
4038 /* The following function starts new automata list and makes it the
4041 automata_list_start (void)
4043 current_automata_list = NULL;
4046 /* The following function adds AUTOMATON to the current list. */
4048 automata_list_add (automaton_t automaton)
4050 automata_list_el_t el;
4052 el = get_free_automata_list_el ();
4053 el->automaton = automaton;
4054 el->next_automata_list_el = current_automata_list;
4055 current_automata_list = el;
4058 /* The following function finishes forming the current list, inserts
4059 it into the table and returns it. */
4060 static automata_list_el_t
4061 automata_list_finish (void)
4065 if (current_automata_list == NULL)
4067 entry_ptr = htab_find_slot (automata_list_table,
4068 (void *) current_automata_list, 1);
4069 if (*entry_ptr == NULL)
4070 *entry_ptr = (void *) current_automata_list;
4072 free_automata_list (current_automata_list);
4073 current_automata_list = NULL;
4074 return (automata_list_el_t) *entry_ptr;
4077 /* Finishing work with the abstract data. */
4079 finish_automata_lists (void)
4081 htab_delete (automata_list_table);
4086 /* The page contains abstract data for work with exclusion sets (see
4087 exclusion_set in file rtl.def). */
4089 /* The following variable refers to an exclusion set returned by
4090 get_excl_set. This is bit string of length equal to cpu units
4091 number. If exclusion set for given unit contains 1 for a unit,
4092 then simultaneous reservation of the units is prohibited. */
4093 static reserv_sets_t excl_set;
4095 /* The array contains exclusion sets for each unit. */
4096 static reserv_sets_t *unit_excl_set_table;
4098 /* The following function forms the array containing exclusion sets
4101 initiate_excl_sets (void)
4104 reserv_sets_t unit_excl_set;
4108 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4109 excl_set = (reserv_sets_t) obstack_base (&irp);
4110 obstack_finish (&irp);
4111 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4112 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4113 obstack_finish (&irp);
4114 /* Evaluate unit exclusion sets. */
4115 for (i = 0; i < description->decls_num; i++)
4117 decl = description->decls [i];
4118 if (decl->mode == dm_unit)
4120 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4121 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4122 obstack_finish (&irp);
4123 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4124 for (el = DECL_UNIT (decl)->excl_list;
4126 el = el->next_unit_set_el)
4128 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4129 el->unit_decl->in_set_p = TRUE;
4131 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4136 /* The function sets up and return EXCL_SET which is union of
4137 exclusion sets for each unit in IN_SET. */
4138 static reserv_sets_t
4139 get_excl_set (reserv_sets_t in_set)
4147 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4148 memset (excl_set, 0, chars_num);
4149 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4150 if (((unsigned char *) in_set) [excl_char_num])
4151 for (i = CHAR_BIT - 1; i >= 0; i--)
4152 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4154 start_unit_num = excl_char_num * CHAR_BIT + i;
4155 if (start_unit_num >= description->units_num)
4157 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4160 |= unit_excl_set_table [start_unit_num] [unit_num];
4168 /* The page contains abstract data for work with presence/absence
4169 pattern sets (see presence_set/absence_set in file rtl.def). */
4171 /* The following arrays contain correspondingly presence, final
4172 presence, absence, and final absence patterns for each unit. */
4173 static pattern_reserv_t *unit_presence_set_table;
4174 static pattern_reserv_t *unit_final_presence_set_table;
4175 static pattern_reserv_t *unit_absence_set_table;
4176 static pattern_reserv_t *unit_final_absence_set_table;
4178 /* The following function forms list of reservation sets for given
4180 static pattern_reserv_t
4181 form_reserv_sets_list (pattern_set_el_t pattern_list)