1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
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"
122 #include "genattrtab.h"
124 /* Positions in machine description file. Now they are not used. But
125 they could be used in the future for better diagnostic messages. */
128 /* The following is element of vector of current (and planned in the
129 future) functional unit reservations. */
130 typedef unsigned HOST_WIDE_INT set_el_t;
132 /* Reservations of function units are represented by value of the following
134 typedef set_el_t *reserv_sets_t;
136 /* The following structure describes a ticker. */
139 /* The following member value is time of the ticker creation with
140 taking into account time when the ticker is off. Active time of
141 the ticker is current time minus the value. */
142 int modified_creation_time;
143 /* The following member value is time (incremented by one) when the
144 ticker was off. Zero value means that now the ticker is on. */
145 int incremented_off_time;
148 /* The ticker is represented by the following type. */
149 typedef struct ticker ticker_t;
151 /* The following type describes elements of output vectors. */
152 typedef HOST_WIDE_INT vect_el_t;
154 /* Forward declaration of structures of internal representation of
155 pipeline description based on NDFA. */
160 struct automaton_decl;
161 struct unit_pattern_rel_decl;
163 struct insn_reserv_decl;
166 struct result_regexp;
167 struct reserv_regexp;
168 struct nothing_regexp;
169 struct sequence_regexp;
170 struct repeat_regexp;
176 struct pattern_set_el;
177 struct pattern_reserv;
183 struct state_ainsn_table;
185 /* The following typedefs are for brevity. */
186 typedef struct unit_decl *unit_decl_t;
187 typedef struct decl *decl_t;
188 typedef struct regexp *regexp_t;
189 typedef struct unit_set_el *unit_set_el_t;
190 typedef struct pattern_set_el *pattern_set_el_t;
191 typedef struct pattern_reserv *pattern_reserv_t;
192 typedef struct alt_state *alt_state_t;
193 typedef struct state *state_t;
194 typedef struct arc *arc_t;
195 typedef struct ainsn *ainsn_t;
196 typedef struct automaton *automaton_t;
197 typedef struct automata_list_el *automata_list_el_t;
198 typedef struct state_ainsn_table *state_ainsn_table_t;
201 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
202 gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
203 gen_absence_set, gen_final_absence_set, gen_automaton,
204 gen_automata_option, gen_reserv, gen_insn_reserv,
205 initiate_automaton_gen, expand_automata, write_automata are
206 described on the file top because the functions are called from
209 static void *create_node (size_t);
210 static void *copy_node (const void *, size_t);
211 static const char *check_name (const char *, pos_t);
212 static char *next_sep_el (const char **, int, int);
213 static int n_sep_els (const char *, int, int);
214 static char **get_str_vect (const char *, int *, int, int);
215 static void gen_presence_absence_set (rtx, int, int);
216 static regexp_t gen_regexp_el (const char *);
217 static regexp_t gen_regexp_repeat (const char *);
218 static regexp_t gen_regexp_allof (const char *);
219 static regexp_t gen_regexp_oneof (const char *);
220 static regexp_t gen_regexp_sequence (const char *);
221 static regexp_t gen_regexp (const char *);
223 static unsigned string_hash (const char *);
224 static unsigned automaton_decl_hash (const void *);
225 static int automaton_decl_eq_p (const void *,
227 static decl_t insert_automaton_decl (decl_t);
228 static decl_t find_automaton_decl (const char *);
229 static void initiate_automaton_decl_table (void);
230 static void finish_automaton_decl_table (void);
232 static hashval_t insn_decl_hash (const void *);
233 static int insn_decl_eq_p (const void *,
235 static decl_t insert_insn_decl (decl_t);
236 static decl_t find_insn_decl (const char *);
237 static void initiate_insn_decl_table (void);
238 static void finish_insn_decl_table (void);
240 static hashval_t decl_hash (const void *);
241 static int decl_eq_p (const void *,
243 static decl_t insert_decl (decl_t);
244 static decl_t find_decl (const char *);
245 static void initiate_decl_table (void);
246 static void finish_decl_table (void);
248 static unit_set_el_t process_excls (char **, int, pos_t);
249 static void add_excls (unit_set_el_t, unit_set_el_t,
251 static unit_set_el_t process_presence_absence_names
252 (char **, int, pos_t,
254 static pattern_set_el_t process_presence_absence_patterns
255 (char ***, int, pos_t,
257 static void add_presence_absence (unit_set_el_t,
260 static void process_decls (void);
261 static struct bypass_decl *find_bypass (struct bypass_decl *,
262 struct insn_reserv_decl *);
263 static void check_automaton_usage (void);
264 static regexp_t process_regexp (regexp_t);
265 static void process_regexp_decls (void);
266 static void check_usage (void);
267 static int loop_in_regexp (regexp_t, decl_t);
268 static void check_loops_in_regexps (void);
269 static void process_regexp_cycles (regexp_t, int, int,
271 static void evaluate_max_reserv_cycles (void);
272 static void check_all_description (void);
274 static ticker_t create_ticker (void);
275 static void ticker_off (ticker_t *);
276 static void ticker_on (ticker_t *);
277 static int active_time (ticker_t);
278 static void print_active_time (FILE *, ticker_t);
280 static void add_advance_cycle_insn_decl (void);
282 static alt_state_t get_free_alt_state (void);
283 static void free_alt_state (alt_state_t);
284 static void free_alt_states (alt_state_t);
285 static int alt_state_cmp (const void *alt_state_ptr_1,
286 const void *alt_state_ptr_2);
287 static alt_state_t uniq_sort_alt_states (alt_state_t);
288 static int alt_states_eq (alt_state_t, alt_state_t);
289 static void initiate_alt_states (void);
290 static void finish_alt_states (void);
292 static reserv_sets_t alloc_empty_reserv_sets (void);
293 static unsigned reserv_sets_hash_value (reserv_sets_t);
294 static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
295 static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
296 static void set_unit_reserv (reserv_sets_t, int, int);
297 static int test_unit_reserv (reserv_sets_t, int, int);
298 static int it_is_empty_reserv_sets (reserv_sets_t)
300 static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
301 static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
302 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
304 static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
307 static void output_cycle_reservs (FILE *, reserv_sets_t,
309 static void output_reserv_sets (FILE *, reserv_sets_t);
310 static state_t get_free_state (int, automaton_t);
311 static void free_state (state_t);
312 static hashval_t state_hash (const void *);
313 static int state_eq_p (const void *, const void *);
314 static state_t insert_state (state_t);
315 static void set_state_reserv (state_t, int, int);
316 static int intersected_state_reservs_p (state_t, state_t);
317 static state_t states_union (state_t, state_t, reserv_sets_t);
318 static state_t state_shift (state_t, reserv_sets_t);
319 static void initiate_states (void);
320 static void finish_states (void);
322 static void free_arc (arc_t);
323 static void remove_arc (state_t, arc_t);
324 static arc_t find_arc (state_t, state_t, ainsn_t);
325 static arc_t add_arc (state_t, state_t, ainsn_t, int);
326 static arc_t first_out_arc (state_t);
327 static arc_t next_out_arc (arc_t);
328 static void initiate_arcs (void);
329 static void finish_arcs (void);
331 static automata_list_el_t get_free_automata_list_el (void);
332 static void free_automata_list_el (automata_list_el_t);
333 static void free_automata_list (automata_list_el_t);
334 static hashval_t automata_list_hash (const void *);
335 static int automata_list_eq_p (const void *, const void *);
336 static void initiate_automata_lists (void);
337 static void automata_list_start (void);
338 static void automata_list_add (automaton_t);
339 static automata_list_el_t automata_list_finish (void);
340 static void finish_automata_lists (void);
342 static void initiate_excl_sets (void);
343 static reserv_sets_t get_excl_set (reserv_sets_t);
345 static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
346 static void initiate_presence_absence_pattern_sets (void);
347 static int check_presence_pattern_sets (reserv_sets_t,
349 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
352 static regexp_t copy_insn_regexp (regexp_t);
353 static regexp_t transform_1 (regexp_t);
354 static regexp_t transform_2 (regexp_t);
355 static regexp_t transform_3 (regexp_t);
356 static regexp_t regexp_transform_func
357 (regexp_t, regexp_t (*) (regexp_t));
358 static regexp_t transform_regexp (regexp_t);
359 static void transform_insn_regexps (void);
361 static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
362 static void check_regexp_units_distribution (const char *, regexp_t);
363 static void check_unit_distributions_to_automata (void);
365 static int process_seq_for_forming_states (regexp_t, automaton_t,
367 static void finish_forming_alt_state (alt_state_t,
369 static void process_alts_for_forming_states (regexp_t,
371 static void create_alt_states (automaton_t);
373 static void form_ainsn_with_same_reservs (automaton_t);
375 static reserv_sets_t form_reservs_matter (automaton_t);
376 static void make_automaton (automaton_t);
377 static void form_arcs_marked_by_insn (state_t);
378 static void NDFA_to_DFA (automaton_t);
379 static void pass_state_graph (state_t, void (*) (state_t));
380 static void pass_states (automaton_t,
382 static void initiate_pass_states (void);
383 static void add_achieved_state (state_t);
384 static int set_out_arc_insns_equiv_num (state_t, int);
385 static void clear_arc_insns_equiv_num (state_t);
386 static int first_cycle_unit_presence (state_t, int);
387 static int state_is_differed (state_t, state_t, int, int);
388 static void set_new_cycle_flags (state_t);
389 static void minimize_DFA (automaton_t);
390 static void incr_states_and_arcs_nums (state_t);
391 static void count_states_and_arcs (automaton_t, int *, int *);
392 static void build_automaton (automaton_t);
394 static void set_order_state_num (state_t);
395 static void enumerate_states (automaton_t);
397 static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
398 static void delete_ainsn_from_equiv_class (ainsn_t);
399 static void process_insn_equiv_class (ainsn_t, arc_t *);
400 static void process_state_for_insn_equiv_partition (state_t);
401 static void set_insn_equiv_classes (automaton_t);
403 static double estimate_one_automaton_bound (void);
404 static int compare_max_occ_cycle_nums (const void *,
406 static void units_to_automata_heuristic_distr (void);
407 static ainsn_t create_ainsns (void);
408 static void units_to_automata_distr (void);
409 static void create_automata (void);
411 static void form_regexp (regexp_t);
412 static const char *regexp_representation (regexp_t);
413 static void finish_regexp_representation (void);
415 static void output_range_type (FILE *, long int, long int);
416 static int longest_path_length (state_t);
417 static void process_state_longest_path_length (state_t);
418 static void output_dfa_max_issue_rate (void);
419 static void output_chip_member_name (FILE *, automaton_t);
420 static void output_temp_chip_member_name (FILE *, automaton_t);
421 static void output_translate_vect_name (FILE *, automaton_t);
422 static void output_trans_full_vect_name (FILE *, automaton_t);
423 static void output_trans_comb_vect_name (FILE *, automaton_t);
424 static void output_trans_check_vect_name (FILE *, automaton_t);
425 static void output_trans_base_vect_name (FILE *, automaton_t);
426 static void output_state_alts_full_vect_name (FILE *, automaton_t);
427 static void output_state_alts_comb_vect_name (FILE *, automaton_t);
428 static void output_state_alts_check_vect_name (FILE *, automaton_t);
429 static void output_state_alts_base_vect_name (FILE *, automaton_t);
430 static void output_min_issue_delay_vect_name (FILE *, automaton_t);
431 static void output_dead_lock_vect_name (FILE *, automaton_t);
432 static void output_reserved_units_table_name (FILE *, automaton_t);
433 static void output_state_member_type (FILE *, automaton_t);
434 static void output_chip_definitions (void);
435 static void output_translate_vect (automaton_t);
436 static int comb_vect_p (state_ainsn_table_t);
437 static state_ainsn_table_t create_state_ainsn_table (automaton_t);
438 static void output_state_ainsn_table
439 (state_ainsn_table_t, const char *, void (*) (FILE *, automaton_t),
440 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
441 void (*) (FILE *, automaton_t));
442 static int out_state_arcs_num (state_t);
443 static int compare_transition_els_num (const void *, const void *);
444 static void add_states_vect_el (state_t);
445 static void output_trans_table (automaton_t);
446 static void output_state_alts_table (automaton_t);
447 static int min_issue_delay_pass_states (state_t, ainsn_t);
448 static int min_issue_delay (state_t, ainsn_t);
449 static void initiate_min_issue_delay_pass_states (void);
450 static void output_min_issue_delay_table (automaton_t);
451 static void output_dead_lock_vect (automaton_t);
452 static void output_reserved_units_table (automaton_t);
453 static void output_tables (void);
454 static void output_max_insn_queue_index_def (void);
455 static void output_insn_code_cases (void (*) (automata_list_el_t));
456 static void output_automata_list_min_issue_delay_code (automata_list_el_t);
457 static void output_internal_min_issue_delay_func (void);
458 static void output_automata_list_transition_code (automata_list_el_t);
459 static void output_internal_trans_func (void);
460 static void output_internal_insn_code_evaluation (const char *,
462 static void output_dfa_insn_code_func (void);
463 static void output_trans_func (void);
464 static void output_automata_list_state_alts_code (automata_list_el_t);
465 static void output_internal_state_alts_func (void);
466 static void output_state_alts_func (void);
467 static void output_min_issue_delay_func (void);
468 static void output_internal_dead_lock_func (void);
469 static void output_dead_lock_func (void);
470 static void output_internal_reset_func (void);
471 static void output_size_func (void);
472 static void output_reset_func (void);
473 static void output_min_insn_conflict_delay_func (void);
474 static void output_internal_insn_latency_func (void);
475 static void output_insn_latency_func (void);
476 static void output_print_reservation_func (void);
477 static int units_cmp (const void *,
479 static void output_get_cpu_unit_code_func (void);
480 static void output_cpu_unit_reservation_p (void);
481 static void output_dfa_clean_insn_cache_func (void);
482 static void output_dfa_start_func (void);
483 static void output_dfa_finish_func (void);
485 static void output_regexp (regexp_t );
486 static void output_unit_set_el_list (unit_set_el_t);
487 static void output_pattern_set_el_list (pattern_set_el_t);
488 static void output_description (void);
489 static void output_automaton_name (FILE *, automaton_t);
490 static void output_automaton_units (automaton_t);
491 static void add_state_reservs (state_t);
492 static void output_state_arcs (state_t);
493 static int state_reservs_cmp (const void *,
495 static void remove_state_duplicate_reservs (void);
496 static void output_state (state_t);
497 static void output_automaton_descriptions (void);
498 static void output_statistics (FILE *);
499 static void output_time_statistics (FILE *);
500 static void generate (void);
502 static void make_insn_alts_attr (void);
503 static void make_internal_dfa_insn_code_attr (void);
504 static void make_default_insn_latency_attr (void);
505 static void make_bypass_attr (void);
506 static const char *file_name_suffix (const char *);
507 static const char *base_file_name (const char *);
508 static void check_automata_insn_issues (void);
509 static void add_automaton_state (state_t);
510 static void form_important_insn_automata_lists (void);
512 /* Undefined position. */
513 static pos_t no_pos = 0;
515 /* All IR is stored in the following obstack. */
516 static struct obstack irp;
519 /* Declare vector types for various data structures: */
521 DEF_VEC_P(alt_state_t);
522 DEF_VEC_ALLOC_P(alt_state_t,heap);
524 DEF_VEC_ALLOC_P(ainsn_t,heap);
526 DEF_VEC_ALLOC_P(state_t,heap);
528 DEF_VEC_ALLOC_P(decl_t,heap);
529 DEF_VEC_P(reserv_sets_t);
530 DEF_VEC_ALLOC_P(reserv_sets_t,heap);
532 DEF_VEC_I(vect_el_t);
533 DEF_VEC_ALLOC_I(vect_el_t, heap);
534 typedef VEC(vect_el_t,heap) *vla_hwint_t;
537 /* Options with the following names can be set up in automata_option
538 construction. Because the strings occur more one time we use the
541 #define NO_MINIMIZATION_OPTION "-no-minimization"
543 #define TIME_OPTION "-time"
545 #define V_OPTION "-v"
547 #define W_OPTION "-w"
549 #define NDFA_OPTION "-ndfa"
551 #define PROGRESS_OPTION "-progress"
553 /* The following flags are set up by function `initiate_automaton_gen'. */
555 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
556 static int ndfa_flag;
558 /* Do not make minimization of DFA (`-no-minimization'). */
559 static int no_minimization_flag;
561 /* Value of this variable is number of automata being generated. The
562 actual number of automata may be less this value if there is not
563 sufficient number of units. This value is defined by argument of
564 option `-split' or by constructions automaton if the value is zero
565 (it is default value of the argument). */
566 static int split_argument;
568 /* Flag of output time statistics (`-time'). */
569 static int time_flag;
571 /* Flag of creation of description file which contains description of
572 result automaton and statistics information (`-v'). */
575 /* Flag of output of a progress bar showing how many states were
576 generated so far for automaton being processed (`-progress'). */
577 static int progress_flag;
579 /* Flag of generating warning instead of error for non-critical errors
584 /* Output file for pipeline hazard recognizer (PHR) being generated.
585 The value is NULL if the file is not defined. */
586 static FILE *output_file;
588 /* Description file of PHR. The value is NULL if the file is not
590 static FILE *output_description_file;
592 /* PHR description file name. */
593 static char *output_description_file_name;
595 /* Value of the following variable is node representing description
596 being processed. This is start point of IR. */
597 static struct description *description;
601 /* This page contains description of IR structure (nodes). */
615 /* This describes define_cpu_unit and define_query_cpu_unit (see file
620 /* NULL if the automaton name is absent. */
621 const char *automaton_name;
622 /* If the following value is not zero, the cpu unit reservation is
623 described in define_query_cpu_unit. */
626 /* The following fields are defined by checker. */
628 /* The following field value is nonzero if the unit is used in an
632 /* The following field value is order number (0, 1, ...) of given
635 /* The following field value is corresponding declaration of
636 automaton which was given in description. If the field value is
637 NULL then automaton in the unit declaration was absent. */
638 struct automaton_decl *automaton_decl;
639 /* The following field value is maximal cycle number (1, ...) on
640 which given unit occurs in insns. Zero value means that given
641 unit is not used in insns. */
642 int max_occ_cycle_num;
643 /* The following field value is minimal cycle number (0, ...) on
644 which given unit occurs in insns. -1 value means that given
645 unit is not used in insns. */
646 int min_occ_cycle_num;
647 /* The following list contains units which conflict with given
649 unit_set_el_t excl_list;
650 /* The following list contains patterns which are required to
651 reservation of given unit. */
652 pattern_set_el_t presence_list;
653 pattern_set_el_t final_presence_list;
654 /* The following list contains patterns which should be not present
655 in reservation for given unit. */
656 pattern_set_el_t absence_list;
657 pattern_set_el_t final_absence_list;
658 /* The following is used only when `query_p' has nonzero value.
659 This is query number for the unit. */
661 /* The following is the last cycle on which the unit was checked for
662 correct distributions of units to automata in a regexp. */
663 int last_distribution_check_cycle;
665 /* The following fields are defined by automaton generator. */
667 /* The following field value is number of the automaton to which
668 given unit belongs. */
669 int corresponding_automaton_num;
670 /* If the following value is not zero, the cpu unit is present in a
671 `exclusion_set' or in right part of a `presence_set',
672 `final_presence_set', `absence_set', and
673 `final_absence_set'define_query_cpu_unit. */
677 /* This describes define_bypass (see file rtl.def). */
681 const char *out_insn_name;
682 const char *in_insn_name;
683 const char *bypass_guard_name;
685 /* The following fields are defined by checker. */
687 /* output and input insns of given bypass. */
688 struct insn_reserv_decl *out_insn_reserv;
689 struct insn_reserv_decl *in_insn_reserv;
690 /* The next bypass for given output insn. */
691 struct bypass_decl *next;
694 /* This describes define_automaton (see file rtl.def). */
695 struct automaton_decl
699 /* The following fields are defined by automaton generator. */
701 /* The following field value is nonzero if the automaton is used in
702 an regexp definition. */
703 char automaton_is_used;
705 /* The following fields are defined by checker. */
707 /* The following field value is the corresponding automaton. This
708 field is not NULL only if the automaton is present in unit
709 declarations and the automatic partition on automata is not
711 automaton_t corresponding_automaton;
714 /* This describes exclusion relations: exclusion_set (see file
719 int first_list_length;
723 /* This describes unit relations: [final_]presence_set or
724 [final_]absence_set (see file rtl.def). */
725 struct unit_pattern_rel_decl
734 /* This describes define_reservation (see file rtl.def). */
740 /* The following fields are defined by checker. */
742 /* The following field value is nonzero if the unit is used in an
745 /* The following field is used to check up cycle in expression
750 /* This describes define_insn_reservation (see file rtl.def). */
751 struct insn_reserv_decl
758 /* The following fields are defined by checker. */
760 /* The following field value is order number (0, 1, ...) of given
763 /* The following field value is list of bypasses in which given insn
765 struct bypass_decl *bypass_list;
767 /* The following fields are defined by automaton generator. */
769 /* The following field is the insn regexp transformed that
770 the regexp has not optional regexp, repetition regexp, and an
771 reservation name (i.e. reservation identifiers are changed by the
772 corresponding regexp) and all alternations are the topest level
773 of the regexp. The value can be NULL only if it is special
774 insn `cycle advancing'. */
775 regexp_t transformed_regexp;
776 /* The following field value is list of arcs marked given
777 insn. The field is used in transformation NDFA -> DFA. */
778 arc_t arcs_marked_by_insn;
779 /* The two following fields are used during minimization of a finite state
781 /* The field value is number of equivalence class of state into
782 which arc marked by given insn enters from a state (fixed during
783 an automaton minimization). */
785 /* The field value is state_alts of arc leaving a state (fixed
786 during an automaton minimization) and marked by given insn
789 /* The following member value is the list to automata which can be
790 changed by the insn issue. */
791 automata_list_el_t important_automata_list;
792 /* The following member is used to process insn once for output. */
796 /* This contains a declaration mentioned above. */
799 /* What node in the union? */
804 struct unit_decl unit;
805 struct bypass_decl bypass;
806 struct automaton_decl automaton;
807 struct excl_rel_decl excl;
808 struct unit_pattern_rel_decl presence;
809 struct unit_pattern_rel_decl absence;
810 struct reserv_decl reserv;
811 struct insn_reserv_decl insn_reserv;
815 /* The following structures represent parsed reservation strings. */
827 /* Cpu unit in reservation. */
831 unit_decl_t unit_decl;
834 /* Define_reservation in a reservation. */
838 struct reserv_decl *reserv_decl;
841 /* Absence of reservation (represented by string `nothing'). */
842 struct nothing_regexp
844 /* This used to be empty but ISO C doesn't allow that. */
848 /* Representation of reservations separated by ',' (see file
850 struct sequence_regexp
853 regexp_t regexps [1];
856 /* Representation of construction `repeat' (see file rtl.def). */
863 /* Representation of reservations separated by '+' (see file
868 regexp_t regexps [1];
871 /* Representation of reservations separated by '|' (see file
876 regexp_t regexps [1];
879 /* Representation of a reservation string. */
882 /* What node in the union? */
883 enum regexp_mode mode;
887 struct unit_regexp unit;
888 struct reserv_regexp reserv;
889 struct nothing_regexp nothing;
890 struct sequence_regexp sequence;
891 struct repeat_regexp repeat;
892 struct allof_regexp allof;
893 struct oneof_regexp oneof;
897 /* Represents description of pipeline hazard description based on
903 /* The following fields are defined by checker. */
905 /* The following fields values are correspondingly number of all
906 units, query units, and insns in the description. */
910 /* The following field value is max length (in cycles) of
911 reservations of insns. The field value is defined only for
913 int max_insn_reserv_cycles;
915 /* The following fields are defined by automaton generator. */
917 /* The following field value is the first automaton. */
918 automaton_t first_automaton;
920 /* The following field is created by pipeline hazard parser and
921 contains all declarations. We allocate additional entry for
922 special insn "cycle advancing" which is added by the automaton
928 /* The following nodes are created in automaton checker. */
930 /* The following nodes represent exclusion set for cpu units. Each
931 element is accessed through only one excl_list. */
934 unit_decl_t unit_decl;
935 unit_set_el_t next_unit_set_el;
938 /* The following nodes represent presence or absence pattern for cpu
939 units. Each element is accessed through only one presence_list or
941 struct pattern_set_el
943 /* The number of units in unit_decls. */
945 /* The units forming the pattern. */
946 struct unit_decl **unit_decls;
947 pattern_set_el_t next_pattern_set_el;
951 /* The following nodes are created in automaton generator. */
954 /* The following nodes represent presence or absence pattern for cpu
955 units. Each element is accessed through only one element of
956 unit_presence_set_table or unit_absence_set_table. */
957 struct pattern_reserv
959 reserv_sets_t reserv;
960 pattern_reserv_t next_pattern_reserv;
963 /* The following node type describes state automaton. The state may
964 be deterministic or non-deterministic. Non-deterministic state has
965 several component states which represent alternative cpu units
966 reservations. The state also is used for describing a
967 deterministic reservation of automaton insn. */
970 /* The following member value is nonzero if there is a transition by
973 /* The following field is list of processor unit reservations on
975 reserv_sets_t reservs;
976 /* The following field is unique number of given state between other
979 /* The following field value is automaton to which given state
981 automaton_t automaton;
982 /* The following field value is the first arc output from given
985 /* The following field is used to form NDFA. */
986 char it_was_placed_in_stack_for_NDFA_forming;
987 /* The following field is used to form DFA. */
988 char it_was_placed_in_stack_for_DFA_forming;
989 /* The following field is used to transform NDFA to DFA and DFA
990 minimization. The field value is not NULL if the state is a
991 compound state. In this case the value of field `unit_sets_list'
992 is NULL. All states in the list are in the hash table. The list
993 is formed through field `next_sorted_alt_state'. We should
994 support only one level of nesting state. */
995 alt_state_t component_states;
996 /* The following field is used for passing graph of states. */
998 /* The list of states belonging to one equivalence class is formed
999 with the aid of the following field. */
1000 state_t next_equiv_class_state;
1001 /* The two following fields are used during minimization of a finite
1003 int equiv_class_num_1, equiv_class_num_2;
1004 /* The following field is used during minimization of a finite state
1005 automaton. The field value is state corresponding to equivalence
1006 class to which given state belongs. */
1007 state_t equiv_class_state;
1008 /* The following field value is the order number of given state.
1009 The states in final DFA is enumerated with the aid of the
1011 int order_state_num;
1012 /* This member is used for passing states for searching minimal
1015 /* The following member is used to evaluate min issue delay of insn
1017 int min_insn_issue_delay;
1018 /* The following member is used to evaluate max issue rate of the
1019 processor. The value of the member is maximal length of the path
1020 from given state no containing arcs marked by special insn `cycle
1022 int longest_path_length;
1025 /* The following macro is an initial value of member
1026 `longest_path_length' of a state. */
1027 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1029 /* Automaton arc. */
1032 /* The following field refers for the state into which given arc
1035 /* The following field describes that the insn issue (with cycle
1036 advancing for special insn `cycle advancing' and without cycle
1037 advancing for others) makes transition from given state to
1038 another given state. */
1040 /* The following field value is the next arc output from the same
1043 /* List of arcs marked given insn is formed with the following
1044 field. The field is used in transformation NDFA -> DFA. */
1045 arc_t next_arc_marked_by_insn;
1046 /* The following field is defined if NDFA_FLAG is zero. The member
1047 value is number of alternative reservations which can be used for
1048 transition for given state by given insn. */
1052 /* The following node type describes a deterministic alternative in
1053 non-deterministic state which characterizes cpu unit reservations
1054 of automaton insn or which is part of NDFA. */
1057 /* The following field is a deterministic state which characterizes
1058 unit reservations of the instruction. */
1060 /* The following field refers to the next state which characterizes
1061 unit reservations of the instruction. */
1062 alt_state_t next_alt_state;
1063 /* The following field refers to the next state in sorted list. */
1064 alt_state_t next_sorted_alt_state;
1067 /* The following node type describes insn of automaton. They are
1068 labels of FA arcs. */
1071 /* The following field value is the corresponding insn declaration
1073 struct insn_reserv_decl *insn_reserv_decl;
1074 /* The following field value is the next insn declaration for an
1077 /* The following field is states which characterize automaton unit
1078 reservations of the instruction. The value can be NULL only if it
1079 is special insn `cycle advancing'. */
1080 alt_state_t alt_states;
1081 /* The following field is sorted list of states which characterize
1082 automaton unit reservations of the instruction. The value can be
1083 NULL only if it is special insn `cycle advancing'. */
1084 alt_state_t sorted_alt_states;
1085 /* The following field refers the next automaton insn with
1086 the same reservations. */
1087 ainsn_t next_same_reservs_insn;
1088 /* The following field is flag of the first automaton insn with the
1089 same reservations in the declaration list. Only arcs marked such
1090 insn is present in the automaton. This significantly decreases
1091 memory requirements especially when several automata are
1093 char first_insn_with_same_reservs;
1094 /* The following member has nonzero value if there is arc from state of
1095 the automaton marked by the ainsn. */
1097 /* Cyclic list of insns of an equivalence class is formed with the
1098 aid of the following field. */
1099 ainsn_t next_equiv_class_insn;
1100 /* The following field value is nonzero if the insn declaration is
1101 the first insn declaration with given equivalence number. */
1102 char first_ainsn_with_given_equivalence_num;
1103 /* The following field is number of class of equivalence of insns.
1104 It is necessary because many insns may be equivalent with the
1105 point of view of pipeline hazards. */
1106 int insn_equiv_class_num;
1107 /* The following member value is TRUE if there is an arc in the
1108 automaton marked by the insn into another state. In other
1109 words, the insn can change the state of the automaton. */
1113 /* The following describes an automaton for PHR. */
1116 /* The following field value is the list of insn declarations for
1119 /* The following field value is the corresponding automaton
1120 declaration. This field is not NULL only if the automatic
1121 partition on automata is not used. */
1122 struct automaton_decl *corresponding_automaton_decl;
1123 /* The following field value is the next automaton. */
1124 automaton_t next_automaton;
1125 /* The following field is start state of FA. There are not unit
1126 reservations in the state. */
1127 state_t start_state;
1128 /* The following field value is number of equivalence classes of
1129 insns (see field `insn_equiv_class_num' in
1130 `insn_reserv_decl'). */
1131 int insn_equiv_classes_num;
1132 /* The following field value is number of states of final DFA. */
1133 int achieved_states_num;
1134 /* The following field value is the order number (0, 1, ...) of
1136 int automaton_order_num;
1137 /* The following fields contain statistics information about
1138 building automaton. */
1139 int NDFA_states_num, DFA_states_num;
1140 /* The following field value is defined only if minimization of DFA
1142 int minimal_DFA_states_num;
1143 int NDFA_arcs_num, DFA_arcs_num;
1144 /* The following field value is defined only if minimization of DFA
1146 int minimal_DFA_arcs_num;
1147 /* The following two members refer for two table state x ainsn ->
1149 state_ainsn_table_t trans_table;
1150 state_ainsn_table_t state_alts_table;
1151 /* The following member value is maximal value of min issue delay
1152 for insns of the automaton. */
1154 /* Usually min issue delay is small and we can place several (2, 4,
1155 8) elements in one vector element. So the compression factor can
1156 be 1 (no compression), 2, 4, 8. */
1157 int min_issue_delay_table_compression_factor;
1160 /* The following is the element of the list of automata. */
1161 struct automata_list_el
1163 /* The automaton itself. */
1164 automaton_t automaton;
1165 /* The next automata set element. */
1166 automata_list_el_t next_automata_list_el;
1169 /* The following structure describes a table state X ainsn -> int(>= 0). */
1170 struct state_ainsn_table
1172 /* Automaton to which given table belongs. */
1173 automaton_t automaton;
1174 /* The following tree vectors for comb vector implementation of the
1176 vla_hwint_t comb_vect;
1177 vla_hwint_t check_vect;
1178 vla_hwint_t base_vect;
1179 /* This is simple implementation of the table. */
1180 vla_hwint_t full_vect;
1181 /* Minimal and maximal values of the previous vectors. */
1182 int min_comb_vect_el_value, max_comb_vect_el_value;
1183 int min_base_vect_el_value, max_base_vect_el_value;
1186 /* Macros to access members of unions. Use only them for access to
1187 union members of declarations and regexps. */
1189 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1191 #define DECL_UNIT(d) __extension__ \
1192 (({ struct decl *const _decl = (d); \
1193 if (_decl->mode != dm_unit) \
1194 decl_mode_check_failed (_decl->mode, "dm_unit", \
1195 __FILE__, __LINE__, __FUNCTION__); \
1196 &(_decl)->decl.unit; }))
1198 #define DECL_BYPASS(d) __extension__ \
1199 (({ struct decl *const _decl = (d); \
1200 if (_decl->mode != dm_bypass) \
1201 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1202 __FILE__, __LINE__, __FUNCTION__); \
1203 &(_decl)->decl.bypass; }))
1205 #define DECL_AUTOMATON(d) __extension__ \
1206 (({ struct decl *const _decl = (d); \
1207 if (_decl->mode != dm_automaton) \
1208 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1209 __FILE__, __LINE__, __FUNCTION__); \
1210 &(_decl)->decl.automaton; }))
1212 #define DECL_EXCL(d) __extension__ \
1213 (({ struct decl *const _decl = (d); \
1214 if (_decl->mode != dm_excl) \
1215 decl_mode_check_failed (_decl->mode, "dm_excl", \
1216 __FILE__, __LINE__, __FUNCTION__); \
1217 &(_decl)->decl.excl; }))
1219 #define DECL_PRESENCE(d) __extension__ \
1220 (({ struct decl *const _decl = (d); \
1221 if (_decl->mode != dm_presence) \
1222 decl_mode_check_failed (_decl->mode, "dm_presence", \
1223 __FILE__, __LINE__, __FUNCTION__); \
1224 &(_decl)->decl.presence; }))
1226 #define DECL_ABSENCE(d) __extension__ \
1227 (({ struct decl *const _decl = (d); \
1228 if (_decl->mode != dm_absence) \
1229 decl_mode_check_failed (_decl->mode, "dm_absence", \
1230 __FILE__, __LINE__, __FUNCTION__); \
1231 &(_decl)->decl.absence; }))
1233 #define DECL_RESERV(d) __extension__ \
1234 (({ struct decl *const _decl = (d); \
1235 if (_decl->mode != dm_reserv) \
1236 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1237 __FILE__, __LINE__, __FUNCTION__); \
1238 &(_decl)->decl.reserv; }))
1240 #define DECL_INSN_RESERV(d) __extension__ \
1241 (({ struct decl *const _decl = (d); \
1242 if (_decl->mode != dm_insn_reserv) \
1243 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1244 __FILE__, __LINE__, __FUNCTION__); \
1245 &(_decl)->decl.insn_reserv; }))
1247 static const char *decl_name (enum decl_mode);
1248 static void decl_mode_check_failed (enum decl_mode, const char *,
1249 const char *, int, const char *)
1252 /* Return string representation of declaration mode MODE. */
1254 decl_name (enum decl_mode mode)
1256 static char str [100];
1258 if (mode == dm_unit)
1260 else if (mode == dm_bypass)
1262 else if (mode == dm_automaton)
1263 return "dm_automaton";
1264 else if (mode == dm_excl)
1266 else if (mode == dm_presence)
1267 return "dm_presence";
1268 else if (mode == dm_absence)
1269 return "dm_absence";
1270 else if (mode == dm_reserv)
1272 else if (mode == dm_insn_reserv)
1273 return "dm_insn_reserv";
1275 sprintf (str, "unknown (%d)", (int) mode);
1279 /* The function prints message about unexpected declaration and finish
1282 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1283 const char *file, int line, const char *func)
1287 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1288 file, line, func, expected_mode_str, decl_name (mode));
1293 #define REGEXP_UNIT(r) __extension__ \
1294 (({ struct regexp *const _regexp = (r); \
1295 if (_regexp->mode != rm_unit) \
1296 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1297 __FILE__, __LINE__, __FUNCTION__); \
1298 &(_regexp)->regexp.unit; }))
1300 #define REGEXP_RESERV(r) __extension__ \
1301 (({ struct regexp *const _regexp = (r); \
1302 if (_regexp->mode != rm_reserv) \
1303 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1304 __FILE__, __LINE__, __FUNCTION__); \
1305 &(_regexp)->regexp.reserv; }))
1307 #define REGEXP_SEQUENCE(r) __extension__ \
1308 (({ struct regexp *const _regexp = (r); \
1309 if (_regexp->mode != rm_sequence) \
1310 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1311 __FILE__, __LINE__, __FUNCTION__); \
1312 &(_regexp)->regexp.sequence; }))
1314 #define REGEXP_REPEAT(r) __extension__ \
1315 (({ struct regexp *const _regexp = (r); \
1316 if (_regexp->mode != rm_repeat) \
1317 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1318 __FILE__, __LINE__, __FUNCTION__); \
1319 &(_regexp)->regexp.repeat; }))
1321 #define REGEXP_ALLOF(r) __extension__ \
1322 (({ struct regexp *const _regexp = (r); \
1323 if (_regexp->mode != rm_allof) \
1324 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1325 __FILE__, __LINE__, __FUNCTION__); \
1326 &(_regexp)->regexp.allof; }))
1328 #define REGEXP_ONEOF(r) __extension__ \
1329 (({ struct regexp *const _regexp = (r); \
1330 if (_regexp->mode != rm_oneof) \
1331 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1332 __FILE__, __LINE__, __FUNCTION__); \
1333 &(_regexp)->regexp.oneof; }))
1335 static const char *regexp_name (enum regexp_mode);
1336 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1338 const char *) ATTRIBUTE_NORETURN;
1341 /* Return string representation of regexp mode MODE. */
1343 regexp_name (enum regexp_mode mode)
1352 return "rm_nothing";
1354 return "rm_sequence";
1366 /* The function prints message about unexpected regexp and finish the
1369 regexp_mode_check_failed (enum regexp_mode mode,
1370 const char *expected_mode_str,
1371 const char *file, int line, const char *func)
1375 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1376 file, line, func, expected_mode_str, regexp_name (mode));
1380 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1382 #define DECL_UNIT(d) (&(d)->decl.unit)
1383 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1384 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1385 #define DECL_EXCL(d) (&(d)->decl.excl)
1386 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1387 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1388 #define DECL_RESERV(d) (&(d)->decl.reserv)
1389 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1391 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1392 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1393 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1394 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1395 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1396 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1398 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1400 /* Create IR structure (node). */
1402 create_node (size_t size)
1406 obstack_blank (&irp, size);
1407 result = obstack_base (&irp);
1408 obstack_finish (&irp);
1409 /* Default values of members are NULL and zero. */
1410 memset (result, 0, size);
1414 /* Copy IR structure (node). */
1416 copy_node (const void *from, size_t size)
1418 void *const result = create_node (size);
1419 memcpy (result, from, size);
1423 /* The function checks that NAME does not contain quotes (`"'). */
1425 check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
1429 for (str = name; *str != '\0'; str++)
1431 error ("Name `%s' contains quotes", name);
1435 /* Pointers to all declarations during IR generation are stored in the
1437 static VEC(decl_t,heap) *decls;
1439 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1440 string containing the next separated element, taking parentheses
1441 into account if PAR_FLAG has nonzero value. Advance the pointer to
1442 after the string scanned, or the end-of-string. Return NULL if at
1445 next_sep_el (const char **pstr, int sep, int par_flag)
1452 /* Remove leading whitespaces. */
1453 while (ISSPACE ((int) **pstr))
1460 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1462 if (par_flag && *p == '(')
1464 else if (par_flag && *p == ')')
1466 else if (pars_num == 0 && *p == sep)
1468 if (pars_num == 0 && ISSPACE ((int) *p))
1472 for (; n_spaces != 0; n_spaces--)
1473 obstack_1grow (&irp, p [-n_spaces]);
1474 obstack_1grow (&irp, *p);
1477 obstack_1grow (&irp, '\0');
1478 out_str = obstack_base (&irp);
1479 obstack_finish (&irp);
1488 /* Given a string and a separator, return the number of separated
1489 elements in it, taking parentheses into account if PAR_FLAG has
1490 nonzero value. Return 0 for the null string, -1 if parentheses is
1493 n_sep_els (const char *s, int sep, int par_flag)
1501 for (pars_num = 0, n = 1; *s; s++)
1502 if (par_flag && *s == '(')
1504 else if (par_flag && *s == ')')
1506 else if (pars_num == 0 && *s == sep)
1509 return (pars_num != 0 ? -1 : n);
1512 /* Given a string and a separator, return vector of strings which are
1513 elements in the string and number of elements through els_num.
1514 Take parentheses into account if PAREN_P has nonzero value. The
1515 function also inserts the end marker NULL at the end of vector.
1516 Return 0 for the null string, -1 if parentheses are not balanced. */
1518 get_str_vect (const char *str, int *els_num, int sep, int paren_p)
1525 *els_num = n_sep_els (str, sep, paren_p);
1528 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1529 vect = (char **) obstack_base (&irp);
1530 obstack_finish (&irp);
1532 for (i = 0; i < *els_num; i++)
1533 vect [i] = next_sep_el (pstr, sep, paren_p);
1534 trail = next_sep_el (pstr, sep, paren_p);
1535 gcc_assert (!trail);
1540 /* Process a DEFINE_CPU_UNIT.
1542 This gives information about a unit contained in CPU. We fill a
1543 struct unit_decl with information used later by `expand_automata'. */
1545 gen_cpu_unit (rtx def)
1548 char **str_cpu_units;
1552 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1553 if (str_cpu_units == NULL)
1554 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1555 for (i = 0; i < vect_length; i++)
1557 decl = create_node (sizeof (struct decl));
1558 decl->mode = dm_unit;
1560 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1561 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1562 DECL_UNIT (decl)->query_p = 0;
1563 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1564 DECL_UNIT (decl)->in_set_p = 0;
1565 VEC_safe_push (decl_t,heap, decls, decl);
1570 /* Process a DEFINE_QUERY_CPU_UNIT.
1572 This gives information about a unit contained in CPU. We fill a
1573 struct unit_decl with information used later by `expand_automata'. */
1575 gen_query_cpu_unit (rtx def)
1578 char **str_cpu_units;
1582 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
1584 if (str_cpu_units == NULL)
1585 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1586 for (i = 0; i < vect_length; i++)
1588 decl = create_node (sizeof (struct decl));
1589 decl->mode = dm_unit;
1591 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1592 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
1593 DECL_UNIT (decl)->query_p = 1;
1594 VEC_safe_push (decl_t,heap, decls, decl);
1599 /* Process a DEFINE_BYPASS.
1601 This gives information about a unit contained in the CPU. We fill
1602 in a struct bypass_decl with information used later by
1603 `expand_automata'. */
1605 gen_bypass (rtx def)
1614 out_insns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
1615 if (out_insns == NULL)
1616 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1617 in_insns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
1618 if (in_insns == NULL)
1619 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1620 for (i = 0; i < out_length; i++)
1621 for (j = 0; j < in_length; j++)
1623 decl = create_node (sizeof (struct decl));
1624 decl->mode = dm_bypass;
1626 DECL_BYPASS (decl)->latency = XINT (def, 0);
1627 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1628 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1629 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
1630 VEC_safe_push (decl_t,heap, decls, decl);
1635 /* Process an EXCLUSION_SET.
1637 This gives information about a cpu unit conflicts. We fill a
1638 struct excl_rel_decl (excl) with information used later by
1639 `expand_automata'. */
1641 gen_excl_set (rtx def)
1644 char **first_str_cpu_units;
1645 char **second_str_cpu_units;
1646 int first_vect_length;
1651 = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
1652 if (first_str_cpu_units == NULL)
1653 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1654 second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
1656 if (second_str_cpu_units == NULL)
1657 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1658 length += first_vect_length;
1659 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1660 decl->mode = dm_excl;
1662 DECL_EXCL (decl)->all_names_num = length;
1663 DECL_EXCL (decl)->first_list_length = first_vect_length;
1664 for (i = 0; i < length; i++)
1665 if (i < first_vect_length)
1666 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1668 DECL_EXCL (decl)->names [i]
1669 = second_str_cpu_units [i - first_vect_length];
1670 VEC_safe_push (decl_t,heap, decls, decl);
1674 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1675 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1677 This gives information about a cpu unit reservation requirements.
1678 We fill a struct unit_pattern_rel_decl with information used later
1679 by `expand_automata'. */
1681 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1684 char **str_cpu_units;
1685 char **str_pattern_lists;
1686 char ***str_patterns;
1687 int cpu_units_length;
1689 int patterns_length;
1692 str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
1694 if (str_cpu_units == NULL)
1697 ? "invalid first string `%s' in final_presence_set"
1698 : "invalid first string `%s' in presence_set")
1700 ? "invalid first string `%s' in final_absence_set"
1701 : "invalid first string `%s' in absence_set")),
1703 str_pattern_lists = get_str_vect (XSTR (def, 1),
1704 &patterns_length, ',', FALSE);
1705 if (str_pattern_lists == NULL)
1708 ? "invalid second string `%s' in final_presence_set"
1709 : "invalid second string `%s' in presence_set")
1711 ? "invalid second string `%s' in final_absence_set"
1712 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1713 str_patterns = obstack_alloc (&irp, patterns_length * sizeof (char **));
1714 for (i = 0; i < patterns_length; i++)
1716 str_patterns [i] = get_str_vect (str_pattern_lists [i],
1717 &length, ' ', FALSE);
1718 gcc_assert (str_patterns [i]);
1720 decl = create_node (sizeof (struct decl));
1724 decl->mode = dm_presence;
1725 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1726 DECL_PRESENCE (decl)->names = str_cpu_units;
1727 DECL_PRESENCE (decl)->patterns = str_patterns;
1728 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1729 DECL_PRESENCE (decl)->final_p = final_p;
1733 decl->mode = dm_absence;
1734 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1735 DECL_ABSENCE (decl)->names = str_cpu_units;
1736 DECL_ABSENCE (decl)->patterns = str_patterns;
1737 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1738 DECL_ABSENCE (decl)->final_p = final_p;
1740 VEC_safe_push (decl_t,heap, decls, decl);
1744 /* Process a PRESENCE_SET.
1746 This gives information about a cpu unit reservation requirements.
1747 We fill a struct unit_pattern_rel_decl (presence) with information
1748 used later by `expand_automata'. */
1750 gen_presence_set (rtx def)
1752 gen_presence_absence_set (def, TRUE, FALSE);
1755 /* Process a FINAL_PRESENCE_SET.
1757 This gives information about a cpu unit reservation requirements.
1758 We fill a struct unit_pattern_rel_decl (presence) with information
1759 used later by `expand_automata'. */
1761 gen_final_presence_set (rtx def)
1763 gen_presence_absence_set (def, TRUE, TRUE);
1766 /* Process an ABSENCE_SET.
1768 This gives information about a cpu unit reservation requirements.
1769 We fill a struct unit_pattern_rel_decl (absence) with information
1770 used later by `expand_automata'. */
1772 gen_absence_set (rtx def)
1774 gen_presence_absence_set (def, FALSE, FALSE);
1777 /* Process a FINAL_ABSENCE_SET.
1779 This gives information about a cpu unit reservation requirements.
1780 We fill a struct unit_pattern_rel_decl (absence) with information
1781 used later by `expand_automata'. */
1783 gen_final_absence_set (rtx def)
1785 gen_presence_absence_set (def, FALSE, TRUE);
1788 /* Process a DEFINE_AUTOMATON.
1790 This gives information about a finite state automaton used for
1791 recognizing pipeline hazards. We fill a struct automaton_decl
1792 with information used later by `expand_automata'. */
1794 gen_automaton (rtx def)
1797 char **str_automata;
1801 str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
1802 if (str_automata == NULL)
1803 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1804 for (i = 0; i < vect_length; i++)
1806 decl = create_node (sizeof (struct decl));
1807 decl->mode = dm_automaton;
1809 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1810 VEC_safe_push (decl_t,heap, decls, decl);
1815 /* Process an AUTOMATA_OPTION.
1817 This gives information how to generate finite state automaton used
1818 for recognizing pipeline hazards. */
1820 gen_automata_option (rtx def)
1822 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1823 no_minimization_flag = 1;
1824 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1826 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1828 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1830 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1832 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1835 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1838 /* Name in reservation to denote absence reservation. */
1839 #define NOTHING_NAME "nothing"
1841 /* The following string contains original reservation string being
1843 static const char *reserv_str;
1845 /* Parse an element in STR. */
1847 gen_regexp_el (const char *str)
1856 if (str [len - 1] != ')')
1857 fatal ("garbage after ) in reservation `%s'", reserv_str);
1858 dstr = alloca (len - 1);
1859 memcpy (dstr, str + 1, len - 2);
1860 dstr [len-2] = '\0';
1861 regexp = gen_regexp_sequence (dstr);
1863 else if (strcmp (str, NOTHING_NAME) == 0)
1865 regexp = create_node (sizeof (struct decl));
1866 regexp->mode = rm_nothing;
1870 regexp = create_node (sizeof (struct decl));
1871 regexp->mode = rm_unit;
1872 REGEXP_UNIT (regexp)->name = str;
1877 /* Parse construction `repeat' in STR. */
1879 gen_regexp_repeat (const char *str)
1887 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1888 if (repeat_vect == NULL)
1889 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1892 regexp = gen_regexp_el (repeat_vect [0]);
1893 for (i = 1; i < els_num; i++)
1895 repeat = create_node (sizeof (struct regexp));
1896 repeat->mode = rm_repeat;
1897 REGEXP_REPEAT (repeat)->regexp = regexp;
1898 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
1899 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
1900 fatal ("repetition `%s' <= 1 in reservation `%s'",
1907 return gen_regexp_el (str);
1910 /* Parse reservation STR which possibly contains separator '+'. */
1912 gen_regexp_allof (const char *str)
1919 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
1920 if (allof_vect == NULL)
1921 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1924 allof = create_node (sizeof (struct regexp)
1925 + sizeof (regexp_t) * (els_num - 1));
1926 allof->mode = rm_allof;
1927 REGEXP_ALLOF (allof)->regexps_num = els_num;
1928 for (i = 0; i < els_num; i++)
1929 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
1933 return gen_regexp_repeat (str);
1936 /* Parse reservation STR which possibly contains separator '|'. */
1938 gen_regexp_oneof (const char *str)
1945 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
1946 if (oneof_vect == NULL)
1947 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1950 oneof = create_node (sizeof (struct regexp)
1951 + sizeof (regexp_t) * (els_num - 1));
1952 oneof->mode = rm_oneof;
1953 REGEXP_ONEOF (oneof)->regexps_num = els_num;
1954 for (i = 0; i < els_num; i++)
1955 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
1959 return gen_regexp_allof (str);
1962 /* Parse reservation STR which possibly contains separator ','. */
1964 gen_regexp_sequence (const char *str)
1967 char **sequence_vect;
1971 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
1974 sequence = create_node (sizeof (struct regexp)
1975 + sizeof (regexp_t) * (els_num - 1));
1976 sequence->mode = rm_sequence;
1977 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
1978 for (i = 0; i < els_num; i++)
1979 REGEXP_SEQUENCE (sequence)->regexps [i]
1980 = gen_regexp_oneof (sequence_vect [i]);
1984 return gen_regexp_oneof (str);
1987 /* Parse construction reservation STR. */
1989 gen_regexp (const char *str)
1992 return gen_regexp_sequence (str);;
1995 /* Process a DEFINE_RESERVATION.
1997 This gives information about a reservation of cpu units. We fill
1998 in a struct reserv_decl with information used later by
1999 `expand_automata'. */
2001 gen_reserv (rtx def)
2005 decl = create_node (sizeof (struct decl));
2006 decl->mode = dm_reserv;
2008 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
2009 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
2010 VEC_safe_push (decl_t,heap, decls, decl);
2014 /* Process a DEFINE_INSN_RESERVATION.
2016 This gives information about the reservation of cpu units by an
2017 insn. We fill a struct insn_reserv_decl with information used
2018 later by `expand_automata'. */
2020 gen_insn_reserv (rtx def)
2024 decl = create_node (sizeof (struct decl));
2025 decl->mode = dm_insn_reserv;
2027 DECL_INSN_RESERV (decl)->name
2028 = check_name (XSTR (def, 0), decl->pos);
2029 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2030 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2031 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
2032 VEC_safe_push (decl_t,heap, decls, decl);
2038 /* The function evaluates hash value (0..UINT_MAX) of string. */
2040 string_hash (const char *string)
2044 for (result = i = 0;*string++ != '\0'; i++)
2045 result += ((unsigned char) *string << (i % CHAR_BIT));
2051 /* This page contains abstract data `table of automaton declarations'.
2052 Elements of the table is nodes representing automaton declarations.
2053 Key of the table elements is name of given automaton. Remember
2054 that automaton names have own space. */
2056 /* The function evaluates hash value of an automaton declaration. The
2057 function is used by abstract data `hashtab'. The function returns
2058 hash value (0..UINT_MAX) of given automaton declaration. */
2060 automaton_decl_hash (const void *automaton_decl)
2062 const decl_t decl = (decl_t) automaton_decl;
2064 gcc_assert (decl->mode != dm_automaton
2065 || DECL_AUTOMATON (decl)->name);
2066 return string_hash (DECL_AUTOMATON (decl)->name);
2069 /* The function tests automaton declarations on equality of their
2070 keys. The function is used by abstract data `hashtab'. The
2071 function returns 1 if the declarations have the same key, 0
2074 automaton_decl_eq_p (const void* automaton_decl_1,
2075 const void* automaton_decl_2)
2077 const decl_t decl1 = (decl_t) automaton_decl_1;
2078 const decl_t decl2 = (decl_t) automaton_decl_2;
2080 gcc_assert (decl1->mode == dm_automaton
2081 && DECL_AUTOMATON (decl1)->name
2082 && decl2->mode == dm_automaton
2083 && DECL_AUTOMATON (decl2)->name);
2084 return strcmp (DECL_AUTOMATON (decl1)->name,
2085 DECL_AUTOMATON (decl2)->name) == 0;
2088 /* The automaton declaration table itself is represented by the
2089 following variable. */
2090 static htab_t automaton_decl_table;
2092 /* The function inserts automaton declaration into the table. The
2093 function does nothing if an automaton declaration with the same key
2094 exists already in the table. The function returns automaton
2095 declaration node in the table with the same key as given automaton
2096 declaration node. */
2098 insert_automaton_decl (decl_t automaton_decl)
2102 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2103 if (*entry_ptr == NULL)
2104 *entry_ptr = (void *) automaton_decl;
2105 return (decl_t) *entry_ptr;
2108 /* The following variable value is node representing automaton
2109 declaration. The node used for searching automaton declaration
2111 static struct decl work_automaton_decl;
2113 /* The function searches for automaton declaration in the table with
2114 the same key as node representing name of the automaton
2115 declaration. The function returns node found in the table, NULL if
2116 such node does not exist in the table. */
2118 find_automaton_decl (const char *name)
2122 work_automaton_decl.mode = dm_automaton;
2123 DECL_AUTOMATON (&work_automaton_decl)->name = name;
2124 entry = htab_find (automaton_decl_table, &work_automaton_decl);
2125 return (decl_t) entry;
2128 /* The function creates empty automaton declaration table and node
2129 representing automaton declaration and used for searching automaton
2130 declaration with given name. The function must be called only once
2131 before any work with the automaton declaration table. */
2133 initiate_automaton_decl_table (void)
2135 work_automaton_decl.mode = dm_automaton;
2136 automaton_decl_table = htab_create (10, automaton_decl_hash,
2137 automaton_decl_eq_p, (htab_del) 0);
2140 /* The function deletes the automaton declaration table. Only call of
2141 function `initiate_automaton_decl_table' is possible immediately
2142 after this function call. */
2144 finish_automaton_decl_table (void)
2146 htab_delete (automaton_decl_table);
2151 /* This page contains abstract data `table of insn declarations'.
2152 Elements of the table is nodes representing insn declarations. Key
2153 of the table elements is name of given insn (in corresponding
2154 define_insn_reservation). Remember that insn names have own
2157 /* The function evaluates hash value of an insn declaration. The
2158 function is used by abstract data `hashtab'. The function returns
2159 hash value (0..UINT_MAX) of given insn declaration. */
2161 insn_decl_hash (const void *insn_decl)
2163 const decl_t decl = (decl_t) insn_decl;
2165 gcc_assert (decl->mode == dm_insn_reserv
2166 && DECL_INSN_RESERV (decl)->name);
2167 return string_hash (DECL_INSN_RESERV (decl)->name);
2170 /* The function tests insn declarations on equality of their keys.
2171 The function is used by abstract data `hashtab'. The function
2172 returns 1 if declarations have the same key, 0 otherwise. */
2174 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2176 const decl_t decl1 = (decl_t) insn_decl_1;
2177 const decl_t decl2 = (decl_t) insn_decl_2;
2179 gcc_assert (decl1->mode == dm_insn_reserv
2180 && DECL_INSN_RESERV (decl1)->name
2181 && decl2->mode == dm_insn_reserv
2182 && DECL_INSN_RESERV (decl2)->name);
2183 return strcmp (DECL_INSN_RESERV (decl1)->name,
2184 DECL_INSN_RESERV (decl2)->name) == 0;
2187 /* The insn declaration table itself is represented by the following
2188 variable. The table does not contain insn reservation
2190 static htab_t insn_decl_table;
2192 /* The function inserts insn declaration into the table. The function
2193 does nothing if an insn declaration with the same key exists
2194 already in the table. The function returns insn declaration node
2195 in the table with the same key as given insn declaration node. */
2197 insert_insn_decl (decl_t insn_decl)
2201 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2202 if (*entry_ptr == NULL)
2203 *entry_ptr = (void *) insn_decl;
2204 return (decl_t) *entry_ptr;
2207 /* The following variable value is node representing insn reservation
2208 declaration. The node used for searching insn reservation
2209 declaration with given name. */
2210 static struct decl work_insn_decl;
2212 /* The function searches for insn reservation declaration in the table
2213 with the same key as node representing name of the insn reservation
2214 declaration. The function returns node found in the table, NULL if
2215 such node does not exist in the table. */
2217 find_insn_decl (const char *name)
2221 work_insn_decl.mode = dm_insn_reserv;
2222 DECL_INSN_RESERV (&work_insn_decl)->name = name;
2223 entry = htab_find (insn_decl_table, &work_insn_decl);
2224 return (decl_t) entry;
2227 /* The function creates empty insn declaration table and node
2228 representing insn declaration and used for searching insn
2229 declaration with given name. The function must be called only once
2230 before any work with the insn declaration table. */
2232 initiate_insn_decl_table (void)
2234 work_insn_decl.mode = dm_insn_reserv;
2235 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2239 /* The function deletes the insn declaration table. Only call of
2240 function `initiate_insn_decl_table' is possible immediately after
2241 this function call. */
2243 finish_insn_decl_table (void)
2245 htab_delete (insn_decl_table);
2250 /* This page contains abstract data `table of declarations'. Elements
2251 of the table is nodes representing declarations (of units and
2252 reservations). Key of the table elements is names of given
2255 /* The function evaluates hash value of a declaration. The function
2256 is used by abstract data `hashtab'. The function returns hash
2257 value (0..UINT_MAX) of given declaration. */
2259 decl_hash (const void *decl)
2261 const decl_t d = (const decl_t) decl;
2263 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
2264 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
2265 return string_hash (d->mode == dm_unit
2266 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2269 /* The function tests declarations on equality of their keys. The
2270 function is used by abstract data 'hashtab'. The function
2271 returns 1 if the declarations have the same key, 0 otherwise. */
2273 decl_eq_p (const void *decl_1, const void *decl_2)
2275 const decl_t d1 = (const decl_t) decl_1;
2276 const decl_t d2 = (const decl_t) decl_2;
2278 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
2279 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
2280 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
2281 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
2282 return strcmp ((d1->mode == dm_unit
2283 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2284 (d2->mode == dm_unit
2285 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2288 /* The declaration table itself is represented by the following
2290 static htab_t decl_table;
2292 /* The function inserts declaration into the table. The function does
2293 nothing if a declaration with the same key exists already in the
2294 table. The function returns declaration node in the table with the
2295 same key as given declaration node. */
2298 insert_decl (decl_t decl)
2302 entry_ptr = htab_find_slot (decl_table, decl, 1);
2303 if (*entry_ptr == NULL)
2304 *entry_ptr = (void *) decl;
2305 return (decl_t) *entry_ptr;
2308 /* The following variable value is node representing declaration. The
2309 node used for searching declaration with given name. */
2310 static struct decl work_decl;
2312 /* The function searches for declaration in the table with the same
2313 key as node representing name of the declaration. The function
2314 returns node found in the table, NULL if such node does not exist
2317 find_decl (const char *name)
2321 work_decl.mode = dm_unit;
2322 DECL_UNIT (&work_decl)->name = name;
2323 entry = htab_find (decl_table, &work_decl);
2324 return (decl_t) entry;
2327 /* The function creates empty declaration table and node representing
2328 declaration and used for searching declaration with given name.
2329 The function must be called only once before any work with the
2330 declaration table. */
2332 initiate_decl_table (void)
2334 work_decl.mode = dm_unit;
2335 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2338 /* The function deletes the declaration table. Only call of function
2339 `initiate_declaration_table' is possible immediately after this
2342 finish_decl_table (void)
2344 htab_delete (decl_table);
2349 /* This page contains checker of pipeline hazard description. */
2351 /* Checking NAMES in an exclusion clause vector and returning formed
2352 unit_set_el_list. */
2353 static unit_set_el_t
2354 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2356 unit_set_el_t el_list;
2357 unit_set_el_t last_el;
2358 unit_set_el_t new_el;
2359 decl_t decl_in_table;
2364 for (i = 0; i < num; i++)
2366 decl_in_table = find_decl (names [i]);
2367 if (decl_in_table == NULL)
2368 error ("unit `%s' in exclusion is not declared", names [i]);
2369 else if (decl_in_table->mode != dm_unit)
2370 error ("`%s' in exclusion is not unit", names [i]);
2373 new_el = create_node (sizeof (struct unit_set_el));
2374 new_el->unit_decl = DECL_UNIT (decl_in_table);
2375 new_el->next_unit_set_el = NULL;
2376 if (last_el == NULL)
2377 el_list = last_el = new_el;
2380 last_el->next_unit_set_el = new_el;
2381 last_el = last_el->next_unit_set_el;
2388 /* The function adds each element from SOURCE_LIST to the exclusion
2389 list of the each element from DEST_LIST. Checking situation "unit
2390 excludes itself". */
2392 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2393 pos_t excl_pos ATTRIBUTE_UNUSED)
2397 unit_set_el_t curr_el;
2398 unit_set_el_t prev_el;
2401 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2402 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2404 if (dst->unit_decl == src->unit_decl)
2406 error ("unit `%s' excludes itself", src->unit_decl->name);
2409 if (dst->unit_decl->automaton_name != NULL
2410 && src->unit_decl->automaton_name != NULL
2411 && strcmp (dst->unit_decl->automaton_name,
2412 src->unit_decl->automaton_name) != 0)
2414 error ("units `%s' and `%s' in exclusion set belong to different automata",
2415 src->unit_decl->name, dst->unit_decl->name);
2418 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2420 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2421 if (curr_el->unit_decl == src->unit_decl)
2423 if (curr_el == NULL)
2425 /* Element not found - insert. */
2426 copy = copy_node (src, sizeof (*src));
2427 copy->next_unit_set_el = NULL;
2428 if (prev_el == NULL)
2429 dst->unit_decl->excl_list = copy;
2431 prev_el->next_unit_set_el = copy;
2436 /* Checking NAMES in presence/absence clause and returning the
2437 formed unit_set_el_list. The function is called only after
2438 processing all exclusion sets. */
2439 static unit_set_el_t
2440 process_presence_absence_names (char **names, int num,
2441 pos_t req_pos ATTRIBUTE_UNUSED,
2442 int presence_p, int final_p)
2444 unit_set_el_t el_list;
2445 unit_set_el_t last_el;
2446 unit_set_el_t new_el;
2447 decl_t decl_in_table;
2452 for (i = 0; i < num; i++)
2454 decl_in_table = find_decl (names [i]);
2455 if (decl_in_table == NULL)
2458 ? "unit `%s' in final presence set is not declared"
2459 : "unit `%s' in presence set is not declared")
2461 ? "unit `%s' in final absence set is not declared"
2462 : "unit `%s' in absence set is not declared")), names [i]);
2463 else if (decl_in_table->mode != dm_unit)
2466 ? "`%s' in final presence set is not unit"
2467 : "`%s' in presence set is not unit")
2469 ? "`%s' in final absence set is not unit"
2470 : "`%s' in absence set is not unit")), names [i]);
2473 new_el = create_node (sizeof (struct unit_set_el));
2474 new_el->unit_decl = DECL_UNIT (decl_in_table);
2475 new_el->next_unit_set_el = NULL;
2476 if (last_el == NULL)
2477 el_list = last_el = new_el;
2480 last_el->next_unit_set_el = new_el;
2481 last_el = last_el->next_unit_set_el;
2488 /* Checking NAMES in patterns of a presence/absence clause and
2489 returning the formed pattern_set_el_list. The function is called
2490 only after processing all exclusion sets. */
2491 static pattern_set_el_t
2492 process_presence_absence_patterns (char ***patterns, int num,
2493 pos_t req_pos ATTRIBUTE_UNUSED,
2494 int presence_p, int final_p)
2496 pattern_set_el_t el_list;
2497 pattern_set_el_t last_el;
2498 pattern_set_el_t new_el;
2499 decl_t decl_in_table;
2504 for (i = 0; i < num; i++)
2506 for (j = 0; patterns [i] [j] != NULL; j++)
2508 new_el = create_node (sizeof (struct pattern_set_el)
2509 + sizeof (struct unit_decl *) * j);
2511 = (struct unit_decl **) ((char *) new_el
2512 + sizeof (struct pattern_set_el));
2513 new_el->next_pattern_set_el = NULL;
2514 if (last_el == NULL)
2515 el_list = last_el = new_el;
2518 last_el->next_pattern_set_el = new_el;
2519 last_el = last_el->next_pattern_set_el;
2521 new_el->units_num = 0;
2522 for (j = 0; patterns [i] [j] != NULL; j++)
2524 decl_in_table = find_decl (patterns [i] [j]);
2525 if (decl_in_table == NULL)
2528 ? "unit `%s' in final presence set is not declared"
2529 : "unit `%s' in presence set is not declared")
2531 ? "unit `%s' in final absence set is not declared"
2532 : "unit `%s' in absence set is not declared")),
2534 else if (decl_in_table->mode != dm_unit)
2537 ? "`%s' in final presence set is not unit"
2538 : "`%s' in presence set is not unit")
2540 ? "`%s' in final absence set is not unit"
2541 : "`%s' in absence set is not unit")),
2545 new_el->unit_decls [new_el->units_num]
2546 = DECL_UNIT (decl_in_table);
2547 new_el->units_num++;
2554 /* The function adds each element from PATTERN_LIST to presence (if
2555 PRESENCE_P) or absence list of the each element from DEST_LIST.
2556 Checking situations "unit requires own absence", and "unit excludes
2557 and requires presence of ...", "unit requires absence and presence
2558 of ...", "units in (final) presence set belong to different
2559 automata", and "units in (final) absence set belong to different
2560 automata". Remember that we process absence sets only after all
2563 add_presence_absence (unit_set_el_t dest_list,
2564 pattern_set_el_t pattern_list,
2565 pos_t req_pos ATTRIBUTE_UNUSED,
2566 int presence_p, int final_p)
2569 pattern_set_el_t pat;
2570 struct unit_decl *unit;
2571 unit_set_el_t curr_excl_el;
2572 pattern_set_el_t curr_pat_el;
2573 pattern_set_el_t prev_el;
2574 pattern_set_el_t copy;
2578 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2579 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2581 for (i = 0; i < pat->units_num; i++)
2583 unit = pat->unit_decls [i];
2584 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2586 error ("unit `%s' requires own absence", unit->name);
2589 if (dst->unit_decl->automaton_name != NULL
2590 && unit->automaton_name != NULL
2591 && strcmp (dst->unit_decl->automaton_name,
2592 unit->automaton_name) != 0)
2596 ? "units `%s' and `%s' in final presence set belong to different automata"
2597 : "units `%s' and `%s' in presence set belong to different automata")
2599 ? "units `%s' and `%s' in final absence set belong to different automata"
2600 : "units `%s' and `%s' in absence set belong to different automata")),
2601 unit->name, dst->unit_decl->name);
2606 for (curr_excl_el = dst->unit_decl->excl_list;
2607 curr_excl_el != NULL;
2608 curr_excl_el = curr_excl_el->next_unit_set_el)
2610 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2614 error ("unit `%s' excludes and requires presence of `%s'",
2615 dst->unit_decl->name, unit->name);
2620 (0, "unit `%s' excludes and requires presence of `%s'",
2621 dst->unit_decl->name, unit->name);
2624 else if (pat->units_num == 1)
2625 for (curr_pat_el = dst->unit_decl->presence_list;
2626 curr_pat_el != NULL;
2627 curr_pat_el = curr_pat_el->next_pattern_set_el)
2628 if (curr_pat_el->units_num == 1
2629 && unit == curr_pat_el->unit_decls [0])
2634 ("unit `%s' requires absence and presence of `%s'",
2635 dst->unit_decl->name, unit->name);
2640 (0, "unit `%s' requires absence and presence of `%s'",
2641 dst->unit_decl->name, unit->name);
2645 for (prev_el = (presence_p
2647 ? dst->unit_decl->final_presence_list
2648 : dst->unit_decl->final_presence_list)
2650 ? dst->unit_decl->final_absence_list
2651 : dst->unit_decl->absence_list));
2652 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2653 prev_el = prev_el->next_pattern_set_el)
2655 copy = copy_node (pat, sizeof (*pat));
2656 copy->next_pattern_set_el = NULL;
2657 if (prev_el == NULL)
2662 dst->unit_decl->final_presence_list = copy;
2664 dst->unit_decl->presence_list = copy;
2667 dst->unit_decl->final_absence_list = copy;
2669 dst->unit_decl->absence_list = copy;
2672 prev_el->next_pattern_set_el = copy;
2679 /* The function searches for bypass with given IN_INSN_RESERV in given
2681 static struct bypass_decl *
2682 find_bypass (struct bypass_decl *bypass_list,
2683 struct insn_reserv_decl *in_insn_reserv)
2685 struct bypass_decl *bypass;
2687 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2688 if (bypass->in_insn_reserv == in_insn_reserv)
2693 /* The function processes pipeline description declarations, checks
2694 their correctness, and forms exclusion/presence/absence sets. */
2696 process_decls (void)
2699 decl_t automaton_decl;
2700 decl_t decl_in_table;
2701 decl_t out_insn_reserv;
2702 decl_t in_insn_reserv;
2703 struct bypass_decl *bypass;
2704 int automaton_presence;
2707 /* Checking repeated automata declarations. */
2708 automaton_presence = 0;
2709 for (i = 0; i < description->decls_num; i++)
2711 decl = description->decls [i];
2712 if (decl->mode == dm_automaton)
2714 automaton_presence = 1;
2715 decl_in_table = insert_automaton_decl (decl);
2716 if (decl_in_table != decl)
2719 error ("repeated declaration of automaton `%s'",
2720 DECL_AUTOMATON (decl)->name);
2722 warning (0, "repeated declaration of automaton `%s'",
2723 DECL_AUTOMATON (decl)->name);
2727 /* Checking undeclared automata, repeated declarations (except for
2728 automata) and correctness of their attributes (insn latency times
2730 for (i = 0; i < description->decls_num; i++)
2732 decl = description->decls [i];
2733 if (decl->mode == dm_insn_reserv)
2735 DECL_INSN_RESERV (decl)->condexp
2736 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2737 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2738 error ("define_insn_reservation `%s' has negative latency time",
2739 DECL_INSN_RESERV (decl)->name);
2740 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2741 description->insns_num++;
2742 decl_in_table = insert_insn_decl (decl);
2743 if (decl_in_table != decl)
2744 error ("`%s' is already used as insn reservation name",
2745 DECL_INSN_RESERV (decl)->name);
2747 else if (decl->mode == dm_bypass)
2749 if (DECL_BYPASS (decl)->latency < 0)
2750 error ("define_bypass `%s - %s' has negative latency time",
2751 DECL_BYPASS (decl)->out_insn_name,
2752 DECL_BYPASS (decl)->in_insn_name);
2754 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2756 if (decl->mode == dm_unit)
2758 DECL_UNIT (decl)->automaton_decl = NULL;
2759 if (DECL_UNIT (decl)->automaton_name != NULL)
2762 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2763 if (automaton_decl == NULL)
2764 error ("automaton `%s' is not declared",
2765 DECL_UNIT (decl)->automaton_name);
2768 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2769 DECL_UNIT (decl)->automaton_decl
2770 = DECL_AUTOMATON (automaton_decl);
2773 else if (automaton_presence)
2774 error ("define_unit `%s' without automaton when one defined",
2775 DECL_UNIT (decl)->name);
2776 DECL_UNIT (decl)->unit_num = description->units_num;
2777 description->units_num++;
2778 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2780 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2783 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2787 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2789 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2792 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2794 if (decl_in_table == NULL)
2795 decl_in_table = insert_decl (decl);
2798 if (decl->mode == dm_unit)
2799 error ("repeated declaration of unit `%s'",
2800 DECL_UNIT (decl)->name);
2802 error ("repeated declaration of reservation `%s'",
2803 DECL_RESERV (decl)->name);
2807 /* Check bypasses and form list of bypasses for each (output)
2809 for (i = 0; i < description->decls_num; i++)
2811 decl = description->decls [i];
2812 if (decl->mode == dm_bypass)
2814 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2815 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2816 if (out_insn_reserv == NULL)
2817 error ("there is no insn reservation `%s'",
2818 DECL_BYPASS (decl)->out_insn_name);
2819 else if (in_insn_reserv == NULL)
2820 error ("there is no insn reservation `%s'",
2821 DECL_BYPASS (decl)->in_insn_name);
2824 DECL_BYPASS (decl)->out_insn_reserv
2825 = DECL_INSN_RESERV (out_insn_reserv);
2826 DECL_BYPASS (decl)->in_insn_reserv
2827 = DECL_INSN_RESERV (in_insn_reserv);
2829 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2830 DECL_BYPASS (decl)->in_insn_reserv);
2833 if (DECL_BYPASS (decl)->latency == bypass->latency)
2837 ("the same bypass `%s - %s' is already defined",
2838 DECL_BYPASS (decl)->out_insn_name,
2839 DECL_BYPASS (decl)->in_insn_name);
2842 (0, "the same bypass `%s - %s' is already defined",
2843 DECL_BYPASS (decl)->out_insn_name,
2844 DECL_BYPASS (decl)->in_insn_name);
2847 error ("bypass `%s - %s' is already defined",
2848 DECL_BYPASS (decl)->out_insn_name,
2849 DECL_BYPASS (decl)->in_insn_name);
2853 DECL_BYPASS (decl)->next
2854 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2855 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2856 = DECL_BYPASS (decl);
2862 /* Check exclusion set declarations and form exclusion sets. */
2863 for (i = 0; i < description->decls_num; i++)
2865 decl = description->decls [i];
2866 if (decl->mode == dm_excl)
2868 unit_set_el_t unit_set_el_list;
2869 unit_set_el_t unit_set_el_list_2;
2872 = process_excls (DECL_EXCL (decl)->names,
2873 DECL_EXCL (decl)->first_list_length, decl->pos);
2875 = process_excls (&DECL_EXCL (decl)->names
2876 [DECL_EXCL (decl)->first_list_length],
2877 DECL_EXCL (decl)->all_names_num
2878 - DECL_EXCL (decl)->first_list_length,
2880 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2881 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2885 /* Check presence set declarations and form presence sets. */
2886 for (i = 0; i < description->decls_num; i++)
2888 decl = description->decls [i];
2889 if (decl->mode == dm_presence)
2891 unit_set_el_t unit_set_el_list;
2892 pattern_set_el_t pattern_set_el_list;
2895 = process_presence_absence_names
2896 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
2897 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2899 = process_presence_absence_patterns
2900 (DECL_PRESENCE (decl)->patterns,
2901 DECL_PRESENCE (decl)->patterns_num,
2902 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2903 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2905 DECL_PRESENCE (decl)->final_p);
2909 /* Check absence set declarations and form absence sets. */
2910 for (i = 0; i < description->decls_num; i++)
2912 decl = description->decls [i];
2913 if (decl->mode == dm_absence)
2915 unit_set_el_t unit_set_el_list;
2916 pattern_set_el_t pattern_set_el_list;
2919 = process_presence_absence_names
2920 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
2921 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2923 = process_presence_absence_patterns
2924 (DECL_ABSENCE (decl)->patterns,
2925 DECL_ABSENCE (decl)->patterns_num,
2926 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2927 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2929 DECL_ABSENCE (decl)->final_p);
2934 /* The following function checks that declared automaton is used. If
2935 the automaton is not used, the function fixes error/warning. The
2936 following function must be called only after `process_decls'. */
2938 check_automaton_usage (void)
2943 for (i = 0; i < description->decls_num; i++)
2945 decl = description->decls [i];
2946 if (decl->mode == dm_automaton
2947 && !DECL_AUTOMATON (decl)->automaton_is_used)
2950 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
2952 warning (0, "automaton `%s' is not used",
2953 DECL_AUTOMATON (decl)->name);
2958 /* The following recursive function processes all regexp in order to
2959 fix usage of units or reservations and to fix errors of undeclared
2960 name. The function may change unit_regexp onto reserv_regexp.
2961 Remember that reserv_regexp does not exist before the function
2964 process_regexp (regexp_t regexp)
2966 decl_t decl_in_table;
2967 regexp_t new_regexp;
2970 switch (regexp->mode)
2973 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
2974 if (decl_in_table == NULL)
2975 error ("undeclared unit or reservation `%s'",
2976 REGEXP_UNIT (regexp)->name);
2978 switch (decl_in_table->mode)
2981 DECL_UNIT (decl_in_table)->unit_is_used = 1;
2982 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
2986 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
2987 new_regexp = create_node (sizeof (struct regexp));
2988 new_regexp->mode = rm_reserv;
2989 new_regexp->pos = regexp->pos;
2990 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
2991 REGEXP_RESERV (new_regexp)->reserv_decl
2992 = DECL_RESERV (decl_in_table);
2993 regexp = new_regexp;
3001 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3002 REGEXP_SEQUENCE (regexp)->regexps [i]
3003 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3006 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3007 REGEXP_ALLOF (regexp)->regexps [i]
3008 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3011 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3012 REGEXP_ONEOF (regexp)->regexps [i]
3013 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3016 REGEXP_REPEAT (regexp)->regexp
3017 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3027 /* The following function processes regexp of define_reservation and
3028 define_insn_reservation with the aid of function
3029 `process_regexp'. */
3031 process_regexp_decls (void)
3036 for (i = 0; i < description->decls_num; i++)
3038 decl = description->decls [i];
3039 if (decl->mode == dm_reserv)
3040 DECL_RESERV (decl)->regexp
3041 = process_regexp (DECL_RESERV (decl)->regexp);
3042 else if (decl->mode == dm_insn_reserv)
3043 DECL_INSN_RESERV (decl)->regexp
3044 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3048 /* The following function checks that declared unit is used. If the
3049 unit is not used, the function fixes errors/warnings. The
3050 following function must be called only after `process_decls',
3051 `process_regexp_decls'. */
3058 for (i = 0; i < description->decls_num; i++)
3060 decl = description->decls [i];
3061 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3064 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3066 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
3068 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3071 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3073 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
3078 /* The following variable value is number of reservation being
3079 processed on loop recognition. */
3080 static int curr_loop_pass_num;
3082 /* The following recursive function returns nonzero value if REGEXP
3083 contains given decl or reservations in given regexp refers for
3086 loop_in_regexp (regexp_t regexp, decl_t start_decl)
3092 switch (regexp->mode)
3098 if (start_decl->mode == dm_reserv
3099 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3101 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3102 == curr_loop_pass_num)
3103 /* declaration has been processed. */
3107 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3108 = curr_loop_pass_num;
3109 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3114 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3115 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3120 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3121 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3126 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3127 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3132 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3142 /* The following function fixes errors "cycle in definition ...". The
3143 function uses function `loop_in_regexp' for that. */
3145 check_loops_in_regexps (void)
3150 for (i = 0; i < description->decls_num; i++)
3152 decl = description->decls [i];
3153 if (decl->mode == dm_reserv)
3154 DECL_RESERV (decl)->loop_pass_num = 0;
3156 for (i = 0; i < description->decls_num; i++)
3158 decl = description->decls [i];
3159 curr_loop_pass_num = i;
3161 if (decl->mode == dm_reserv)
3163 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3164 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3166 gcc_assert (DECL_RESERV (decl)->regexp);
3167 error ("cycle in definition of reservation `%s'",
3168 DECL_RESERV (decl)->name);
3174 /* The function recursively processes IR of reservation and defines
3175 max and min cycle for reservation of unit. */
3177 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3178 int min_start_cycle, int *max_finish_cycle,
3179 int *min_finish_cycle)
3183 switch (regexp->mode)
3186 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3187 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3188 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3189 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3190 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3191 *max_finish_cycle = max_start_cycle;
3192 *min_finish_cycle = min_start_cycle;
3196 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3197 max_start_cycle, min_start_cycle,
3198 max_finish_cycle, min_finish_cycle);
3202 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3204 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3205 max_start_cycle, min_start_cycle,
3206 max_finish_cycle, min_finish_cycle);
3207 max_start_cycle = *max_finish_cycle + 1;
3208 min_start_cycle = *min_finish_cycle + 1;
3213 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3215 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3216 max_start_cycle, min_start_cycle,
3217 max_finish_cycle, min_finish_cycle);
3218 max_start_cycle = *max_finish_cycle + 1;
3219 min_start_cycle = *min_finish_cycle + 1;
3228 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3230 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3231 max_start_cycle, min_start_cycle,
3232 max_finish_cycle, min_finish_cycle);
3233 if (max_cycle < *max_finish_cycle)
3234 max_cycle = *max_finish_cycle;
3235 if (i == 0 || min_cycle > *min_finish_cycle)
3236 min_cycle = *min_finish_cycle;
3238 *max_finish_cycle = max_cycle;
3239 *min_finish_cycle = min_cycle;
3248 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3250 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3251 max_start_cycle, min_start_cycle,
3252 max_finish_cycle, min_finish_cycle);
3253 if (max_cycle < *max_finish_cycle)
3254 max_cycle = *max_finish_cycle;
3255 if (i == 0 || min_cycle > *min_finish_cycle)
3256 min_cycle = *min_finish_cycle;
3258 *max_finish_cycle = max_cycle;
3259 *min_finish_cycle = min_cycle;
3264 *max_finish_cycle = max_start_cycle;
3265 *min_finish_cycle = min_start_cycle;
3273 /* The following function is called only for correct program. The
3274 function defines max reservation of insns in cycles. */
3276 evaluate_max_reserv_cycles (void)
3278 int max_insn_cycles_num;
3279 int min_insn_cycles_num;
3283 description->max_insn_reserv_cycles = 0;
3284 for (i = 0; i < description->decls_num; i++)
3286 decl = description->decls [i];
3287 if (decl->mode == dm_insn_reserv)
3289 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3290 &max_insn_cycles_num, &min_insn_cycles_num);
3291 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3292 description->max_insn_reserv_cycles = max_insn_cycles_num;
3295 description->max_insn_reserv_cycles++;
3298 /* The following function calls functions for checking all
3301 check_all_description (void)
3304 check_automaton_usage ();
3305 process_regexp_decls ();
3307 check_loops_in_regexps ();
3309 evaluate_max_reserv_cycles ();
3314 /* The page contains abstract data `ticker'. This data is used to
3315 report time of different phases of building automata. It is
3316 possibly to write a description for which automata will be built
3317 during several minutes even on fast machine. */
3319 /* The following function creates ticker and makes it active. */
3321 create_ticker (void)
3325 ticker.modified_creation_time = get_run_time ();
3326 ticker.incremented_off_time = 0;
3330 /* The following function switches off given ticker. */
3332 ticker_off (ticker_t *ticker)
3334 if (ticker->incremented_off_time == 0)
3335 ticker->incremented_off_time = get_run_time () + 1;
3338 /* The following function switches on given ticker. */
3340 ticker_on (ticker_t *ticker)
3342 if (ticker->incremented_off_time != 0)
3344 ticker->modified_creation_time
3345 += get_run_time () - ticker->incremented_off_time + 1;
3346 ticker->incremented_off_time = 0;
3350 /* The following function returns current time in milliseconds since
3351 the moment when given ticker was created. */
3353 active_time (ticker_t ticker)
3355 if (ticker.incremented_off_time != 0)
3356 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3358 return get_run_time () - ticker.modified_creation_time;
3361 /* The following function returns string representation of active time
3362 of given ticker. The result is string representation of seconds
3363 with accuracy of 1/100 second. Only result of the last call of the
3364 function exists. Therefore the following code is not correct
3366 printf ("parser time: %s\ngeneration time: %s\n",
3367 active_time_string (parser_ticker),
3368 active_time_string (generation_ticker));
3370 Correct code has to be the following
3372 printf ("parser time: %s\n", active_time_string (parser_ticker));
3373 printf ("generation time: %s\n",
3374 active_time_string (generation_ticker));
3378 print_active_time (FILE *f, ticker_t ticker)
3382 msecs = active_time (ticker);
3383 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3388 /* The following variable value is number of automaton which are
3389 really being created. This value is defined on the base of
3390 argument of option `-split'. If the variable has zero value the
3391 number of automata is defined by the constructions `%automaton'.
3392 This case occurs when option `-split' is absent or has zero
3393 argument. If constructions `define_automaton' is absent only one
3394 automaton is created. */
3395 static int automata_num;
3397 /* The following variable values are times of
3398 o transformation of regular expressions
3399 o building NDFA (DFA if !ndfa_flag)
3400 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3402 o building insn equivalence classes
3405 static ticker_t transform_time;
3406 static ticker_t NDFA_time;
3407 static ticker_t NDFA_to_DFA_time;
3408 static ticker_t minimize_time;
3409 static ticker_t equiv_time;
3410 static ticker_t automaton_generation_time;
3411 static ticker_t output_time;
3413 /* The following variable values are times of
3416 all pipeline hazard translator work */
3417 static ticker_t check_time;
3418 static ticker_t generation_time;
3419 static ticker_t all_time;
3423 /* Pseudo insn decl which denotes advancing cycle. */
3424 static decl_t advance_cycle_insn_decl;
3426 add_advance_cycle_insn_decl (void)
3428 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3429 advance_cycle_insn_decl->mode = dm_insn_reserv;
3430 advance_cycle_insn_decl->pos = no_pos;
3431 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3432 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
3433 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3434 = description->insns_num;
3435 description->decls [description->decls_num] = advance_cycle_insn_decl;
3436 description->decls_num++;
3437 description->insns_num++;
3442 /* Abstract data `alternative states' which represents
3443 nondeterministic nature of the description (see comments for
3444 structures alt_state and state). */
3446 /* List of free states. */
3447 static alt_state_t first_free_alt_state;
3450 /* The following variables is maximal number of allocated nodes
3452 static int allocated_alt_states_num = 0;
3455 /* The following function returns free node alt_state. It may be new
3456 allocated node or node freed earlier. */
3458 get_free_alt_state (void)
3462 if (first_free_alt_state != NULL)
3464 result = first_free_alt_state;
3465 first_free_alt_state = first_free_alt_state->next_alt_state;
3470 allocated_alt_states_num++;
3472 result = create_node (sizeof (struct alt_state));
3474 result->state = NULL;
3475 result->next_alt_state = NULL;
3476 result->next_sorted_alt_state = NULL;
3480 /* The function frees node ALT_STATE. */
3482 free_alt_state (alt_state_t alt_state)
3484 if (alt_state == NULL)
3486 alt_state->next_alt_state = first_free_alt_state;
3487 first_free_alt_state = alt_state;
3490 /* The function frees list started with node ALT_STATE_LIST. */
3492 free_alt_states (alt_state_t alt_states_list)
3494 alt_state_t curr_alt_state;
3495 alt_state_t next_alt_state;
3497 for (curr_alt_state = alt_states_list;
3498 curr_alt_state != NULL;
3499 curr_alt_state = next_alt_state)
3501 next_alt_state = curr_alt_state->next_alt_state;
3502 free_alt_state (curr_alt_state);
3506 /* The function compares unique numbers of alt states. */
3508 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3510 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3511 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3513 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3514 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3520 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3521 states from the list. The comparison key is alt state unique
3525 uniq_sort_alt_states (alt_state_t alt_states_list)
3527 alt_state_t curr_alt_state;
3528 VEC(alt_state_t,heap) *alt_states;
3530 size_t prev_unique_state_ind;
3533 if (alt_states_list == 0)
3535 if (alt_states_list->next_alt_state == 0)
3536 return alt_states_list;
3538 alt_states = VEC_alloc (alt_state_t,heap, 150);
3539 for (curr_alt_state = alt_states_list;
3540 curr_alt_state != NULL;
3541 curr_alt_state = curr_alt_state->next_alt_state)
3542 VEC_safe_push (alt_state_t,heap, alt_states, curr_alt_state);
3544 qsort (VEC_address (alt_state_t, alt_states),
3545 VEC_length (alt_state_t, alt_states),
3546 sizeof (alt_state_t), alt_state_cmp);
3548 prev_unique_state_ind = 0;
3549 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3550 if (VEC_index (alt_state_t, alt_states, prev_unique_state_ind)->state
3551 != VEC_index (alt_state_t, alt_states, i)->state)
3553 prev_unique_state_ind++;
3554 VEC_replace (alt_state_t, alt_states, prev_unique_state_ind,
3555 VEC_index (alt_state_t, alt_states, i));
3557 VEC_truncate (alt_state_t, alt_states, prev_unique_state_ind + 1);
3559 for (i = 1; i < VEC_length (alt_state_t, alt_states); i++)
3560 VEC_index (alt_state_t, alt_states, i-1)->next_sorted_alt_state
3561 = VEC_index (alt_state_t, alt_states, i);
3562 VEC_last (alt_state_t, alt_states)->next_sorted_alt_state = 0;
3564 result = VEC_index (alt_state_t, alt_states, 0);
3566 VEC_free (alt_state_t,heap, alt_states);
3570 /* The function checks equality of alt state lists. Remember that the
3571 lists must be already sorted by the previous function. */
3573 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3575 while (alt_states_1 != NULL && alt_states_2 != NULL
3576 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3578 alt_states_1 = alt_states_1->next_sorted_alt_state;
3579 alt_states_2 = alt_states_2->next_sorted_alt_state;
3581 return alt_states_1 == alt_states_2;
3584 /* Initialization of the abstract data. */
3586 initiate_alt_states (void)
3588 first_free_alt_state = NULL;
3591 /* Finishing work with the abstract data. */
3593 finish_alt_states (void)
3599 /* The page contains macros for work with bits strings. We could use
3600 standard gcc bitmap or sbitmap but it would result in difficulties
3601 of building canadian cross. */
3603 /* Set bit number bitno in the bit string. The macro is not side
3605 #define SET_BIT(bitstring, bitno) \
3606 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3608 #define CLEAR_BIT(bitstring, bitno) \
3609 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3611 /* Test if bit number bitno in the bitstring is set. The macro is not
3612 side effect proof. */
3613 #define TEST_BIT(bitstring, bitno) \
3614 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3618 /* This page contains abstract data `state'. */
3620 /* Maximal length of reservations in cycles (>= 1). */
3621 static int max_cycles_num;
3623 /* Number of set elements (see type set_el_t) needed for
3624 representation of one cycle reservation. It is depended on units
3626 static int els_in_cycle_reserv;
3628 /* Number of set elements (see type set_el_t) needed for
3629 representation of maximal length reservation. Deterministic
3630 reservation is stored as set (bit string) of length equal to the
3631 variable value * number of bits in set_el_t. */
3632 static int els_in_reservs;
3634 /* Array of pointers to unit declarations. */
3635 static unit_decl_t *units_array;
3637 /* Temporary reservation of maximal length. */
3638 static reserv_sets_t temp_reserv;
3640 /* The state table itself is represented by the following variable. */
3641 static htab_t state_table;
3643 /* Linked list of free 'state' structures to be recycled. The
3644 next_equiv_class_state pointer is borrowed for a free list. */
3645 static state_t first_free_state;
3647 static int curr_unique_state_num;
3650 /* The following variables is maximal number of allocated nodes
3652 static int allocated_states_num = 0;
3655 /* Allocate new reservation set. */
3656 static reserv_sets_t
3657 alloc_empty_reserv_sets (void)
3659 reserv_sets_t result;
3661 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3662 result = (reserv_sets_t) obstack_base (&irp);
3663 obstack_finish (&irp);
3664 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3668 /* Hash value of reservation set. */
3670 reserv_sets_hash_value (reserv_sets_t reservs)
3672 set_el_t hash_value;
3675 set_el_t *reserv_ptr;
3678 reservs_num = els_in_reservs;
3679 reserv_ptr = reservs;
3681 while (reservs_num != 0)
3684 hash_value += ((*reserv_ptr >> i)
3685 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3687 if (i == sizeof (set_el_t) * CHAR_BIT)
3691 if (sizeof (set_el_t) <= sizeof (unsigned))
3694 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3696 result += (unsigned) hash_value;
3697 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3702 /* Comparison of given reservation sets. */
3704 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3707 set_el_t *reserv_ptr_1;
3708 set_el_t *reserv_ptr_2;
3710 gcc_assert (reservs_1 && reservs_2);
3711 reservs_num = els_in_reservs;
3712 reserv_ptr_1 = reservs_1;
3713 reserv_ptr_2 = reservs_2;
3714 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3720 if (reservs_num == 0)
3722 else if (*reserv_ptr_1 < *reserv_ptr_2)
3728 /* The function checks equality of the reservation sets. */
3730 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3732 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3735 /* Set up in the reservation set that unit with UNIT_NUM is used on
3738 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3740 gcc_assert (cycle_num < max_cycles_num);
3741 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3742 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3745 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3746 used on CYCLE_NUM. */
3748 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3750 gcc_assert (cycle_num < max_cycles_num);
3751 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3752 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3755 /* The function checks that the reservation set represents no one unit
3758 it_is_empty_reserv_sets (reserv_sets_t operand)
3760 set_el_t *reserv_ptr;
3763 gcc_assert (operand);
3764 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3766 reserv_ptr++, reservs_num--)
3767 if (*reserv_ptr != 0)
3772 /* The function checks that the reservation sets are intersected,
3773 i.e. there is a unit reservation on a cycle in both reservation
3776 reserv_sets_are_intersected (reserv_sets_t operand_1,
3777 reserv_sets_t operand_2)
3781 set_el_t *cycle_ptr_1;
3782 set_el_t *cycle_ptr_2;
3784 gcc_assert (operand_1 && operand_2);
3785 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3786 el_ptr_1 < operand_1 + els_in_reservs;
3787 el_ptr_1++, el_ptr_2++)
3788 if (*el_ptr_1 & *el_ptr_2)
3790 reserv_sets_or (temp_reserv, operand_1, operand_2);
3791 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3792 cycle_ptr_1 < operand_1 + els_in_reservs;
3793 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3795 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3796 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3797 el_ptr_1++, el_ptr_2++)
3798 if (*el_ptr_1 & *el_ptr_2)
3800 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3802 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3806 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3808 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3815 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3816 cpu cycle. The remaining bits of OPERAND (representing the last
3817 cycle unit reservations) are not changed. */
3819 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3823 gcc_assert (result && operand && result != operand);
3824 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3825 result [i - els_in_cycle_reserv] = operand [i];
3828 /* OR of the reservation sets. */
3830 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3831 reserv_sets_t operand_2)
3835 set_el_t *result_set_el_ptr;
3837 gcc_assert (result && operand_1 && operand_2);
3838 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3839 el_ptr_1 < operand_1 + els_in_reservs;
3840 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3841 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3844 /* AND of the reservation sets. */
3846 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3847 reserv_sets_t operand_2)
3851 set_el_t *result_set_el_ptr;
3853 gcc_assert (result && operand_1 && operand_2);
3854 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3855 el_ptr_1 < operand_1 + els_in_reservs;
3856 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3857 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3860 /* The function outputs string representation of units reservation on
3861 cycle START_CYCLE in the reservation set. The function uses repeat
3862 construction if REPETITION_NUM > 1. */
3864 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3868 int reserved_units_num;
3870 reserved_units_num = 0;
3871 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3872 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3873 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3874 reserved_units_num++;
3875 gcc_assert (repetition_num > 0);
3876 if (repetition_num != 1 && reserved_units_num > 1)
3878 reserved_units_num = 0;
3880 unit_num < description->units_num;
3882 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3883 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3885 if (reserved_units_num != 0)
3887 reserved_units_num++;
3888 fprintf (f, "%s", units_array [unit_num]->name);
3890 if (reserved_units_num == 0)
3891 fprintf (f, NOTHING_NAME);
3892 gcc_assert (repetition_num > 0);
3893 if (repetition_num != 1 && reserved_units_num > 1)
3895 if (repetition_num != 1)
3896 fprintf (f, "*%d", repetition_num);
3899 /* The function outputs string representation of units reservation in
3900 the reservation set. */
3902 output_reserv_sets (FILE *f, reserv_sets_t reservs)
3904 int start_cycle = 0;
3909 for (cycle = 0; cycle < max_cycles_num; cycle++)
3910 if (repetition_num == 0)
3913 start_cycle = cycle;
3916 ((char *) reservs + start_cycle * els_in_cycle_reserv
3917 * sizeof (set_el_t),
3918 (char *) reservs + cycle * els_in_cycle_reserv
3919 * sizeof (set_el_t),
3920 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3924 if (start_cycle != 0)
3926 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3928 start_cycle = cycle;
3930 if (start_cycle < max_cycles_num)
3932 if (start_cycle != 0)
3934 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3938 /* The following function returns free node state for AUTOMATON. It
3939 may be new allocated node or node freed earlier. The function also
3940 allocates reservation set if WITH_RESERVS has nonzero value. */
3942 get_free_state (int with_reservs, automaton_t automaton)
3946 gcc_assert (max_cycles_num > 0 && automaton);
3947 if (first_free_state)
3949 result = first_free_state;
3950 first_free_state = result->next_equiv_class_state;
3952 result->next_equiv_class_state = NULL;
3953 result->automaton = automaton;
3954 result->first_out_arc = NULL;
3955 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3956 result->it_was_placed_in_stack_for_DFA_forming = 0;
3957 result->component_states = NULL;
3958 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3963 allocated_states_num++;
3965 result = create_node (sizeof (struct state));
3966 result->automaton = automaton;
3967 result->first_out_arc = NULL;
3968 result->unique_num = curr_unique_state_num;
3969 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3970 curr_unique_state_num++;
3974 if (result->reservs == NULL)
3975 result->reservs = alloc_empty_reserv_sets ();
3977 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3982 /* The function frees node STATE. */
3984 free_state (state_t state)
3986 free_alt_states (state->component_states);
3987 state->next_equiv_class_state = first_free_state;
3988 first_free_state = state;
3991 /* Hash value of STATE. If STATE represents deterministic state it is
3992 simply hash value of the corresponding reservation set. Otherwise
3993 it is formed from hash values of the component deterministic
3994 states. One more key is order number of state automaton. */
3996 state_hash (const void *state)
3998 unsigned int hash_value;
3999 alt_state_t alt_state;
4001 if (((state_t) state)->component_states == NULL)
4002 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4006 for (alt_state = ((state_t) state)->component_states;
4008 alt_state = alt_state->next_sorted_alt_state)
4009 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4010 | (hash_value << CHAR_BIT))
4011 + alt_state->state->unique_num);
4013 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4014 | (hash_value << CHAR_BIT))
4015 + ((state_t) state)->automaton->automaton_order_num);
4019 /* Return nonzero value if the states are the same. */
4021 state_eq_p (const void *state_1, const void *state_2)
4023 alt_state_t alt_state_1;
4024 alt_state_t alt_state_2;
4026 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4028 else if (((state_t) state_1)->component_states == NULL
4029 && ((state_t) state_2)->component_states == NULL)
4030 return reserv_sets_eq (((state_t) state_1)->reservs,
4031 ((state_t) state_2)->reservs);
4032 else if (((state_t) state_1)->component_states != NULL
4033 && ((state_t) state_2)->component_states != NULL)
4035 for (alt_state_1 = ((state_t) state_1)->component_states,
4036 alt_state_2 = ((state_t) state_2)->component_states;
4037 alt_state_1 != NULL && alt_state_2 != NULL;
4038 alt_state_1 = alt_state_1->next_sorted_alt_state,
4039 alt_state_2 = alt_state_2->next_sorted_alt_state)
4040 /* All state in the list must be already in the hash table.
4041 Also the lists must be sorted. */
4042 if (alt_state_1->state != alt_state_2->state)
4044 return alt_state_1 == alt_state_2;
4050 /* Insert STATE into the state table. */
4052 insert_state (state_t state)
4056 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4057 if (*entry_ptr == NULL)
4058 *entry_ptr = (void *) state;
4059 return (state_t) *entry_ptr;
4062 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4063 deterministic STATE. */
4065 set_state_reserv (state_t state, int cycle_num, int unit_num)
4067 set_unit_reserv (state->reservs, cycle_num, unit_num);
4070 /* Return nonzero value if the deterministic states contains a
4071 reservation of the same cpu unit on the same cpu cycle. */
4073 intersected_state_reservs_p (state_t state1, state_t state2)
4075 gcc_assert (state1->automaton == state2->automaton);
4076 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4079 /* Return deterministic state (inserted into the table) which
4080 representing the automaton state which is union of reservations of
4081 the deterministic states masked by RESERVS. */
4083 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4086 state_t state_in_table;
4088 gcc_assert (state1->automaton == state2->automaton);
4089 result = get_free_state (1, state1->automaton);
4090 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4091 reserv_sets_and (result->reservs, result->reservs, reservs);
4092 state_in_table = insert_state (result);
4093 if (result != state_in_table)
4095 free_state (result);
4096 result = state_in_table;
4101 /* Return deterministic state (inserted into the table) which
4102 represent the automaton state is obtained from deterministic STATE
4103 by advancing cpu cycle and masking by RESERVS. */
4105 state_shift (state_t state, reserv_sets_t reservs)
4108 state_t state_in_table;
4110 result = get_free_state (1, state->automaton);
4111 reserv_sets_shift (result->reservs, state->reservs);
4112 reserv_sets_and (result->reservs, result->reservs, reservs);
4113 state_in_table = insert_state (result);
4114 if (result != state_in_table)
4116 free_state (result);
4117 result = state_in_table;
4122 /* Initialization of the abstract data. */
4124 initiate_states (void)
4129 if (description->units_num)
4130 units_array = xmalloc (description->units_num * sizeof (unit_decl_t));
4134 for (i = 0; i < description->decls_num; i++)
4136 decl = description->decls [i];
4137 if (decl->mode == dm_unit)
4138 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4140 max_cycles_num = description->max_insn_reserv_cycles;
4142 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4143 / (sizeof (set_el_t) * CHAR_BIT));
4144 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4145 curr_unique_state_num = 0;
4146 initiate_alt_states ();
4147 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4148 temp_reserv = alloc_empty_reserv_sets ();
4151 /* Finishing work with the abstract data. */
4153 finish_states (void)
4157 htab_delete (state_table);
4158 first_free_state = NULL;
4159 finish_alt_states ();
4164 /* Abstract data `arcs'. */
4166 /* List of free arcs. */
4167 static arc_t first_free_arc;
4170 /* The following variables is maximal number of allocated nodes
4172 static int allocated_arcs_num = 0;
4175 /* The function frees node ARC. */
4177 free_arc (arc_t arc)
4179 arc->next_out_arc = first_free_arc;
4180 first_free_arc = arc;
4183 /* The function removes and frees ARC staring from FROM_STATE. */
4185 remove_arc (state_t from_state, arc_t arc)
4191 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4193 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4194 if (curr_arc == arc)
4196 gcc_assert (curr_arc);
4197 if (prev_arc == NULL)
4198 from_state->first_out_arc = arc->next_out_arc;
4200 prev_arc->next_out_arc = arc->next_out_arc;
4204 /* The functions returns arc with given characteristics (or NULL if
4205 the arc does not exist). */
4207 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4211 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4212 if (arc->to_state == to_state && arc->insn == insn)
4217 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4218 and with given STATE_ALTS. The function returns added arc (or
4219 already existing arc). */
4221 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4226 new_arc = find_arc (from_state, to_state, ainsn);
4227 if (new_arc != NULL)
4229 if (first_free_arc == NULL)
4232 allocated_arcs_num++;
4234 new_arc = create_node (sizeof (struct arc));
4235 new_arc->to_state = NULL;
4236 new_arc->insn = NULL;
4237 new_arc->next_out_arc = NULL;
4241 new_arc = first_free_arc;
4242 first_free_arc = first_free_arc->next_out_arc;
4244 new_arc->to_state = to_state;
4245 new_arc->insn = ainsn;
4246 ainsn->arc_exists_p = 1;
4247 new_arc->next_out_arc = from_state->first_out_arc;
4248 from_state->first_out_arc = new_arc;
4249 new_arc->next_arc_marked_by_insn = NULL;
4250 new_arc->state_alts = state_alts;
4254 /* The function returns the first arc starting from STATE. */
4256 first_out_arc (state_t state)
4258 return state->first_out_arc;
4261 /* The function returns next out arc after ARC. */
4263 next_out_arc (arc_t arc)
4265 return arc->next_out_arc;
4268 /* Initialization of the abstract data. */
4270 initiate_arcs (void)
4272 first_free_arc = NULL;
4275 /* Finishing work with the abstract data. */
4283 /* Abstract data `automata lists'. */
4285 /* List of free states. */
4286 static automata_list_el_t first_free_automata_list_el;
4288 /* The list being formed. */
4289 static automata_list_el_t current_automata_list;
4291 /* Hash table of automata lists. */
4292 static htab_t automata_list_table;
4294 /* The following function returns free automata list el. It may be
4295 new allocated node or node freed earlier. */
4296 static automata_list_el_t
4297 get_free_automata_list_el (void)
4299 automata_list_el_t result;
4301 if (first_free_automata_list_el != NULL)
4303 result = first_free_automata_list_el;
4304 first_free_automata_list_el
4305 = first_free_automata_list_el->next_automata_list_el;
4308 result = create_node (sizeof (struct automata_list_el));
4309 result->automaton = NULL;
4310 result->next_automata_list_el = NULL;
4314 /* The function frees node AUTOMATA_LIST_EL. */
4316 free_automata_list_el (automata_list_el_t automata_list_el)
4318 if (automata_list_el == NULL)
4320 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4321 first_free_automata_list_el = automata_list_el;
4324 /* The function frees list AUTOMATA_LIST. */
4326 free_automata_list (automata_list_el_t automata_list)
4328 automata_list_el_t curr_automata_list_el;
4329 automata_list_el_t next_automata_list_el;
4331 for (curr_automata_list_el = automata_list;
4332 curr_automata_list_el != NULL;
4333 curr_automata_list_el = next_automata_list_el)
4335 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4336 free_automata_list_el (curr_automata_list_el);
4340 /* Hash value of AUTOMATA_LIST. */
4342 automata_list_hash (const void *automata_list)
4344 unsigned int hash_value;
4345 automata_list_el_t curr_automata_list_el;
4348 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4349 curr_automata_list_el != NULL;
4350 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4351 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4352 | (hash_value << CHAR_BIT))
4353 + curr_automata_list_el->automaton->automaton_order_num);
4357 /* Return nonzero value if the automata_lists are the same. */
4359 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4361 automata_list_el_t automata_list_el_1;
4362 automata_list_el_t automata_list_el_2;
4364 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4365 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4366 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4367 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4368 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4369 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4371 return automata_list_el_1 == automata_list_el_2;
4374 /* Initialization of the abstract data. */
4376 initiate_automata_lists (void)
4378 first_free_automata_list_el = NULL;
4379 automata_list_table = htab_create (1500, automata_list_hash,
4380 automata_list_eq_p, (htab_del) 0);
4383 /* The following function starts new automata list and makes it the
4386 automata_list_start (void)
4388 current_automata_list = NULL;
4391 /* The following function adds AUTOMATON to the current list. */
4393 automata_list_add (automaton_t automaton)
4395 automata_list_el_t el;
4397 el = get_free_automata_list_el ();
4398 el->automaton = automaton;
4399 el->next_automata_list_el = current_automata_list;
4400 current_automata_list = el;
4403 /* The following function finishes forming the current list, inserts
4404 it into the table and returns it. */
4405 static automata_list_el_t
4406 automata_list_finish (void)
4410 if (current_automata_list == NULL)
4412 entry_ptr = htab_find_slot (automata_list_table,
4413 (void *) current_automata_list, 1);
4414 if (*entry_ptr == NULL)
4415 *entry_ptr = (void *) current_automata_list;
4417 free_automata_list (current_automata_list);
4418 current_automata_list = NULL;
4419 return (automata_list_el_t) *entry_ptr;
4422 /* Finishing work with the abstract data. */
4424 finish_automata_lists (void)
4426 htab_delete (automata_list_table);
4431 /* The page contains abstract data for work with exclusion sets (see
4432 exclusion_set in file rtl.def). */
4434 /* The following variable refers to an exclusion set returned by
4435 get_excl_set. This is bit string of length equal to cpu units
4436 number. If exclusion set for given unit contains 1 for a unit,
4437 then simultaneous reservation of the units is prohibited. */
4438 static reserv_sets_t excl_set;
4440 /* The array contains exclusion sets for each unit. */
4441 static reserv_sets_t *unit_excl_set_table;
4443 /* The following function forms the array containing exclusion sets
4446 initiate_excl_sets (void)
4449 reserv_sets_t unit_excl_set;
4453 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4454 excl_set = (reserv_sets_t) obstack_base (&irp);
4455 obstack_finish (&irp);
4456 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4457 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4458 obstack_finish (&irp);
4459 /* Evaluate unit exclusion sets. */
4460 for (i = 0; i < description->decls_num; i++)
4462 decl = description->decls [i];
4463 if (decl->mode == dm_unit)
4465 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4466 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4467 obstack_finish (&irp);
4468 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4469 for (el = DECL_UNIT (decl)->excl_list;
4471 el = el->next_unit_set_el)
4473 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4474 el->unit_decl->in_set_p = TRUE;
4476 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4481 /* The function sets up and return EXCL_SET which is union of
4482 exclusion sets for each unit in IN_SET. */
4483 static reserv_sets_t
4484 get_excl_set (reserv_sets_t in_set)
4492 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4493 memset (excl_set, 0, chars_num);
4494 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4495 if (((unsigned char *) in_set) [excl_char_num])
4496 for (i = CHAR_BIT - 1; i >= 0; i--)
4497 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4499 start_unit_num = excl_char_num * CHAR_BIT + i;
4500 if (start_unit_num >= description->units_num)
4502 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4505 |= unit_excl_set_table [start_unit_num] [unit_num];
4513 /* The page contains abstract data for work with presence/absence
4514 pattern sets (see presence_set/absence_set in file rtl.def). */
4516 /* The following arrays contain correspondingly presence, final
4517 presence, absence, and final absence patterns for each unit. */
4518 static pattern_reserv_t *unit_presence_set_table;
4519 static pattern_reserv_t *unit_final_presence_set_table;
4520 static pattern_reserv_t *unit_absence_set_table;
4521 static pattern_reserv_t *unit_final_absence_set_table;
4523 /* The following function forms list of reservation sets for given
4525 static pattern_reserv_t
4526 form_reserv_sets_list (pattern_set_el_t pattern_list)
4528 pattern_set_el_t el;
4529 pattern_reserv_t first, curr, prev;
4532 prev = first = NULL;
4533 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4535 curr = create_node (sizeof (struct pattern_reserv));
4536 curr->reserv = alloc_empty_reserv_sets ();
4537 curr->next_pattern_reserv = NULL;
4538 for (i = 0; i < el->units_num; i++)
4540 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4541 el->unit_decls [i]->in_set_p = TRUE;
4544 prev->next_pattern_reserv = curr;
4552 /* The following function forms the array containing presence and
4553 absence pattern sets for each unit. */
4555 initiate_presence_absence_pattern_sets (void)
4560 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4561 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4562 obstack_finish (&irp);
4563 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4564 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4565 obstack_finish (&irp);
4566 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4567 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4568 obstack_finish (&irp);
4569 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4570 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4571 obstack_finish (&irp);
4572 /* Evaluate unit presence/absence sets. */
4573 for (i = 0; i < description->decls_num; i++)
4575 decl = description->decls [i];
4576 if (decl->mode == dm_unit)
4578 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4579 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4580 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4581 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4582 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4583 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4584 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4585 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4590 /* The function checks that CHECKED_SET satisfies all presence pattern
4591 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4594 check_presence_pattern_sets (reserv_sets_t checked_set,
4595 reserv_sets_t origional_set,
4604 pattern_reserv_t pat_reserv;
4606 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4607 for (char_num = 0; char_num < chars_num; char_num++)
4608 if (((unsigned char *) origional_set) [char_num])
4609 for (i = CHAR_BIT - 1; i >= 0; i--)
4610 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4612 start_unit_num = char_num * CHAR_BIT + i;
4613 if (start_unit_num >= description->units_num)
4616 && unit_final_presence_set_table [start_unit_num] == NULL)
4618 && unit_presence_set_table [start_unit_num] == NULL))
4621 for (pat_reserv = (final_p
4622 ? unit_final_presence_set_table [start_unit_num]
4623 : unit_presence_set_table [start_unit_num]);
4625 pat_reserv = pat_reserv->next_pattern_reserv)
4627 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4628 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4629 != pat_reserv->reserv [unit_num])
4631 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4639 /* The function checks that CHECKED_SET satisfies all absence pattern
4640 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4643 check_absence_pattern_sets (reserv_sets_t checked_set,
4644 reserv_sets_t origional_set,
4652 pattern_reserv_t pat_reserv;
4654 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4655 for (char_num = 0; char_num < chars_num; char_num++)
4656 if (((unsigned char *) origional_set) [char_num])
4657 for (i = CHAR_BIT - 1; i >= 0; i--)
4658 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4660 start_unit_num = char_num * CHAR_BIT + i;
4661 if (start_unit_num >= description->units_num)
4663 for (pat_reserv = (final_p
4664 ? unit_final_absence_set_table [start_unit_num]
4665 : unit_absence_set_table [start_unit_num]);
4667 pat_reserv = pat_reserv->next_pattern_reserv)
4669 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4670 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4671 != pat_reserv->reserv [unit_num]
4672 && pat_reserv->reserv [unit_num])
4674 if (unit_num >= els_in_cycle_reserv)
4683 /* This page contains code for transformation of original reservations
4684 described in .md file. The main goal of transformations is
4685 simplifying reservation and lifting up all `|' on the top of IR
4686 reservation representation. */
4689 /* The following function makes copy of IR representation of
4690 reservation. The function also substitutes all reservations
4691 defined by define_reservation by corresponding value during making
4694 copy_insn_regexp (regexp_t regexp)
4699 switch (regexp->mode)
4702 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4706 result = copy_node (regexp, sizeof (struct regexp));
4710 result = copy_node (regexp, sizeof (struct regexp));
4711 REGEXP_REPEAT (result)->regexp
4712 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4716 result = copy_node (regexp,
4717 sizeof (struct regexp) + sizeof (regexp_t)
4718 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4719 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4720 REGEXP_SEQUENCE (result)->regexps [i]
4721 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4725 result = copy_node (regexp,
4726 sizeof (struct regexp) + sizeof (regexp_t)
4727 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4728 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4729 REGEXP_ALLOF (result)->regexps [i]
4730 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4734 result = copy_node (regexp,
4735 sizeof (struct regexp) + sizeof (regexp_t)
4736 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4737 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4738 REGEXP_ONEOF (result)->regexps [i]
4739 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4743 result = copy_node (regexp, sizeof (struct regexp));
4752 /* The following variable is set up 1 if a transformation has been
4754 static int regexp_transformed_p;
4756 /* The function makes transformation
4759 transform_1 (regexp_t regexp)
4766 if (regexp->mode == rm_repeat)
4768 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4769 gcc_assert (repeat_num > 1);
4770 operand = REGEXP_REPEAT (regexp)->regexp;
4772 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4773 * (repeat_num - 1));
4774 regexp->mode = rm_sequence;
4776 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4777 for (i = 0; i < repeat_num; i++)
4778 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4779 regexp_transformed_p = 1;
4784 /* The function makes transformations
4785 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4786 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4787 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4789 transform_2 (regexp_t regexp)
4791 if (regexp->mode == rm_sequence)
4793 regexp_t sequence = NULL;
4795 int sequence_index = 0;
4798 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4799 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4802 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4805 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4807 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4808 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4809 result = create_node (sizeof (struct regexp)
4811 * (REGEXP_SEQUENCE (regexp)->regexps_num
4812 + REGEXP_SEQUENCE (sequence)->regexps_num
4814 result->mode = rm_sequence;
4815 result->pos = regexp->pos;
4816 REGEXP_SEQUENCE (result)->regexps_num
4817 = (REGEXP_SEQUENCE (regexp)->regexps_num
4818 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4819 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4820 if (i < sequence_index)
4821 REGEXP_SEQUENCE (result)->regexps [i]
4822 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4823 else if (i > sequence_index)
4824 REGEXP_SEQUENCE (result)->regexps
4825 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4826 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4828 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4829 REGEXP_SEQUENCE (result)->regexps [i + j]
4830 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4831 regexp_transformed_p = 1;
4835 else if (regexp->mode == rm_allof)
4837 regexp_t allof = NULL;
4839 int allof_index = 0;
4842 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4843 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4846 allof = REGEXP_ALLOF (regexp)->regexps [i];
4849 if (i < REGEXP_ALLOF (regexp)->regexps_num)
4851 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4852 && REGEXP_ALLOF (regexp)->regexps_num > 1);
4853 result = create_node (sizeof (struct regexp)
4855 * (REGEXP_ALLOF (regexp)->regexps_num
4856 + REGEXP_ALLOF (allof)->regexps_num - 2));
4857 result->mode = rm_allof;
4858 result->pos = regexp->pos;
4859 REGEXP_ALLOF (result)->regexps_num
4860 = (REGEXP_ALLOF (regexp)->regexps_num
4861 + REGEXP_ALLOF (allof)->regexps_num - 1);
4862 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4863 if (i < allof_index)
4864 REGEXP_ALLOF (result)->regexps [i]
4865 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4866 else if (i > allof_index)
4867 REGEXP_ALLOF (result)->regexps
4868 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4869 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4871 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4872 REGEXP_ALLOF (result)->regexps [i + j]
4873 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4874 regexp_transformed_p = 1;
4878 else if (regexp->mode == rm_oneof)
4880 regexp_t oneof = NULL;
4882 int oneof_index = 0;
4885 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4886 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4889 oneof = REGEXP_ONEOF (regexp)->regexps [i];
4892 if (i < REGEXP_ONEOF (regexp)->regexps_num)
4894 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4895 && REGEXP_ONEOF (regexp)->regexps_num > 1);
4896 result = create_node (sizeof (struct regexp)
4898 * (REGEXP_ONEOF (regexp)->regexps_num
4899 + REGEXP_ONEOF (oneof)->regexps_num - 2));
4900 result->mode = rm_oneof;
4901 result->pos = regexp->pos;
4902 REGEXP_ONEOF (result)->regexps_num
4903 = (REGEXP_ONEOF (regexp)->regexps_num
4904 + REGEXP_ONEOF (oneof)->regexps_num - 1);
4905 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4906 if (i < oneof_index)
4907 REGEXP_ONEOF (result)->regexps [i]
4908 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4909 else if (i > oneof_index)
4910 REGEXP_ONEOF (result)->regexps
4911 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
4912 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4914 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
4915 REGEXP_ONEOF (result)->regexps [i + j]
4916 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
4917 regexp_transformed_p = 1;
4924 /* The function makes transformations
4925 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4926 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4927 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4928 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
4930 transform_3 (regexp_t regexp)
4932 if (regexp->mode == rm_sequence)
4934 regexp_t oneof = NULL;
4935 int oneof_index = 0;
4940 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4941 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
4944 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
4947 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4949 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4950 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4951 result = create_node (sizeof (struct regexp)
4953 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
4954 result->mode = rm_oneof;
4955 result->pos = regexp->pos;
4956 REGEXP_ONEOF (result)->regexps_num
4957 = REGEXP_ONEOF (oneof)->regexps_num;
4958 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
4961 = create_node (sizeof (struct regexp)
4963 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4964 sequence->mode = rm_sequence;
4965 sequence->pos = regexp->pos;
4966 REGEXP_SEQUENCE (sequence)->regexps_num
4967 = REGEXP_SEQUENCE (regexp)->regexps_num;
4968 REGEXP_ONEOF (result)->regexps [i] = sequence;
4969 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4970 if (j != oneof_index)
4971 REGEXP_SEQUENCE (sequence)->regexps [j]
4972 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
4974 REGEXP_SEQUENCE (sequence)->regexps [j]
4975 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
4977 regexp_transformed_p = 1;
4981 else if (regexp->mode == rm_allof)
4983 regexp_t oneof = NULL;
4985 int oneof_index = 0;
4986 int max_seq_length, allof_length;
4988 regexp_t allof = NULL;
4989 regexp_t allof_op = NULL;
4992 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4993 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
4996 oneof = REGEXP_ALLOF (regexp)->regexps [i];
4999 if (i < REGEXP_ALLOF (regexp)->regexps_num)
5001 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5002 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5003 result = create_node (sizeof (struct regexp)
5005 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5006 result->mode = rm_oneof;
5007 result->pos = regexp->pos;
5008 REGEXP_ONEOF (result)->regexps_num
5009 = REGEXP_ONEOF (oneof)->regexps_num;
5010 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5013 = create_node (sizeof (struct regexp)
5015 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5016 allof->mode = rm_allof;
5017 allof->pos = regexp->pos;
5018 REGEXP_ALLOF (allof)->regexps_num
5019 = REGEXP_ALLOF (regexp)->regexps_num;
5020 REGEXP_ONEOF (result)->regexps [i] = allof;
5021 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5022 if (j != oneof_index)
5023 REGEXP_ALLOF (allof)->regexps [j]
5024 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5026 REGEXP_ALLOF (allof)->regexps [j]
5027 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5029 regexp_transformed_p = 1;
5033 if (regexp->mode == rm_allof)
5034 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5036 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
5039 seq = REGEXP_ALLOF (regexp)->regexps [i];
5040 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5041 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5054 if (max_seq_length != 0)
5056 gcc_assert (max_seq_length != 1
5057 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5058 result = create_node (sizeof (struct regexp)
5059 + sizeof (regexp_t) * (max_seq_length - 1));
5060 result->mode = rm_sequence;
5061 result->pos = regexp->pos;
5062 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5063 for (i = 0; i < max_seq_length; i++)
5066 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5067 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
5070 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5071 ->regexps [j])->regexps_num))
5074 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5084 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5092 if (allof_length == 1)
5093 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5096 allof = create_node (sizeof (struct regexp)
5098 * (allof_length - 1));
5099 allof->mode = rm_allof;
5100 allof->pos = regexp->pos;
5101 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5102 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5104 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5105 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5107 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5108 ->regexps [j])->regexps_num)))
5110 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5113 REGEXP_ALLOF (allof)->regexps [allof_length]
5118 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5120 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5123 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5124 REGEXP_ALLOF (allof)->regexps [allof_length]
5130 regexp_transformed_p = 1;
5137 /* The function traverses IR of reservation and applies transformations
5138 implemented by FUNC. */
5140 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5144 switch (regexp->mode)
5147 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5148 REGEXP_SEQUENCE (regexp)->regexps [i]
5149 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
5154 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5155 REGEXP_ALLOF (regexp)->regexps [i]
5156 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5160 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5161 REGEXP_ONEOF (regexp)->regexps [i]
5162 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5166 REGEXP_REPEAT (regexp)->regexp
5167 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5177 return (*func) (regexp);
5180 /* The function applies all transformations for IR representation of
5181 reservation REGEXP. */
5183 transform_regexp (regexp_t regexp)
5185 regexp = regexp_transform_func (regexp, transform_1);
5188 regexp_transformed_p = 0;
5189 regexp = regexp_transform_func (regexp, transform_2);
5190 regexp = regexp_transform_func (regexp, transform_3);
5192 while (regexp_transformed_p);
5196 /* The function applies all transformations for reservations of all
5197 insn declarations. */
5199 transform_insn_regexps (void)
5204 transform_time = create_ticker ();
5205 add_advance_cycle_insn_decl ();
5207 fprintf (stderr, "Reservation transformation...");
5208 for (i = 0; i < description->decls_num; i++)
5210 decl = description->decls [i];
5211 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5212 DECL_INSN_RESERV (decl)->transformed_regexp
5213 = transform_regexp (copy_insn_regexp
5214 (DECL_INSN_RESERV (decl)->regexp));
5217 fprintf (stderr, "done\n");
5218 ticker_off (&transform_time);
5223 /* The following variable value is TRUE if the first annotated message
5224 about units to automata distribution has been output. */
5225 static int annotation_message_reported_p;
5227 /* The following structure describes usage of a unit in a reservation. */
5230 unit_decl_t unit_decl;
5231 /* The following forms a list of units used on the same cycle in the
5232 same alternative. */
5233 struct unit_usage *next;
5235 typedef struct unit_usage *unit_usage_t;
5237 DEF_VEC_P(unit_usage_t);
5238 DEF_VEC_ALLOC_P(unit_usage_t,heap);
5240 /* Obstack for unit_usage structures. */
5241 static struct obstack unit_usages;
5243 /* VLA for representation of array of pointers to unit usage
5244 structures. There is an element for each combination of
5245 (alternative number, cycle). Unit usages on given cycle in
5246 alternative with given number are referred through element with
5247 index equals to the cycle * number of all alternatives in the regexp
5248 + the alternative number. */
5249 static VEC(unit_usage_t,heap) *cycle_alt_unit_usages;
5251 /* The following function creates the structure unit_usage for UNIT on
5252 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5253 accessed through cycle_alt_unit_usages. */
5255 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5259 unit_decl_t unit_decl;
5260 unit_usage_t unit_usage_ptr;
5263 gcc_assert (regexp && regexp->mode == rm_oneof
5264 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
5265 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5267 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5268 while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length)
5269 VEC_safe_push (unit_usage_t,heap, cycle_alt_unit_usages, 0);
5271 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5272 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5273 obstack_finish (&unit_usages);
5274 unit_usage_ptr->unit_decl = unit_decl;
5275 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5276 unit_usage_ptr->next = VEC_index (unit_usage_t, cycle_alt_unit_usages, index);
5277 VEC_replace (unit_usage_t, cycle_alt_unit_usages, index, unit_usage_ptr);
5278 unit_decl->last_distribution_check_cycle = -1; /* undefined */
5281 /* The function processes given REGEXP to find units with the wrong
5284 check_regexp_units_distribution (const char *insn_reserv_name,
5288 regexp_t seq, allof, unit;
5289 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5291 if (regexp == NULL || regexp->mode != rm_oneof)
5293 /* Store all unit usages in the regexp: */
5294 obstack_init (&unit_usages);
5295 cycle_alt_unit_usages = 0;
5297 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5299 seq = REGEXP_ONEOF (regexp)->regexps [i];
5303 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5305 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5306 switch (allof->mode)
5309 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5311 unit = REGEXP_ALLOF (allof)->regexps [k];
5312 if (unit->mode == rm_unit)
5313 store_alt_unit_usage (regexp, unit, j, i);
5315 gcc_assert (unit->mode == rm_nothing);
5320 store_alt_unit_usage (regexp, allof, j, i);
5333 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5335 unit = REGEXP_ALLOF (seq)->regexps [k];
5339 store_alt_unit_usage (regexp, unit, 0, i);
5352 store_alt_unit_usage (regexp, seq, 0, i);
5362 /* Check distribution: */
5363 for (i = 0; i < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages); i++)
5365 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5366 for (unit_usage_ptr = VEC_index (unit_usage_t, cycle_alt_unit_usages, i);
5367 unit_usage_ptr != NULL;
5368 unit_usage_ptr = unit_usage_ptr->next)
5369 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5371 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5372 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5373 k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
5374 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5377 for (other_unit_usage_ptr
5378 = VEC_index (unit_usage_t, cycle_alt_unit_usages, k);
5379 other_unit_usage_ptr != NULL;
5380 other_unit_usage_ptr = other_unit_usage_ptr->next)
5381 if (unit_usage_ptr->unit_decl->automaton_decl
5382 == other_unit_usage_ptr->unit_decl->automaton_decl)
5384 if (other_unit_usage_ptr == NULL
5385 && (VEC_index (unit_usage_t, cycle_alt_unit_usages, k)
5389 if (k < (int) VEC_length (unit_usage_t, cycle_alt_unit_usages)
5390 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5392 if (!annotation_message_reported_p)
5394 fprintf (stderr, "\n");
5395 error ("The following units do not satisfy units-automata distribution rule");
5396 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5397 annotation_message_reported_p = TRUE;
5399 error ("Unit %s, reserv. %s, cycle %d",
5400 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5405 VEC_free (unit_usage_t,heap, cycle_alt_unit_usages);
5406 obstack_free (&unit_usages, NULL);
5409 /* The function finds units which violates units to automata
5410 distribution rule. If the units exist, report about them. */
5412 check_unit_distributions_to_automata (void)
5418 fprintf (stderr, "Check unit distributions to automata...");
5419 annotation_message_reported_p = FALSE;
5420 for (i = 0; i < description->decls_num; i++)
5422 decl = description->decls [i];
5423 if (decl->mode == dm_insn_reserv)
5424 check_regexp_units_distribution
5425 (DECL_INSN_RESERV (decl)->name,
5426 DECL_INSN_RESERV (decl)->transformed_regexp);
5429 fprintf (stderr, "done\n");
5434 /* The page contains code for building alt_states (see comments for
5435 IR) describing all possible insns reservations of an automaton. */
5437 /* Current state being formed for which the current alt_state
5439 static state_t state_being_formed;
5441 /* Current alt_state being formed. */
5442 static alt_state_t alt_state_being_formed;
5444 /* This recursive function processes `,' and units in reservation
5445 REGEXP for forming alt_states of AUTOMATON. It is believed that
5446 CURR_CYCLE is start cycle of all reservation REGEXP. */
5448 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5456 switch (regexp->mode)
5459 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5460 == automaton->automaton_order_num)
5461 set_state_reserv (state_being_formed, curr_cycle,
5462 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5466 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5468 = process_seq_for_forming_states
5469 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5474 int finish_cycle = 0;
5477 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5479 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5481 automaton, curr_cycle);
5482 if (finish_cycle < cycle)
5483 finish_cycle = cycle;
5485 return finish_cycle;
5496 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5497 inserts alt_state into the table. */
5499 finish_forming_alt_state (alt_state_t alt_state,
5500 automaton_t automaton ATTRIBUTE_UNUSED)
5502 state_t state_in_table;
5503 state_t corresponding_state;
5505 corresponding_state = alt_state->state;
5506 state_in_table = insert_state (corresponding_state);
5507 if (state_in_table != corresponding_state)
5509 free_state (corresponding_state);
5510 alt_state->state = state_in_table;
5514 /* The following variable value is current automaton insn for whose
5515 reservation the alt states are created. */
5516 static ainsn_t curr_ainsn;
5518 /* This recursive function processes `|' in reservation REGEXP for
5519 forming alt_states of AUTOMATON. List of the alt states should
5520 have the same order as in the description. */
5522 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5527 if (regexp->mode != rm_oneof)
5529 alt_state_being_formed = get_free_alt_state ();
5530 state_being_formed = get_free_state (1, automaton);
5531 alt_state_being_formed->state = state_being_formed;
5532 /* We inserts in reverse order but we process alternatives also
5533 in reverse order. So we have the same order of alternative
5534 as in the description. */
5535 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5536 curr_ainsn->alt_states = alt_state_being_formed;
5537 (void) process_seq_for_forming_states (regexp, automaton, 0);
5538 finish_forming_alt_state (alt_state_being_formed, automaton);
5542 gcc_assert (!inside_oneof_p);
5543 /* We processes it in reverse order to get list with the same
5544 order as in the description. See also the previous
5546 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5547 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5552 /* Create nodes alt_state for all AUTOMATON insns. */
5554 create_alt_states (automaton_t automaton)
5556 struct insn_reserv_decl *reserv_decl;
5558 for (curr_ainsn = automaton->ainsn_list;
5560 curr_ainsn = curr_ainsn->next_ainsn)
5562 reserv_decl = curr_ainsn->insn_reserv_decl;
5563 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5565 curr_ainsn->alt_states = NULL;
5566 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5568 curr_ainsn->sorted_alt_states
5569 = uniq_sort_alt_states (curr_ainsn->alt_states);
5576 /* The page contains major code for building DFA(s) for fast pipeline
5577 hazards recognition. */
5579 /* The function forms list of ainsns of AUTOMATON with the same
5583 form_ainsn_with_same_reservs (automaton_t automaton)
5587 VEC(ainsn_t,heap) *last_insns = VEC_alloc (ainsn_t,heap, 150);
5589 for (curr_ainsn = automaton->ainsn_list;
5591 curr_ainsn = curr_ainsn->next_ainsn)
5592 if (curr_ainsn->insn_reserv_decl
5593 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5595 curr_ainsn->next_same_reservs_insn = NULL;
5596 curr_ainsn->first_insn_with_same_reservs = 1;
5600 for (i = 0; i < VEC_length (ainsn_t, last_insns); i++)
5602 (curr_ainsn->sorted_alt_states,
5603 VEC_index (ainsn_t, last_insns, i)->sorted_alt_states))
5605 curr_ainsn->next_same_reservs_insn = NULL;
5606 if (i < VEC_length (ainsn_t, last_insns))
5608 curr_ainsn->first_insn_with_same_reservs = 0;
5609 VEC_index (ainsn_t, last_insns, i)->next_same_reservs_insn
5611 VEC_replace (ainsn_t, last_insns, i, curr_ainsn);
5615 VEC_safe_push (ainsn_t, heap, last_insns, curr_ainsn);
5616 curr_ainsn->first_insn_with_same_reservs = 1;
5619 VEC_free (ainsn_t,heap, last_insns);
5622 /* Forming unit reservations which can affect creating the automaton
5623 states achieved from a given state. It permits to build smaller
5624 automata in many cases. We would have the same automata after
5625 the minimization without such optimization, but the automaton
5626 right after the building could be huge. So in other words, usage
5627 of reservs_matter means some minimization during building the
5629 static reserv_sets_t
5630 form_reservs_matter (automaton_t automaton)
5633 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5635 for (cycle = 0; cycle < max_cycles_num; cycle++)
5636 for (unit = 0; unit < description->units_num; unit++)
5637 if (units_array [unit]->automaton_decl
5638 == automaton->corresponding_automaton_decl
5639 && (cycle >= units_array [unit]->min_occ_cycle_num
5640 /* We can not remove queried unit from reservations. */
5641 || units_array [unit]->query_p
5642 /* We can not remove units which are used
5643 `exclusion_set', `presence_set',
5644 `final_presence_set', `absence_set', and
5645 `final_absence_set'. */
5646 || units_array [unit]->in_set_p))
5647 set_unit_reserv (reservs_matter, cycle, unit);
5648 return reservs_matter;
5651 /* The following function creates all states of nondeterministic AUTOMATON. */
5653 make_automaton (automaton_t automaton)
5656 struct insn_reserv_decl *insn_reserv_decl;
5657 alt_state_t alt_state;
5659 state_t start_state;
5661 ainsn_t advance_cycle_ainsn;
5663 VEC(state_t,heap) *state_stack = VEC_alloc(state_t,heap, 150);
5665 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5667 /* Create the start state (empty state). */
5668 start_state = insert_state (get_free_state (1, automaton));
5669 automaton->start_state = start_state;
5670 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5671 VEC_safe_push (state_t,heap, state_stack, start_state);
5673 while (VEC_length (state_t, state_stack) != 0)
5675 state = VEC_pop (state_t, state_stack);
5676 advance_cycle_ainsn = NULL;
5677 for (ainsn = automaton->ainsn_list;
5679 ainsn = ainsn->next_ainsn)
5680 if (ainsn->first_insn_with_same_reservs)
5682 insn_reserv_decl = ainsn->insn_reserv_decl;
5683 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5685 /* We process alt_states in the same order as they are
5686 present in the description. */
5688 for (alt_state = ainsn->alt_states;
5690 alt_state = alt_state->next_alt_state)
5692 state2 = alt_state->state;
5693 if (!intersected_state_reservs_p (state, state2))
5695 state2 = states_union (state, state2, reservs_matter);
5696 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5698 state2->it_was_placed_in_stack_for_NDFA_forming
5700 VEC_safe_push (state_t,heap, state_stack, state2);
5702 if (progress_flag && states_n % 100 == 0)
5703 fprintf (stderr, ".");
5705 added_arc = add_arc (state, state2, ainsn, 1);
5710 if (!ndfa_flag && added_arc != NULL)
5712 added_arc->state_alts = 0;
5713 for (alt_state = ainsn->alt_states;
5715 alt_state = alt_state->next_alt_state)
5717 state2 = alt_state->state;
5718 if (!intersected_state_reservs_p (state, state2))
5719 added_arc->state_alts++;
5724 advance_cycle_ainsn = ainsn;
5726 /* Add transition to advance cycle. */
5727 state2 = state_shift (state, reservs_matter);
5728 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5730 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5731 VEC_safe_push (state_t,heap, state_stack, state2);
5733 if (progress_flag && states_n % 100 == 0)
5734 fprintf (stderr, ".");
5736 gcc_assert (advance_cycle_ainsn);
5737 add_arc (state, state2, advance_cycle_ainsn, 1);
5739 VEC_free (state_t,heap, state_stack);
5742 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5744 form_arcs_marked_by_insn (state_t state)
5750 for (i = 0; i < description->decls_num; i++)
5752 decl = description->decls [i];
5753 if (decl->mode == dm_insn_reserv)
5754 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5756 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5758 gcc_assert (arc->insn);
5759 arc->next_arc_marked_by_insn
5760 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5761 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5765 /* The function creates composed state (see comments for IR) from
5766 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5767 same insn. If the composed state is not in STATE_STACK yet, it is
5768 pushed into STATE_STACK. */
5771 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5772 VEC(state_t,heap) **state_stack)
5775 alt_state_t alt_state, curr_alt_state;
5776 alt_state_t new_alt_state;
5779 state_t state_in_table;
5781 alt_state_t canonical_alt_states_list;
5783 int new_state_p = 0;
5785 if (arcs_marked_by_insn == NULL)
5787 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5788 state = arcs_marked_by_insn->to_state;
5791 gcc_assert (ndfa_flag);
5792 /* Create composed state. */
5793 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5794 curr_alt_state = NULL;
5795 for (curr_arc = arcs_marked_by_insn;
5797 curr_arc = curr_arc->next_arc_marked_by_insn)
5798 if (curr_arc->to_state->component_states == NULL)
5800 new_alt_state = get_free_alt_state ();
5801 new_alt_state->next_alt_state = curr_alt_state;
5802 new_alt_state->state = curr_arc->to_state;
5803 curr_alt_state = new_alt_state;
5806 for (alt_state = curr_arc->to_state->component_states;
5808 alt_state = alt_state->next_sorted_alt_state)
5810 new_alt_state = get_free_alt_state ();
5811 new_alt_state->next_alt_state = curr_alt_state;
5812 new_alt_state->state = alt_state->state;
5813 gcc_assert (!alt_state->state->component_states);
5814 curr_alt_state = new_alt_state;
5816 /* There are not identical sets in the alt state list. */
5817 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5818 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5821 state = canonical_alt_states_list->state;
5822 free_state (temp_state);
5826 state->component_states = canonical_alt_states_list;
5827 state_in_table = insert_state (state);
5828 if (state_in_table != state)
5831 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5833 state = state_in_table;
5837 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5839 for (curr_alt_state = state->component_states;
5840 curr_alt_state != NULL;
5841 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5842 for (curr_arc = first_out_arc (curr_alt_state->state);
5844 curr_arc = next_out_arc (curr_arc))
5845 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5847 arcs_marked_by_insn->to_state = state;
5848 for (alts_number = 0,
5849 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5851 curr_arc = next_arc)
5853 next_arc = curr_arc->next_arc_marked_by_insn;
5854 remove_arc (original_state, curr_arc);
5857 arcs_marked_by_insn->state_alts = alts_number;
5860 if (!state->it_was_placed_in_stack_for_DFA_forming)
5862 state->it_was_placed_in_stack_for_DFA_forming = 1;
5863 VEC_safe_push (state_t,heap, *state_stack, state);
5868 /* The function transforms nondeterministic AUTOMATON into
5872 NDFA_to_DFA (automaton_t automaton)
5874 state_t start_state;
5877 VEC(state_t,heap) *state_stack;
5881 state_stack = VEC_alloc (state_t,heap, 0);
5883 /* Create the start state (empty state). */
5884 start_state = automaton->start_state;
5885 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5886 VEC_safe_push (state_t,heap, state_stack, start_state);
5888 while (VEC_length (state_t, state_stack) != 0)
5890 state = VEC_pop (state_t, state_stack);
5891 form_arcs_marked_by_insn (state);
5892 for (i = 0; i < description->decls_num; i++)
5894 decl = description->decls [i];
5895 if (decl->mode == dm_insn_reserv
5896 && create_composed_state
5897 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5901 if (progress_flag && states_n % 100 == 0)
5902 fprintf (stderr, ".");
5906 VEC_free (state_t,heap, state_stack);
5909 /* The following variable value is current number (1, 2, ...) of passing
5911 static int curr_state_graph_pass_num;
5913 /* This recursive function passes all states achieved from START_STATE
5914 and applies APPLIED_FUNC to them. */
5916 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
5920 if (start_state->pass_num == curr_state_graph_pass_num)
5922 start_state->pass_num = curr_state_graph_pass_num;
5923 (*applied_func) (start_state);
5924 for (arc = first_out_arc (start_state);
5926 arc = next_out_arc (arc))
5927 pass_state_graph (arc->to_state, applied_func);
5930 /* This recursive function passes all states of AUTOMATON and applies
5931 APPLIED_FUNC to them. */
5933 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
5935 curr_state_graph_pass_num++;
5936 pass_state_graph (automaton->start_state, applied_func);
5939 /* The function initializes code for passing of all states. */
5941 initiate_pass_states (void)
5943 curr_state_graph_pass_num = 0;
5946 /* The following vla is used for storing pointers to all achieved
5948 static VEC(state_t,heap) *all_achieved_states;
5950 /* This function is called by function pass_states to add an achieved
5953 add_achieved_state (state_t state)
5955 VEC_safe_push (state_t,heap, all_achieved_states, state);
5958 /* The function sets up equivalence numbers of insns which mark all
5959 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5960 nonzero value) or by equiv_class_num_2 of the destination state.
5961 The function returns number of out arcs of STATE. */
5963 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
5965 int state_out_arcs_num;
5968 state_out_arcs_num = 0;
5969 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5971 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
5972 && !arc->insn->insn_reserv_decl->state_alts);
5973 state_out_arcs_num++;
5974 arc->insn->insn_reserv_decl->equiv_class_num
5975 = (odd_iteration_flag
5976 ? arc->to_state->equiv_class_num_1
5977 : arc->to_state->equiv_class_num_2);
5978 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5979 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
5980 && arc->insn->insn_reserv_decl->state_alts > 0);
5982 return state_out_arcs_num;
5985 /* The function clears equivalence numbers and alt_states in all insns
5986 which mark all out arcs of STATE. */
5988 clear_arc_insns_equiv_num (state_t state)
5992 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5994 arc->insn->insn_reserv_decl->equiv_class_num = 0;
5995 arc->insn->insn_reserv_decl->state_alts = 0;
6000 /* The following function returns TRUE if STATE reserves the unit with
6001 UNIT_NUM on the first cycle. */
6003 first_cycle_unit_presence (state_t state, int unit_num)
6005 alt_state_t alt_state;
6007 if (state->component_states == NULL)
6008 return test_unit_reserv (state->reservs, 0, unit_num);
6011 for (alt_state = state->component_states;
6013 alt_state = alt_state->next_sorted_alt_state)
6014 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
6020 /* The function returns nonzero value if STATE is not equivalent to
6021 ANOTHER_STATE from the same current partition on equivalence
6022 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6023 output arcs. Iteration of making equivalence partition is defined
6024 by ODD_ITERATION_FLAG. */
6026 state_is_differed (state_t state, state_t another_state,
6027 int another_state_out_arcs_num, int odd_iteration_flag)
6030 int state_out_arcs_num;
6031 int i, presence1_p, presence2_p;
6033 state_out_arcs_num = 0;
6034 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6036 state_out_arcs_num++;
6037 if ((odd_iteration_flag
6038 ? arc->to_state->equiv_class_num_1
6039 : arc->to_state->equiv_class_num_2)
6040 != arc->insn->insn_reserv_decl->equiv_class_num
6041 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6044 if (state_out_arcs_num != another_state_out_arcs_num)
6046 /* Now we are looking at the states with the point of view of query
6048 for (i = 0; i < description->units_num; i++)
6049 if (units_array [i]->query_p)
6051 presence1_p = first_cycle_unit_presence (state, i);
6052 presence2_p = first_cycle_unit_presence (another_state, i);
6053 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6059 /* The function makes initial partition of STATES on equivalent
6062 init_equiv_class (VEC(state_t,heap) *states)
6067 for (i = 0; i < VEC_length (state_t, states); i++)
6069 VEC_index (state_t, states, i)->equiv_class_num_1 = 1;
6070 VEC_index (state_t, states, i)->next_equiv_class_state = prev;
6071 prev = VEC_index (state_t, states, i);
6076 /* The function copies pointers to equivalent states from vla FROM
6079 copy_equiv_class (VEC(state_t,heap) **to, VEC(state_t,heap) *from)
6081 VEC_free (state_t,heap, *to);
6082 *to = VEC_copy (state_t,heap, from);
6084 /* The function processes equivalence class given by its first state,
6085 FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
6086 are not equivalent states, the function partitions the class
6087 removing nonequivalent states and placing them in
6088 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6089 assigns it to the state equivalence number. If the class has been
6090 partitioned, the function returns nonzero value. */
6092 partition_equiv_class (state_t first_state, int odd_iteration_flag,
6093 VEC(state_t,heap) **next_iteration_classes,
6094 int *new_equiv_class_num_ptr)
6096 state_t new_equiv_class;
6105 while (first_state != NULL)
6107 new_equiv_class = NULL;
6108 if (first_state->next_equiv_class_state != NULL)
6110 /* There are more one states in the class equivalence. */
6111 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6112 odd_iteration_flag);
6113 for (prev_state = first_state,
6114 curr_state = first_state->next_equiv_class_state;
6116 curr_state = next_state)
6118 next_state = curr_state->next_equiv_class_state;
6119 if (state_is_differed (curr_state, first_state, out_arcs_num,
6120 odd_iteration_flag))
6122 /* Remove curr state from the class equivalence. */
6123 prev_state->next_equiv_class_state = next_state;
6124 /* Add curr state to the new class equivalence. */
6125 curr_state->next_equiv_class_state = new_equiv_class;
6126 if (new_equiv_class == NULL)
6127 (*new_equiv_class_num_ptr)++;
6128 if (odd_iteration_flag)
6129 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6131 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6132 new_equiv_class = curr_state;
6136 prev_state = curr_state;
6138 clear_arc_insns_equiv_num (first_state);
6140 if (new_equiv_class != NULL)
6141 VEC_safe_push (state_t,heap, *next_iteration_classes, new_equiv_class);
6142 first_state = new_equiv_class;
6147 /* The function finds equivalent states of AUTOMATON. */
6149 evaluate_equiv_classes (automaton_t automaton,
6150 VEC(state_t,heap) **equiv_classes)
6152 state_t new_equiv_class;
6153 int new_equiv_class_num;
6154 int odd_iteration_flag;
6156 VEC (state_t,heap) *next_iteration_classes;
6159 all_achieved_states = VEC_alloc (state_t,heap, 1500);
6160 pass_states (automaton, add_achieved_state);
6161 new_equiv_class = init_equiv_class (all_achieved_states);
6162 odd_iteration_flag = 0;
6163 new_equiv_class_num = 1;
6165 next_iteration_classes = VEC_alloc (state_t,heap, 150);
6166 VEC_quick_push (state_t, next_iteration_classes, new_equiv_class);
6170 odd_iteration_flag = !odd_iteration_flag;
6172 copy_equiv_class (equiv_classes, next_iteration_classes);
6174 /* Transfer equiv numbers for the next iteration. */
6175 for (i = 0; i < VEC_length (state_t, all_achieved_states); i++)
6176 if (odd_iteration_flag)
6177 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2
6178 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1;
6180 VEC_index (state_t, all_achieved_states, i)->equiv_class_num_1
6181 = VEC_index (state_t, all_achieved_states, i)->equiv_class_num_2;
6183 for (i = 0; i < VEC_length (state_t, *equiv_classes); i++)
6184 if (partition_equiv_class (VEC_index (state_t, *equiv_classes, i),
6186 &next_iteration_classes,
6187 &new_equiv_class_num))
6190 while (!finish_flag);
6191 VEC_free (state_t,heap, next_iteration_classes);
6192 VEC_free (state_t,heap, all_achieved_states);
6195 /* The function merges equivalent states of AUTOMATON. */
6197 merge_states (automaton_t automaton, VEC(state_t,heap) *equiv_classes)
6201 state_t first_class_state;
6202 alt_state_t alt_states;
6203 alt_state_t alt_state, new_alt_state;
6208 /* Create states corresponding to equivalence classes containing two
6210 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
6212 curr_state = VEC_index (state_t, equiv_classes, i);
6213 if (curr_state->next_equiv_class_state != NULL)
6215 /* There are more one states in the class equivalence. */
6216 /* Create new compound state. */
6217 new_state = get_free_state (0, automaton);
6219 first_class_state = curr_state;
6220 for (curr_state = first_class_state;
6222 curr_state = curr_state->next_equiv_class_state)
6224 curr_state->equiv_class_state = new_state;
6225 if (curr_state->component_states == NULL)
6227 new_alt_state = get_free_alt_state ();
6228 new_alt_state->state = curr_state;
6229 new_alt_state->next_alt_state = alt_states;
6230 alt_states = new_alt_state;
6233 for (alt_state = curr_state->component_states;
6235 alt_state = alt_state->next_sorted_alt_state)
6237 new_alt_state = get_free_alt_state ();
6238 new_alt_state->state = alt_state->state;
6239 new_alt_state->next_alt_state = alt_states;
6240 alt_states = new_alt_state;
6243 /* Its is important that alt states were sorted before and
6244 after merging to have the same querying results. */
6245 new_state->component_states = uniq_sort_alt_states (alt_states);
6248 curr_state->equiv_class_state = curr_state;
6251 for (i = 0; i < VEC_length (state_t, equiv_classes); i++)
6253 curr_state = VEC_index (state_t, equiv_classes, i);
6254 if (curr_state->next_equiv_class_state != NULL)
6256 first_class_state = curr_state;
6257 /* Create new arcs output from the state corresponding to
6259 for (curr_arc = first_out_arc (first_class_state);
6261 curr_arc = next_out_arc (curr_arc))
6262 add_arc (first_class_state->equiv_class_state,
6263 curr_arc->to_state->equiv_class_state,
6264 curr_arc->insn, curr_arc->state_alts);
6265 /* Delete output arcs from states of given class equivalence. */
6266 for (curr_state = first_class_state;
6268 curr_state = curr_state->next_equiv_class_state)
6270 if (automaton->start_state == curr_state)
6271 automaton->start_state = curr_state->equiv_class_state;
6272 /* Delete the state and its output arcs. */
6273 for (curr_arc = first_out_arc (curr_state);
6275 curr_arc = next_arc)
6277 next_arc = next_out_arc (curr_arc);
6278 free_arc (curr_arc);
6284 /* Change `to_state' of arcs output from the state of given
6285 equivalence class. */
6286 for (curr_arc = first_out_arc (curr_state);
6288 curr_arc = next_out_arc (curr_arc))
6289 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6294 /* The function sets up new_cycle_p for states if there is arc to the
6295 state marked by advance_cycle_insn_decl. */
6297 set_new_cycle_flags (state_t state)
6301 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6302 if (arc->insn->insn_reserv_decl
6303 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6304 arc->to_state->new_cycle_p = 1;
6307 /* The top level function for minimization of deterministic
6310 minimize_DFA (automaton_t automaton)
6312 VEC(state_t,heap) *equiv_classes = 0;
6314 evaluate_equiv_classes (automaton, &equiv_classes);
6315 merge_states (automaton, equiv_classes);
6316 pass_states (automaton, set_new_cycle_flags);
6318 VEC_free (state_t,heap, equiv_classes);
6321 /* Values of two variables are counted number of states and arcs in an
6323 static int curr_counted_states_num;
6324 static int curr_counted_arcs_num;
6326 /* The function is called by function `pass_states' to count states
6327 and arcs of an automaton. */
6329 incr_states_and_arcs_nums (state_t state)
6333 curr_counted_states_num++;
6334 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6335 curr_counted_arcs_num++;
6338 /* The function counts states and arcs of AUTOMATON. */
6340 count_states_and_arcs (automaton_t automaton, int *states_num,
6343 curr_counted_states_num = 0;
6344 curr_counted_arcs_num = 0;
6345 pass_states (automaton, incr_states_and_arcs_nums);
6346 *states_num = curr_counted_states_num;
6347 *arcs_num = curr_counted_arcs_num;
6350 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6351 recognition after checking and simplifying IR of the
6354 build_automaton (automaton_t automaton)
6359 ticker_on (&NDFA_time);
6362 if (automaton->corresponding_automaton_decl == NULL)
6363 fprintf (stderr, "Create anonymous automaton");
6365 fprintf (stderr, "Create automaton `%s'",
6366 automaton->corresponding_automaton_decl->name);
6367 fprintf (stderr, " (1 dot is 100 new states):");
6369 make_automaton (automaton);
6371 fprintf (stderr, " done\n");
6372 ticker_off (&NDFA_time);
6373 count_states_and_arcs (automaton, &states_num, &arcs_num);
6374 automaton->NDFA_states_num = states_num;
6375 automaton->NDFA_arcs_num = arcs_num;
6376 ticker_on (&NDFA_to_DFA_time);
6379 if (automaton->corresponding_automaton_decl == NULL)
6380 fprintf (stderr, "Make anonymous DFA");
6382 fprintf (stderr, "Make DFA `%s'",
6383 automaton->corresponding_automaton_decl->name);
6384 fprintf (stderr, " (1 dot is 100 new states):");
6386 NDFA_to_DFA (automaton);
6388 fprintf (stderr, " done\n");
6389 ticker_off (&NDFA_to_DFA_time);
6390 count_states_and_arcs (automaton, &states_num, &arcs_num);
6391 automaton->DFA_states_num = states_num;
6392 automaton->DFA_arcs_num = arcs_num;
6393 if (!no_minimization_flag)
6395 ticker_on (&minimize_time);
6398 if (automaton->corresponding_automaton_decl == NULL)
6399 fprintf (stderr, "Minimize anonymous DFA...");
6401 fprintf (stderr, "Minimize DFA `%s'...",
6402 automaton->corresponding_automaton_decl->name);
6404 minimize_DFA (automaton);
6406 fprintf (stderr, "done\n");
6407 ticker_off (&minimize_time);
6408 count_states_and_arcs (automaton, &states_num, &arcs_num);
6409 automaton->minimal_DFA_states_num = states_num;
6410 automaton->minimal_DFA_arcs_num = arcs_num;
6416 /* The page contains code for enumeration of all states of an automaton. */
6418 /* Variable used for enumeration of all states of an automaton. Its
6419 value is current number of automaton states. */
6420 static int curr_state_order_num;
6422 /* The function is called by function `pass_states' for enumerating
6425 set_order_state_num (state_t state)
6427 state->order_state_num = curr_state_order_num;
6428 curr_state_order_num++;
6431 /* The function enumerates all states of AUTOMATON. */
6433 enumerate_states (automaton_t automaton)
6435 curr_state_order_num = 0;
6436 pass_states (automaton, set_order_state_num);
6437 automaton->achieved_states_num = curr_state_order_num;
6442 /* The page contains code for finding equivalent automaton insns
6445 /* The function inserts AINSN into cyclic list
6446 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6448 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6449 ainsn_t cyclic_equiv_class_insn_list)
6451 if (cyclic_equiv_class_insn_list == NULL)
6452 ainsn->next_equiv_class_insn = ainsn;
6455 ainsn->next_equiv_class_insn
6456 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6457 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6462 /* The function deletes equiv_class_insn into cyclic list of
6463 equivalent ainsns. */
6465 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6467 ainsn_t curr_equiv_class_insn;
6468 ainsn_t prev_equiv_class_insn;
6470 prev_equiv_class_insn = equiv_class_insn;
6471 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6472 curr_equiv_class_insn != equiv_class_insn;
6473 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6474 prev_equiv_class_insn = curr_equiv_class_insn;
6475 if (prev_equiv_class_insn != equiv_class_insn)
6476 prev_equiv_class_insn->next_equiv_class_insn
6477 = equiv_class_insn->next_equiv_class_insn;
6480 /* The function processes AINSN of a state in order to find equivalent
6481 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6484 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6488 ainsn_t cyclic_insn_list;
6491 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6493 /* New class of ainsns which are not equivalent to given ainsn. */
6494 cyclic_insn_list = NULL;
6497 next_insn = curr_insn->next_equiv_class_insn;
6498 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6500 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6503 delete_ainsn_from_equiv_class (curr_insn);
6504 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6507 curr_insn = next_insn;
6509 while (curr_insn != ainsn);
6512 /* The function processes STATE in order to find equivalent ainsns. */
6514 process_state_for_insn_equiv_partition (state_t state)
6517 arc_t *insn_arcs_array = xmalloc (description->insns_num * sizeof(arc_t));
6519 /* Process insns of the arcs. */
6520 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6521 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6522 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6523 process_insn_equiv_class (arc->insn, insn_arcs_array);
6525 free (insn_arcs_array);
6528 /* The function searches for equivalent ainsns of AUTOMATON. */
6530 set_insn_equiv_classes (automaton_t automaton)
6535 ainsn_t cyclic_insn_list;
6536 ainsn_t insn_with_same_reservs;
6537 int equiv_classes_num;
6539 /* All insns are included in one equivalence class. */
6540 cyclic_insn_list = NULL;
6541 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6542 if (ainsn->first_insn_with_same_reservs)
6543 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6545 /* Process insns in order to make equivalence partition. */
6546 pass_states (automaton, process_state_for_insn_equiv_partition);
6547 /* Enumerate equiv classes. */
6548 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6549 /* Set undefined value. */
6550 ainsn->insn_equiv_class_num = -1;
6551 equiv_classes_num = 0;
6552 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6553 if (ainsn->insn_equiv_class_num < 0)
6556 gcc_assert (first_insn->first_insn_with_same_reservs);
6557 first_insn->first_ainsn_with_given_equivalence_num = 1;
6558 curr_insn = first_insn;
6561 for (insn_with_same_reservs = curr_insn;
6562 insn_with_same_reservs != NULL;
6563 insn_with_same_reservs
6564 = insn_with_same_reservs->next_same_reservs_insn)
6565 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6566 curr_insn = curr_insn->next_equiv_class_insn;
6568 while (curr_insn != first_insn);
6569 equiv_classes_num++;
6571 automaton->insn_equiv_classes_num = equiv_classes_num;
6576 /* This page contains code for creating DFA(s) and calls functions
6580 /* The following value is used to prevent floating point overflow for
6581 estimating an automaton bound. The value should be less DBL_MAX on
6582 the host machine. We use here approximate minimum of maximal
6583 double floating point value required by ANSI C standard. It
6584 will work for non ANSI sun compiler too. */
6586 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6588 /* The function estimate size of the single DFA used by PHR (pipeline
6589 hazards recognizer). */
6591 estimate_one_automaton_bound (void)
6594 double one_automaton_estimation_bound;
6598 one_automaton_estimation_bound = 1.0;
6599 for (i = 0; i < description->decls_num; i++)
6601 decl = description->decls [i];
6602 if (decl->mode == dm_unit)
6604 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6605 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6607 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6608 > one_automaton_estimation_bound)
6609 one_automaton_estimation_bound *= root_value;
6612 return one_automaton_estimation_bound;
6615 /* The function compares unit declarations according to their maximal
6616 cycle in reservations. */
6618 compare_max_occ_cycle_nums (const void *unit_decl_1,
6619 const void *unit_decl_2)
6621 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6622 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6624 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6625 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6631 /* The function makes heuristic assigning automata to units. Actually
6632 efficacy of the algorithm has been checked yet??? */
6635 units_to_automata_heuristic_distr (void)
6637 double estimation_bound;
6641 unit_decl_t *unit_decls;
6644 if (description->units_num == 0)
6646 estimation_bound = estimate_one_automaton_bound ();
6647 unit_decls = xmalloc (description->units_num * sizeof (unit_decl_t));
6649 for (i = 0, j = 0; i < description->decls_num; i++)
6650 if (description->decls[i]->mode == dm_unit)
6651 unit_decls[j++] = DECL_UNIT (description->decls[i]);
6652 gcc_assert (j == description->units_num);
6654 qsort (unit_decls, description->units_num,
6655 sizeof (unit_decl_t), compare_max_occ_cycle_nums);
6658 bound_value = unit_decls[0]->max_occ_cycle_num;
6659 unit_decls[0]->corresponding_automaton_num = automaton_num;
6661 for (i = 1; i < description->units_num; i++)
6663 rest_units_num = description->units_num - i + 1;
6664 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6665 if (automaton_num < automata_num - 1
6666 && ((automata_num - automaton_num - 1 == rest_units_num)
6669 / unit_decls[i]->max_occ_cycle_num))))
6671 bound_value = unit_decls[i]->max_occ_cycle_num;
6675 bound_value *= unit_decls[i]->max_occ_cycle_num;
6676 unit_decls[i]->corresponding_automaton_num = automaton_num;
6678 gcc_assert (automaton_num == automata_num - 1);
6682 /* The functions creates automaton insns for each automata. Automaton
6683 insn is simply insn for given automaton which makes reservation
6684 only of units of the automaton. */
6686 create_ainsns (void)
6689 ainsn_t first_ainsn;
6696 for (i = 0; i < description->decls_num; i++)
6698 decl = description->decls [i];
6699 if (decl->mode == dm_insn_reserv)
6701 curr_ainsn = create_node (sizeof (struct ainsn));
6702 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6703 curr_ainsn->important_p = FALSE;
6704 curr_ainsn->next_ainsn = NULL;
6705 if (prev_ainsn == NULL)
6706 first_ainsn = curr_ainsn;
6708 prev_ainsn->next_ainsn = curr_ainsn;
6709 prev_ainsn = curr_ainsn;
6715 /* The function assigns automata to units according to constructions
6716 `define_automaton' in the description. */
6718 units_to_automata_distr (void)
6723 for (i = 0; i < description->decls_num; i++)
6725 decl = description->decls [i];
6726 if (decl->mode == dm_unit)
6728 if (DECL_UNIT (decl)->automaton_decl == NULL
6729 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6731 /* Distribute to the first automaton. */
6732 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6734 DECL_UNIT (decl)->corresponding_automaton_num
6735 = (DECL_UNIT (decl)->automaton_decl
6736 ->corresponding_automaton->automaton_order_num);
6741 /* The function creates DFA(s) for fast pipeline hazards recognition
6742 after checking and simplifying IR of the description. */
6744 create_automata (void)
6746 automaton_t curr_automaton;
6747 automaton_t prev_automaton;
6749 int curr_automaton_num;
6752 if (automata_num != 0)
6754 units_to_automata_heuristic_distr ();
6755 for (prev_automaton = NULL, curr_automaton_num = 0;
6756 curr_automaton_num < automata_num;
6757 curr_automaton_num++, prev_automaton = curr_automaton)
6759 curr_automaton = create_node (sizeof (struct automaton));
6760 curr_automaton->ainsn_list = create_ainsns ();
6761 curr_automaton->corresponding_automaton_decl = NULL;
6762 curr_automaton->next_automaton = NULL;
6763 curr_automaton->automaton_order_num = curr_automaton_num;
6764 if (prev_automaton == NULL)
6765 description->first_automaton = curr_automaton;
6767 prev_automaton->next_automaton = curr_automaton;
6772 curr_automaton_num = 0;
6773 prev_automaton = NULL;
6774 for (i = 0; i < description->decls_num; i++)
6776 decl = description->decls [i];
6777 if (decl->mode == dm_automaton
6778 && DECL_AUTOMATON (decl)->automaton_is_used)
6780 curr_automaton = create_node (sizeof (struct automaton));
6781 curr_automaton->ainsn_list = create_ainsns ();
6782 curr_automaton->corresponding_automaton_decl
6783 = DECL_AUTOMATON (decl);
6784 curr_automaton->next_automaton = NULL;
6785 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6786 curr_automaton->automaton_order_num = curr_automaton_num;
6787 if (prev_automaton == NULL)
6788 description->first_automaton = curr_automaton;
6790 prev_automaton->next_automaton = curr_automaton;
6791 curr_automaton_num++;
6792 prev_automaton = curr_automaton;
6795 if (curr_automaton_num == 0)
6797 curr_automaton = create_node (sizeof (struct automaton));
6798 curr_automaton->ainsn_list = create_ainsns ();
6799 curr_automaton->corresponding_automaton_decl = NULL;
6800 curr_automaton->next_automaton = NULL;
6801 description->first_automaton = curr_automaton;
6803 units_to_automata_distr ();
6805 NDFA_time = create_ticker ();
6806 ticker_off (&NDFA_time);
6807 NDFA_to_DFA_time = create_ticker ();
6808 ticker_off (&NDFA_to_DFA_time);
6809 minimize_time = create_ticker ();
6810 ticker_off (&minimize_time);
6811 equiv_time = create_ticker ();
6812 ticker_off (&equiv_time);
6813 for (curr_automaton = description->first_automaton;
6814 curr_automaton != NULL;
6815 curr_automaton = curr_automaton->next_automaton)
6819 if (curr_automaton->corresponding_automaton_decl == NULL)
6820 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6822 fprintf (stderr, "Prepare automaton `%s' creation...",
6823 curr_automaton->corresponding_automaton_decl->name);
6825 create_alt_states (curr_automaton);
6826 form_ainsn_with_same_reservs (curr_automaton);
6828 fprintf (stderr, "done\n");
6829 build_automaton (curr_automaton);
6830 enumerate_states (curr_automaton);
6831 ticker_on (&equiv_time);
6832 set_insn_equiv_classes (curr_automaton);
6833 ticker_off (&equiv_time);
6839 /* This page contains code for forming string representation of
6840 regexp. The representation is formed on IR obstack. So you should
6841 not work with IR obstack between regexp_representation and
6842 finish_regexp_representation calls. */
6844 /* This recursive function forms string representation of regexp
6845 (without tailing '\0'). */
6847 form_regexp (regexp_t regexp)
6851 switch (regexp->mode)
6853 case rm_unit: case rm_reserv:
6855 const char *name = (regexp->mode == rm_unit
6856 ? REGEXP_UNIT (regexp)->name
6857 : REGEXP_RESERV (regexp)->name);
6859 obstack_grow (&irp, name, strlen (name));
6864 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6867 obstack_1grow (&irp, ',');
6868 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6873 obstack_1grow (&irp, '(');
6874 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6877 obstack_1grow (&irp, '+');
6878 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6879 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6880 obstack_1grow (&irp, '(');
6881 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6882 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6883 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6884 obstack_1grow (&irp, ')');
6886 obstack_1grow (&irp, ')');
6890 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6893 obstack_1grow (&irp, '|');
6894 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6895 obstack_1grow (&irp, '(');
6896 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6897 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6898 obstack_1grow (&irp, ')');
6906 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6907 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6908 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6909 obstack_1grow (&irp, '(');
6910 form_regexp (REGEXP_REPEAT (regexp)->regexp);
6911 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6912 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6913 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6914 obstack_1grow (&irp, ')');
6915 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6916 obstack_grow (&irp, digits, strlen (digits));
6921 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6929 /* The function returns string representation of REGEXP on IR
6932 regexp_representation (regexp_t regexp)
6934 form_regexp (regexp);
6935 obstack_1grow (&irp, '\0');
6936 return obstack_base (&irp);
6939 /* The function frees memory allocated for last formed string
6940 representation of regexp. */
6942 finish_regexp_representation (void)
6944 int length = obstack_object_size (&irp);
6946 obstack_blank_fast (&irp, -length);
6951 /* This page contains code for output PHR (pipeline hazards recognizer). */
6953 /* The function outputs minimal C type which is sufficient for
6954 representation numbers in range min_range_value and
6955 max_range_value. Because host machine and build machine may be
6956 different, we use here minimal values required by ANSI C standard
6957 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6961 output_range_type (FILE *f, long int min_range_value,
6962 long int max_range_value)
6964 if (min_range_value >= 0 && max_range_value <= 255)
6965 fprintf (f, "unsigned char");
6966 else if (min_range_value >= -127 && max_range_value <= 127)
6967 fprintf (f, "signed char");
6968 else if (min_range_value >= 0 && max_range_value <= 65535)
6969 fprintf (f, "unsigned short");
6970 else if (min_range_value >= -32767 && max_range_value <= 32767)
6971 fprintf (f, "short");
6976 /* The following macro value is used as value of member
6977 `longest_path_length' of state when we are processing path and the
6978 state on the path. */
6980 #define ON_THE_PATH -2
6982 /* The following recursive function searches for the length of the
6983 longest path starting from STATE which does not contain cycles and
6984 `cycle advance' arcs. */
6987 longest_path_length (state_t state)
6992 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6994 /* We don't expect the path cycle here. Our graph may contain
6995 only cycles with one state on the path not containing `cycle
6996 advance' arcs -- see comment below. */
6997 gcc_assert (state->longest_path_length != ON_THE_PATH);
6999 /* We already visited the state. */
7000 return state->longest_path_length;
7004 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7005 /* Ignore cycles containing one state and `cycle advance' arcs. */
7006 if (arc->to_state != state
7007 && (arc->insn->insn_reserv_decl
7008 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7010 length = longest_path_length (arc->to_state);
7011 if (length > result)
7014 state->longest_path_length = result + 1;
7018 /* The following variable value is value of the corresponding global
7019 variable in the automaton based pipeline interface. */
7021 static int max_dfa_issue_rate;
7023 /* The following function processes the longest path length staring
7024 from STATE to find MAX_DFA_ISSUE_RATE. */
7027 process_state_longest_path_length (state_t state)
7031 value = longest_path_length (state);
7032 if (value > max_dfa_issue_rate)
7033 max_dfa_issue_rate = value;
7036 /* The following macro value is name of the corresponding global
7037 variable in the automaton based pipeline interface. */
7039 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7041 /* The following function calculates value of the corresponding
7042 global variable and outputs its declaration. */
7045 output_dfa_max_issue_rate (void)
7047 automaton_t automaton;
7049 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
7050 max_dfa_issue_rate = 0;
7051 for (automaton = description->first_automaton;
7053 automaton = automaton->next_automaton)
7054 pass_states (automaton, process_state_longest_path_length);
7055 fprintf (output_file, "\nint %s = %d;\n",
7056 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7059 /* The function outputs all initialization values of VECT. */
7061 output_vect (vla_hwint_t vect)
7064 size_t vect_length = VEC_length (vect_el_t, vect);
7068 if (vect_length == 0)
7069 fputs ("0 /* This is dummy el because the vect is empty */", output_file);
7071 for (i = 0; i < vect_length; i++)
7073 fprintf (output_file, "%5ld", (long) VEC_index (vect_el_t, vect, i));
7074 if (els_on_line == 10)
7077 fputs (",\n", output_file);
7079 else if (i < vect_length-1)
7080 fputs (", ", output_file);
7085 /* The following is name of the structure which represents DFA(s) for
7087 #define CHIP_NAME "DFA_chip"
7089 /* The following is name of member which represents state of a DFA for
7092 output_chip_member_name (FILE *f, automaton_t automaton)
7094 if (automaton->corresponding_automaton_decl == NULL)
7095 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7097 fprintf (f, "%s_automaton_state",
7098 automaton->corresponding_automaton_decl->name);
7101 /* The following is name of temporary variable which stores state of a
7104 output_temp_chip_member_name (FILE *f, automaton_t automaton)
7107 output_chip_member_name (f, automaton);
7110 /* This is name of macro value which is code of pseudo_insn
7111 representing advancing cpu cycle. Its value is used as internal
7112 code unknown insn. */
7113 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7115 /* Output name of translate vector for given automaton. */
7117 output_translate_vect_name (FILE *f, automaton_t automaton)
7119 if (automaton->corresponding_automaton_decl == NULL)
7120 fprintf (f, "translate_%d", automaton->automaton_order_num);
7122 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7125 /* Output name for simple transition table representation. */
7127 output_trans_full_vect_name (FILE *f, automaton_t automaton)
7129 if (automaton->corresponding_automaton_decl == NULL)
7130 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7132 fprintf (f, "%s_transitions",
7133 automaton->corresponding_automaton_decl->name);
7136 /* Output name of comb vector of the transition table for given
7139 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7141 if (automaton->corresponding_automaton_decl == NULL)
7142 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7144 fprintf (f, "%s_transitions",
7145 automaton->corresponding_automaton_decl->name);
7148 /* Output name of check vector of the transition table for given
7151 output_trans_check_vect_name (FILE *f, automaton_t automaton)
7153 if (automaton->corresponding_automaton_decl == NULL)
7154 fprintf (f, "check_%d", automaton->automaton_order_num);
7156 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7159 /* Output name of base vector of the transition table for given
7162 output_trans_base_vect_name (FILE *f, automaton_t automaton)
7164 if (automaton->corresponding_automaton_decl == NULL)
7165 fprintf (f, "base_%d", automaton->automaton_order_num);
7167 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7170 /* Output name for simple alternatives number representation. */
7172 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7174 if (automaton->corresponding_automaton_decl == NULL)
7175 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7177 fprintf (f, "%s_state_alts",
7178 automaton->corresponding_automaton_decl->name);
7181 /* Output name of comb vector of the alternatives number table for given
7184 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7186 if (automaton->corresponding_automaton_decl == NULL)
7187 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7189 fprintf (f, "%s_state_alts",
7190 automaton->corresponding_automaton_decl->name);
7193 /* Output name of check vector of the alternatives number table for given
7196 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7198 if (automaton->corresponding_automaton_decl == NULL)
7199 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7201 fprintf (f, "%s_check_state_alts",
7202 automaton->corresponding_automaton_decl->name);
7205 /* Output name of base vector of the alternatives number table for given
7208 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7210 if (automaton->corresponding_automaton_decl == NULL)
7211 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7213 fprintf (f, "%s_base_state_alts",
7214 automaton->corresponding_automaton_decl->name);
7217 /* Output name of simple min issue delay table representation. */
7219 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7221 if (automaton->corresponding_automaton_decl == NULL)
7222 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7224 fprintf (f, "%s_min_issue_delay",
7225 automaton->corresponding_automaton_decl->name);
7228 /* Output name of deadlock vector for given automaton. */
7230 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7232 if (automaton->corresponding_automaton_decl == NULL)
7233 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7235 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7238 /* Output name of reserved units table for AUTOMATON into file F. */
7240 output_reserved_units_table_name (FILE *f, automaton_t automaton)
7242 if (automaton->corresponding_automaton_decl == NULL)
7243 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7245 fprintf (f, "%s_reserved_units",
7246 automaton->corresponding_automaton_decl->name);
7249 /* Name of the PHR interface macro. */
7250 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7252 /* Name of the PHR interface macro. */
7253 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7255 /* Names of an internal functions: */
7256 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7258 /* This is external type of DFA(s) state. */
7259 #define STATE_TYPE_NAME "state_t"
7261 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7263 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7265 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7267 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7269 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7271 /* Name of cache of insn dfa codes. */
7272 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7274 /* Name of length of cache of insn dfa codes. */
7275 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7277 /* Names of the PHR interface functions: */
7278 #define SIZE_FUNC_NAME "state_size"
7280 #define TRANSITION_FUNC_NAME "state_transition"
7282 #define STATE_ALTS_FUNC_NAME "state_alts"
7284 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7286 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7288 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7290 #define RESET_FUNC_NAME "state_reset"
7292 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7294 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7296 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7298 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7300 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7302 #define DFA_START_FUNC_NAME "dfa_start"
7304 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7306 /* Names of parameters of the PHR interface functions. */
7307 #define STATE_NAME "state"
7309 #define INSN_PARAMETER_NAME "insn"
7311 #define INSN2_PARAMETER_NAME "insn2"
7313 #define CHIP_PARAMETER_NAME "chip"
7315 #define FILE_PARAMETER_NAME "f"
7317 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7319 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7321 /* Names of the variables whose values are internal insn code of rtx
7323 #define INTERNAL_INSN_CODE_NAME "insn_code"
7325 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7327 /* Names of temporary variables in some functions. */
7328 #define TEMPORARY_VARIABLE_NAME "temp"
7330 #define I_VARIABLE_NAME "i"
7332 /* Name of result variable in some functions. */
7333 #define RESULT_VARIABLE_NAME "res"
7335 /* Name of function (attribute) to translate insn into internal insn
7337 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7339 /* Name of function (attribute) to translate insn into internal insn
7340 code with caching. */
7341 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7343 /* Name of function (attribute) to translate insn into internal insn
7345 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7347 /* Name of function (attribute) to translate insn into internal insn
7349 #define BYPASS_P_FUNC_NAME "bypass_p"
7351 /* Output C type which is used for representation of codes of states
7354 output_state_member_type (FILE *f, automaton_t automaton)
7356 output_range_type (f, 0, automaton->achieved_states_num);
7359 /* Output definition of the structure representing current DFA(s)
7362 output_chip_definitions (void)
7364 automaton_t automaton;
7366 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7367 for (automaton = description->first_automaton;
7369 automaton = automaton->next_automaton)
7371 fprintf (output_file, " ");
7372 output_state_member_type (output_file, automaton);
7373 fprintf (output_file, " ");
7374 output_chip_member_name (output_file, automaton);
7375 fprintf (output_file, ";\n");
7377 fprintf (output_file, "};\n\n");
7379 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7384 /* The function outputs translate vector of internal insn code into
7385 insn equivalence class number. The equivalence class number is
7386 used to access to table and vectors representing DFA(s). */
7388 output_translate_vect (automaton_t automaton)
7392 vla_hwint_t translate_vect;
7394 translate_vect = VEC_alloc (vect_el_t,heap, description->insns_num);
7396 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7397 /* Undefined value */
7398 VEC_quick_push (vect_el_t, translate_vect,
7399 automaton->insn_equiv_classes_num);
7401 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7402 VEC_replace (vect_el_t, translate_vect,
7403 ainsn->insn_reserv_decl->insn_num,
7404 ainsn->insn_equiv_class_num);
7406 fprintf (output_file,
7407 "/* Vector translating external insn codes to internal ones.*/\n");
7408 fprintf (output_file, "static const ");
7409 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7410 fprintf (output_file, " ");
7411 output_translate_vect_name (output_file, automaton);
7412 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7413 output_vect (translate_vect);
7414 fprintf (output_file, "};\n\n");
7415 VEC_free (vect_el_t,heap, translate_vect);
7418 /* The value in a table state x ainsn -> something which represents
7420 static int undefined_vect_el_value;
7422 /* The following function returns nonzero value if the best
7423 representation of the table is comb vector. */
7425 comb_vect_p (state_ainsn_table_t tab)
7427 return (2 * VEC_length (vect_el_t, tab->full_vect)
7428 > 5 * VEC_length (vect_el_t, tab->comb_vect));
7431 /* The following function creates new table for AUTOMATON. */
7432 static state_ainsn_table_t
7433 create_state_ainsn_table (automaton_t automaton)
7435 state_ainsn_table_t tab;
7436 int full_vect_length;
7439 tab = create_node (sizeof (struct state_ainsn_table));
7440 tab->automaton = automaton;
7442 tab->comb_vect = VEC_alloc (vect_el_t,heap, 10000);
7443 tab->check_vect = VEC_alloc (vect_el_t,heap, 10000);
7446 VEC_safe_grow (vect_el_t,heap, tab->base_vect,
7447 automaton->achieved_states_num);
7449 full_vect_length = (automaton->insn_equiv_classes_num
7450 * automaton->achieved_states_num);
7451 tab->full_vect = VEC_alloc (vect_el_t,heap, full_vect_length);
7452 for (i = 0; i < full_vect_length; i++)
7453 VEC_quick_push (vect_el_t, tab->full_vect, undefined_vect_el_value);
7455 tab->min_base_vect_el_value = 0;
7456 tab->max_base_vect_el_value = 0;
7457 tab->min_comb_vect_el_value = 0;
7458 tab->max_comb_vect_el_value = 0;
7462 /* The following function outputs the best C representation of the
7463 table TAB of given TABLE_NAME. */
7465 output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
7466 void (*output_full_vect_name_func) (FILE *, automaton_t),
7467 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7468 void (*output_check_vect_name_func) (FILE *, automaton_t),
7469 void (*output_base_vect_name_func) (FILE *, automaton_t))
7471 if (!comb_vect_p (tab))
7473 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7474 fprintf (output_file, "static const ");
7475 output_range_type (output_file, tab->min_comb_vect_el_value,
7476 tab->max_comb_vect_el_value);
7477 fprintf (output_file, " ");
7478 (*output_full_vect_name_func) (output_file, tab->automaton);
7479 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7480 output_vect (tab->full_vect);
7481 fprintf (output_file, "};\n\n");
7485 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7486 fprintf (output_file, "static const ");
7487 output_range_type (output_file, tab->min_comb_vect_el_value,
7488 tab->max_comb_vect_el_value);
7489 fprintf (output_file, " ");
7490 (*output_comb_vect_name_func) (output_file, tab->automaton);
7491 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7492 output_vect (tab->comb_vect);
7493 fprintf (output_file, "};\n\n");
7494 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7495 fprintf (output_file, "static const ");
7496 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7497 fprintf (output_file, " ");
7498 (*output_check_vect_name_func) (output_file, tab->automaton);
7499 fprintf (output_file, "[] = {\n");
7500 output_vect (tab->check_vect);
7501 fprintf (output_file, "};\n\n");
7502 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7503 fprintf (output_file, "static const ");
7504 output_range_type (output_file, tab->min_base_vect_el_value,
7505 tab->max_base_vect_el_value);
7506 fprintf (output_file, " ");
7507 (*output_base_vect_name_func) (output_file, tab->automaton);
7508 fprintf (output_file, "[] = {\n");
7509 output_vect (tab->base_vect);
7510 fprintf (output_file, "};\n\n");
7514 /* The following function adds vector VECT to table TAB as its line
7515 with number VECT_NUM. */
7517 add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
7520 size_t real_vect_length;
7521 int comb_vect_index;
7522 int comb_vect_els_num;
7524 int first_unempty_vect_index;
7525 int additional_els_num;
7529 unsigned long vect_mask, comb_vect_mask;
7531 vect_length = VEC_length (vect_el_t, vect);
7532 gcc_assert (vect_length);
7533 gcc_assert (VEC_last (vect_el_t, vect) != undefined_vect_el_value);
7534 real_vect_length = tab->automaton->insn_equiv_classes_num;
7535 /* Form full vector in the table: */
7537 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
7538 if (VEC_length (vect_el_t, tab->full_vect) < full_base + vect_length)
7539 VEC_safe_grow (vect_el_t,heap, tab->full_vect,
7540 full_base + vect_length);
7541 for (i = 0; i < vect_length; i++)
7542 VEC_replace (vect_el_t, tab->full_vect, full_base + i,
7543 VEC_index (vect_el_t, vect, i));
7545 /* Form comb vector in the table: */
7546 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7547 == VEC_length (vect_el_t, tab->check_vect));
7549 comb_vect_els_num = VEC_length (vect_el_t, tab->comb_vect);
7550 for (first_unempty_vect_index = 0;
7551 first_unempty_vect_index < vect_length;
7552 first_unempty_vect_index++)
7553 if (VEC_index (vect_el_t, vect, first_unempty_vect_index)
7554 != undefined_vect_el_value)
7557 /* Search for the place in comb vect for the inserted vect. */
7560 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7562 for (comb_vect_index = 0;
7563 comb_vect_index < comb_vect_els_num;
7566 for (vect_index = first_unempty_vect_index;
7567 vect_index < vect_length
7568 && vect_index + comb_vect_index < comb_vect_els_num;
7570 if (VEC_index (vect_el_t, vect, vect_index)
7571 != undefined_vect_el_value
7572 && (VEC_index (vect_el_t, tab->comb_vect,
7573 vect_index + comb_vect_index)
7574 != undefined_vect_el_value))
7576 if (vect_index >= vect_length
7577 || vect_index + comb_vect_index >= comb_vect_els_num)
7585 for (vect_index = first_unempty_vect_index;
7586 vect_index < vect_length;
7589 vect_mask = vect_mask << 1;
7590 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
7594 /* Search for the place in comb vect for the inserted vect. */
7595 comb_vect_index = 0;
7596 if (comb_vect_els_num == 0)
7600 for (vect_index = first_unempty_vect_index;
7601 vect_index < vect_length && vect_index < comb_vect_els_num;
7604 comb_vect_mask <<= 1;
7605 if (vect_index + comb_vect_index < comb_vect_els_num
7606 && VEC_index (vect_el_t, tab->comb_vect, vect_index + comb_vect_index)
7607 != undefined_vect_el_value)
7608 comb_vect_mask |= 1;
7610 if ((vect_mask & comb_vect_mask) == 0)
7613 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7614 comb_vect_index++, i++)
7616 comb_vect_mask = (comb_vect_mask << 1) | 1;
7617 comb_vect_mask ^= (VEC_index (vect_el_t, tab->comb_vect, i)
7618 == undefined_vect_el_value);
7619 if ((vect_mask & comb_vect_mask) == 0)
7622 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7624 comb_vect_mask <<= 1;
7625 if ((vect_mask & comb_vect_mask) == 0)
7630 /* Slot was found. */
7631 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7632 if (additional_els_num < 0)
7633 additional_els_num = 0;
7634 /* Expand comb and check vectors. */
7635 vect_el = undefined_vect_el_value;
7636 no_state_value = tab->automaton->achieved_states_num;
7637 while (additional_els_num > 0)
7639 VEC_safe_push (vect_el_t,heap, tab->comb_vect, vect_el);
7640 VEC_safe_push (vect_el_t,heap, tab->check_vect, no_state_value);
7641 additional_els_num--;
7643 gcc_assert (VEC_length (vect_el_t, tab->comb_vect)
7644 >= comb_vect_index + real_vect_length);
7645 /* Fill comb and check vectors. */
7646 for (vect_index = 0; vect_index < vect_length; vect_index++)
7647 if (VEC_index (vect_el_t, vect, vect_index) != undefined_vect_el_value)
7649 vect_el_t x = VEC_index (vect_el_t, vect, vect_index);
7650 gcc_assert (VEC_index (vect_el_t, tab->comb_vect,
7651 comb_vect_index + vect_index)
7652 == undefined_vect_el_value);
7653 gcc_assert (x >= 0);
7654 if (tab->max_comb_vect_el_value < x)
7655 tab->max_comb_vect_el_value = x;
7656 if (tab->min_comb_vect_el_value > x)
7657 tab->min_comb_vect_el_value = x;
7658 VEC_replace (vect_el_t, tab->comb_vect,
7659 comb_vect_index + vect_index, x);
7660 VEC_replace (vect_el_t, tab->check_vect,
7661 comb_vect_index + vect_index, vect_num);
7663 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7664 tab->max_comb_vect_el_value = undefined_vect_el_value;
7665 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7666 tab->min_comb_vect_el_value = undefined_vect_el_value;
7667 if (tab->max_base_vect_el_value < comb_vect_index)
7668 tab->max_base_vect_el_value = comb_vect_index;
7669 if (tab->min_base_vect_el_value > comb_vect_index)
7670 tab->min_base_vect_el_value = comb_vect_index;
7672 VEC_replace (vect_el_t, tab->base_vect, vect_num, comb_vect_index);
7675 /* Return number of out arcs of STATE. */
7677 out_state_arcs_num (state_t state)
7683 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7685 gcc_assert (arc->insn);
7686 if (arc->insn->first_ainsn_with_given_equivalence_num)
7692 /* Compare number of possible transitions from the states. */
7694 compare_transition_els_num (const void *state_ptr_1,
7695 const void *state_ptr_2)
7697 int transition_els_num_1;
7698 int transition_els_num_2;
7700 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7701 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7702 if (transition_els_num_1 < transition_els_num_2)
7704 else if (transition_els_num_1 == transition_els_num_2)
7710 /* The function adds element EL_VALUE to vector VECT for a table state
7713 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7715 int equiv_class_num;
7719 equiv_class_num = ainsn->insn_equiv_class_num;
7720 for (vect_index = VEC_length (vect_el_t, *vect);
7721 vect_index <= equiv_class_num;
7723 VEC_safe_push (vect_el_t,heap, *vect, undefined_vect_el_value);
7724 VEC_replace (vect_el_t, *vect, equiv_class_num, el_value);
7727 /* This is for forming vector of states of an automaton. */
7728 static VEC(state_t,heap) *output_states_vect;
7730 /* The function is called by function pass_states. The function adds
7731 STATE to `output_states_vect'. */
7733 add_states_vect_el (state_t state)
7735 VEC_safe_push (state_t,heap, output_states_vect, state);
7738 /* Form and output vectors (comb, check, base or full vector)
7739 representing transition table of AUTOMATON. */
7741 output_trans_table (automaton_t automaton)
7745 vla_hwint_t transition_vect = 0;
7747 undefined_vect_el_value = automaton->achieved_states_num;
7748 automaton->trans_table = create_state_ainsn_table (automaton);
7749 /* Create vect of pointers to states ordered by num of transitions
7750 from the state (state with the maximum num is the first). */
7751 output_states_vect = 0;
7752 pass_states (automaton, add_states_vect_el);
7753 qsort (VEC_address (state_t, output_states_vect),
7754 VEC_length (state_t, output_states_vect),
7755 sizeof (state_t), compare_transition_els_num);
7757 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7759 VEC_truncate (vect_el_t, transition_vect, 0);
7760 for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
7762 arc = next_out_arc (arc))
7764 gcc_assert (arc->insn);
7765 if (arc->insn->first_ainsn_with_given_equivalence_num)
7766 add_vect_el (&transition_vect, arc->insn,
7767 arc->to_state->order_state_num);
7769 add_vect (automaton->trans_table,
7770 VEC_index (state_t, output_states_vect, i)->order_state_num,
7773 output_state_ainsn_table
7774 (automaton->trans_table, "state transitions",
7775 output_trans_full_vect_name, output_trans_comb_vect_name,
7776 output_trans_check_vect_name, output_trans_base_vect_name);
7778 VEC_free (state_t,heap, output_states_vect);
7779 VEC_free (vect_el_t,heap, transition_vect);
7782 /* Form and output vectors (comb, check, base or simple vect)
7783 representing alts number table of AUTOMATON. The table is state x
7784 ainsn -> number of possible alternative reservations by the
7787 output_state_alts_table (automaton_t automaton)
7791 vla_hwint_t state_alts_vect;
7793 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7794 automaton->state_alts_table = create_state_ainsn_table (automaton);
7795 /* Create vect of pointers to states ordered by num of transitions
7796 from the state (state with the maximum num is the first). */
7797 output_states_vect = 0;
7798 pass_states (automaton, add_states_vect_el);
7799 qsort (VEC_address (state_t, output_states_vect),
7800 VEC_length (state_t, output_states_vect),
7801 sizeof (state_t), compare_transition_els_num);
7803 /* Create base, comb, and check vectors. */
7804 state_alts_vect = 0;
7806 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7808 VEC_truncate (vect_el_t, state_alts_vect, 0);
7809 for (arc = first_out_arc (VEC_index (state_t, output_states_vect, i));
7811 arc = next_out_arc (arc))
7813 gcc_assert (arc->insn);
7814 if (arc->insn->first_ainsn_with_given_equivalence_num)
7815 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7817 add_vect (automaton->state_alts_table,
7818 VEC_index (state_t, output_states_vect, i)->order_state_num,
7821 output_state_ainsn_table
7822 (automaton->state_alts_table, "state insn alternatives",
7823 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7824 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7826 VEC_free (state_t,heap, output_states_vect);
7827 VEC_free (vect_el_t,heap, state_alts_vect);
7830 /* The current number of passing states to find minimal issue delay
7831 value for an ainsn and state. */
7832 static int curr_state_pass_num;
7834 /* This recursive function passes states to find minimal issue delay
7835 value for AINSN. The state being visited is STATE. The function
7836 returns minimal issue delay value for AINSN in STATE or -1 if we
7837 enter into a loop. */
7839 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7842 int min_insn_issue_delay, insn_issue_delay;
7844 if (state->state_pass_num == curr_state_pass_num
7845 || state->min_insn_issue_delay != -1)
7846 /* We've entered into a loop or already have the correct value for
7847 given state and ainsn. */
7848 return state->min_insn_issue_delay;
7849 state->state_pass_num = curr_state_pass_num;
7850 min_insn_issue_delay = -1;
7851 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7852 if (arc->insn == ainsn)
7854 min_insn_issue_delay = 0;
7859 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7860 if (insn_issue_delay != -1)
7862 if (arc->insn->insn_reserv_decl
7863 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7865 if (min_insn_issue_delay == -1
7866 || min_insn_issue_delay > insn_issue_delay)
7868 min_insn_issue_delay = insn_issue_delay;
7869 if (insn_issue_delay == 0)
7874 return min_insn_issue_delay;
7877 /* The function searches minimal issue delay value for AINSN in STATE.
7878 The function can return negative value if we can not issue AINSN. We
7879 will report about it later. */
7881 min_issue_delay (state_t state, ainsn_t ainsn)
7883 curr_state_pass_num++;
7884 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7885 return state->min_insn_issue_delay;
7888 /* The function initiates code for finding minimal issue delay values.
7889 It should be called only once. */
7891 initiate_min_issue_delay_pass_states (void)
7893 curr_state_pass_num = 0;
7896 /* Form and output vectors representing minimal issue delay table of
7897 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7900 output_min_issue_delay_table (automaton_t automaton)
7902 vla_hwint_t min_issue_delay_vect;
7903 vla_hwint_t compressed_min_issue_delay_vect;
7904 vect_el_t min_delay;
7906 size_t i, min_issue_delay_len;
7907 size_t compressed_min_issue_delay_len;
7910 /* Create vect of pointers to states ordered by num of transitions
7911 from the state (state with the maximum num is the first). */
7912 output_states_vect = 0;
7913 pass_states (automaton, add_states_vect_el);
7915 min_issue_delay_len = (VEC_length (state_t, output_states_vect)
7916 * automaton->insn_equiv_classes_num);
7917 min_issue_delay_vect = VEC_alloc (vect_el_t,heap, min_issue_delay_len);
7918 for (i = 0; i < min_issue_delay_len; i++)
7919 VEC_quick_push (vect_el_t, min_issue_delay_vect, 0);
7921 automaton->max_min_delay = 0;
7922 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7923 if (ainsn->first_ainsn_with_given_equivalence_num)
7925 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7926 VEC_index (state_t, output_states_vect, i)->min_insn_issue_delay = -1;
7927 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
7929 state_t s = VEC_index (state_t, output_states_vect, i);
7930 min_delay = min_issue_delay (s, ainsn);
7931 if (automaton->max_min_delay < min_delay)
7932 automaton->max_min_delay = min_delay;
7933 VEC_replace (vect_el_t, min_issue_delay_vect,
7935 * automaton->insn_equiv_classes_num
7936 + ainsn->insn_equiv_class_num,
7940 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
7941 fprintf (output_file, "static const ");
7942 output_range_type (output_file, 0, automaton->max_min_delay);
7943 fprintf (output_file, " ");
7944 output_min_issue_delay_vect_name (output_file, automaton);
7945 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7946 /* Compress the vector. */
7947 if (automaton->max_min_delay < 2)
7949 else if (automaton->max_min_delay < 4)
7951 else if (automaton->max_min_delay < 16)
7955 automaton->min_issue_delay_table_compression_factor = cfactor;
7957 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
7958 compressed_min_issue_delay_vect
7959 = VEC_alloc (vect_el_t,heap, compressed_min_issue_delay_len);
7961 for (i = 0; i < compressed_min_issue_delay_len; i++)
7962 VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0);
7964 for (i = 0; i < min_issue_delay_len; i++)
7966 size_t ci = i / cfactor;
7967 vect_el_t x = VEC_index (vect_el_t, min_issue_delay_vect, i);
7968 vect_el_t cx = VEC_index (vect_el_t, compressed_min_issue_delay_vect, ci);
7970 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
7971 VEC_replace (vect_el_t, compressed_min_issue_delay_vect, ci, cx);
7973 output_vect (compressed_min_issue_delay_vect);
7974 fprintf (output_file, "};\n\n");
7975 VEC_free (state_t,heap, output_states_vect);
7976 VEC_free (vect_el_t,heap, min_issue_delay_vect);
7977 VEC_free (vect_el_t,heap, compressed_min_issue_delay_vect);
7981 /* Number of states which contains transition only by advancing cpu
7983 static int locked_states_num;
7986 /* Form and output vector representing the locked states of
7989 output_dead_lock_vect (automaton_t automaton)
7993 vla_hwint_t dead_lock_vect = 0;
7995 /* Create vect of pointers to states ordered by num of
7996 transitions from the state (state with the maximum num is the
7998 output_states_vect = 0;
7999 pass_states (automaton, add_states_vect_el);
8001 VEC_safe_grow (vect_el_t,heap, dead_lock_vect,
8002 VEC_length (state_t, output_states_vect));
8003 for (i = 0; i < VEC_length (state_t, output_states_vect); i++)
8005 state_t s = VEC_index (state_t, output_states_vect, i);
8006 arc = first_out_arc (s);
8008 VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num,
8009 (next_out_arc (arc) == NULL
8010 && (arc->insn->insn_reserv_decl
8011 == DECL_INSN_RESERV (advance_cycle_insn_decl))
8014 if (VEC_index (vect_el_t,dead_lock_vect, s->order_state_num))
8015 locked_states_num++;
8018 fprintf (output_file, "/* Vector for locked state flags. */\n");
8019 fprintf (output_file, "static const ");
8020 output_range_type (output_file, 0, 1);
8021 fprintf (output_file, " ");
8022 output_dead_lock_vect_name (output_file, automaton);
8023 fprintf (output_file, "[] = {\n");
8024 output_vect (dead_lock_vect);
8025 fprintf (output_file, "};\n\n");
8026 VEC_free (state_t,heap, output_states_vect);
8027 VEC_free (vect_el_t,heap, dead_lock_vect);
8030 /* Form and output vector representing reserved units of the states of
8033 output_reserved_units_table (automaton_t automaton)
8035 vla_hwint_t reserved_units_table = 0;
8036 int state_byte_size;
8037 int reserved_units_size;
8041 /* Create vect of pointers to states. */
8042 output_states_vect = 0;
8043 pass_states (automaton, add_states_vect_el);
8044 /* Create vector. */
8045 state_byte_size = (description->query_units_num + 7) / 8;
8046 reserved_units_size = (VEC_length (state_t, output_states_vect)
8049 reserved_units_table = VEC_alloc (vect_el_t,heap, reserved_units_size);
8051 for (i = 0; i < reserved_units_size; i++)
8052 VEC_quick_push (vect_el_t, reserved_units_table, 0);
8053 for (n = 0; n < VEC_length (state_t, output_states_vect); n++)
8055 state_t s = VEC_index (state_t, output_states_vect, n);
8056 for (i = 0; i < description->units_num; i++)
8057 if (units_array [i]->query_p
8058 && first_cycle_unit_presence (s, i))
8060 int ri = (s->order_state_num * state_byte_size
8061 + units_array [i]->query_num / 8);
8062 vect_el_t x = VEC_index (vect_el_t, reserved_units_table, ri);
8064 x += 1 << (units_array [i]->query_num % 8);
8065 VEC_replace (vect_el_t, reserved_units_table, ri, x);
8068 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8069 fprintf (output_file, "static const ");
8070 output_range_type (output_file, 0, 255);
8071 fprintf (output_file, " ");
8072 output_reserved_units_table_name (output_file, automaton);
8073 fprintf (output_file, "[] = {\n");
8074 output_vect (reserved_units_table);
8075 fprintf (output_file, "};\n\n");
8077 VEC_free (state_t,heap, output_states_vect);
8078 VEC_free (vect_el_t,heap, reserved_units_table);
8081 /* The function outputs all tables representing DFA(s) used for fast
8082 pipeline hazards recognition. */
8084 output_tables (void)
8086 automaton_t automaton;
8089 locked_states_num = 0;
8091 initiate_min_issue_delay_pass_states ();
8092 for (automaton = description->first_automaton;
8094 automaton = automaton->next_automaton)
8096 output_translate_vect (automaton);
8097 output_trans_table (automaton);
8098 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8099 output_state_alts_table (automaton);
8100 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8101 AUTOMATON_STATE_ALTS_MACRO_NAME);
8102 output_min_issue_delay_table (automaton);
8103 output_dead_lock_vect (automaton);
8104 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8105 output_reserved_units_table (automaton);
8106 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8107 CPU_UNITS_QUERY_MACRO_NAME);
8109 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8110 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8113 /* The function outputs definition and value of PHR interface variable
8114 `max_insn_queue_index'. Its value is not less than maximal queue
8115 length needed for the insn scheduler. */
8117 output_max_insn_queue_index_def (void)
8119 int i, max, latency;
8122 max = description->max_insn_reserv_cycles;
8123 for (i = 0; i < description->decls_num; i++)
8125 decl = description->decls [i];
8126 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8128 latency = DECL_INSN_RESERV (decl)->default_latency;
8132 else if (decl->mode == dm_bypass)
8134 latency = DECL_BYPASS (decl)->latency;
8139 for (i = 0; (1 << i) <= max; i++)
8141 gcc_assert (i >= 0);
8142 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8146 /* The function outputs switch cases for insn reservations using
8147 function *output_automata_list_code. */
8149 output_insn_code_cases (void (*output_automata_list_code)
8150 (automata_list_el_t))
8155 for (i = 0; i < description->decls_num; i++)
8157 decl = description->decls [i];
8158 if (decl->mode == dm_insn_reserv)
8159 DECL_INSN_RESERV (decl)->processed_p = FALSE;
8161 for (i = 0; i < description->decls_num; i++)
8163 decl = description->decls [i];
8164 if (decl->mode == dm_insn_reserv
8165 && !DECL_INSN_RESERV (decl)->processed_p)
8167 for (j = i; j < description->decls_num; j++)
8169 decl2 = description->decls [j];
8170 if (decl2->mode == dm_insn_reserv
8171 && (DECL_INSN_RESERV (decl2)->important_automata_list
8172 == DECL_INSN_RESERV (decl)->important_automata_list))
8174 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8175 fprintf (output_file, " case %d: /* %s */\n",
8176 DECL_INSN_RESERV (decl2)->insn_num,
8177 DECL_INSN_RESERV (decl2)->name);
8180 (*output_automata_list_code)
8181 (DECL_INSN_RESERV (decl)->important_automata_list);
8187 /* The function outputs a code for evaluation of a minimal delay of
8188 issue of insns which have reservations in given AUTOMATA_LIST. */
8190 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8192 automata_list_el_t el;
8193 automaton_t automaton;
8195 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8197 automaton = el->automaton;
8198 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8199 output_min_issue_delay_vect_name (output_file, automaton);
8200 fprintf (output_file,
8201 (automaton->min_issue_delay_table_compression_factor != 1
8203 output_translate_vect_name (output_file, automaton);
8204 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8205 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8206 output_chip_member_name (output_file, automaton);
8207 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8208 if (automaton->min_issue_delay_table_compression_factor == 1)
8209 fprintf (output_file, "];\n");
8212 fprintf (output_file, ") / %d];\n",
8213 automaton->min_issue_delay_table_compression_factor);
8214 fprintf (output_file, " %s = (%s >> (8 - (",
8215 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8216 output_translate_vect_name (output_file, automaton);
8218 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8219 INTERNAL_INSN_CODE_NAME,
8220 automaton->min_issue_delay_table_compression_factor,
8221 8 / automaton->min_issue_delay_table_compression_factor,
8222 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8225 if (el == automata_list)
8226 fprintf (output_file, " %s = %s;\n",
8227 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8230 fprintf (output_file, " if (%s > %s)\n",
8231 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8232 fprintf (output_file, " %s = %s;\n",
8233 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8236 fprintf (output_file, " break;\n\n");
8239 /* Output function `internal_min_issue_delay'. */
8241 output_internal_min_issue_delay_func (void)
8243 fprintf (output_file,
8244 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8245 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8246 CHIP_NAME, CHIP_PARAMETER_NAME);
8247 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8248 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8249 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8250 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8251 fprintf (output_file,
8252 "\n default:\n %s = -1;\n break;\n }\n",
8253 RESULT_VARIABLE_NAME);
8254 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8255 fprintf (output_file, "}\n\n");
8258 /* The function outputs a code changing state after issue of insns
8259 which have reservations in given AUTOMATA_LIST. */
8261 output_automata_list_transition_code (automata_list_el_t automata_list)
8263 automata_list_el_t el, next_el;
8265 fprintf (output_file, " {\n");
8266 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8267 for (el = automata_list;; el = next_el)
8269 next_el = el->next_automata_list_el;
8270 if (next_el == NULL)
8272 fprintf (output_file, " ");
8273 output_state_member_type (output_file, el->automaton);
8274 fprintf (output_file, " ");
8275 output_temp_chip_member_name (output_file, el->automaton);
8276 fprintf (output_file, ";\n");
8278 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8279 if (comb_vect_p (el->automaton->trans_table))
8281 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8282 output_trans_base_vect_name (output_file, el->automaton);
8283 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8284 output_chip_member_name (output_file, el->automaton);
8285 fprintf (output_file, "] + ");
8286 output_translate_vect_name (output_file, el->automaton);
8287 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8288 fprintf (output_file, " if (");
8289 output_trans_check_vect_name (output_file, el->automaton);
8290 fprintf (output_file, " [%s] != %s->",
8291 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8292 output_chip_member_name (output_file, el->automaton);
8293 fprintf (output_file, ")\n");
8294 fprintf (output_file, " return %s (%s, %s);\n",
8295 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8296 CHIP_PARAMETER_NAME);
8297 fprintf (output_file, " else\n");
8298 fprintf (output_file, " ");
8299 if (el->next_automata_list_el != NULL)
8300 output_temp_chip_member_name (output_file, el->automaton);
8303 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8304 output_chip_member_name (output_file, el->automaton);
8306 fprintf (output_file, " = ");
8307 output_trans_comb_vect_name (output_file, el->automaton);
8308 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8312 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8313 output_trans_full_vect_name (output_file, el->automaton);
8314 fprintf (output_file, " [");
8315 output_translate_vect_name (output_file, el->automaton);
8316 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8317 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8318 output_chip_member_name (output_file, el->automaton);
8319 fprintf (output_file, " * %d];\n",
8320 el->automaton->insn_equiv_classes_num);
8321 fprintf (output_file, " if (%s >= %d)\n",
8322 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8323 fprintf (output_file, " return %s (%s, %s);\n",
8324 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8325 CHIP_PARAMETER_NAME);
8326 fprintf (output_file, " else\n ");
8327 if (el->next_automata_list_el != NULL)
8328 output_temp_chip_member_name (output_file, el->automaton);
8331 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8332 output_chip_member_name (output_file, el->automaton);
8334 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8336 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8337 for (el = automata_list;; el = next_el)
8339 next_el = el->next_automata_list_el;
8340 if (next_el == NULL)
8342 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8343 output_chip_member_name (output_file, el->automaton);
8344 fprintf (output_file, " = ");
8345 output_temp_chip_member_name (output_file, el->automaton);
8346 fprintf (output_file, ";\n");
8348 fprintf (output_file, " return -1;\n");
8349 fprintf (output_file, " }\n");
8352 /* Output function `internal_state_transition'. */
8354 output_internal_trans_func (void)
8356 fprintf (output_file,
8357 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8358 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8359 CHIP_NAME, CHIP_PARAMETER_NAME);
8360 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8361 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8362 output_insn_code_cases (output_automata_list_transition_code);
8363 fprintf (output_file, "\n default:\n return -1;\n }\n");
8364 fprintf (output_file, "}\n\n");
8371 insn_code = dfa_insn_code (insn);
8372 if (insn_code > DFA__ADVANCE_CYCLE)
8376 insn_code = DFA__ADVANCE_CYCLE;
8378 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8379 code denotes CODE. */
8381 output_internal_insn_code_evaluation (const char *insn_name,
8382 const char *insn_code_name,
8385 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8386 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8387 DFA_INSN_CODE_FUNC_NAME, insn_name);
8388 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8389 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8390 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8391 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8395 /* This function outputs `dfa_insn_code' and its helper function
8396 `dfa_insn_code_enlarge'. */
8398 output_dfa_insn_code_func (void)
8400 /* Emacs c-mode gets really confused if there's a { or } in column 0
8401 inside a string, so don't do that. */
8402 fprintf (output_file, "\
8404 dfa_insn_code_enlarge (int uid)\n\
8408 %s = xrealloc (%s,\n\
8409 %s * sizeof(int));\n\
8410 for (; i < %s; i++)\n\
8411 %s[i] = -1;\n}\n\n",
8412 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8413 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8414 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8415 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8416 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8417 DFA_INSN_CODES_VARIABLE_NAME);
8418 fprintf (output_file, "\
8419 static inline int\n%s (rtx %s)\n\
8421 int uid = INSN_UID (%s);\n\
8423 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8424 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8426 fprintf (output_file,
8427 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8428 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8429 fprintf (output_file, " %s = %s[uid];\n",
8430 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8431 fprintf (output_file, "\
8437 INTERNAL_INSN_CODE_NAME,
8438 INTERNAL_INSN_CODE_NAME,
8439 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8440 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8441 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8444 /* The function outputs PHR interface function `state_transition'. */
8446 output_trans_func (void)
8448 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8449 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8450 INSN_PARAMETER_NAME);
8451 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8452 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8453 INTERNAL_INSN_CODE_NAME, -1);
8454 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8455 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8458 /* The function outputs a code for evaluation of alternative states
8459 number for insns which have reservations in given AUTOMATA_LIST. */
8461 output_automata_list_state_alts_code (automata_list_el_t automata_list)
8463 automata_list_el_t el;
8464 automaton_t automaton;
8466 fprintf (output_file, " {\n");
8467 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8468 if (comb_vect_p (el->automaton->state_alts_table))
8470 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8473 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8475 automaton = el->automaton;
8476 if (comb_vect_p (automaton->state_alts_table))
8478 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8479 output_state_alts_base_vect_name (output_file, automaton);
8480 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8481 output_chip_member_name (output_file, automaton);
8482 fprintf (output_file, "] + ");
8483 output_translate_vect_name (output_file, automaton);
8484 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8485 fprintf (output_file, " if (");
8486 output_state_alts_check_vect_name (output_file, automaton);
8487 fprintf (output_file, " [%s] != %s->",
8488 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8489 output_chip_member_name (output_file, automaton);
8490 fprintf (output_file, ")\n");
8491 fprintf (output_file, " return 0;\n");
8492 fprintf (output_file, " else\n");
8493 fprintf (output_file,
8494 (el == automata_list
8495 ? " %s = " : " %s += "),
8496 RESULT_VARIABLE_NAME);
8497 output_state_alts_comb_vect_name (output_file, automaton);
8498 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8502 fprintf (output_file,
8503 (el == automata_list
8504 ? "\n %s = " : " %s += "),
8505 RESULT_VARIABLE_NAME);
8506 output_state_alts_full_vect_name (output_file, automaton);
8507 fprintf (output_file, " [");
8508 output_translate_vect_name (output_file, automaton);
8509 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8510 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8511 output_chip_member_name (output_file, automaton);
8512 fprintf (output_file, " * %d];\n",
8513 automaton->insn_equiv_classes_num);
8516 fprintf (output_file, " break;\n }\n\n");
8519 /* Output function `internal_state_alts'. */
8521 output_internal_state_alts_func (void)
8523 fprintf (output_file,
8524 "static int\n%s (int %s, struct %s *%s)\n",
8525 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8526 CHIP_NAME, CHIP_PARAMETER_NAME);
8527 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8528 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8529 output_insn_code_cases (output_automata_list_state_alts_code);
8530 fprintf (output_file,
8531 "\n default:\n %s = 0;\n break;\n }\n",
8532 RESULT_VARIABLE_NAME);
8533 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8534 fprintf (output_file, "}\n\n");
8537 /* The function outputs PHR interface function `state_alts'. */
8539 output_state_alts_func (void)
8541 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8542 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8543 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8544 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8545 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8546 INTERNAL_INSN_CODE_NAME, 0);
8547 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8548 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8551 /* Output function `min_issue_delay'. */
8553 output_min_issue_delay_func (void)
8555 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8556 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8557 INSN_PARAMETER_NAME);
8558 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8559 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8560 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8561 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8562 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8563 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8564 fprintf (output_file, " }\n else\n %s = %s;\n",
8565 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8566 fprintf (output_file, "\n return %s (%s, %s);\n",
8567 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8569 fprintf (output_file, "}\n\n");
8572 /* Output function `internal_dead_lock'. */
8574 output_internal_dead_lock_func (void)
8576 automaton_t automaton;
8578 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8579 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8580 fprintf (output_file, "{\n");
8581 for (automaton = description->first_automaton;
8583 automaton = automaton->next_automaton)
8585 fprintf (output_file, " if (");
8586 output_dead_lock_vect_name (output_file, automaton);
8587 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8588 output_chip_member_name (output_file, automaton);
8589 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8591 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8594 /* The function outputs PHR interface function `state_dead_lock_p'. */
8596 output_dead_lock_func (void)
8598 fprintf (output_file, "int\n%s (%s %s)\n",
8599 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8600 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8601 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8604 /* Output function `internal_reset'. */
8606 output_internal_reset_func (void)
8608 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8609 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8610 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8611 CHIP_PARAMETER_NAME, CHIP_NAME);
8614 /* The function outputs PHR interface function `state_size'. */
8616 output_size_func (void)
8618 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8619 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8622 /* The function outputs PHR interface function `state_reset'. */
8624 output_reset_func (void)
8626 fprintf (output_file, "void\n%s (%s %s)\n",
8627 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8628 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8632 /* Output function `min_insn_conflict_delay'. */
8634 output_min_insn_conflict_delay_func (void)
8636 fprintf (output_file,
8637 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8638 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8639 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8640 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
8641 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8642 INTERNAL_INSN2_CODE_NAME);
8643 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8644 INTERNAL_INSN_CODE_NAME, 0);
8645 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8646 INTERNAL_INSN2_CODE_NAME, 0);
8647 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8648 CHIP_NAME, STATE_NAME, CHIP_NAME);
8649 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8650 fprintf (output_file, " transition = %s (%s, &%s);\n",
8651 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8652 fprintf (output_file, " gcc_assert (transition <= 0);\n");
8653 fprintf (output_file, " return %s (%s, &%s);\n",
8654 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8656 fprintf (output_file, "}\n\n");
8659 /* Output function `internal_insn_latency'. */
8661 output_internal_insn_latency_func (void)
8664 struct bypass_decl *bypass;
8666 const char *tabletype = "unsigned char";
8668 /* Find the smallest integer type that can hold all the default
8670 for (i = 0; i < description->decls_num; i++)
8671 if (description->decls[i]->mode == dm_insn_reserv)
8673 decl = description->decls[i];
8674 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8675 && tabletype[0] != 'i') /* Don't shrink it. */
8676 tabletype = "unsigned short";
8677 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8681 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8682 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8683 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8684 INSN2_PARAMETER_NAME);
8685 fprintf (output_file, "{\n");
8687 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8689 fputs (" return 0;\n}\n\n", output_file);
8693 fprintf (output_file, " static const %s default_latencies[] =\n {",
8696 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8697 if (description->decls[i]->mode == dm_insn_reserv
8698 && description->decls[i] != advance_cycle_insn_decl)
8700 if ((col = (col+1) % 8) == 0)
8701 fputs ("\n ", output_file);
8702 decl = description->decls[i];
8703 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8704 fprintf (output_file, "% 4d,",
8705 DECL_INSN_RESERV (decl)->default_latency);
8707 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8708 fputs ("\n };\n", output_file);
8710 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8711 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8712 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8714 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8715 for (i = 0; i < description->decls_num; i++)
8716 if (description->decls[i]->mode == dm_insn_reserv
8717 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8719 decl = description->decls [i];
8720 fprintf (output_file,
8721 " case %d:\n switch (%s)\n {\n",
8722 DECL_INSN_RESERV (decl)->insn_num,
8723 INTERNAL_INSN2_CODE_NAME);
8724 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8726 bypass = bypass->next)
8728 gcc_assert (bypass->in_insn_reserv->insn_num
8729 != (DECL_INSN_RESERV
8730 (advance_cycle_insn_decl)->insn_num));
8731 fprintf (output_file, " case %d:\n",
8732 bypass->in_insn_reserv->insn_num);
8733 if (bypass->bypass_guard_name == NULL)
8734 fprintf (output_file, " return %d;\n",
8738 fprintf (output_file,
8739 " if (%s (%s, %s))\n",
8740 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8741 INSN2_PARAMETER_NAME);
8742 fprintf (output_file,
8743 " return %d;\n break;\n",
8747 fputs (" }\n break;\n", output_file);
8750 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8751 INTERNAL_INSN_CODE_NAME);
8754 /* The function outputs PHR interface function `insn_latency'. */
8756 output_insn_latency_func (void)
8758 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8759 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8760 fprintf (output_file, "{\n int %s, %s;\n",
8761 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8762 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8763 INTERNAL_INSN_CODE_NAME, 0);
8764 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8765 INTERNAL_INSN2_CODE_NAME, 0);
8766 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8767 INTERNAL_INSN_LATENCY_FUNC_NAME,
8768 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8769 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8772 /* The function outputs PHR interface function `print_reservation'. */
8774 output_print_reservation_func (void)
8779 fprintf (output_file,
8780 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8781 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8782 INSN_PARAMETER_NAME);
8784 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8786 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8787 NOTHING_NAME, FILE_PARAMETER_NAME);
8792 fputs (" static const char *const reservation_names[] =\n {",
8795 for (i = 0, j = 0; i < description->decls_num; i++)
8797 decl = description->decls [i];
8798 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8800 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8803 fprintf (output_file, "\n \"%s\",",
8804 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8805 finish_regexp_representation ();
8808 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8810 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8811 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8813 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8814 INSN_PARAMETER_NAME,
8815 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8816 fprintf (output_file, " else\n\
8822 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8823 INSN_PARAMETER_NAME,
8824 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8825 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8827 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8828 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8831 /* The following function is used to sort unit declaration by their
8834 units_cmp (const void *unit1, const void *unit2)
8836 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8837 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8839 return strcmp (u1->name, u2->name);
8842 /* The following macro value is name of struct containing unit name
8844 #define NAME_CODE_STRUCT_NAME "name_code"
8846 /* The following macro value is name of table of struct name_code. */
8847 #define NAME_CODE_TABLE_NAME "name_code_table"
8849 /* The following macro values are member names for struct name_code. */
8850 #define NAME_MEMBER_NAME "name"
8851 #define CODE_MEMBER_NAME "code"
8853 /* The following macro values are local variable names for function
8854 `get_cpu_unit_code'. */
8855 #define CMP_VARIABLE_NAME "cmp"
8856 #define LOW_VARIABLE_NAME "l"
8857 #define MIDDLE_VARIABLE_NAME "m"
8858 #define HIGH_VARIABLE_NAME "h"
8860 /* The following function outputs function to obtain internal cpu unit
8861 code by the cpu unit name. */
8863 output_get_cpu_unit_code_func (void)
8868 fprintf (output_file, "int\n%s (const char *%s)\n",
8869 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
8870 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8871 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8872 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8873 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8874 fprintf (output_file, " static struct %s %s [] =\n {\n",
8875 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8876 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8877 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8878 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8879 for (i = 0; i < description->units_num; i++)
8880 if (units [i]->query_p)
8881 fprintf (output_file, " {\"%s\", %d},\n",
8882 units[i]->name, units[i]->query_num);
8883 fprintf (output_file, " };\n\n");
8884 fprintf (output_file, " /* The following is binary search: */\n");
8885 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8886 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8887 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8888 fprintf (output_file, " while (%s <= %s)\n {\n",
8889 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8890 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8891 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8892 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8893 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8894 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8895 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8896 fprintf (output_file, " %s = %s - 1;\n",
8897 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8898 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8899 fprintf (output_file, " %s = %s + 1;\n",
8900 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8901 fprintf (output_file, " else\n");
8902 fprintf (output_file, " return %s [%s].%s;\n }\n",
8903 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8904 fprintf (output_file, " return -1;\n}\n\n");
8908 /* The following function outputs function to check reservation of cpu
8909 unit (its internal code will be passed as the function argument) in
8912 output_cpu_unit_reservation_p (void)
8914 automaton_t automaton;
8916 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
8917 CPU_UNIT_RESERVATION_P_FUNC_NAME,
8918 STATE_TYPE_NAME, STATE_NAME,
8919 CPU_CODE_PARAMETER_NAME);
8920 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
8921 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8922 description->query_units_num);
8923 for (automaton = description->first_automaton;
8925 automaton = automaton->next_automaton)
8927 fprintf (output_file, " if ((");
8928 output_reserved_units_table_name (output_file, automaton);
8929 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8930 output_chip_member_name (output_file, automaton);
8931 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8932 (description->query_units_num + 7) / 8,
8933 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8934 fprintf (output_file, " return 1;\n");
8936 fprintf (output_file, " return 0;\n}\n\n");
8939 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
8941 output_dfa_clean_insn_cache_func (void)
8943 fprintf (output_file,
8944 "void\n%s (void)\n{\n int %s;\n\n",
8945 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
8946 fprintf (output_file,
8947 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8948 I_VARIABLE_NAME, I_VARIABLE_NAME,
8949 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8950 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8953 /* The function outputs PHR interface function `dfa_start'. */
8955 output_dfa_start_func (void)
8957 fprintf (output_file,
8958 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
8959 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8960 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
8961 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8962 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8965 /* The function outputs PHR interface function `dfa_finish'. */
8967 output_dfa_finish_func (void)
8969 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
8970 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8975 /* The page contains code for output description file (readable
8976 representation of original description and generated DFA(s). */
8978 /* The function outputs string representation of IR reservation. */
8980 output_regexp (regexp_t regexp)
8982 fprintf (output_description_file, "%s", regexp_representation (regexp));
8983 finish_regexp_representation ();
8986 /* Output names of units in LIST separated by comma. */
8988 output_unit_set_el_list (unit_set_el_t list)
8992 for (el = list; el != NULL; el = el->next_unit_set_el)
8995 fprintf (output_description_file, ", ");
8996 fprintf (output_description_file, "%s", el->unit_decl->name);
9000 /* Output patterns in LIST separated by comma. */
9002 output_pattern_set_el_list (pattern_set_el_t list)
9004 pattern_set_el_t el;
9007 for (el = list; el != NULL; el = el->next_pattern_set_el)
9010 fprintf (output_description_file, ", ");
9011 for (i = 0; i < el->units_num; i++)
9012 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9013 el->unit_decls [i]->name);
9017 /* The function outputs string representation of IR define_reservation
9018 and define_insn_reservation. */
9020 output_description (void)
9025 for (i = 0; i < description->decls_num; i++)
9027 decl = description->decls [i];
9028 if (decl->mode == dm_unit)
9030 if (DECL_UNIT (decl)->excl_list != NULL)
9032 fprintf (output_description_file, "unit %s exlusion_set: ",
9033 DECL_UNIT (decl)->name);
9034 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9035 fprintf (output_description_file, "\n");
9037 if (DECL_UNIT (decl)->presence_list != NULL)
9039 fprintf (output_description_file, "unit %s presence_set: ",
9040 DECL_UNIT (decl)->name);
9041 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9042 fprintf (output_description_file, "\n");
9044 if (DECL_UNIT (decl)->final_presence_list != NULL)
9046 fprintf (output_description_file, "unit %s final_presence_set: ",
9047 DECL_UNIT (decl)->name);
9048 output_pattern_set_el_list
9049 (DECL_UNIT (decl)->final_presence_list);
9050 fprintf (output_description_file, "\n");
9052 if (DECL_UNIT (decl)->absence_list != NULL)
9054 fprintf (output_description_file, "unit %s absence_set: ",
9055 DECL_UNIT (decl)->name);
9056 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9057 fprintf (output_description_file, "\n");
9059 if (DECL_UNIT (decl)->final_absence_list != NULL)
9061 fprintf (output_description_file, "unit %s final_absence_set: ",
9062 DECL_UNIT (decl)->name);
9063 output_pattern_set_el_list
9064 (DECL_UNIT (decl)->final_absence_list);
9065 fprintf (output_description_file, "\n");
9069 fprintf (output_description_file, "\n");
9070 for (i = 0; i < description->decls_num; i++)
9072 decl = description->decls [i];
9073 if (decl->mode == dm_reserv)
9075 fprintf (output_description_file, "reservation %s: ",
9076 DECL_RESERV (decl)->name);
9077 output_regexp (DECL_RESERV (decl)->regexp);
9078 fprintf (output_description_file, "\n");
9080 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9082 fprintf (output_description_file, "insn reservation %s ",
9083 DECL_INSN_RESERV (decl)->name);
9084 print_rtl (output_description_file,
9085 DECL_INSN_RESERV (decl)->condexp);
9086 fprintf (output_description_file, ": ");
9087 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9088 fprintf (output_description_file, "\n");
9090 else if (decl->mode == dm_bypass)
9091 fprintf (output_description_file, "bypass %d %s %s\n",
9092 DECL_BYPASS (decl)->latency,
9093 DECL_BYPASS (decl)->out_insn_name,
9094 DECL_BYPASS (decl)->in_insn_name);
9096 fprintf (output_description_file, "\n\f\n");
9099 /* The function outputs name of AUTOMATON. */
9101 output_automaton_name (FILE *f, automaton_t automaton)
9103 if (automaton->corresponding_automaton_decl == NULL)
9104 fprintf (f, "#%d", automaton->automaton_order_num);
9106 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9109 /* Maximal length of line for pretty printing into description
9111 #define MAX_LINE_LENGTH 70
9113 /* The function outputs units name belonging to AUTOMATON. */
9115 output_automaton_units (automaton_t automaton)
9119 int curr_line_length;
9120 int there_is_an_automaton_unit;
9123 fprintf (output_description_file, "\n Corresponding units:\n");
9124 fprintf (output_description_file, " ");
9125 curr_line_length = 4;
9126 there_is_an_automaton_unit = 0;
9127 for (i = 0; i < description->decls_num; i++)
9129 decl = description->decls [i];
9130 if (decl->mode == dm_unit
9131 && (DECL_UNIT (decl)->corresponding_automaton_num
9132 == automaton->automaton_order_num))
9134 there_is_an_automaton_unit = 1;
9135 name = DECL_UNIT (decl)->name;
9136 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9138 curr_line_length = strlen (name) + 4;
9139 fprintf (output_description_file, "\n ");
9143 curr_line_length += strlen (name) + 1;
9144 fprintf (output_description_file, " ");
9146 fprintf (output_description_file, "%s", name);
9149 if (!there_is_an_automaton_unit)
9150 fprintf (output_description_file, "<None>");
9151 fprintf (output_description_file, "\n\n");
9154 /* The following variable is used for forming array of all possible cpu unit
9155 reservations described by the current DFA state. */
9156 static VEC(reserv_sets_t,heap) *state_reservs;
9158 /* The function forms `state_reservs' for STATE. */
9160 add_state_reservs (state_t state)
9162 alt_state_t curr_alt_state;
9164 if (state->component_states != NULL)
9165 for (curr_alt_state = state->component_states;
9166 curr_alt_state != NULL;
9167 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9168 add_state_reservs (curr_alt_state->state);
9170 VEC_safe_push (reserv_sets_t,heap, state_reservs, state->reservs);
9173 /* The function outputs readable representation of all out arcs of
9176 output_state_arcs (state_t state)
9180 const char *insn_name;
9181 int curr_line_length;
9183 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9186 gcc_assert (ainsn->first_insn_with_same_reservs);
9187 fprintf (output_description_file, " ");
9188 curr_line_length = 7;
9189 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9192 insn_name = ainsn->insn_reserv_decl->name;
9193 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9195 if (ainsn != arc->insn)
9197 fprintf (output_description_file, ",\n ");
9198 curr_line_length = strlen (insn_name) + 6;
9201 curr_line_length += strlen (insn_name);
9205 curr_line_length += strlen (insn_name);
9206 if (ainsn != arc->insn)
9208 curr_line_length += 2;
9209 fprintf (output_description_file, ", ");
9212 fprintf (output_description_file, "%s", insn_name);
9213 ainsn = ainsn->next_same_reservs_insn;
9215 while (ainsn != NULL);
9216 fprintf (output_description_file, " %d (%d)\n",
9217 arc->to_state->order_state_num, arc->state_alts);
9219 fprintf (output_description_file, "\n");
9222 /* The following function is used for sorting possible cpu unit
9223 reservation of a DFA state. */
9225 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9227 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9228 *(reserv_sets_t *) reservs_ptr_2);
9231 /* The following function is used for sorting possible cpu unit
9232 reservation of a DFA state. */
9234 remove_state_duplicate_reservs (void)
9238 for (i = 1, j = 0; i < VEC_length (reserv_sets_t, state_reservs); i++)
9239 if (reserv_sets_cmp (VEC_index (reserv_sets_t, state_reservs, j),
9240 VEC_index (reserv_sets_t, state_reservs, i)))
9243 VEC_replace (reserv_sets_t, state_reservs, j,
9244 VEC_index (reserv_sets_t, state_reservs, i));
9246 VEC_truncate (reserv_sets_t, state_reservs, j + 1);
9249 /* The following function output readable representation of DFA(s)
9250 state used for fast recognition of pipeline hazards. State is
9251 described by possible (current and scheduled) cpu unit
9254 output_state (state_t state)
9260 fprintf (output_description_file, " State #%d", state->order_state_num);
9261 fprintf (output_description_file,
9262 state->new_cycle_p ? " (new cycle)\n" : "\n");
9263 add_state_reservs (state);
9264 qsort (VEC_address (reserv_sets_t, state_reservs),
9265 VEC_length (reserv_sets_t, state_reservs),
9266 sizeof (reserv_sets_t), state_reservs_cmp);
9267 remove_state_duplicate_reservs ();
9268 for (i = 1; i < VEC_length (reserv_sets_t, state_reservs); i++)
9270 fprintf (output_description_file, " ");
9271 output_reserv_sets (output_description_file,
9272 VEC_index (reserv_sets_t, state_reservs, i));
9273 fprintf (output_description_file, "\n");
9275 fprintf (output_description_file, "\n");
9276 output_state_arcs (state);
9277 VEC_free (reserv_sets_t,heap, state_reservs);
9280 /* The following function output readable representation of
9281 DFAs used for fast recognition of pipeline hazards. */
9283 output_automaton_descriptions (void)
9285 automaton_t automaton;
9287 for (automaton = description->first_automaton;
9289 automaton = automaton->next_automaton)
9291 fprintf (output_description_file, "\nAutomaton ");
9292 output_automaton_name (output_description_file, automaton);
9293 fprintf (output_description_file, "\n");
9294 output_automaton_units (automaton);
9295 pass_states (automaton, output_state);
9301 /* The page contains top level function for generation DFA(s) used for
9304 /* The function outputs statistics about work of different phases of
9307 output_statistics (FILE *f)
9309 automaton_t automaton;
9312 int transition_comb_vect_els = 0;
9313 int transition_full_vect_els = 0;
9314 int state_alts_comb_vect_els = 0;
9315 int state_alts_full_vect_els = 0;
9316 int min_issue_delay_vect_els = 0;
9319 for (automaton = description->first_automaton;
9321 automaton = automaton->next_automaton)
9323 fprintf (f, "\nAutomaton ");
9324 output_automaton_name (f, automaton);
9325 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9326 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9327 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9328 automaton->DFA_states_num, automaton->DFA_arcs_num);
9329 states_num = automaton->DFA_states_num;
9330 if (!no_minimization_flag)
9332 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9333 automaton->minimal_DFA_states_num,
9334 automaton->minimal_DFA_arcs_num);
9335 states_num = automaton->minimal_DFA_states_num;
9337 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9338 description->insns_num, automaton->insn_equiv_classes_num);
9341 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9342 (long) VEC_length (vect_el_t, automaton->trans_table->comb_vect),
9343 (long) VEC_length (vect_el_t, automaton->trans_table->full_vect),
9344 (comb_vect_p (automaton->trans_table)
9345 ? "use comb vect" : "use simple vect"));
9347 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9348 (long) VEC_length (vect_el_t, automaton->state_alts_table->comb_vect),
9349 (long) VEC_length (vect_el_t, automaton->state_alts_table->full_vect),
9350 (comb_vect_p (automaton->state_alts_table)
9351 ? "use comb vect" : "use simple vect"));
9353 (f, "%5ld min delay table els, compression factor %d\n",
9354 (long) states_num * automaton->insn_equiv_classes_num,
9355 automaton->min_issue_delay_table_compression_factor);
9356 transition_comb_vect_els
9357 += VEC_length (vect_el_t, automaton->trans_table->comb_vect);
9358 transition_full_vect_els
9359 += VEC_length (vect_el_t, automaton->trans_table->full_vect);
9360 state_alts_comb_vect_els
9361 += VEC_length (vect_el_t, automaton->state_alts_table->comb_vect);
9362 state_alts_full_vect_els
9363 += VEC_length (vect_el_t, automaton->state_alts_table->full_vect);
9364 min_issue_delay_vect_els
9365 += states_num * automaton->insn_equiv_classes_num;
9369 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9370 allocated_states_num, allocated_arcs_num);
9371 fprintf (f, "%5d all allocated alternative states\n",
9372 allocated_alt_states_num);
9373 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9374 transition_comb_vect_els, transition_full_vect_els);
9376 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9377 state_alts_comb_vect_els, state_alts_full_vect_els);
9378 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9379 fprintf (f, "%5d locked states num\n", locked_states_num);
9383 /* The function output times of work of different phases of DFA
9386 output_time_statistics (FILE *f)
9388 fprintf (f, "\n transformation: ");
9389 print_active_time (f, transform_time);
9390 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9391 print_active_time (f, NDFA_time);
9394 fprintf (f, ", NDFA -> DFA: ");
9395 print_active_time (f, NDFA_to_DFA_time);
9397 fprintf (f, "\n DFA minimization: ");
9398 print_active_time (f, minimize_time);
9399 fprintf (f, ", making insn equivalence: ");
9400 print_active_time (f, equiv_time);
9401 fprintf (f, "\n all automaton generation: ");
9402 print_active_time (f, automaton_generation_time);
9403 fprintf (f, ", output: ");
9404 print_active_time (f, output_time);
9408 /* The function generates DFA (deterministic finite state automaton)
9409 for fast recognition of pipeline hazards. No errors during
9410 checking must be fixed before this function call. */
9414 automata_num = split_argument;
9415 if (description->units_num < automata_num)
9416 automata_num = description->units_num;
9419 initiate_automata_lists ();
9420 initiate_pass_states ();
9421 initiate_excl_sets ();
9422 initiate_presence_absence_pattern_sets ();
9423 automaton_generation_time = create_ticker ();
9425 ticker_off (&automaton_generation_time);
9430 /* The following function creates insn attribute whose values are
9431 number alternatives in insn reservations. */
9433 make_insn_alts_attr (void)
9439 condexp = rtx_alloc (COND);
9440 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9441 XEXP (condexp, 1) = make_numeric_value (0);
9442 for (i = insn_num = 0; i < description->decls_num; i++)
9444 decl = description->decls [i];
9445 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9447 XVECEXP (condexp, 0, 2 * insn_num)
9448 = DECL_INSN_RESERV (decl)->condexp;
9449 XVECEXP (condexp, 0, 2 * insn_num + 1)
9450 = make_numeric_value
9451 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9452 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9453 ->transformed_regexp)->regexps_num);
9457 gcc_assert (description->insns_num == insn_num + 1);
9458 make_internal_attr (attr_printf (sizeof ("*")
9459 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9460 "*%s", INSN_ALTS_FUNC_NAME),
9461 condexp, ATTR_NONE);
9466 /* The following function creates attribute which is order number of
9467 insn in pipeline hazard description translator. */
9469 make_internal_dfa_insn_code_attr (void)
9475 condexp = rtx_alloc (COND);
9476 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9478 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9480 for (i = insn_num = 0; i < description->decls_num; i++)
9482 decl = description->decls [i];
9483 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9485 XVECEXP (condexp, 0, 2 * insn_num)
9486 = DECL_INSN_RESERV (decl)->condexp;
9487 XVECEXP (condexp, 0, 2 * insn_num + 1)
9488 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9492 gcc_assert (description->insns_num == insn_num + 1);
9494 (attr_printf (sizeof ("*")
9495 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9496 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9497 condexp, ATTR_STATIC);
9502 /* The following function creates attribute which order number of insn
9503 in pipeline hazard description translator. */
9505 make_default_insn_latency_attr (void)
9511 condexp = rtx_alloc (COND);
9512 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9513 XEXP (condexp, 1) = make_numeric_value (0);
9514 for (i = insn_num = 0; i < description->decls_num; i++)
9516 decl = description->decls [i];
9517 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9519 XVECEXP (condexp, 0, 2 * insn_num)
9520 = DECL_INSN_RESERV (decl)->condexp;
9521 XVECEXP (condexp, 0, 2 * insn_num + 1)
9522 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9526 gcc_assert (description->insns_num == insn_num + 1);
9527 make_internal_attr (attr_printf (sizeof ("*")
9528 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9529 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9530 condexp, ATTR_NONE);
9535 /* The following function creates attribute which returns 1 if given
9536 output insn has bypassing and 0 otherwise. */
9538 make_bypass_attr (void)
9541 int bypass_insns_num = 0;
9545 for (i = 0; i < description->decls_num; i++)
9547 decl = description->decls [i];
9548 if (decl->mode == dm_insn_reserv
9549 && DECL_INSN_RESERV (decl)->condexp != NULL
9550 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9553 if (bypass_insns_num == 0)
9554 result_rtx = make_numeric_value (0);
9557 result_rtx = rtx_alloc (COND);
9558 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9559 XEXP (result_rtx, 1) = make_numeric_value (0);
9561 for (i = bypass_insn = 0; i < description->decls_num; i++)
9563 decl = description->decls [i];
9564 if (decl->mode == dm_insn_reserv
9565 && DECL_INSN_RESERV (decl)->condexp != NULL
9566 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9568 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9569 = DECL_INSN_RESERV (decl)->condexp;
9570 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9571 = make_numeric_value (1);
9576 make_internal_attr (attr_printf (sizeof ("*")
9577 + strlen (BYPASS_P_FUNC_NAME) + 1,
9578 "*%s", BYPASS_P_FUNC_NAME),
9579 result_rtx, ATTR_NONE);
9584 /* This page mainly contains top level functions of pipeline hazards
9585 description translator. */
9587 /* The following macro value is suffix of name of description file of
9588 pipeline hazards description translator. */
9589 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9591 /* The function returns suffix of given file name. The returned
9592 string can not be changed. */
9594 file_name_suffix (const char *file_name)
9596 const char *last_period;
9598 for (last_period = NULL; *file_name != '\0'; file_name++)
9599 if (*file_name == '.')
9600 last_period = file_name;
9601 return (last_period == NULL ? file_name : last_period);
9604 /* The function returns base name of given file name, i.e. pointer to
9605 first char after last `/' (or `\' for WIN32) in given file name,
9606 given file name itself if the directory name is absent. The
9607 returned string can not be changed. */
9609 base_file_name (const char *file_name)
9611 int directory_name_length;
9613 directory_name_length = strlen (file_name);
9615 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9616 && file_name[directory_name_length] != '\\')
9618 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9620 directory_name_length--;
9621 return file_name + directory_name_length + 1;
9624 /* The following is top level function to initialize the work of
9625 pipeline hazards description translator. */
9627 initiate_automaton_gen (int argc, char **argv)
9629 const char *base_name;
9633 split_argument = 0; /* default value */
9634 no_minimization_flag = 0;
9639 for (i = 2; i < argc; i++)
9640 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9641 no_minimization_flag = 1;
9642 else if (strcmp (argv [i], TIME_OPTION) == 0)
9644 else if (strcmp (argv [i], V_OPTION) == 0)
9646 else if (strcmp (argv [i], W_OPTION) == 0)
9648 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9650 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9652 else if (strcmp (argv [i], "-split") == 0)
9655 fatal ("-split has no argument.");
9656 fatal ("option `-split' has not been implemented yet\n");
9657 /* split_argument = atoi (argument_vect [i + 1]); */
9660 /* Initialize IR storage. */
9661 obstack_init (&irp);
9662 initiate_automaton_decl_table ();
9663 initiate_insn_decl_table ();
9664 initiate_decl_table ();
9665 output_file = stdout;
9666 output_description_file = NULL;
9667 base_name = base_file_name (argv[1]);
9668 obstack_grow (&irp, base_name,
9669 strlen (base_name) - strlen (file_name_suffix (base_name)));
9670 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9671 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9672 obstack_1grow (&irp, '\0');
9673 output_description_file_name = obstack_base (&irp);
9674 obstack_finish (&irp);
9677 /* The following function checks existence at least one arc marked by
9680 check_automata_insn_issues (void)
9682 automaton_t automaton;
9683 ainsn_t ainsn, reserv_ainsn;
9685 for (automaton = description->first_automaton;
9687 automaton = automaton->next_automaton)
9689 for (ainsn = automaton->ainsn_list;
9691 ainsn = ainsn->next_ainsn)
9692 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9694 for (reserv_ainsn = ainsn;
9695 reserv_ainsn != NULL;
9696 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9697 if (automaton->corresponding_automaton_decl != NULL)
9700 error ("Automaton `%s': Insn `%s' will never be issued",
9701 automaton->corresponding_automaton_decl->name,
9702 reserv_ainsn->insn_reserv_decl->name);
9705 (0, "Automaton `%s': Insn `%s' will never be issued",
9706 automaton->corresponding_automaton_decl->name,
9707 reserv_ainsn->insn_reserv_decl->name);
9712 error ("Insn `%s' will never be issued",
9713 reserv_ainsn->insn_reserv_decl->name);
9715 warning (0, "Insn `%s' will never be issued",
9716 reserv_ainsn->insn_reserv_decl->name);
9722 /* The following vla is used for storing pointers to all achieved
9724 static VEC(state_t,heap) *automaton_states;
9726 /* This function is called by function pass_states to add an achieved
9729 add_automaton_state (state_t state)
9731 VEC_safe_push (state_t,heap, automaton_states, state);
9734 /* The following function forms list of important automata (whose
9735 states may be changed after the insn issue) for each insn. */
9737 form_important_insn_automata_lists (void)
9739 automaton_t automaton;
9746 automaton_states = 0;
9747 /* Mark important ainsns. */
9748 for (automaton = description->first_automaton;
9750 automaton = automaton->next_automaton)
9752 VEC_truncate (state_t, automaton_states, 0);
9753 pass_states (automaton, add_automaton_state);
9754 for (n = 0; n < VEC_length (state_t, automaton_states); n++)
9756 state_t s = VEC_index (state_t, automaton_states, n);
9757 for (arc = first_out_arc (s);
9759 arc = next_out_arc (arc))
9760 if (arc->to_state != s)
9762 gcc_assert (arc->insn->first_insn_with_same_reservs);
9763 for (ainsn = arc->insn;
9765 ainsn = ainsn->next_same_reservs_insn)
9766 ainsn->important_p = TRUE;
9770 VEC_free (state_t,heap, automaton_states);
9772 /* Create automata sets for the insns. */
9773 for (i = 0; i < description->decls_num; i++)
9775 decl = description->decls [i];
9776 if (decl->mode == dm_insn_reserv)
9778 automata_list_start ();
9779 for (automaton = description->first_automaton;
9781 automaton = automaton->next_automaton)
9782 for (ainsn = automaton->ainsn_list;
9784 ainsn = ainsn->next_ainsn)
9785 if (ainsn->important_p
9786 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9788 automata_list_add (automaton);
9791 DECL_INSN_RESERV (decl)->important_automata_list
9792 = automata_list_finish ();
9798 /* The following is top level function to generate automat(a,on) for
9799 fast recognition of pipeline hazards. */
9801 expand_automata (void)
9805 description = create_node (sizeof (struct description)
9806 /* One entry for cycle advancing insn. */
9807 + sizeof (decl_t) * VEC_length (decl_t, decls));
9808 description->decls_num = VEC_length (decl_t, decls);
9809 description->query_units_num = 0;
9810 for (i = 0; i < description->decls_num; i++)
9812 description->decls [i] = VEC_index (decl_t, decls, i);
9813 if (description->decls [i]->mode == dm_unit
9814 && DECL_UNIT (description->decls [i])->query_p)
9815 DECL_UNIT (description->decls [i])->query_num
9816 = description->query_units_num++;
9818 all_time = create_ticker ();
9819 check_time = create_ticker ();
9821 fprintf (stderr, "Check description...");
9822 check_all_description ();
9824 fprintf (stderr, "done\n");
9825 ticker_off (&check_time);
9826 generation_time = create_ticker ();
9829 transform_insn_regexps ();
9830 check_unit_distributions_to_automata ();
9835 check_automata_insn_issues ();
9839 form_important_insn_automata_lists ();
9841 fprintf (stderr, "Generation of attributes...");
9842 make_internal_dfa_insn_code_attr ();
9843 make_insn_alts_attr ();
9844 make_default_insn_latency_attr ();
9845 make_bypass_attr ();
9847 fprintf (stderr, "done\n");
9849 ticker_off (&generation_time);
9850 ticker_off (&all_time);
9852 fprintf (stderr, "All other genattrtab stuff...");
9855 /* The following is top level function to output PHR and to finish
9856 work with pipeline description translator. */
9858 write_automata (void)
9861 fprintf (stderr, "done\n");
9863 fatal ("Errors in DFA description");
9864 ticker_on (&all_time);
9865 output_time = create_ticker ();
9867 fprintf (stderr, "Forming and outputting automata tables...");
9868 output_dfa_max_issue_rate ();
9872 fprintf (stderr, "done\n");
9873 fprintf (stderr, "Output functions to work with automata...");
9875 output_chip_definitions ();
9876 output_max_insn_queue_index_def ();
9877 output_internal_min_issue_delay_func ();
9878 output_internal_trans_func ();
9879 /* Cache of insn dfa codes: */
9880 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9881 fprintf (output_file, "\nstatic int %s;\n\n",
9882 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9883 output_dfa_insn_code_func ();
9884 output_trans_func ();
9885 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9886 output_internal_state_alts_func ();
9887 output_state_alts_func ();
9888 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9889 AUTOMATON_STATE_ALTS_MACRO_NAME);
9890 output_min_issue_delay_func ();
9891 output_internal_dead_lock_func ();
9892 output_dead_lock_func ();
9893 output_size_func ();
9894 output_internal_reset_func ();
9895 output_reset_func ();
9896 output_min_insn_conflict_delay_func ();
9897 output_internal_insn_latency_func ();
9898 output_insn_latency_func ();
9899 output_print_reservation_func ();
9900 /* Output function get_cpu_unit_code. */
9901 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9902 output_get_cpu_unit_code_func ();
9903 output_cpu_unit_reservation_p ();
9904 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9905 CPU_UNITS_QUERY_MACRO_NAME);
9906 output_dfa_clean_insn_cache_func ();
9907 output_dfa_start_func ();
9908 output_dfa_finish_func ();
9910 fprintf (stderr, "done\n");
9913 output_description_file = fopen (output_description_file_name, "w");
9914 if (output_description_file == NULL)
9916 perror (output_description_file_name);
9917 exit (FATAL_EXIT_CODE);
9920 fprintf (stderr, "Output automata description...");
9921 output_description ();
9922 output_automaton_descriptions ();
9924 fprintf (stderr, "done\n");
9925 output_statistics (output_description_file);
9927 output_statistics (stderr);
9928 ticker_off (&output_time);
9929 output_time_statistics (stderr);
9932 finish_automata_lists ();
9935 fprintf (stderr, "Summary:\n");
9936 fprintf (stderr, " check time ");
9937 print_active_time (stderr, check_time);
9938 fprintf (stderr, ", generation time ");
9939 print_active_time (stderr, generation_time);
9940 fprintf (stderr, ", all time ");
9941 print_active_time (stderr, all_time);
9942 fprintf (stderr, "\n");
9944 /* Finish all work. */
9945 if (output_description_file != NULL)
9947 fflush (output_description_file);
9948 if (ferror (stdout) != 0)
9949 fatal ("Error in writing DFA description file %s",
9950 output_description_file_name);
9951 fclose (output_description_file);
9953 finish_automaton_decl_table ();
9954 finish_insn_decl_table ();
9955 finish_decl_table ();
9956 obstack_free (&irp, NULL);
9957 if (have_error && output_description_file != NULL)
9958 remove (output_description_file_name);