PR other/22202
[official-gcc.git] / gcc / genautomata.c
blobe39d32727a9564ffd27d5f9074f9761b99b5f9d2
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
12 later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
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
22 02110-1301, USA. */
24 /* References:
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
37 recognizers.
39 The current implementation is different from the 2nd article in the
40 following:
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
49 automaton state.
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
57 really need this.
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
67 VLIW insn packing.
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
76 further processing.
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
80 It can be divided on:
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
103 other gcc code. */
105 #include "bconfig.h"
106 #include "system.h"
107 #include "coretypes.h"
108 #include "tm.h"
109 #include "rtl.h"
110 #include "obstack.h"
111 #include "errors.h"
113 #include <math.h>
114 #include "hashtab.h"
115 #include "varray.h"
117 #ifndef CHAR_BIT
118 #define CHAR_BIT 8
119 #endif
121 #include "genattrtab.h"
123 /* Positions in machine description file. Now they are not used. But
124 they could be used in the future for better diagnostic messages. */
125 typedef int pos_t;
127 /* The following is element of vector of current (and planned in the
128 future) functional unit reservations. */
129 typedef unsigned HOST_WIDE_INT set_el_t;
131 /* Reservations of function units are represented by value of the following
132 type. */
133 typedef set_el_t *reserv_sets_t;
135 /* The following structure represents variable length array (vla) of
136 pointers and HOST WIDE INTs. We could be use only varray. But we
137 add new lay because we add elements very frequently and this could
138 stress OS allocator when varray is used only. */
139 typedef struct {
140 size_t length; /* current size of vla. */
141 varray_type varray; /* container for vla. */
142 } vla_ptr_t;
144 typedef vla_ptr_t vla_hwint_t;
146 /* The following structure describes a ticker. */
147 struct ticker
149 /* The following member value is time of the ticker creation with
150 taking into account time when the ticker is off. Active time of
151 the ticker is current time minus the value. */
152 int modified_creation_time;
153 /* The following member value is time (incremented by one) when the
154 ticker was off. Zero value means that now the ticker is on. */
155 int incremented_off_time;
158 /* The ticker is represented by the following type. */
159 typedef struct ticker ticker_t;
161 /* The following type describes elements of output vectors. */
162 typedef HOST_WIDE_INT vect_el_t;
164 /* Forward declaration of structures of internal representation of
165 pipeline description based on NDFA. */
167 struct unit_decl;
168 struct bypass_decl;
169 struct result_decl;
170 struct automaton_decl;
171 struct unit_pattern_rel_decl;
172 struct reserv_decl;
173 struct insn_reserv_decl;
174 struct decl;
175 struct unit_regexp;
176 struct result_regexp;
177 struct reserv_regexp;
178 struct nothing_regexp;
179 struct sequence_regexp;
180 struct repeat_regexp;
181 struct allof_regexp;
182 struct oneof_regexp;
183 struct regexp;
184 struct description;
185 struct unit_set_el;
186 struct pattern_set_el;
187 struct pattern_reserv;
188 struct state;
189 struct alt_state;
190 struct arc;
191 struct ainsn;
192 struct automaton;
193 struct state_ainsn_table;
195 /* The following typedefs are for brevity. */
196 typedef struct unit_decl *unit_decl_t;
197 typedef struct decl *decl_t;
198 typedef struct regexp *regexp_t;
199 typedef struct unit_set_el *unit_set_el_t;
200 typedef struct pattern_set_el *pattern_set_el_t;
201 typedef struct pattern_reserv *pattern_reserv_t;
202 typedef struct alt_state *alt_state_t;
203 typedef struct state *state_t;
204 typedef struct arc *arc_t;
205 typedef struct ainsn *ainsn_t;
206 typedef struct automaton *automaton_t;
207 typedef struct automata_list_el *automata_list_el_t;
208 typedef struct state_ainsn_table *state_ainsn_table_t;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
213 gen_absence_set, gen_final_absence_set, gen_automaton,
214 gen_automata_option, gen_reserv, gen_insn_reserv,
215 initiate_automaton_gen, expand_automata, write_automata are
216 described on the file top because the functions are called from
217 function `main'. */
219 static void *create_node (size_t);
220 static void *copy_node (const void *, size_t);
221 static char *check_name (char *, pos_t);
222 static char *next_sep_el (char **, int, int);
223 static int n_sep_els (char *, int, int);
224 static char **get_str_vect (char *, int *, int, int);
225 static void gen_presence_absence_set (rtx, int, int);
226 static regexp_t gen_regexp_el (char *);
227 static regexp_t gen_regexp_repeat (char *);
228 static regexp_t gen_regexp_allof (char *);
229 static regexp_t gen_regexp_oneof (char *);
230 static regexp_t gen_regexp_sequence (char *);
231 static regexp_t gen_regexp (char *);
233 static unsigned string_hash (const char *);
234 static unsigned automaton_decl_hash (const void *);
235 static int automaton_decl_eq_p (const void *,
236 const void *);
237 static decl_t insert_automaton_decl (decl_t);
238 static decl_t find_automaton_decl (char *);
239 static void initiate_automaton_decl_table (void);
240 static void finish_automaton_decl_table (void);
242 static hashval_t insn_decl_hash (const void *);
243 static int insn_decl_eq_p (const void *,
244 const void *);
245 static decl_t insert_insn_decl (decl_t);
246 static decl_t find_insn_decl (char *);
247 static void initiate_insn_decl_table (void);
248 static void finish_insn_decl_table (void);
250 static hashval_t decl_hash (const void *);
251 static int decl_eq_p (const void *,
252 const void *);
253 static decl_t insert_decl (decl_t);
254 static decl_t find_decl (char *);
255 static void initiate_decl_table (void);
256 static void finish_decl_table (void);
258 static unit_set_el_t process_excls (char **, int, pos_t);
259 static void add_excls (unit_set_el_t, unit_set_el_t,
260 pos_t);
261 static unit_set_el_t process_presence_absence_names
262 (char **, int, pos_t,
263 int, int);
264 static pattern_set_el_t process_presence_absence_patterns
265 (char ***, int, pos_t,
266 int, int);
267 static void add_presence_absence (unit_set_el_t,
268 pattern_set_el_t,
269 pos_t, int, int);
270 static void process_decls (void);
271 static struct bypass_decl *find_bypass (struct bypass_decl *,
272 struct insn_reserv_decl *);
273 static void check_automaton_usage (void);
274 static regexp_t process_regexp (regexp_t);
275 static void process_regexp_decls (void);
276 static void check_usage (void);
277 static int loop_in_regexp (regexp_t, decl_t);
278 static void check_loops_in_regexps (void);
279 static void process_regexp_cycles (regexp_t, int, int,
280 int *, int *);
281 static void evaluate_max_reserv_cycles (void);
282 static void check_all_description (void);
284 static ticker_t create_ticker (void);
285 static void ticker_off (ticker_t *);
286 static void ticker_on (ticker_t *);
287 static int active_time (ticker_t);
288 static void print_active_time (FILE *, ticker_t);
290 static void add_advance_cycle_insn_decl (void);
292 static alt_state_t get_free_alt_state (void);
293 static void free_alt_state (alt_state_t);
294 static void free_alt_states (alt_state_t);
295 static int alt_state_cmp (const void *alt_state_ptr_1,
296 const void *alt_state_ptr_2);
297 static alt_state_t uniq_sort_alt_states (alt_state_t);
298 static int alt_states_eq (alt_state_t, alt_state_t);
299 static void initiate_alt_states (void);
300 static void finish_alt_states (void);
302 static reserv_sets_t alloc_empty_reserv_sets (void);
303 static unsigned reserv_sets_hash_value (reserv_sets_t);
304 static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
305 static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
306 static void set_unit_reserv (reserv_sets_t, int, int);
307 static int test_unit_reserv (reserv_sets_t, int, int);
308 static int it_is_empty_reserv_sets (reserv_sets_t)
309 ATTRIBUTE_UNUSED;
310 static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
311 static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
312 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
313 reserv_sets_t);
314 static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
315 reserv_sets_t)
316 ATTRIBUTE_UNUSED;
317 static void output_cycle_reservs (FILE *, reserv_sets_t,
318 int, int);
319 static void output_reserv_sets (FILE *, reserv_sets_t);
320 static state_t get_free_state (int, automaton_t);
321 static void free_state (state_t);
322 static hashval_t state_hash (const void *);
323 static int state_eq_p (const void *, const void *);
324 static state_t insert_state (state_t);
325 static void set_state_reserv (state_t, int, int);
326 static int intersected_state_reservs_p (state_t, state_t);
327 static state_t states_union (state_t, state_t, reserv_sets_t);
328 static state_t state_shift (state_t, reserv_sets_t);
329 static void initiate_states (void);
330 static void finish_states (void);
332 static void free_arc (arc_t);
333 static void remove_arc (state_t, arc_t);
334 static arc_t find_arc (state_t, state_t, ainsn_t);
335 static arc_t add_arc (state_t, state_t, ainsn_t, int);
336 static arc_t first_out_arc (state_t);
337 static arc_t next_out_arc (arc_t);
338 static void initiate_arcs (void);
339 static void finish_arcs (void);
341 static automata_list_el_t get_free_automata_list_el (void);
342 static void free_automata_list_el (automata_list_el_t);
343 static void free_automata_list (automata_list_el_t);
344 static hashval_t automata_list_hash (const void *);
345 static int automata_list_eq_p (const void *, const void *);
346 static void initiate_automata_lists (void);
347 static void automata_list_start (void);
348 static void automata_list_add (automaton_t);
349 static automata_list_el_t automata_list_finish (void);
350 static void finish_automata_lists (void);
352 static void initiate_excl_sets (void);
353 static reserv_sets_t get_excl_set (reserv_sets_t);
355 static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
356 static void initiate_presence_absence_pattern_sets (void);
357 static int check_presence_pattern_sets (reserv_sets_t,
358 reserv_sets_t, int);
359 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
360 int);
362 static regexp_t copy_insn_regexp (regexp_t);
363 static regexp_t transform_1 (regexp_t);
364 static regexp_t transform_2 (regexp_t);
365 static regexp_t transform_3 (regexp_t);
366 static regexp_t regexp_transform_func
367 (regexp_t, regexp_t (*) (regexp_t));
368 static regexp_t transform_regexp (regexp_t);
369 static void transform_insn_regexps (void);
371 static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
372 static void check_regexp_units_distribution (const char *, regexp_t);
373 static void check_unit_distributions_to_automata (void);
375 static int process_seq_for_forming_states (regexp_t, automaton_t,
376 int);
377 static void finish_forming_alt_state (alt_state_t,
378 automaton_t);
379 static void process_alts_for_forming_states (regexp_t,
380 automaton_t, int);
381 static void create_alt_states (automaton_t);
383 static void form_ainsn_with_same_reservs (automaton_t);
385 static reserv_sets_t form_reservs_matter (automaton_t);
386 static void make_automaton (automaton_t);
387 static void form_arcs_marked_by_insn (state_t);
388 static int create_composed_state (state_t, arc_t, vla_ptr_t *);
389 static void NDFA_to_DFA (automaton_t);
390 static void pass_state_graph (state_t, void (*) (state_t));
391 static void pass_states (automaton_t,
392 void (*) (state_t));
393 static void initiate_pass_states (void);
394 static void add_achieved_state (state_t);
395 static int set_out_arc_insns_equiv_num (state_t, int);
396 static void clear_arc_insns_equiv_num (state_t);
397 static void copy_equiv_class (vla_ptr_t *to,
398 const vla_ptr_t *from);
399 static int first_cycle_unit_presence (state_t, int);
400 static int state_is_differed (state_t, state_t, int, int);
401 static state_t init_equiv_class (state_t *states, int);
402 static int partition_equiv_class (state_t *, int,
403 vla_ptr_t *, int *);
404 static void evaluate_equiv_classes (automaton_t, vla_ptr_t *);
405 static void merge_states (automaton_t, vla_ptr_t *);
406 static void set_new_cycle_flags (state_t);
407 static void minimize_DFA (automaton_t);
408 static void incr_states_and_arcs_nums (state_t);
409 static void count_states_and_arcs (automaton_t, int *, int *);
410 static void build_automaton (automaton_t);
412 static void set_order_state_num (state_t);
413 static void enumerate_states (automaton_t);
415 static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
416 static void delete_ainsn_from_equiv_class (ainsn_t);
417 static void process_insn_equiv_class (ainsn_t, arc_t *);
418 static void process_state_for_insn_equiv_partition (state_t);
419 static void set_insn_equiv_classes (automaton_t);
421 static double estimate_one_automaton_bound (void);
422 static int compare_max_occ_cycle_nums (const void *,
423 const void *);
424 static void units_to_automata_heuristic_distr (void);
425 static ainsn_t create_ainsns (void);
426 static void units_to_automata_distr (void);
427 static void create_automata (void);
429 static void form_regexp (regexp_t);
430 static const char *regexp_representation (regexp_t);
431 static void finish_regexp_representation (void);
433 static void output_range_type (FILE *, long int, long int);
434 static int longest_path_length (state_t);
435 static void process_state_longest_path_length (state_t);
436 static void output_dfa_max_issue_rate (void);
437 static void output_vect (vect_el_t *, int);
438 static void output_chip_member_name (FILE *, automaton_t);
439 static void output_temp_chip_member_name (FILE *, automaton_t);
440 static void output_translate_vect_name (FILE *, automaton_t);
441 static void output_trans_full_vect_name (FILE *, automaton_t);
442 static void output_trans_comb_vect_name (FILE *, automaton_t);
443 static void output_trans_check_vect_name (FILE *, automaton_t);
444 static void output_trans_base_vect_name (FILE *, automaton_t);
445 static void output_state_alts_full_vect_name (FILE *, automaton_t);
446 static void output_state_alts_comb_vect_name (FILE *, automaton_t);
447 static void output_state_alts_check_vect_name (FILE *, automaton_t);
448 static void output_state_alts_base_vect_name (FILE *, automaton_t);
449 static void output_min_issue_delay_vect_name (FILE *, automaton_t);
450 static void output_dead_lock_vect_name (FILE *, automaton_t);
451 static void output_reserved_units_table_name (FILE *, automaton_t);
452 static void output_state_member_type (FILE *, automaton_t);
453 static void output_chip_definitions (void);
454 static void output_translate_vect (automaton_t);
455 static int comb_vect_p (state_ainsn_table_t);
456 static state_ainsn_table_t create_state_ainsn_table (automaton_t);
457 static void output_state_ainsn_table
458 (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
459 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
460 void (*) (FILE *, automaton_t));
461 static void add_vect (state_ainsn_table_t,
462 int, vect_el_t *, int);
463 static int out_state_arcs_num (state_t);
464 static int compare_transition_els_num (const void *, const void *);
465 static void add_vect_el (vla_hwint_t *,
466 ainsn_t, int);
467 static void add_states_vect_el (state_t);
468 static void output_trans_table (automaton_t);
469 static void output_state_alts_table (automaton_t);
470 static int min_issue_delay_pass_states (state_t, ainsn_t);
471 static int min_issue_delay (state_t, ainsn_t);
472 static void initiate_min_issue_delay_pass_states (void);
473 static void output_min_issue_delay_table (automaton_t);
474 static void output_dead_lock_vect (automaton_t);
475 static void output_reserved_units_table (automaton_t);
476 static void output_tables (void);
477 static void output_max_insn_queue_index_def (void);
478 static void output_insn_code_cases (void (*) (automata_list_el_t));
479 static void output_automata_list_min_issue_delay_code (automata_list_el_t);
480 static void output_internal_min_issue_delay_func (void);
481 static void output_automata_list_transition_code (automata_list_el_t);
482 static void output_internal_trans_func (void);
483 static void output_internal_insn_code_evaluation (const char *,
484 const char *, int);
485 static void output_dfa_insn_code_func (void);
486 static void output_trans_func (void);
487 static void output_automata_list_state_alts_code (automata_list_el_t);
488 static void output_internal_state_alts_func (void);
489 static void output_state_alts_func (void);
490 static void output_min_issue_delay_func (void);
491 static void output_internal_dead_lock_func (void);
492 static void output_dead_lock_func (void);
493 static void output_internal_reset_func (void);
494 static void output_size_func (void);
495 static void output_reset_func (void);
496 static void output_min_insn_conflict_delay_func (void);
497 static void output_internal_insn_latency_func (void);
498 static void output_insn_latency_func (void);
499 static void output_print_reservation_func (void);
500 static int units_cmp (const void *,
501 const void *);
502 static void output_get_cpu_unit_code_func (void);
503 static void output_cpu_unit_reservation_p (void);
504 static void output_dfa_clean_insn_cache_func (void);
505 static void output_dfa_start_func (void);
506 static void output_dfa_finish_func (void);
508 static void output_regexp (regexp_t );
509 static void output_unit_set_el_list (unit_set_el_t);
510 static void output_pattern_set_el_list (pattern_set_el_t);
511 static void output_description (void);
512 static void output_automaton_name (FILE *, automaton_t);
513 static void output_automaton_units (automaton_t);
514 static void add_state_reservs (state_t);
515 static void output_state_arcs (state_t);
516 static int state_reservs_cmp (const void *,
517 const void *);
518 static void remove_state_duplicate_reservs (void);
519 static void output_state (state_t);
520 static void output_automaton_descriptions (void);
521 static void output_statistics (FILE *);
522 static void output_time_statistics (FILE *);
523 static void generate (void);
525 static void make_insn_alts_attr (void);
526 static void make_internal_dfa_insn_code_attr (void);
527 static void make_default_insn_latency_attr (void);
528 static void make_bypass_attr (void);
529 static const char *file_name_suffix (const char *);
530 static const char *base_file_name (const char *);
531 static void check_automata_insn_issues (void);
532 static void add_automaton_state (state_t);
533 static void form_important_insn_automata_lists (void);
535 /* Undefined position. */
536 static pos_t no_pos = 0;
538 /* All IR is stored in the following obstack. */
539 static struct obstack irp;
543 /* This page contains code for work with variable length array (vla)
544 of pointers. We could be use only varray. But we add new lay
545 because we add elements very frequently and this could stress OS
546 allocator when varray is used only. */
548 /* Start work with vla. */
549 #define VLA_PTR_CREATE(vla, allocated_length, name) \
550 do \
552 vla_ptr_t *const _vla_ptr = &(vla); \
554 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
555 _vla_ptr->length = 0; \
557 while (0)
559 /* Finish work with the vla. */
560 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
562 /* Return start address of the vla. */
563 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
565 /* Address of the last element of the vla. Do not use side effects in
566 the macro argument. */
567 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
568 (vla).length - 1))
569 /* Nullify the vla. */
570 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
572 /* Shorten the vla on given number bytes. */
573 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
575 /* Expand the vla on N elements. The values of new elements are
576 undefined. */
577 #define VLA_PTR_EXPAND(vla, n) \
578 do { \
579 vla_ptr_t *const _expand_vla_ptr = &(vla); \
580 const size_t _new_length = (n) + _expand_vla_ptr->length; \
582 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
583 VARRAY_GROW (_expand_vla_ptr->varray, \
584 (_new_length - _expand_vla_ptr->length < 128 \
585 ? _expand_vla_ptr->length + 128 : _new_length)); \
586 _expand_vla_ptr->length = _new_length; \
587 } while (0)
589 /* Add element to the end of the vla. */
590 #define VLA_PTR_ADD(vla, ptr) \
591 do { \
592 vla_ptr_t *const _vla_ptr = &(vla); \
594 VLA_PTR_EXPAND (*_vla_ptr, 1); \
595 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
596 } while (0)
598 /* Length of the vla in elements. */
599 #define VLA_PTR_LENGTH(vla) ((vla).length)
601 /* N-th element of the vla. */
602 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
605 /* The following macros are analogous to the previous ones but for
606 VLAs of HOST WIDE INTs. */
608 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
609 do { \
610 vla_hwint_t *const _vla_ptr = &(vla); \
612 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
613 _vla_ptr->length = 0; \
614 } while (0)
616 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
618 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
620 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
622 #define VLA_HWINT_EXPAND(vla, n) \
623 do { \
624 vla_hwint_t *const _expand_vla_ptr = &(vla); \
625 const size_t _new_length = (n) + _expand_vla_ptr->length; \
627 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
628 VARRAY_GROW (_expand_vla_ptr->varray, \
629 (_new_length - _expand_vla_ptr->length < 128 \
630 ? _expand_vla_ptr->length + 128 : _new_length)); \
631 _expand_vla_ptr->length = _new_length; \
632 } while (0)
634 #define VLA_HWINT_ADD(vla, ptr) \
635 do { \
636 vla_hwint_t *const _vla_ptr = &(vla); \
638 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
639 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
640 } while (0)
642 #define VLA_HWINT_LENGTH(vla) ((vla).length)
644 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
648 /* Options with the following names can be set up in automata_option
649 construction. Because the strings occur more one time we use the
650 macros. */
652 #define NO_MINIMIZATION_OPTION "-no-minimization"
654 #define TIME_OPTION "-time"
656 #define V_OPTION "-v"
658 #define W_OPTION "-w"
660 #define NDFA_OPTION "-ndfa"
662 #define PROGRESS_OPTION "-progress"
664 /* The following flags are set up by function `initiate_automaton_gen'. */
666 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
667 static int ndfa_flag;
669 /* Do not make minimization of DFA (`-no-minimization'). */
670 static int no_minimization_flag;
672 /* Value of this variable is number of automata being generated. The
673 actual number of automata may be less this value if there is not
674 sufficient number of units. This value is defined by argument of
675 option `-split' or by constructions automaton if the value is zero
676 (it is default value of the argument). */
677 static int split_argument;
679 /* Flag of output time statistics (`-time'). */
680 static int time_flag;
682 /* Flag of creation of description file which contains description of
683 result automaton and statistics information (`-v'). */
684 static int v_flag;
686 /* Flag of output of a progress bar showing how many states were
687 generated so far for automaton being processed (`-progress'). */
688 static int progress_flag;
690 /* Flag of generating warning instead of error for non-critical errors
691 (`-w'). */
692 static int w_flag;
695 /* Output file for pipeline hazard recognizer (PHR) being generated.
696 The value is NULL if the file is not defined. */
697 static FILE *output_file;
699 /* Description file of PHR. The value is NULL if the file is not
700 created. */
701 static FILE *output_description_file;
703 /* PHR description file name. */
704 static char *output_description_file_name;
706 /* Value of the following variable is node representing description
707 being processed. This is start point of IR. */
708 static struct description *description;
712 /* This page contains description of IR structure (nodes). */
714 enum decl_mode
716 dm_unit,
717 dm_bypass,
718 dm_automaton,
719 dm_excl,
720 dm_presence,
721 dm_absence,
722 dm_reserv,
723 dm_insn_reserv
726 /* This describes define_cpu_unit and define_query_cpu_unit (see file
727 rtl.def). */
728 struct unit_decl
730 char *name;
731 /* NULL if the automaton name is absent. */
732 char *automaton_name;
733 /* If the following value is not zero, the cpu unit reservation is
734 described in define_query_cpu_unit. */
735 char query_p;
737 /* The following fields are defined by checker. */
739 /* The following field value is nonzero if the unit is used in an
740 regexp. */
741 char unit_is_used;
743 /* The following field value is order number (0, 1, ...) of given
744 unit. */
745 int unit_num;
746 /* The following field value is corresponding declaration of
747 automaton which was given in description. If the field value is
748 NULL then automaton in the unit declaration was absent. */
749 struct automaton_decl *automaton_decl;
750 /* The following field value is maximal cycle number (1, ...) on
751 which given unit occurs in insns. Zero value means that given
752 unit is not used in insns. */
753 int max_occ_cycle_num;
754 /* The following field value is minimal cycle number (0, ...) on
755 which given unit occurs in insns. -1 value means that given
756 unit is not used in insns. */
757 int min_occ_cycle_num;
758 /* The following list contains units which conflict with given
759 unit. */
760 unit_set_el_t excl_list;
761 /* The following list contains patterns which are required to
762 reservation of given unit. */
763 pattern_set_el_t presence_list;
764 pattern_set_el_t final_presence_list;
765 /* The following list contains patterns which should be not present
766 in reservation for given unit. */
767 pattern_set_el_t absence_list;
768 pattern_set_el_t final_absence_list;
769 /* The following is used only when `query_p' has nonzero value.
770 This is query number for the unit. */
771 int query_num;
772 /* The following is the last cycle on which the unit was checked for
773 correct distributions of units to automata in a regexp. */
774 int last_distribution_check_cycle;
776 /* The following fields are defined by automaton generator. */
778 /* The following field value is number of the automaton to which
779 given unit belongs. */
780 int corresponding_automaton_num;
781 /* If the following value is not zero, the cpu unit is present in a
782 `exclusion_set' or in right part of a `presence_set',
783 `final_presence_set', `absence_set', and
784 `final_absence_set'define_query_cpu_unit. */
785 char in_set_p;
788 /* This describes define_bypass (see file rtl.def). */
789 struct bypass_decl
791 int latency;
792 char *out_insn_name;
793 char *in_insn_name;
794 char *bypass_guard_name;
796 /* The following fields are defined by checker. */
798 /* output and input insns of given bypass. */
799 struct insn_reserv_decl *out_insn_reserv;
800 struct insn_reserv_decl *in_insn_reserv;
801 /* The next bypass for given output insn. */
802 struct bypass_decl *next;
805 /* This describes define_automaton (see file rtl.def). */
806 struct automaton_decl
808 char *name;
810 /* The following fields are defined by automaton generator. */
812 /* The following field value is nonzero if the automaton is used in
813 an regexp definition. */
814 char automaton_is_used;
816 /* The following fields are defined by checker. */
818 /* The following field value is the corresponding automaton. This
819 field is not NULL only if the automaton is present in unit
820 declarations and the automatic partition on automata is not
821 used. */
822 automaton_t corresponding_automaton;
825 /* This describes exclusion relations: exclusion_set (see file
826 rtl.def). */
827 struct excl_rel_decl
829 int all_names_num;
830 int first_list_length;
831 char *names [1];
834 /* This describes unit relations: [final_]presence_set or
835 [final_]absence_set (see file rtl.def). */
836 struct unit_pattern_rel_decl
838 int final_p;
839 int names_num;
840 int patterns_num;
841 char **names;
842 char ***patterns;
845 /* This describes define_reservation (see file rtl.def). */
846 struct reserv_decl
848 char *name;
849 regexp_t regexp;
851 /* The following fields are defined by checker. */
853 /* The following field value is nonzero if the unit is used in an
854 regexp. */
855 char reserv_is_used;
856 /* The following field is used to check up cycle in expression
857 definition. */
858 int loop_pass_num;
861 /* This describes define_insn_reservation (see file rtl.def). */
862 struct insn_reserv_decl
864 rtx condexp;
865 int default_latency;
866 regexp_t regexp;
867 char *name;
869 /* The following fields are defined by checker. */
871 /* The following field value is order number (0, 1, ...) of given
872 insn. */
873 int insn_num;
874 /* The following field value is list of bypasses in which given insn
875 is output insn. */
876 struct bypass_decl *bypass_list;
878 /* The following fields are defined by automaton generator. */
880 /* The following field is the insn regexp transformed that
881 the regexp has not optional regexp, repetition regexp, and an
882 reservation name (i.e. reservation identifiers are changed by the
883 corresponding regexp) and all alternations are the topest level
884 of the regexp. The value can be NULL only if it is special
885 insn `cycle advancing'. */
886 regexp_t transformed_regexp;
887 /* The following field value is list of arcs marked given
888 insn. The field is used in transformation NDFA -> DFA. */
889 arc_t arcs_marked_by_insn;
890 /* The two following fields are used during minimization of a finite state
891 automaton. */
892 /* The field value is number of equivalence class of state into
893 which arc marked by given insn enters from a state (fixed during
894 an automaton minimization). */
895 int equiv_class_num;
896 /* The field value is state_alts of arc leaving a state (fixed
897 during an automaton minimization) and marked by given insn
898 enters. */
899 int state_alts;
900 /* The following member value is the list to automata which can be
901 changed by the insn issue. */
902 automata_list_el_t important_automata_list;
903 /* The following member is used to process insn once for output. */
904 int processed_p;
907 /* This contains a declaration mentioned above. */
908 struct decl
910 /* What node in the union? */
911 enum decl_mode mode;
912 pos_t pos;
913 union
915 struct unit_decl unit;
916 struct bypass_decl bypass;
917 struct automaton_decl automaton;
918 struct excl_rel_decl excl;
919 struct unit_pattern_rel_decl presence;
920 struct unit_pattern_rel_decl absence;
921 struct reserv_decl reserv;
922 struct insn_reserv_decl insn_reserv;
923 } decl;
926 /* The following structures represent parsed reservation strings. */
927 enum regexp_mode
929 rm_unit,
930 rm_reserv,
931 rm_nothing,
932 rm_sequence,
933 rm_repeat,
934 rm_allof,
935 rm_oneof
938 /* Cpu unit in reservation. */
939 struct unit_regexp
941 char *name;
942 unit_decl_t unit_decl;
945 /* Define_reservation in a reservation. */
946 struct reserv_regexp
948 char *name;
949 struct reserv_decl *reserv_decl;
952 /* Absence of reservation (represented by string `nothing'). */
953 struct nothing_regexp
955 /* This used to be empty but ISO C doesn't allow that. */
956 char unused;
959 /* Representation of reservations separated by ',' (see file
960 rtl.def). */
961 struct sequence_regexp
963 int regexps_num;
964 regexp_t regexps [1];
967 /* Representation of construction `repeat' (see file rtl.def). */
968 struct repeat_regexp
970 int repeat_num;
971 regexp_t regexp;
974 /* Representation of reservations separated by '+' (see file
975 rtl.def). */
976 struct allof_regexp
978 int regexps_num;
979 regexp_t regexps [1];
982 /* Representation of reservations separated by '|' (see file
983 rtl.def). */
984 struct oneof_regexp
986 int regexps_num;
987 regexp_t regexps [1];
990 /* Representation of a reservation string. */
991 struct regexp
993 /* What node in the union? */
994 enum regexp_mode mode;
995 pos_t pos;
996 union
998 struct unit_regexp unit;
999 struct reserv_regexp reserv;
1000 struct nothing_regexp nothing;
1001 struct sequence_regexp sequence;
1002 struct repeat_regexp repeat;
1003 struct allof_regexp allof;
1004 struct oneof_regexp oneof;
1005 } regexp;
1008 /* Represents description of pipeline hazard description based on
1009 NDFA. */
1010 struct description
1012 int decls_num;
1014 /* The following fields are defined by checker. */
1016 /* The following fields values are correspondingly number of all
1017 units, query units, and insns in the description. */
1018 int units_num;
1019 int query_units_num;
1020 int insns_num;
1021 /* The following field value is max length (in cycles) of
1022 reservations of insns. The field value is defined only for
1023 correct programs. */
1024 int max_insn_reserv_cycles;
1026 /* The following fields are defined by automaton generator. */
1028 /* The following field value is the first automaton. */
1029 automaton_t first_automaton;
1031 /* The following field is created by pipeline hazard parser and
1032 contains all declarations. We allocate additional entry for
1033 special insn "cycle advancing" which is added by the automaton
1034 generator. */
1035 decl_t decls [1];
1039 /* The following nodes are created in automaton checker. */
1041 /* The following nodes represent exclusion set for cpu units. Each
1042 element is accessed through only one excl_list. */
1043 struct unit_set_el
1045 unit_decl_t unit_decl;
1046 unit_set_el_t next_unit_set_el;
1049 /* The following nodes represent presence or absence pattern for cpu
1050 units. Each element is accessed through only one presence_list or
1051 absence_list. */
1052 struct pattern_set_el
1054 /* The number of units in unit_decls. */
1055 int units_num;
1056 /* The units forming the pattern. */
1057 struct unit_decl **unit_decls;
1058 pattern_set_el_t next_pattern_set_el;
1062 /* The following nodes are created in automaton generator. */
1065 /* The following nodes represent presence or absence pattern for cpu
1066 units. Each element is accessed through only one element of
1067 unit_presence_set_table or unit_absence_set_table. */
1068 struct pattern_reserv
1070 reserv_sets_t reserv;
1071 pattern_reserv_t next_pattern_reserv;
1074 /* The following node type describes state automaton. The state may
1075 be deterministic or non-deterministic. Non-deterministic state has
1076 several component states which represent alternative cpu units
1077 reservations. The state also is used for describing a
1078 deterministic reservation of automaton insn. */
1079 struct state
1081 /* The following member value is nonzero if there is a transition by
1082 cycle advancing. */
1083 int new_cycle_p;
1084 /* The following field is list of processor unit reservations on
1085 each cycle. */
1086 reserv_sets_t reservs;
1087 /* The following field is unique number of given state between other
1088 states. */
1089 int unique_num;
1090 /* The following field value is automaton to which given state
1091 belongs. */
1092 automaton_t automaton;
1093 /* The following field value is the first arc output from given
1094 state. */
1095 arc_t first_out_arc;
1096 /* The following field is used to form NDFA. */
1097 char it_was_placed_in_stack_for_NDFA_forming;
1098 /* The following field is used to form DFA. */
1099 char it_was_placed_in_stack_for_DFA_forming;
1100 /* The following field is used to transform NDFA to DFA and DFA
1101 minimization. The field value is not NULL if the state is a
1102 compound state. In this case the value of field `unit_sets_list'
1103 is NULL. All states in the list are in the hash table. The list
1104 is formed through field `next_sorted_alt_state'. We should
1105 support only one level of nesting state. */
1106 alt_state_t component_states;
1107 /* The following field is used for passing graph of states. */
1108 int pass_num;
1109 /* The list of states belonging to one equivalence class is formed
1110 with the aid of the following field. */
1111 state_t next_equiv_class_state;
1112 /* The two following fields are used during minimization of a finite
1113 state automaton. */
1114 int equiv_class_num_1, equiv_class_num_2;
1115 /* The following field is used during minimization of a finite state
1116 automaton. The field value is state corresponding to equivalence
1117 class to which given state belongs. */
1118 state_t equiv_class_state;
1119 /* The following field value is the order number of given state.
1120 The states in final DFA is enumerated with the aid of the
1121 following field. */
1122 int order_state_num;
1123 /* This member is used for passing states for searching minimal
1124 delay time. */
1125 int state_pass_num;
1126 /* The following member is used to evaluate min issue delay of insn
1127 for a state. */
1128 int min_insn_issue_delay;
1129 /* The following member is used to evaluate max issue rate of the
1130 processor. The value of the member is maximal length of the path
1131 from given state no containing arcs marked by special insn `cycle
1132 advancing'. */
1133 int longest_path_length;
1136 /* The following macro is an initial value of member
1137 `longest_path_length' of a state. */
1138 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1140 /* Automaton arc. */
1141 struct arc
1143 /* The following field refers for the state into which given arc
1144 enters. */
1145 state_t to_state;
1146 /* The following field describes that the insn issue (with cycle
1147 advancing for special insn `cycle advancing' and without cycle
1148 advancing for others) makes transition from given state to
1149 another given state. */
1150 ainsn_t insn;
1151 /* The following field value is the next arc output from the same
1152 state. */
1153 arc_t next_out_arc;
1154 /* List of arcs marked given insn is formed with the following
1155 field. The field is used in transformation NDFA -> DFA. */
1156 arc_t next_arc_marked_by_insn;
1157 /* The following field is defined if NDFA_FLAG is zero. The member
1158 value is number of alternative reservations which can be used for
1159 transition for given state by given insn. */
1160 int state_alts;
1163 /* The following node type describes a deterministic alternative in
1164 non-deterministic state which characterizes cpu unit reservations
1165 of automaton insn or which is part of NDFA. */
1166 struct alt_state
1168 /* The following field is a deterministic state which characterizes
1169 unit reservations of the instruction. */
1170 state_t state;
1171 /* The following field refers to the next state which characterizes
1172 unit reservations of the instruction. */
1173 alt_state_t next_alt_state;
1174 /* The following field refers to the next state in sorted list. */
1175 alt_state_t next_sorted_alt_state;
1178 /* The following node type describes insn of automaton. They are
1179 labels of FA arcs. */
1180 struct ainsn
1182 /* The following field value is the corresponding insn declaration
1183 of description. */
1184 struct insn_reserv_decl *insn_reserv_decl;
1185 /* The following field value is the next insn declaration for an
1186 automaton. */
1187 ainsn_t next_ainsn;
1188 /* The following field is states which characterize automaton unit
1189 reservations of the instruction. The value can be NULL only if it
1190 is special insn `cycle advancing'. */
1191 alt_state_t alt_states;
1192 /* The following field is sorted list of states which characterize
1193 automaton unit reservations of the instruction. The value can be
1194 NULL only if it is special insn `cycle advancing'. */
1195 alt_state_t sorted_alt_states;
1196 /* The following field refers the next automaton insn with
1197 the same reservations. */
1198 ainsn_t next_same_reservs_insn;
1199 /* The following field is flag of the first automaton insn with the
1200 same reservations in the declaration list. Only arcs marked such
1201 insn is present in the automaton. This significantly decreases
1202 memory requirements especially when several automata are
1203 formed. */
1204 char first_insn_with_same_reservs;
1205 /* The following member has nonzero value if there is arc from state of
1206 the automaton marked by the ainsn. */
1207 char arc_exists_p;
1208 /* Cyclic list of insns of an equivalence class is formed with the
1209 aid of the following field. */
1210 ainsn_t next_equiv_class_insn;
1211 /* The following field value is nonzero if the insn declaration is
1212 the first insn declaration with given equivalence number. */
1213 char first_ainsn_with_given_equivalence_num;
1214 /* The following field is number of class of equivalence of insns.
1215 It is necessary because many insns may be equivalent with the
1216 point of view of pipeline hazards. */
1217 int insn_equiv_class_num;
1218 /* The following member value is TRUE if there is an arc in the
1219 automaton marked by the insn into another state. In other
1220 words, the insn can change the state of the automaton. */
1221 int important_p;
1224 /* The following describes an automaton for PHR. */
1225 struct automaton
1227 /* The following field value is the list of insn declarations for
1228 given automaton. */
1229 ainsn_t ainsn_list;
1230 /* The following field value is the corresponding automaton
1231 declaration. This field is not NULL only if the automatic
1232 partition on automata is not used. */
1233 struct automaton_decl *corresponding_automaton_decl;
1234 /* The following field value is the next automaton. */
1235 automaton_t next_automaton;
1236 /* The following field is start state of FA. There are not unit
1237 reservations in the state. */
1238 state_t start_state;
1239 /* The following field value is number of equivalence classes of
1240 insns (see field `insn_equiv_class_num' in
1241 `insn_reserv_decl'). */
1242 int insn_equiv_classes_num;
1243 /* The following field value is number of states of final DFA. */
1244 int achieved_states_num;
1245 /* The following field value is the order number (0, 1, ...) of
1246 given automaton. */
1247 int automaton_order_num;
1248 /* The following fields contain statistics information about
1249 building automaton. */
1250 int NDFA_states_num, DFA_states_num;
1251 /* The following field value is defined only if minimization of DFA
1252 is used. */
1253 int minimal_DFA_states_num;
1254 int NDFA_arcs_num, DFA_arcs_num;
1255 /* The following field value is defined only if minimization of DFA
1256 is used. */
1257 int minimal_DFA_arcs_num;
1258 /* The following two members refer for two table state x ainsn ->
1259 int. */
1260 state_ainsn_table_t trans_table;
1261 state_ainsn_table_t state_alts_table;
1262 /* The following member value is maximal value of min issue delay
1263 for insns of the automaton. */
1264 int max_min_delay;
1265 /* Usually min issue delay is small and we can place several (2, 4,
1266 8) elements in one vector element. So the compression factor can
1267 be 1 (no compression), 2, 4, 8. */
1268 int min_issue_delay_table_compression_factor;
1271 /* The following is the element of the list of automata. */
1272 struct automata_list_el
1274 /* The automaton itself. */
1275 automaton_t automaton;
1276 /* The next automata set element. */
1277 automata_list_el_t next_automata_list_el;
1280 /* The following structure describes a table state X ainsn -> int(>= 0). */
1281 struct state_ainsn_table
1283 /* Automaton to which given table belongs. */
1284 automaton_t automaton;
1285 /* The following tree vectors for comb vector implementation of the
1286 table. */
1287 vla_hwint_t comb_vect;
1288 vla_hwint_t check_vect;
1289 vla_hwint_t base_vect;
1290 /* This is simple implementation of the table. */
1291 vla_hwint_t full_vect;
1292 /* Minimal and maximal values of the previous vectors. */
1293 int min_comb_vect_el_value, max_comb_vect_el_value;
1294 int min_base_vect_el_value, max_base_vect_el_value;
1297 /* Macros to access members of unions. Use only them for access to
1298 union members of declarations and regexps. */
1300 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1302 #define DECL_UNIT(d) __extension__ \
1303 (({ struct decl *const _decl = (d); \
1304 if (_decl->mode != dm_unit) \
1305 decl_mode_check_failed (_decl->mode, "dm_unit", \
1306 __FILE__, __LINE__, __FUNCTION__); \
1307 &(_decl)->decl.unit; }))
1309 #define DECL_BYPASS(d) __extension__ \
1310 (({ struct decl *const _decl = (d); \
1311 if (_decl->mode != dm_bypass) \
1312 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1313 __FILE__, __LINE__, __FUNCTION__); \
1314 &(_decl)->decl.bypass; }))
1316 #define DECL_AUTOMATON(d) __extension__ \
1317 (({ struct decl *const _decl = (d); \
1318 if (_decl->mode != dm_automaton) \
1319 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1320 __FILE__, __LINE__, __FUNCTION__); \
1321 &(_decl)->decl.automaton; }))
1323 #define DECL_EXCL(d) __extension__ \
1324 (({ struct decl *const _decl = (d); \
1325 if (_decl->mode != dm_excl) \
1326 decl_mode_check_failed (_decl->mode, "dm_excl", \
1327 __FILE__, __LINE__, __FUNCTION__); \
1328 &(_decl)->decl.excl; }))
1330 #define DECL_PRESENCE(d) __extension__ \
1331 (({ struct decl *const _decl = (d); \
1332 if (_decl->mode != dm_presence) \
1333 decl_mode_check_failed (_decl->mode, "dm_presence", \
1334 __FILE__, __LINE__, __FUNCTION__); \
1335 &(_decl)->decl.presence; }))
1337 #define DECL_ABSENCE(d) __extension__ \
1338 (({ struct decl *const _decl = (d); \
1339 if (_decl->mode != dm_absence) \
1340 decl_mode_check_failed (_decl->mode, "dm_absence", \
1341 __FILE__, __LINE__, __FUNCTION__); \
1342 &(_decl)->decl.absence; }))
1344 #define DECL_RESERV(d) __extension__ \
1345 (({ struct decl *const _decl = (d); \
1346 if (_decl->mode != dm_reserv) \
1347 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1348 __FILE__, __LINE__, __FUNCTION__); \
1349 &(_decl)->decl.reserv; }))
1351 #define DECL_INSN_RESERV(d) __extension__ \
1352 (({ struct decl *const _decl = (d); \
1353 if (_decl->mode != dm_insn_reserv) \
1354 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1355 __FILE__, __LINE__, __FUNCTION__); \
1356 &(_decl)->decl.insn_reserv; }))
1358 static const char *decl_name (enum decl_mode);
1359 static void decl_mode_check_failed (enum decl_mode, const char *,
1360 const char *, int, const char *)
1361 ATTRIBUTE_NORETURN;
1363 /* Return string representation of declaration mode MODE. */
1364 static const char *
1365 decl_name (enum decl_mode mode)
1367 static char str [100];
1369 if (mode == dm_unit)
1370 return "dm_unit";
1371 else if (mode == dm_bypass)
1372 return "dm_bypass";
1373 else if (mode == dm_automaton)
1374 return "dm_automaton";
1375 else if (mode == dm_excl)
1376 return "dm_excl";
1377 else if (mode == dm_presence)
1378 return "dm_presence";
1379 else if (mode == dm_absence)
1380 return "dm_absence";
1381 else if (mode == dm_reserv)
1382 return "dm_reserv";
1383 else if (mode == dm_insn_reserv)
1384 return "dm_insn_reserv";
1385 else
1386 sprintf (str, "unknown (%d)", (int) mode);
1387 return str;
1390 /* The function prints message about unexpected declaration and finish
1391 the program. */
1392 static void
1393 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1394 const char *file, int line, const char *func)
1396 fprintf
1397 (stderr,
1398 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1399 file, line, func, expected_mode_str, decl_name (mode));
1400 exit (1);
1404 #define REGEXP_UNIT(r) __extension__ \
1405 (({ struct regexp *const _regexp = (r); \
1406 if (_regexp->mode != rm_unit) \
1407 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1408 __FILE__, __LINE__, __FUNCTION__); \
1409 &(_regexp)->regexp.unit; }))
1411 #define REGEXP_RESERV(r) __extension__ \
1412 (({ struct regexp *const _regexp = (r); \
1413 if (_regexp->mode != rm_reserv) \
1414 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1415 __FILE__, __LINE__, __FUNCTION__); \
1416 &(_regexp)->regexp.reserv; }))
1418 #define REGEXP_SEQUENCE(r) __extension__ \
1419 (({ struct regexp *const _regexp = (r); \
1420 if (_regexp->mode != rm_sequence) \
1421 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1422 __FILE__, __LINE__, __FUNCTION__); \
1423 &(_regexp)->regexp.sequence; }))
1425 #define REGEXP_REPEAT(r) __extension__ \
1426 (({ struct regexp *const _regexp = (r); \
1427 if (_regexp->mode != rm_repeat) \
1428 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1429 __FILE__, __LINE__, __FUNCTION__); \
1430 &(_regexp)->regexp.repeat; }))
1432 #define REGEXP_ALLOF(r) __extension__ \
1433 (({ struct regexp *const _regexp = (r); \
1434 if (_regexp->mode != rm_allof) \
1435 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1436 __FILE__, __LINE__, __FUNCTION__); \
1437 &(_regexp)->regexp.allof; }))
1439 #define REGEXP_ONEOF(r) __extension__ \
1440 (({ struct regexp *const _regexp = (r); \
1441 if (_regexp->mode != rm_oneof) \
1442 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1443 __FILE__, __LINE__, __FUNCTION__); \
1444 &(_regexp)->regexp.oneof; }))
1446 static const char *regexp_name (enum regexp_mode);
1447 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1448 const char *, int,
1449 const char *) ATTRIBUTE_NORETURN;
1452 /* Return string representation of regexp mode MODE. */
1453 static const char *
1454 regexp_name (enum regexp_mode mode)
1456 switch (mode)
1458 case rm_unit:
1459 return "rm_unit";
1460 case rm_reserv:
1461 return "rm_reserv";
1462 case rm_nothing:
1463 return "rm_nothing";
1464 case rm_sequence:
1465 return "rm_sequence";
1466 case rm_repeat:
1467 return "rm_repeat";
1468 case rm_allof:
1469 return "rm_allof";
1470 case rm_oneof:
1471 return "rm_oneof";
1472 default:
1473 gcc_unreachable ();
1477 /* The function prints message about unexpected regexp and finish the
1478 program. */
1479 static void
1480 regexp_mode_check_failed (enum regexp_mode mode,
1481 const char *expected_mode_str,
1482 const char *file, int line, const char *func)
1484 fprintf
1485 (stderr,
1486 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1487 file, line, func, expected_mode_str, regexp_name (mode));
1488 exit (1);
1491 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1493 #define DECL_UNIT(d) (&(d)->decl.unit)
1494 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1495 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1496 #define DECL_EXCL(d) (&(d)->decl.excl)
1497 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1498 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1499 #define DECL_RESERV(d) (&(d)->decl.reserv)
1500 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1502 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1503 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1504 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1505 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1506 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1507 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1509 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1511 /* Create IR structure (node). */
1512 static void *
1513 create_node (size_t size)
1515 void *result;
1517 obstack_blank (&irp, size);
1518 result = obstack_base (&irp);
1519 obstack_finish (&irp);
1520 /* Default values of members are NULL and zero. */
1521 memset (result, 0, size);
1522 return result;
1525 /* Copy IR structure (node). */
1526 static void *
1527 copy_node (const void *from, size_t size)
1529 void *const result = create_node (size);
1530 memcpy (result, from, size);
1531 return result;
1534 /* The function checks that NAME does not contain quotes (`"'). */
1535 static char *
1536 check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
1538 const char *str;
1540 for (str = name; *str != '\0'; str++)
1541 if (*str == '\"')
1542 error ("Name `%s' contains quotes", name);
1543 return name;
1546 /* Pointers to all declarations during IR generation are stored in the
1547 following. */
1548 static vla_ptr_t decls;
1550 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1551 string containing the next separated element, taking parentheses
1552 into account if PAR_FLAG has nonzero value. Advance the pointer to
1553 after the string scanned, or the end-of-string. Return NULL if at
1554 end of string. */
1555 static char *
1556 next_sep_el (char **pstr, int sep, int par_flag)
1558 char *out_str;
1559 char *p;
1560 int pars_num;
1561 int n_spaces;
1563 /* Remove leading whitespaces. */
1564 while (ISSPACE ((int) **pstr))
1565 (*pstr)++;
1567 if (**pstr == '\0')
1568 return NULL;
1570 n_spaces = 0;
1571 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1573 if (par_flag && *p == '(')
1574 pars_num++;
1575 else if (par_flag && *p == ')')
1576 pars_num--;
1577 else if (pars_num == 0 && *p == sep)
1578 break;
1579 if (pars_num == 0 && ISSPACE ((int) *p))
1580 n_spaces++;
1581 else
1583 for (; n_spaces != 0; n_spaces--)
1584 obstack_1grow (&irp, p [-n_spaces]);
1585 obstack_1grow (&irp, *p);
1588 obstack_1grow (&irp, '\0');
1589 out_str = obstack_base (&irp);
1590 obstack_finish (&irp);
1592 *pstr = p;
1593 if (**pstr == sep)
1594 (*pstr)++;
1596 return out_str;
1599 /* Given a string and a separator, return the number of separated
1600 elements in it, taking parentheses into account if PAR_FLAG has
1601 nonzero value. Return 0 for the null string, -1 if parentheses is
1602 not balanced. */
1603 static int
1604 n_sep_els (char *s, int sep, int par_flag)
1606 int n;
1607 int pars_num;
1609 if (*s == '\0')
1610 return 0;
1612 for (pars_num = 0, n = 1; *s; s++)
1613 if (par_flag && *s == '(')
1614 pars_num++;
1615 else if (par_flag && *s == ')')
1616 pars_num--;
1617 else if (pars_num == 0 && *s == sep)
1618 n++;
1620 return (pars_num != 0 ? -1 : n);
1623 /* Given a string and a separator, return vector of strings which are
1624 elements in the string and number of elements through els_num.
1625 Take parentheses into account if PAREN_P has nonzero value. The
1626 function also inserts the end marker NULL at the end of vector.
1627 Return 0 for the null string, -1 if parentheses are not balanced. */
1628 static char **
1629 get_str_vect (char *str, int *els_num, int sep, int paren_p)
1631 int i;
1632 char **vect;
1633 char **pstr;
1634 char *trail;
1636 *els_num = n_sep_els (str, sep, paren_p);
1637 if (*els_num <= 0)
1638 return NULL;
1639 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1640 vect = (char **) obstack_base (&irp);
1641 obstack_finish (&irp);
1642 pstr = &str;
1643 for (i = 0; i < *els_num; i++)
1644 vect [i] = next_sep_el (pstr, sep, paren_p);
1645 trail = next_sep_el (pstr, sep, paren_p);
1646 gcc_assert (!trail);
1647 vect [i] = NULL;
1648 return vect;
1651 /* Process a DEFINE_CPU_UNIT.
1653 This gives information about a unit contained in CPU. We fill a
1654 struct unit_decl with information used later by `expand_automata'. */
1655 void
1656 gen_cpu_unit (rtx def)
1658 decl_t decl;
1659 char **str_cpu_units;
1660 int vect_length;
1661 int i;
1663 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1664 FALSE);
1665 if (str_cpu_units == NULL)
1666 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1667 for (i = 0; i < vect_length; i++)
1669 decl = create_node (sizeof (struct decl));
1670 decl->mode = dm_unit;
1671 decl->pos = 0;
1672 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1673 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1674 DECL_UNIT (decl)->query_p = 0;
1675 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1676 DECL_UNIT (decl)->in_set_p = 0;
1677 VLA_PTR_ADD (decls, decl);
1678 num_dfa_decls++;
1682 /* Process a DEFINE_QUERY_CPU_UNIT.
1684 This gives information about a unit contained in CPU. We fill a
1685 struct unit_decl with information used later by `expand_automata'. */
1686 void
1687 gen_query_cpu_unit (rtx def)
1689 decl_t decl;
1690 char **str_cpu_units;
1691 int vect_length;
1692 int i;
1694 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1695 FALSE);
1696 if (str_cpu_units == NULL)
1697 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1698 for (i = 0; i < vect_length; i++)
1700 decl = create_node (sizeof (struct decl));
1701 decl->mode = dm_unit;
1702 decl->pos = 0;
1703 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1704 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1705 DECL_UNIT (decl)->query_p = 1;
1706 VLA_PTR_ADD (decls, decl);
1707 num_dfa_decls++;
1711 /* Process a DEFINE_BYPASS.
1713 This gives information about a unit contained in the CPU. We fill
1714 in a struct bypass_decl with information used later by
1715 `expand_automata'. */
1716 void
1717 gen_bypass (rtx def)
1719 decl_t decl;
1720 char **out_insns;
1721 int out_length;
1722 char **in_insns;
1723 int in_length;
1724 int i, j;
1726 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1727 if (out_insns == NULL)
1728 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1729 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1730 if (in_insns == NULL)
1731 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1732 for (i = 0; i < out_length; i++)
1733 for (j = 0; j < in_length; j++)
1735 decl = create_node (sizeof (struct decl));
1736 decl->mode = dm_bypass;
1737 decl->pos = 0;
1738 DECL_BYPASS (decl)->latency = XINT (def, 0);
1739 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1740 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1741 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1742 VLA_PTR_ADD (decls, decl);
1743 num_dfa_decls++;
1747 /* Process an EXCLUSION_SET.
1749 This gives information about a cpu unit conflicts. We fill a
1750 struct excl_rel_decl (excl) with information used later by
1751 `expand_automata'. */
1752 void
1753 gen_excl_set (rtx def)
1755 decl_t decl;
1756 char **first_str_cpu_units;
1757 char **second_str_cpu_units;
1758 int first_vect_length;
1759 int length;
1760 int i;
1762 first_str_cpu_units
1763 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1764 if (first_str_cpu_units == NULL)
1765 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1766 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1767 FALSE);
1768 if (second_str_cpu_units == NULL)
1769 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1770 length += first_vect_length;
1771 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1772 decl->mode = dm_excl;
1773 decl->pos = 0;
1774 DECL_EXCL (decl)->all_names_num = length;
1775 DECL_EXCL (decl)->first_list_length = first_vect_length;
1776 for (i = 0; i < length; i++)
1777 if (i < first_vect_length)
1778 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1779 else
1780 DECL_EXCL (decl)->names [i]
1781 = second_str_cpu_units [i - first_vect_length];
1782 VLA_PTR_ADD (decls, decl);
1783 num_dfa_decls++;
1786 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1787 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1789 This gives information about a cpu unit reservation requirements.
1790 We fill a struct unit_pattern_rel_decl with information used later
1791 by `expand_automata'. */
1792 static void
1793 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1795 decl_t decl;
1796 char **str_cpu_units;
1797 char ***str_patterns;
1798 int cpu_units_length;
1799 int length;
1800 int patterns_length;
1801 int i;
1803 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1804 FALSE);
1805 if (str_cpu_units == NULL)
1806 fatal ((presence_p
1807 ? (final_p
1808 ? "invalid first string `%s' in final_presence_set"
1809 : "invalid first string `%s' in presence_set")
1810 : (final_p
1811 ? "invalid first string `%s' in final_absence_set"
1812 : "invalid first string `%s' in absence_set")),
1813 XSTR (def, 0));
1814 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1815 &patterns_length, ',', FALSE);
1816 if (str_patterns == NULL)
1817 fatal ((presence_p
1818 ? (final_p
1819 ? "invalid second string `%s' in final_presence_set"
1820 : "invalid second string `%s' in presence_set")
1821 : (final_p
1822 ? "invalid second string `%s' in final_absence_set"
1823 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1824 for (i = 0; i < patterns_length; i++)
1826 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1827 FALSE);
1828 gcc_assert (str_patterns [i]);
1830 decl = create_node (sizeof (struct decl));
1831 decl->pos = 0;
1832 if (presence_p)
1834 decl->mode = dm_presence;
1835 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1836 DECL_PRESENCE (decl)->names = str_cpu_units;
1837 DECL_PRESENCE (decl)->patterns = str_patterns;
1838 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1839 DECL_PRESENCE (decl)->final_p = final_p;
1841 else
1843 decl->mode = dm_absence;
1844 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1845 DECL_ABSENCE (decl)->names = str_cpu_units;
1846 DECL_ABSENCE (decl)->patterns = str_patterns;
1847 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1848 DECL_ABSENCE (decl)->final_p = final_p;
1850 VLA_PTR_ADD (decls, decl);
1851 num_dfa_decls++;
1854 /* Process a PRESENCE_SET.
1856 This gives information about a cpu unit reservation requirements.
1857 We fill a struct unit_pattern_rel_decl (presence) with information
1858 used later by `expand_automata'. */
1859 void
1860 gen_presence_set (rtx def)
1862 gen_presence_absence_set (def, TRUE, FALSE);
1865 /* Process a FINAL_PRESENCE_SET.
1867 This gives information about a cpu unit reservation requirements.
1868 We fill a struct unit_pattern_rel_decl (presence) with information
1869 used later by `expand_automata'. */
1870 void
1871 gen_final_presence_set (rtx def)
1873 gen_presence_absence_set (def, TRUE, TRUE);
1876 /* Process an ABSENCE_SET.
1878 This gives information about a cpu unit reservation requirements.
1879 We fill a struct unit_pattern_rel_decl (absence) with information
1880 used later by `expand_automata'. */
1881 void
1882 gen_absence_set (rtx def)
1884 gen_presence_absence_set (def, FALSE, FALSE);
1887 /* Process a FINAL_ABSENCE_SET.
1889 This gives information about a cpu unit reservation requirements.
1890 We fill a struct unit_pattern_rel_decl (absence) with information
1891 used later by `expand_automata'. */
1892 void
1893 gen_final_absence_set (rtx def)
1895 gen_presence_absence_set (def, FALSE, TRUE);
1898 /* Process a DEFINE_AUTOMATON.
1900 This gives information about a finite state automaton used for
1901 recognizing pipeline hazards. We fill a struct automaton_decl
1902 with information used later by `expand_automata'. */
1903 void
1904 gen_automaton (rtx def)
1906 decl_t decl;
1907 char **str_automata;
1908 int vect_length;
1909 int i;
1911 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1912 FALSE);
1913 if (str_automata == NULL)
1914 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1915 for (i = 0; i < vect_length; i++)
1917 decl = create_node (sizeof (struct decl));
1918 decl->mode = dm_automaton;
1919 decl->pos = 0;
1920 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1921 VLA_PTR_ADD (decls, decl);
1922 num_dfa_decls++;
1926 /* Process an AUTOMATA_OPTION.
1928 This gives information how to generate finite state automaton used
1929 for recognizing pipeline hazards. */
1930 void
1931 gen_automata_option (rtx def)
1933 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1934 no_minimization_flag = 1;
1935 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1936 time_flag = 1;
1937 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1938 v_flag = 1;
1939 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1940 w_flag = 1;
1941 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1942 ndfa_flag = 1;
1943 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1944 progress_flag = 1;
1945 else
1946 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1949 /* Name in reservation to denote absence reservation. */
1950 #define NOTHING_NAME "nothing"
1952 /* The following string contains original reservation string being
1953 parsed. */
1954 static char *reserv_str;
1956 /* Parse an element in STR. */
1957 static regexp_t
1958 gen_regexp_el (char *str)
1960 regexp_t regexp;
1961 int len;
1963 if (*str == '(')
1965 len = strlen (str);
1966 if (str [len - 1] != ')')
1967 fatal ("garbage after ) in reservation `%s'", reserv_str);
1968 str [len - 1] = '\0';
1969 regexp = gen_regexp_sequence (str + 1);
1971 else if (strcmp (str, NOTHING_NAME) == 0)
1973 regexp = create_node (sizeof (struct decl));
1974 regexp->mode = rm_nothing;
1976 else
1978 regexp = create_node (sizeof (struct decl));
1979 regexp->mode = rm_unit;
1980 REGEXP_UNIT (regexp)->name = str;
1982 return regexp;
1985 /* Parse construction `repeat' in STR. */
1986 static regexp_t
1987 gen_regexp_repeat (char *str)
1989 regexp_t regexp;
1990 regexp_t repeat;
1991 char **repeat_vect;
1992 int els_num;
1993 int i;
1995 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1996 if (repeat_vect == NULL)
1997 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1998 if (els_num > 1)
2000 regexp = gen_regexp_el (repeat_vect [0]);
2001 for (i = 1; i < els_num; i++)
2003 repeat = create_node (sizeof (struct regexp));
2004 repeat->mode = rm_repeat;
2005 REGEXP_REPEAT (repeat)->regexp = regexp;
2006 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
2007 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
2008 fatal ("repetition `%s' <= 1 in reservation `%s'",
2009 str, reserv_str);
2010 regexp = repeat;
2012 return regexp;
2014 else
2015 return gen_regexp_el (str);
2018 /* Parse reservation STR which possibly contains separator '+'. */
2019 static regexp_t
2020 gen_regexp_allof (char *str)
2022 regexp_t allof;
2023 char **allof_vect;
2024 int els_num;
2025 int i;
2027 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
2028 if (allof_vect == NULL)
2029 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2030 if (els_num > 1)
2032 allof = create_node (sizeof (struct regexp)
2033 + sizeof (regexp_t) * (els_num - 1));
2034 allof->mode = rm_allof;
2035 REGEXP_ALLOF (allof)->regexps_num = els_num;
2036 for (i = 0; i < els_num; i++)
2037 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2038 return allof;
2040 else
2041 return gen_regexp_repeat (str);
2044 /* Parse reservation STR which possibly contains separator '|'. */
2045 static regexp_t
2046 gen_regexp_oneof (char *str)
2048 regexp_t oneof;
2049 char **oneof_vect;
2050 int els_num;
2051 int i;
2053 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
2054 if (oneof_vect == NULL)
2055 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2056 if (els_num > 1)
2058 oneof = create_node (sizeof (struct regexp)
2059 + sizeof (regexp_t) * (els_num - 1));
2060 oneof->mode = rm_oneof;
2061 REGEXP_ONEOF (oneof)->regexps_num = els_num;
2062 for (i = 0; i < els_num; i++)
2063 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2064 return oneof;
2066 else
2067 return gen_regexp_allof (str);
2070 /* Parse reservation STR which possibly contains separator ','. */
2071 static regexp_t
2072 gen_regexp_sequence (char *str)
2074 regexp_t sequence;
2075 char **sequence_vect;
2076 int els_num;
2077 int i;
2079 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
2080 if (els_num > 1)
2082 sequence = create_node (sizeof (struct regexp)
2083 + sizeof (regexp_t) * (els_num - 1));
2084 sequence->mode = rm_sequence;
2085 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
2086 for (i = 0; i < els_num; i++)
2087 REGEXP_SEQUENCE (sequence)->regexps [i]
2088 = gen_regexp_oneof (sequence_vect [i]);
2089 return sequence;
2091 else
2092 return gen_regexp_oneof (str);
2095 /* Parse construction reservation STR. */
2096 static regexp_t
2097 gen_regexp (char *str)
2099 reserv_str = str;
2100 return gen_regexp_sequence (str);;
2103 /* Process a DEFINE_RESERVATION.
2105 This gives information about a reservation of cpu units. We fill
2106 in a struct reserv_decl with information used later by
2107 `expand_automata'. */
2108 void
2109 gen_reserv (rtx def)
2111 decl_t decl;
2113 decl = create_node (sizeof (struct decl));
2114 decl->mode = dm_reserv;
2115 decl->pos = 0;
2116 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
2117 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2118 VLA_PTR_ADD (decls, decl);
2119 num_dfa_decls++;
2122 /* Process a DEFINE_INSN_RESERVATION.
2124 This gives information about the reservation of cpu units by an
2125 insn. We fill a struct insn_reserv_decl with information used
2126 later by `expand_automata'. */
2127 void
2128 gen_insn_reserv (rtx def)
2130 decl_t decl;
2132 decl = create_node (sizeof (struct decl));
2133 decl->mode = dm_insn_reserv;
2134 decl->pos = 0;
2135 DECL_INSN_RESERV (decl)->name
2136 = check_name ((char *) XSTR (def, 0), decl->pos);
2137 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2138 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2139 DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
2140 VLA_PTR_ADD (decls, decl);
2141 num_dfa_decls++;
2146 /* The function evaluates hash value (0..UINT_MAX) of string. */
2147 static unsigned
2148 string_hash (const char *string)
2150 unsigned result, i;
2152 for (result = i = 0;*string++ != '\0'; i++)
2153 result += ((unsigned char) *string << (i % CHAR_BIT));
2154 return result;
2159 /* This page contains abstract data `table of automaton declarations'.
2160 Elements of the table is nodes representing automaton declarations.
2161 Key of the table elements is name of given automaton. Remember
2162 that automaton names have own space. */
2164 /* The function evaluates hash value of an automaton declaration. The
2165 function is used by abstract data `hashtab'. The function returns
2166 hash value (0..UINT_MAX) of given automaton declaration. */
2167 static hashval_t
2168 automaton_decl_hash (const void *automaton_decl)
2170 const decl_t decl = (decl_t) automaton_decl;
2172 gcc_assert (decl->mode != dm_automaton
2173 || DECL_AUTOMATON (decl)->name);
2174 return string_hash (DECL_AUTOMATON (decl)->name);
2177 /* The function tests automaton declarations on equality of their
2178 keys. The function is used by abstract data `hashtab'. The
2179 function returns 1 if the declarations have the same key, 0
2180 otherwise. */
2181 static int
2182 automaton_decl_eq_p (const void* automaton_decl_1,
2183 const void* automaton_decl_2)
2185 const decl_t decl1 = (decl_t) automaton_decl_1;
2186 const decl_t decl2 = (decl_t) automaton_decl_2;
2188 gcc_assert (decl1->mode == dm_automaton
2189 && DECL_AUTOMATON (decl1)->name
2190 && decl2->mode == dm_automaton
2191 && DECL_AUTOMATON (decl2)->name);
2192 return strcmp (DECL_AUTOMATON (decl1)->name,
2193 DECL_AUTOMATON (decl2)->name) == 0;
2196 /* The automaton declaration table itself is represented by the
2197 following variable. */
2198 static htab_t automaton_decl_table;
2200 /* The function inserts automaton declaration into the table. The
2201 function does nothing if an automaton declaration with the same key
2202 exists already in the table. The function returns automaton
2203 declaration node in the table with the same key as given automaton
2204 declaration node. */
2205 static decl_t
2206 insert_automaton_decl (decl_t automaton_decl)
2208 void **entry_ptr;
2210 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2211 if (*entry_ptr == NULL)
2212 *entry_ptr = (void *) automaton_decl;
2213 return (decl_t) *entry_ptr;
2216 /* The following variable value is node representing automaton
2217 declaration. The node used for searching automaton declaration
2218 with given name. */
2219 static struct decl work_automaton_decl;
2221 /* The function searches for automaton declaration in the table with
2222 the same key as node representing name of the automaton
2223 declaration. The function returns node found in the table, NULL if
2224 such node does not exist in the table. */
2225 static decl_t
2226 find_automaton_decl (char *name)
2228 void *entry;
2230 work_automaton_decl.mode = dm_automaton;
2231 DECL_AUTOMATON (&work_automaton_decl)->name = name;
2232 entry = htab_find (automaton_decl_table, &work_automaton_decl);
2233 return (decl_t) entry;
2236 /* The function creates empty automaton declaration table and node
2237 representing automaton declaration and used for searching automaton
2238 declaration with given name. The function must be called only once
2239 before any work with the automaton declaration table. */
2240 static void
2241 initiate_automaton_decl_table (void)
2243 work_automaton_decl.mode = dm_automaton;
2244 automaton_decl_table = htab_create (10, automaton_decl_hash,
2245 automaton_decl_eq_p, (htab_del) 0);
2248 /* The function deletes the automaton declaration table. Only call of
2249 function `initiate_automaton_decl_table' is possible immediately
2250 after this function call. */
2251 static void
2252 finish_automaton_decl_table (void)
2254 htab_delete (automaton_decl_table);
2259 /* This page contains abstract data `table of insn declarations'.
2260 Elements of the table is nodes representing insn declarations. Key
2261 of the table elements is name of given insn (in corresponding
2262 define_insn_reservation). Remember that insn names have own
2263 space. */
2265 /* The function evaluates hash value of an insn declaration. The
2266 function is used by abstract data `hashtab'. The function returns
2267 hash value (0..UINT_MAX) of given insn declaration. */
2268 static hashval_t
2269 insn_decl_hash (const void *insn_decl)
2271 const decl_t decl = (decl_t) insn_decl;
2273 gcc_assert (decl->mode == dm_insn_reserv
2274 && DECL_INSN_RESERV (decl)->name);
2275 return string_hash (DECL_INSN_RESERV (decl)->name);
2278 /* The function tests insn declarations on equality of their keys.
2279 The function is used by abstract data `hashtab'. The function
2280 returns 1 if declarations have the same key, 0 otherwise. */
2281 static int
2282 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2284 const decl_t decl1 = (decl_t) insn_decl_1;
2285 const decl_t decl2 = (decl_t) insn_decl_2;
2287 gcc_assert (decl1->mode == dm_insn_reserv
2288 && DECL_INSN_RESERV (decl1)->name
2289 && decl2->mode == dm_insn_reserv
2290 && DECL_INSN_RESERV (decl2)->name);
2291 return strcmp (DECL_INSN_RESERV (decl1)->name,
2292 DECL_INSN_RESERV (decl2)->name) == 0;
2295 /* The insn declaration table itself is represented by the following
2296 variable. The table does not contain insn reservation
2297 declarations. */
2298 static htab_t insn_decl_table;
2300 /* The function inserts insn declaration into the table. The function
2301 does nothing if an insn declaration with the same key exists
2302 already in the table. The function returns insn declaration node
2303 in the table with the same key as given insn declaration node. */
2304 static decl_t
2305 insert_insn_decl (decl_t insn_decl)
2307 void **entry_ptr;
2309 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2310 if (*entry_ptr == NULL)
2311 *entry_ptr = (void *) insn_decl;
2312 return (decl_t) *entry_ptr;
2315 /* The following variable value is node representing insn reservation
2316 declaration. The node used for searching insn reservation
2317 declaration with given name. */
2318 static struct decl work_insn_decl;
2320 /* The function searches for insn reservation declaration in the table
2321 with the same key as node representing name of the insn reservation
2322 declaration. The function returns node found in the table, NULL if
2323 such node does not exist in the table. */
2324 static decl_t
2325 find_insn_decl (char *name)
2327 void *entry;
2329 work_insn_decl.mode = dm_insn_reserv;
2330 DECL_INSN_RESERV (&work_insn_decl)->name = name;
2331 entry = htab_find (insn_decl_table, &work_insn_decl);
2332 return (decl_t) entry;
2335 /* The function creates empty insn declaration table and node
2336 representing insn declaration and used for searching insn
2337 declaration with given name. The function must be called only once
2338 before any work with the insn declaration table. */
2339 static void
2340 initiate_insn_decl_table (void)
2342 work_insn_decl.mode = dm_insn_reserv;
2343 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2344 (htab_del) 0);
2347 /* The function deletes the insn declaration table. Only call of
2348 function `initiate_insn_decl_table' is possible immediately after
2349 this function call. */
2350 static void
2351 finish_insn_decl_table (void)
2353 htab_delete (insn_decl_table);
2358 /* This page contains abstract data `table of declarations'. Elements
2359 of the table is nodes representing declarations (of units and
2360 reservations). Key of the table elements is names of given
2361 declarations. */
2363 /* The function evaluates hash value of a declaration. The function
2364 is used by abstract data `hashtab'. The function returns hash
2365 value (0..UINT_MAX) of given declaration. */
2366 static hashval_t
2367 decl_hash (const void *decl)
2369 const decl_t d = (const decl_t) decl;
2371 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
2372 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
2373 return string_hash (d->mode == dm_unit
2374 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2377 /* The function tests declarations on equality of their keys. The
2378 function is used by abstract data 'hashtab'. The function
2379 returns 1 if the declarations have the same key, 0 otherwise. */
2380 static int
2381 decl_eq_p (const void *decl_1, const void *decl_2)
2383 const decl_t d1 = (const decl_t) decl_1;
2384 const decl_t d2 = (const decl_t) decl_2;
2386 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
2387 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
2388 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
2389 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
2390 return strcmp ((d1->mode == dm_unit
2391 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2392 (d2->mode == dm_unit
2393 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2396 /* The declaration table itself is represented by the following
2397 variable. */
2398 static htab_t decl_table;
2400 /* The function inserts declaration into the table. The function does
2401 nothing if a declaration with the same key exists already in the
2402 table. The function returns declaration node in the table with the
2403 same key as given declaration node. */
2405 static decl_t
2406 insert_decl (decl_t decl)
2408 void **entry_ptr;
2410 entry_ptr = htab_find_slot (decl_table, decl, 1);
2411 if (*entry_ptr == NULL)
2412 *entry_ptr = (void *) decl;
2413 return (decl_t) *entry_ptr;
2416 /* The following variable value is node representing declaration. The
2417 node used for searching declaration with given name. */
2418 static struct decl work_decl;
2420 /* The function searches for declaration in the table with the same
2421 key as node representing name of the declaration. The function
2422 returns node found in the table, NULL if such node does not exist
2423 in the table. */
2424 static decl_t
2425 find_decl (char *name)
2427 void *entry;
2429 work_decl.mode = dm_unit;
2430 DECL_UNIT (&work_decl)->name = name;
2431 entry = htab_find (decl_table, &work_decl);
2432 return (decl_t) entry;
2435 /* The function creates empty declaration table and node representing
2436 declaration and used for searching declaration with given name.
2437 The function must be called only once before any work with the
2438 declaration table. */
2439 static void
2440 initiate_decl_table (void)
2442 work_decl.mode = dm_unit;
2443 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2446 /* The function deletes the declaration table. Only call of function
2447 `initiate_declaration_table' is possible immediately after this
2448 function call. */
2449 static void
2450 finish_decl_table (void)
2452 htab_delete (decl_table);
2457 /* This page contains checker of pipeline hazard description. */
2459 /* Checking NAMES in an exclusion clause vector and returning formed
2460 unit_set_el_list. */
2461 static unit_set_el_t
2462 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2464 unit_set_el_t el_list;
2465 unit_set_el_t last_el;
2466 unit_set_el_t new_el;
2467 decl_t decl_in_table;
2468 int i;
2470 el_list = NULL;
2471 last_el = NULL;
2472 for (i = 0; i < num; i++)
2474 decl_in_table = find_decl (names [i]);
2475 if (decl_in_table == NULL)
2476 error ("unit `%s' in exclusion is not declared", names [i]);
2477 else if (decl_in_table->mode != dm_unit)
2478 error ("`%s' in exclusion is not unit", names [i]);
2479 else
2481 new_el = create_node (sizeof (struct unit_set_el));
2482 new_el->unit_decl = DECL_UNIT (decl_in_table);
2483 new_el->next_unit_set_el = NULL;
2484 if (last_el == NULL)
2485 el_list = last_el = new_el;
2486 else
2488 last_el->next_unit_set_el = new_el;
2489 last_el = last_el->next_unit_set_el;
2493 return el_list;
2496 /* The function adds each element from SOURCE_LIST to the exclusion
2497 list of the each element from DEST_LIST. Checking situation "unit
2498 excludes itself". */
2499 static void
2500 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2501 pos_t excl_pos ATTRIBUTE_UNUSED)
2503 unit_set_el_t dst;
2504 unit_set_el_t src;
2505 unit_set_el_t curr_el;
2506 unit_set_el_t prev_el;
2507 unit_set_el_t copy;
2509 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2510 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2512 if (dst->unit_decl == src->unit_decl)
2514 error ("unit `%s' excludes itself", src->unit_decl->name);
2515 continue;
2517 if (dst->unit_decl->automaton_name != NULL
2518 && src->unit_decl->automaton_name != NULL
2519 && strcmp (dst->unit_decl->automaton_name,
2520 src->unit_decl->automaton_name) != 0)
2522 error ("units `%s' and `%s' in exclusion set belong to different automata",
2523 src->unit_decl->name, dst->unit_decl->name);
2524 continue;
2526 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2527 curr_el != NULL;
2528 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2529 if (curr_el->unit_decl == src->unit_decl)
2530 break;
2531 if (curr_el == NULL)
2533 /* Element not found - insert. */
2534 copy = copy_node (src, sizeof (*src));
2535 copy->next_unit_set_el = NULL;
2536 if (prev_el == NULL)
2537 dst->unit_decl->excl_list = copy;
2538 else
2539 prev_el->next_unit_set_el = copy;
2544 /* Checking NAMES in presence/absence clause and returning the
2545 formed unit_set_el_list. The function is called only after
2546 processing all exclusion sets. */
2547 static unit_set_el_t
2548 process_presence_absence_names (char **names, int num,
2549 pos_t req_pos ATTRIBUTE_UNUSED,
2550 int presence_p, int final_p)
2552 unit_set_el_t el_list;
2553 unit_set_el_t last_el;
2554 unit_set_el_t new_el;
2555 decl_t decl_in_table;
2556 int i;
2558 el_list = NULL;
2559 last_el = NULL;
2560 for (i = 0; i < num; i++)
2562 decl_in_table = find_decl (names [i]);
2563 if (decl_in_table == NULL)
2564 error ((presence_p
2565 ? (final_p
2566 ? "unit `%s' in final presence set is not declared"
2567 : "unit `%s' in presence set is not declared")
2568 : (final_p
2569 ? "unit `%s' in final absence set is not declared"
2570 : "unit `%s' in absence set is not declared")), names [i]);
2571 else if (decl_in_table->mode != dm_unit)
2572 error ((presence_p
2573 ? (final_p
2574 ? "`%s' in final presence set is not unit"
2575 : "`%s' in presence set is not unit")
2576 : (final_p
2577 ? "`%s' in final absence set is not unit"
2578 : "`%s' in absence set is not unit")), names [i]);
2579 else
2581 new_el = create_node (sizeof (struct unit_set_el));
2582 new_el->unit_decl = DECL_UNIT (decl_in_table);
2583 new_el->next_unit_set_el = NULL;
2584 if (last_el == NULL)
2585 el_list = last_el = new_el;
2586 else
2588 last_el->next_unit_set_el = new_el;
2589 last_el = last_el->next_unit_set_el;
2593 return el_list;
2596 /* Checking NAMES in patterns of a presence/absence clause and
2597 returning the formed pattern_set_el_list. The function is called
2598 only after processing all exclusion sets. */
2599 static pattern_set_el_t
2600 process_presence_absence_patterns (char ***patterns, int num,
2601 pos_t req_pos ATTRIBUTE_UNUSED,
2602 int presence_p, int final_p)
2604 pattern_set_el_t el_list;
2605 pattern_set_el_t last_el;
2606 pattern_set_el_t new_el;
2607 decl_t decl_in_table;
2608 int i, j;
2610 el_list = NULL;
2611 last_el = NULL;
2612 for (i = 0; i < num; i++)
2614 for (j = 0; patterns [i] [j] != NULL; j++)
2616 new_el = create_node (sizeof (struct pattern_set_el)
2617 + sizeof (struct unit_decl *) * j);
2618 new_el->unit_decls
2619 = (struct unit_decl **) ((char *) new_el
2620 + sizeof (struct pattern_set_el));
2621 new_el->next_pattern_set_el = NULL;
2622 if (last_el == NULL)
2623 el_list = last_el = new_el;
2624 else
2626 last_el->next_pattern_set_el = new_el;
2627 last_el = last_el->next_pattern_set_el;
2629 new_el->units_num = 0;
2630 for (j = 0; patterns [i] [j] != NULL; j++)
2632 decl_in_table = find_decl (patterns [i] [j]);
2633 if (decl_in_table == NULL)
2634 error ((presence_p
2635 ? (final_p
2636 ? "unit `%s' in final presence set is not declared"
2637 : "unit `%s' in presence set is not declared")
2638 : (final_p
2639 ? "unit `%s' in final absence set is not declared"
2640 : "unit `%s' in absence set is not declared")),
2641 patterns [i] [j]);
2642 else if (decl_in_table->mode != dm_unit)
2643 error ((presence_p
2644 ? (final_p
2645 ? "`%s' in final presence set is not unit"
2646 : "`%s' in presence set is not unit")
2647 : (final_p
2648 ? "`%s' in final absence set is not unit"
2649 : "`%s' in absence set is not unit")),
2650 patterns [i] [j]);
2651 else
2653 new_el->unit_decls [new_el->units_num]
2654 = DECL_UNIT (decl_in_table);
2655 new_el->units_num++;
2659 return el_list;
2662 /* The function adds each element from PATTERN_LIST to presence (if
2663 PRESENCE_P) or absence list of the each element from DEST_LIST.
2664 Checking situations "unit requires own absence", and "unit excludes
2665 and requires presence of ...", "unit requires absence and presence
2666 of ...", "units in (final) presence set belong to different
2667 automata", and "units in (final) absence set belong to different
2668 automata". Remember that we process absence sets only after all
2669 presence sets. */
2670 static void
2671 add_presence_absence (unit_set_el_t dest_list,
2672 pattern_set_el_t pattern_list,
2673 pos_t req_pos ATTRIBUTE_UNUSED,
2674 int presence_p, int final_p)
2676 unit_set_el_t dst;
2677 pattern_set_el_t pat;
2678 struct unit_decl *unit;
2679 unit_set_el_t curr_excl_el;
2680 pattern_set_el_t curr_pat_el;
2681 pattern_set_el_t prev_el;
2682 pattern_set_el_t copy;
2683 int i;
2684 int no_error_flag;
2686 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2687 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2689 for (i = 0; i < pat->units_num; i++)
2691 unit = pat->unit_decls [i];
2692 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2694 error ("unit `%s' requires own absence", unit->name);
2695 continue;
2697 if (dst->unit_decl->automaton_name != NULL
2698 && unit->automaton_name != NULL
2699 && strcmp (dst->unit_decl->automaton_name,
2700 unit->automaton_name) != 0)
2702 error ((presence_p
2703 ? (final_p
2704 ? "units `%s' and `%s' in final presence set belong to different automata"
2705 : "units `%s' and `%s' in presence set belong to different automata")
2706 : (final_p
2707 ? "units `%s' and `%s' in final absence set belong to different automata"
2708 : "units `%s' and `%s' in absence set belong to different automata")),
2709 unit->name, dst->unit_decl->name);
2710 continue;
2712 no_error_flag = 1;
2713 if (presence_p)
2714 for (curr_excl_el = dst->unit_decl->excl_list;
2715 curr_excl_el != NULL;
2716 curr_excl_el = curr_excl_el->next_unit_set_el)
2718 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2720 if (!w_flag)
2722 error ("unit `%s' excludes and requires presence of `%s'",
2723 dst->unit_decl->name, unit->name);
2724 no_error_flag = 0;
2726 else
2727 warning
2728 (0, "unit `%s' excludes and requires presence of `%s'",
2729 dst->unit_decl->name, unit->name);
2732 else if (pat->units_num == 1)
2733 for (curr_pat_el = dst->unit_decl->presence_list;
2734 curr_pat_el != NULL;
2735 curr_pat_el = curr_pat_el->next_pattern_set_el)
2736 if (curr_pat_el->units_num == 1
2737 && unit == curr_pat_el->unit_decls [0])
2739 if (!w_flag)
2741 error
2742 ("unit `%s' requires absence and presence of `%s'",
2743 dst->unit_decl->name, unit->name);
2744 no_error_flag = 0;
2746 else
2747 warning
2748 (0, "unit `%s' requires absence and presence of `%s'",
2749 dst->unit_decl->name, unit->name);
2751 if (no_error_flag)
2753 for (prev_el = (presence_p
2754 ? (final_p
2755 ? dst->unit_decl->final_presence_list
2756 : dst->unit_decl->final_presence_list)
2757 : (final_p
2758 ? dst->unit_decl->final_absence_list
2759 : dst->unit_decl->absence_list));
2760 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2761 prev_el = prev_el->next_pattern_set_el)
2763 copy = copy_node (pat, sizeof (*pat));
2764 copy->next_pattern_set_el = NULL;
2765 if (prev_el == NULL)
2767 if (presence_p)
2769 if (final_p)
2770 dst->unit_decl->final_presence_list = copy;
2771 else
2772 dst->unit_decl->presence_list = copy;
2774 else if (final_p)
2775 dst->unit_decl->final_absence_list = copy;
2776 else
2777 dst->unit_decl->absence_list = copy;
2779 else
2780 prev_el->next_pattern_set_el = copy;
2787 /* The function searches for bypass with given IN_INSN_RESERV in given
2788 BYPASS_LIST. */
2789 static struct bypass_decl *
2790 find_bypass (struct bypass_decl *bypass_list,
2791 struct insn_reserv_decl *in_insn_reserv)
2793 struct bypass_decl *bypass;
2795 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2796 if (bypass->in_insn_reserv == in_insn_reserv)
2797 break;
2798 return bypass;
2801 /* The function processes pipeline description declarations, checks
2802 their correctness, and forms exclusion/presence/absence sets. */
2803 static void
2804 process_decls (void)
2806 decl_t decl;
2807 decl_t automaton_decl;
2808 decl_t decl_in_table;
2809 decl_t out_insn_reserv;
2810 decl_t in_insn_reserv;
2811 struct bypass_decl *bypass;
2812 int automaton_presence;
2813 int i;
2815 /* Checking repeated automata declarations. */
2816 automaton_presence = 0;
2817 for (i = 0; i < description->decls_num; i++)
2819 decl = description->decls [i];
2820 if (decl->mode == dm_automaton)
2822 automaton_presence = 1;
2823 decl_in_table = insert_automaton_decl (decl);
2824 if (decl_in_table != decl)
2826 if (!w_flag)
2827 error ("repeated declaration of automaton `%s'",
2828 DECL_AUTOMATON (decl)->name);
2829 else
2830 warning (0, "repeated declaration of automaton `%s'",
2831 DECL_AUTOMATON (decl)->name);
2835 /* Checking undeclared automata, repeated declarations (except for
2836 automata) and correctness of their attributes (insn latency times
2837 etc.). */
2838 for (i = 0; i < description->decls_num; i++)
2840 decl = description->decls [i];
2841 if (decl->mode == dm_insn_reserv)
2843 DECL_INSN_RESERV (decl)->condexp
2844 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2845 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2846 error ("define_insn_reservation `%s' has negative latency time",
2847 DECL_INSN_RESERV (decl)->name);
2848 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2849 description->insns_num++;
2850 decl_in_table = insert_insn_decl (decl);
2851 if (decl_in_table != decl)
2852 error ("`%s' is already used as insn reservation name",
2853 DECL_INSN_RESERV (decl)->name);
2855 else if (decl->mode == dm_bypass)
2857 if (DECL_BYPASS (decl)->latency < 0)
2858 error ("define_bypass `%s - %s' has negative latency time",
2859 DECL_BYPASS (decl)->out_insn_name,
2860 DECL_BYPASS (decl)->in_insn_name);
2862 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2864 if (decl->mode == dm_unit)
2866 DECL_UNIT (decl)->automaton_decl = NULL;
2867 if (DECL_UNIT (decl)->automaton_name != NULL)
2869 automaton_decl
2870 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2871 if (automaton_decl == NULL)
2872 error ("automaton `%s' is not declared",
2873 DECL_UNIT (decl)->automaton_name);
2874 else
2876 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2877 DECL_UNIT (decl)->automaton_decl
2878 = DECL_AUTOMATON (automaton_decl);
2881 else if (automaton_presence)
2882 error ("define_unit `%s' without automaton when one defined",
2883 DECL_UNIT (decl)->name);
2884 DECL_UNIT (decl)->unit_num = description->units_num;
2885 description->units_num++;
2886 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2888 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2889 continue;
2891 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2893 else
2895 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2897 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2898 continue;
2900 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2902 if (decl_in_table == NULL)
2903 decl_in_table = insert_decl (decl);
2904 else
2906 if (decl->mode == dm_unit)
2907 error ("repeated declaration of unit `%s'",
2908 DECL_UNIT (decl)->name);
2909 else
2910 error ("repeated declaration of reservation `%s'",
2911 DECL_RESERV (decl)->name);
2915 /* Check bypasses and form list of bypasses for each (output)
2916 insn. */
2917 for (i = 0; i < description->decls_num; i++)
2919 decl = description->decls [i];
2920 if (decl->mode == dm_bypass)
2922 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2923 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2924 if (out_insn_reserv == NULL)
2925 error ("there is no insn reservation `%s'",
2926 DECL_BYPASS (decl)->out_insn_name);
2927 else if (in_insn_reserv == NULL)
2928 error ("there is no insn reservation `%s'",
2929 DECL_BYPASS (decl)->in_insn_name);
2930 else
2932 DECL_BYPASS (decl)->out_insn_reserv
2933 = DECL_INSN_RESERV (out_insn_reserv);
2934 DECL_BYPASS (decl)->in_insn_reserv
2935 = DECL_INSN_RESERV (in_insn_reserv);
2936 bypass
2937 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2938 DECL_BYPASS (decl)->in_insn_reserv);
2939 if (bypass != NULL)
2941 if (DECL_BYPASS (decl)->latency == bypass->latency)
2943 if (!w_flag)
2944 error
2945 ("the same bypass `%s - %s' is already defined",
2946 DECL_BYPASS (decl)->out_insn_name,
2947 DECL_BYPASS (decl)->in_insn_name);
2948 else
2949 warning
2950 (0, "the same bypass `%s - %s' is already defined",
2951 DECL_BYPASS (decl)->out_insn_name,
2952 DECL_BYPASS (decl)->in_insn_name);
2954 else
2955 error ("bypass `%s - %s' is already defined",
2956 DECL_BYPASS (decl)->out_insn_name,
2957 DECL_BYPASS (decl)->in_insn_name);
2959 else
2961 DECL_BYPASS (decl)->next
2962 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2963 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2964 = DECL_BYPASS (decl);
2970 /* Check exclusion set declarations and form exclusion sets. */
2971 for (i = 0; i < description->decls_num; i++)
2973 decl = description->decls [i];
2974 if (decl->mode == dm_excl)
2976 unit_set_el_t unit_set_el_list;
2977 unit_set_el_t unit_set_el_list_2;
2979 unit_set_el_list
2980 = process_excls (DECL_EXCL (decl)->names,
2981 DECL_EXCL (decl)->first_list_length, decl->pos);
2982 unit_set_el_list_2
2983 = process_excls (&DECL_EXCL (decl)->names
2984 [DECL_EXCL (decl)->first_list_length],
2985 DECL_EXCL (decl)->all_names_num
2986 - DECL_EXCL (decl)->first_list_length,
2987 decl->pos);
2988 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2989 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2993 /* Check presence set declarations and form presence sets. */
2994 for (i = 0; i < description->decls_num; i++)
2996 decl = description->decls [i];
2997 if (decl->mode == dm_presence)
2999 unit_set_el_t unit_set_el_list;
3000 pattern_set_el_t pattern_set_el_list;
3002 unit_set_el_list
3003 = process_presence_absence_names
3004 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
3005 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3006 pattern_set_el_list
3007 = process_presence_absence_patterns
3008 (DECL_PRESENCE (decl)->patterns,
3009 DECL_PRESENCE (decl)->patterns_num,
3010 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3011 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3012 decl->pos, TRUE,
3013 DECL_PRESENCE (decl)->final_p);
3017 /* Check absence set declarations and form absence sets. */
3018 for (i = 0; i < description->decls_num; i++)
3020 decl = description->decls [i];
3021 if (decl->mode == dm_absence)
3023 unit_set_el_t unit_set_el_list;
3024 pattern_set_el_t pattern_set_el_list;
3026 unit_set_el_list
3027 = process_presence_absence_names
3028 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3029 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3030 pattern_set_el_list
3031 = process_presence_absence_patterns
3032 (DECL_ABSENCE (decl)->patterns,
3033 DECL_ABSENCE (decl)->patterns_num,
3034 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3035 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3036 decl->pos, FALSE,
3037 DECL_ABSENCE (decl)->final_p);
3042 /* The following function checks that declared automaton is used. If
3043 the automaton is not used, the function fixes error/warning. The
3044 following function must be called only after `process_decls'. */
3045 static void
3046 check_automaton_usage (void)
3048 decl_t decl;
3049 int i;
3051 for (i = 0; i < description->decls_num; i++)
3053 decl = description->decls [i];
3054 if (decl->mode == dm_automaton
3055 && !DECL_AUTOMATON (decl)->automaton_is_used)
3057 if (!w_flag)
3058 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3059 else
3060 warning (0, "automaton `%s' is not used",
3061 DECL_AUTOMATON (decl)->name);
3066 /* The following recursive function processes all regexp in order to
3067 fix usage of units or reservations and to fix errors of undeclared
3068 name. The function may change unit_regexp onto reserv_regexp.
3069 Remember that reserv_regexp does not exist before the function
3070 call. */
3071 static regexp_t
3072 process_regexp (regexp_t regexp)
3074 decl_t decl_in_table;
3075 regexp_t new_regexp;
3076 int i;
3078 switch (regexp->mode)
3080 case rm_unit:
3081 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3082 if (decl_in_table == NULL)
3083 error ("undeclared unit or reservation `%s'",
3084 REGEXP_UNIT (regexp)->name);
3085 else
3086 switch (decl_in_table->mode)
3088 case dm_unit:
3089 DECL_UNIT (decl_in_table)->unit_is_used = 1;
3090 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3091 break;
3093 case dm_reserv:
3094 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3095 new_regexp = create_node (sizeof (struct regexp));
3096 new_regexp->mode = rm_reserv;
3097 new_regexp->pos = regexp->pos;
3098 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3099 REGEXP_RESERV (new_regexp)->reserv_decl
3100 = DECL_RESERV (decl_in_table);
3101 regexp = new_regexp;
3102 break;
3104 default:
3105 gcc_unreachable ();
3107 break;
3108 case rm_sequence:
3109 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3110 REGEXP_SEQUENCE (regexp)->regexps [i]
3111 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3112 break;
3113 case rm_allof:
3114 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3115 REGEXP_ALLOF (regexp)->regexps [i]
3116 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3117 break;
3118 case rm_oneof:
3119 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3120 REGEXP_ONEOF (regexp)->regexps [i]
3121 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3122 break;
3123 case rm_repeat:
3124 REGEXP_REPEAT (regexp)->regexp
3125 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3126 break;
3127 case rm_nothing:
3128 break;
3129 default:
3130 gcc_unreachable ();
3132 return regexp;
3135 /* The following function processes regexp of define_reservation and
3136 define_insn_reservation with the aid of function
3137 `process_regexp'. */
3138 static void
3139 process_regexp_decls (void)
3141 decl_t decl;
3142 int i;
3144 for (i = 0; i < description->decls_num; i++)
3146 decl = description->decls [i];
3147 if (decl->mode == dm_reserv)
3148 DECL_RESERV (decl)->regexp
3149 = process_regexp (DECL_RESERV (decl)->regexp);
3150 else if (decl->mode == dm_insn_reserv)
3151 DECL_INSN_RESERV (decl)->regexp
3152 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3156 /* The following function checks that declared unit is used. If the
3157 unit is not used, the function fixes errors/warnings. The
3158 following function must be called only after `process_decls',
3159 `process_regexp_decls'. */
3160 static void
3161 check_usage (void)
3163 decl_t decl;
3164 int i;
3166 for (i = 0; i < description->decls_num; i++)
3168 decl = description->decls [i];
3169 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3171 if (!w_flag)
3172 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3173 else
3174 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
3176 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3178 if (!w_flag)
3179 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3180 else
3181 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
3186 /* The following variable value is number of reservation being
3187 processed on loop recognition. */
3188 static int curr_loop_pass_num;
3190 /* The following recursive function returns nonzero value if REGEXP
3191 contains given decl or reservations in given regexp refers for
3192 given decl. */
3193 static int
3194 loop_in_regexp (regexp_t regexp, decl_t start_decl)
3196 int i;
3198 if (regexp == NULL)
3199 return 0;
3200 switch (regexp->mode)
3202 case rm_unit:
3203 return 0;
3205 case rm_reserv:
3206 if (start_decl->mode == dm_reserv
3207 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3208 return 1;
3209 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3210 == curr_loop_pass_num)
3211 /* declaration has been processed. */
3212 return 0;
3213 else
3215 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3216 = curr_loop_pass_num;
3217 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3218 start_decl);
3221 case rm_sequence:
3222 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3223 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3224 return 1;
3225 return 0;
3227 case rm_allof:
3228 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3229 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3230 return 1;
3231 return 0;
3233 case rm_oneof:
3234 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3235 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3236 return 1;
3237 return 0;
3239 case rm_repeat:
3240 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3242 case rm_nothing:
3243 return 0;
3245 default:
3246 gcc_unreachable ();
3250 /* The following function fixes errors "cycle in definition ...". The
3251 function uses function `loop_in_regexp' for that. */
3252 static void
3253 check_loops_in_regexps (void)
3255 decl_t decl;
3256 int i;
3258 for (i = 0; i < description->decls_num; i++)
3260 decl = description->decls [i];
3261 if (decl->mode == dm_reserv)
3262 DECL_RESERV (decl)->loop_pass_num = 0;
3264 for (i = 0; i < description->decls_num; i++)
3266 decl = description->decls [i];
3267 curr_loop_pass_num = i;
3269 if (decl->mode == dm_reserv)
3271 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3272 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3274 gcc_assert (DECL_RESERV (decl)->regexp);
3275 error ("cycle in definition of reservation `%s'",
3276 DECL_RESERV (decl)->name);
3282 /* The function recursively processes IR of reservation and defines
3283 max and min cycle for reservation of unit. */
3284 static void
3285 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3286 int min_start_cycle, int *max_finish_cycle,
3287 int *min_finish_cycle)
3289 int i;
3291 switch (regexp->mode)
3293 case rm_unit:
3294 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3295 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3296 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3297 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3298 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3299 *max_finish_cycle = max_start_cycle;
3300 *min_finish_cycle = min_start_cycle;
3301 break;
3303 case rm_reserv:
3304 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3305 max_start_cycle, min_start_cycle,
3306 max_finish_cycle, min_finish_cycle);
3307 break;
3309 case rm_repeat:
3310 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3312 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3313 max_start_cycle, min_start_cycle,
3314 max_finish_cycle, min_finish_cycle);
3315 max_start_cycle = *max_finish_cycle + 1;
3316 min_start_cycle = *min_finish_cycle + 1;
3318 break;
3320 case rm_sequence:
3321 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3323 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3324 max_start_cycle, min_start_cycle,
3325 max_finish_cycle, min_finish_cycle);
3326 max_start_cycle = *max_finish_cycle + 1;
3327 min_start_cycle = *min_finish_cycle + 1;
3329 break;
3331 case rm_allof:
3333 int max_cycle = 0;
3334 int min_cycle = 0;
3336 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3338 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3339 max_start_cycle, min_start_cycle,
3340 max_finish_cycle, min_finish_cycle);
3341 if (max_cycle < *max_finish_cycle)
3342 max_cycle = *max_finish_cycle;
3343 if (i == 0 || min_cycle > *min_finish_cycle)
3344 min_cycle = *min_finish_cycle;
3346 *max_finish_cycle = max_cycle;
3347 *min_finish_cycle = min_cycle;
3349 break;
3351 case rm_oneof:
3353 int max_cycle = 0;
3354 int min_cycle = 0;
3356 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3358 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3359 max_start_cycle, min_start_cycle,
3360 max_finish_cycle, min_finish_cycle);
3361 if (max_cycle < *max_finish_cycle)
3362 max_cycle = *max_finish_cycle;
3363 if (i == 0 || min_cycle > *min_finish_cycle)
3364 min_cycle = *min_finish_cycle;
3366 *max_finish_cycle = max_cycle;
3367 *min_finish_cycle = min_cycle;
3369 break;
3371 case rm_nothing:
3372 *max_finish_cycle = max_start_cycle;
3373 *min_finish_cycle = min_start_cycle;
3374 break;
3376 default:
3377 gcc_unreachable ();
3381 /* The following function is called only for correct program. The
3382 function defines max reservation of insns in cycles. */
3383 static void
3384 evaluate_max_reserv_cycles (void)
3386 int max_insn_cycles_num;
3387 int min_insn_cycles_num;
3388 decl_t decl;
3389 int i;
3391 description->max_insn_reserv_cycles = 0;
3392 for (i = 0; i < description->decls_num; i++)
3394 decl = description->decls [i];
3395 if (decl->mode == dm_insn_reserv)
3397 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3398 &max_insn_cycles_num, &min_insn_cycles_num);
3399 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3400 description->max_insn_reserv_cycles = max_insn_cycles_num;
3403 description->max_insn_reserv_cycles++;
3406 /* The following function calls functions for checking all
3407 description. */
3408 static void
3409 check_all_description (void)
3411 process_decls ();
3412 check_automaton_usage ();
3413 process_regexp_decls ();
3414 check_usage ();
3415 check_loops_in_regexps ();
3416 if (!have_error)
3417 evaluate_max_reserv_cycles ();
3422 /* The page contains abstract data `ticker'. This data is used to
3423 report time of different phases of building automata. It is
3424 possibly to write a description for which automata will be built
3425 during several minutes even on fast machine. */
3427 /* The following function creates ticker and makes it active. */
3428 static ticker_t
3429 create_ticker (void)
3431 ticker_t ticker;
3433 ticker.modified_creation_time = get_run_time ();
3434 ticker.incremented_off_time = 0;
3435 return ticker;
3438 /* The following function switches off given ticker. */
3439 static void
3440 ticker_off (ticker_t *ticker)
3442 if (ticker->incremented_off_time == 0)
3443 ticker->incremented_off_time = get_run_time () + 1;
3446 /* The following function switches on given ticker. */
3447 static void
3448 ticker_on (ticker_t *ticker)
3450 if (ticker->incremented_off_time != 0)
3452 ticker->modified_creation_time
3453 += get_run_time () - ticker->incremented_off_time + 1;
3454 ticker->incremented_off_time = 0;
3458 /* The following function returns current time in milliseconds since
3459 the moment when given ticker was created. */
3460 static int
3461 active_time (ticker_t ticker)
3463 if (ticker.incremented_off_time != 0)
3464 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3465 else
3466 return get_run_time () - ticker.modified_creation_time;
3469 /* The following function returns string representation of active time
3470 of given ticker. The result is string representation of seconds
3471 with accuracy of 1/100 second. Only result of the last call of the
3472 function exists. Therefore the following code is not correct
3474 printf ("parser time: %s\ngeneration time: %s\n",
3475 active_time_string (parser_ticker),
3476 active_time_string (generation_ticker));
3478 Correct code has to be the following
3480 printf ("parser time: %s\n", active_time_string (parser_ticker));
3481 printf ("generation time: %s\n",
3482 active_time_string (generation_ticker));
3485 static void
3486 print_active_time (FILE *f, ticker_t ticker)
3488 int msecs;
3490 msecs = active_time (ticker);
3491 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3496 /* The following variable value is number of automaton which are
3497 really being created. This value is defined on the base of
3498 argument of option `-split'. If the variable has zero value the
3499 number of automata is defined by the constructions `%automaton'.
3500 This case occurs when option `-split' is absent or has zero
3501 argument. If constructions `define_automaton' is absent only one
3502 automaton is created. */
3503 static int automata_num;
3505 /* The following variable values are times of
3506 o transformation of regular expressions
3507 o building NDFA (DFA if !ndfa_flag)
3508 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3509 o DFA minimization
3510 o building insn equivalence classes
3511 o all previous ones
3512 o code output */
3513 static ticker_t transform_time;
3514 static ticker_t NDFA_time;
3515 static ticker_t NDFA_to_DFA_time;
3516 static ticker_t minimize_time;
3517 static ticker_t equiv_time;
3518 static ticker_t automaton_generation_time;
3519 static ticker_t output_time;
3521 /* The following variable values are times of
3522 all checking
3523 all generation
3524 all pipeline hazard translator work */
3525 static ticker_t check_time;
3526 static ticker_t generation_time;
3527 static ticker_t all_time;
3531 /* Pseudo insn decl which denotes advancing cycle. */
3532 static decl_t advance_cycle_insn_decl;
3533 static void
3534 add_advance_cycle_insn_decl (void)
3536 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3537 advance_cycle_insn_decl->mode = dm_insn_reserv;
3538 advance_cycle_insn_decl->pos = no_pos;
3539 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3540 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
3541 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3542 = description->insns_num;
3543 description->decls [description->decls_num] = advance_cycle_insn_decl;
3544 description->decls_num++;
3545 description->insns_num++;
3546 num_dfa_decls++;
3550 /* Abstract data `alternative states' which represents
3551 nondeterministic nature of the description (see comments for
3552 structures alt_state and state). */
3554 /* List of free states. */
3555 static alt_state_t first_free_alt_state;
3557 #ifndef NDEBUG
3558 /* The following variables is maximal number of allocated nodes
3559 alt_state. */
3560 static int allocated_alt_states_num = 0;
3561 #endif
3563 /* The following function returns free node alt_state. It may be new
3564 allocated node or node freed earlier. */
3565 static alt_state_t
3566 get_free_alt_state (void)
3568 alt_state_t result;
3570 if (first_free_alt_state != NULL)
3572 result = first_free_alt_state;
3573 first_free_alt_state = first_free_alt_state->next_alt_state;
3575 else
3577 #ifndef NDEBUG
3578 allocated_alt_states_num++;
3579 #endif
3580 result = create_node (sizeof (struct alt_state));
3582 result->state = NULL;
3583 result->next_alt_state = NULL;
3584 result->next_sorted_alt_state = NULL;
3585 return result;
3588 /* The function frees node ALT_STATE. */
3589 static void
3590 free_alt_state (alt_state_t alt_state)
3592 if (alt_state == NULL)
3593 return;
3594 alt_state->next_alt_state = first_free_alt_state;
3595 first_free_alt_state = alt_state;
3598 /* The function frees list started with node ALT_STATE_LIST. */
3599 static void
3600 free_alt_states (alt_state_t alt_states_list)
3602 alt_state_t curr_alt_state;
3603 alt_state_t next_alt_state;
3605 for (curr_alt_state = alt_states_list;
3606 curr_alt_state != NULL;
3607 curr_alt_state = next_alt_state)
3609 next_alt_state = curr_alt_state->next_alt_state;
3610 free_alt_state (curr_alt_state);
3614 /* The function compares unique numbers of alt states. */
3615 static int
3616 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3618 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3619 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3620 return 0;
3621 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3622 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3623 return -1;
3624 else
3625 return 1;
3628 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3629 states from the list. The comparison key is alt state unique
3630 number. */
3631 static alt_state_t
3632 uniq_sort_alt_states (alt_state_t alt_states_list)
3634 alt_state_t curr_alt_state;
3635 vla_ptr_t alt_states;
3636 size_t i;
3637 size_t prev_unique_state_ind;
3638 alt_state_t result;
3639 alt_state_t *result_ptr;
3641 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3642 for (curr_alt_state = alt_states_list;
3643 curr_alt_state != NULL;
3644 curr_alt_state = curr_alt_state->next_alt_state)
3645 VLA_PTR_ADD (alt_states, curr_alt_state);
3646 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3647 sizeof (alt_state_t), alt_state_cmp);
3648 if (VLA_PTR_LENGTH (alt_states) == 0)
3649 result = NULL;
3650 else
3652 result_ptr = VLA_PTR_BEGIN (alt_states);
3653 prev_unique_state_ind = 0;
3654 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3655 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3657 prev_unique_state_ind++;
3658 result_ptr [prev_unique_state_ind] = result_ptr [i];
3660 #if 0
3661 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3662 free_alt_state (result_ptr [i]);
3663 #endif
3664 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3665 result_ptr = VLA_PTR_BEGIN (alt_states);
3666 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3667 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3668 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3669 result = *result_ptr;
3671 VLA_PTR_DELETE (alt_states);
3672 return result;
3675 /* The function checks equality of alt state lists. Remember that the
3676 lists must be already sorted by the previous function. */
3677 static int
3678 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3680 while (alt_states_1 != NULL && alt_states_2 != NULL
3681 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3683 alt_states_1 = alt_states_1->next_sorted_alt_state;
3684 alt_states_2 = alt_states_2->next_sorted_alt_state;
3686 return alt_states_1 == alt_states_2;
3689 /* Initialization of the abstract data. */
3690 static void
3691 initiate_alt_states (void)
3693 first_free_alt_state = NULL;
3696 /* Finishing work with the abstract data. */
3697 static void
3698 finish_alt_states (void)
3704 /* The page contains macros for work with bits strings. We could use
3705 standard gcc bitmap or sbitmap but it would result in difficulties
3706 of building canadian cross. */
3708 /* Set bit number bitno in the bit string. The macro is not side
3709 effect proof. */
3710 #define SET_BIT(bitstring, bitno) \
3711 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3713 #define CLEAR_BIT(bitstring, bitno) \
3714 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3716 /* Test if bit number bitno in the bitstring is set. The macro is not
3717 side effect proof. */
3718 #define TEST_BIT(bitstring, bitno) \
3719 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3723 /* This page contains abstract data `state'. */
3725 /* Maximal length of reservations in cycles (>= 1). */
3726 static int max_cycles_num;
3728 /* Number of set elements (see type set_el_t) needed for
3729 representation of one cycle reservation. It is depended on units
3730 number. */
3731 static int els_in_cycle_reserv;
3733 /* Number of set elements (see type set_el_t) needed for
3734 representation of maximal length reservation. Deterministic
3735 reservation is stored as set (bit string) of length equal to the
3736 variable value * number of bits in set_el_t. */
3737 static int els_in_reservs;
3739 /* VLA for representation of array of pointers to unit
3740 declarations. */
3741 static vla_ptr_t units_container;
3743 /* The start address of the array. */
3744 static unit_decl_t *units_array;
3746 /* Temporary reservation of maximal length. */
3747 static reserv_sets_t temp_reserv;
3749 /* The state table itself is represented by the following variable. */
3750 static htab_t state_table;
3752 /* VLA for representation of array of pointers to free nodes
3753 `state'. */
3754 static vla_ptr_t free_states;
3756 static int curr_unique_state_num;
3758 #ifndef NDEBUG
3759 /* The following variables is maximal number of allocated nodes
3760 `state'. */
3761 static int allocated_states_num = 0;
3762 #endif
3764 /* Allocate new reservation set. */
3765 static reserv_sets_t
3766 alloc_empty_reserv_sets (void)
3768 reserv_sets_t result;
3770 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3771 result = (reserv_sets_t) obstack_base (&irp);
3772 obstack_finish (&irp);
3773 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3774 return result;
3777 /* Hash value of reservation set. */
3778 static unsigned
3779 reserv_sets_hash_value (reserv_sets_t reservs)
3781 set_el_t hash_value;
3782 unsigned result;
3783 int reservs_num, i;
3784 set_el_t *reserv_ptr;
3786 hash_value = 0;
3787 reservs_num = els_in_reservs;
3788 reserv_ptr = reservs;
3789 i = 0;
3790 while (reservs_num != 0)
3792 reservs_num--;
3793 hash_value += ((*reserv_ptr >> i)
3794 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3795 i++;
3796 if (i == sizeof (set_el_t) * CHAR_BIT)
3797 i = 0;
3798 reserv_ptr++;
3800 if (sizeof (set_el_t) <= sizeof (unsigned))
3801 return hash_value;
3802 result = 0;
3803 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3805 result += (unsigned) hash_value;
3806 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3808 return result;
3811 /* Comparison of given reservation sets. */
3812 static int
3813 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3815 int reservs_num;
3816 set_el_t *reserv_ptr_1;
3817 set_el_t *reserv_ptr_2;
3819 gcc_assert (reservs_1 && reservs_2);
3820 reservs_num = els_in_reservs;
3821 reserv_ptr_1 = reservs_1;
3822 reserv_ptr_2 = reservs_2;
3823 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3825 reservs_num--;
3826 reserv_ptr_1++;
3827 reserv_ptr_2++;
3829 if (reservs_num == 0)
3830 return 0;
3831 else if (*reserv_ptr_1 < *reserv_ptr_2)
3832 return -1;
3833 else
3834 return 1;
3837 /* The function checks equality of the reservation sets. */
3838 static int
3839 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3841 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3844 /* Set up in the reservation set that unit with UNIT_NUM is used on
3845 CYCLE_NUM. */
3846 static void
3847 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3849 gcc_assert (cycle_num < max_cycles_num);
3850 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3851 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3854 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3855 used on CYCLE_NUM. */
3856 static int
3857 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3859 gcc_assert (cycle_num < max_cycles_num);
3860 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3861 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3864 /* The function checks that the reservation set represents no one unit
3865 reservation. */
3866 static int
3867 it_is_empty_reserv_sets (reserv_sets_t operand)
3869 set_el_t *reserv_ptr;
3870 int reservs_num;
3872 gcc_assert (operand);
3873 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3874 reservs_num != 0;
3875 reserv_ptr++, reservs_num--)
3876 if (*reserv_ptr != 0)
3877 return 0;
3878 return 1;
3881 /* The function checks that the reservation sets are intersected,
3882 i.e. there is a unit reservation on a cycle in both reservation
3883 sets. */
3884 static int
3885 reserv_sets_are_intersected (reserv_sets_t operand_1,
3886 reserv_sets_t operand_2)
3888 set_el_t *el_ptr_1;
3889 set_el_t *el_ptr_2;
3890 set_el_t *cycle_ptr_1;
3891 set_el_t *cycle_ptr_2;
3893 gcc_assert (operand_1 && operand_2);
3894 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3895 el_ptr_1 < operand_1 + els_in_reservs;
3896 el_ptr_1++, el_ptr_2++)
3897 if (*el_ptr_1 & *el_ptr_2)
3898 return 1;
3899 reserv_sets_or (temp_reserv, operand_1, operand_2);
3900 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3901 cycle_ptr_1 < operand_1 + els_in_reservs;
3902 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3904 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3905 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3906 el_ptr_1++, el_ptr_2++)
3907 if (*el_ptr_1 & *el_ptr_2)
3908 return 1;
3909 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3910 return 1;
3911 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3912 - operand_2),
3913 cycle_ptr_2, TRUE))
3914 return 1;
3915 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3916 return 1;
3917 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3918 cycle_ptr_2, TRUE))
3919 return 1;
3921 return 0;
3924 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3925 cpu cycle. The remaining bits of OPERAND (representing the last
3926 cycle unit reservations) are not changed. */
3927 static void
3928 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3930 int i;
3932 gcc_assert (result && operand && result != operand);
3933 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3934 result [i - els_in_cycle_reserv] = operand [i];
3937 /* OR of the reservation sets. */
3938 static void
3939 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3940 reserv_sets_t operand_2)
3942 set_el_t *el_ptr_1;
3943 set_el_t *el_ptr_2;
3944 set_el_t *result_set_el_ptr;
3946 gcc_assert (result && operand_1 && operand_2);
3947 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3948 el_ptr_1 < operand_1 + els_in_reservs;
3949 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3950 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3953 /* AND of the reservation sets. */
3954 static void
3955 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3956 reserv_sets_t operand_2)
3958 set_el_t *el_ptr_1;
3959 set_el_t *el_ptr_2;
3960 set_el_t *result_set_el_ptr;
3962 gcc_assert (result && operand_1 && operand_2);
3963 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3964 el_ptr_1 < operand_1 + els_in_reservs;
3965 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3966 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3969 /* The function outputs string representation of units reservation on
3970 cycle START_CYCLE in the reservation set. The function uses repeat
3971 construction if REPETITION_NUM > 1. */
3972 static void
3973 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3974 int repetition_num)
3976 int unit_num;
3977 int reserved_units_num;
3979 reserved_units_num = 0;
3980 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3981 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3982 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3983 reserved_units_num++;
3984 gcc_assert (repetition_num > 0);
3985 if (repetition_num != 1 && reserved_units_num > 1)
3986 fprintf (f, "(");
3987 reserved_units_num = 0;
3988 for (unit_num = 0;
3989 unit_num < description->units_num;
3990 unit_num++)
3991 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3992 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3994 if (reserved_units_num != 0)
3995 fprintf (f, "+");
3996 reserved_units_num++;
3997 fprintf (f, "%s", units_array [unit_num]->name);
3999 if (reserved_units_num == 0)
4000 fprintf (f, NOTHING_NAME);
4001 gcc_assert (repetition_num > 0);
4002 if (repetition_num != 1 && reserved_units_num > 1)
4003 fprintf (f, ")");
4004 if (repetition_num != 1)
4005 fprintf (f, "*%d", repetition_num);
4008 /* The function outputs string representation of units reservation in
4009 the reservation set. */
4010 static void
4011 output_reserv_sets (FILE *f, reserv_sets_t reservs)
4013 int start_cycle = 0;
4014 int cycle;
4015 int repetition_num;
4017 repetition_num = 0;
4018 for (cycle = 0; cycle < max_cycles_num; cycle++)
4019 if (repetition_num == 0)
4021 repetition_num++;
4022 start_cycle = cycle;
4024 else if (memcmp
4025 ((char *) reservs + start_cycle * els_in_cycle_reserv
4026 * sizeof (set_el_t),
4027 (char *) reservs + cycle * els_in_cycle_reserv
4028 * sizeof (set_el_t),
4029 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
4030 repetition_num++;
4031 else
4033 if (start_cycle != 0)
4034 fprintf (f, ", ");
4035 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4036 repetition_num = 1;
4037 start_cycle = cycle;
4039 if (start_cycle < max_cycles_num)
4041 if (start_cycle != 0)
4042 fprintf (f, ", ");
4043 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4047 /* The following function returns free node state for AUTOMATON. It
4048 may be new allocated node or node freed earlier. The function also
4049 allocates reservation set if WITH_RESERVS has nonzero value. */
4050 static state_t
4051 get_free_state (int with_reservs, automaton_t automaton)
4053 state_t result;
4055 gcc_assert (max_cycles_num > 0 && automaton);
4056 if (VLA_PTR_LENGTH (free_states) != 0)
4058 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
4059 VLA_PTR_SHORTEN (free_states, 1);
4060 result->automaton = automaton;
4061 result->first_out_arc = NULL;
4062 result->it_was_placed_in_stack_for_NDFA_forming = 0;
4063 result->it_was_placed_in_stack_for_DFA_forming = 0;
4064 result->component_states = NULL;
4065 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4067 else
4069 #ifndef NDEBUG
4070 allocated_states_num++;
4071 #endif
4072 result = create_node (sizeof (struct state));
4073 result->automaton = automaton;
4074 result->first_out_arc = NULL;
4075 result->unique_num = curr_unique_state_num;
4076 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4077 curr_unique_state_num++;
4079 if (with_reservs)
4081 if (result->reservs == NULL)
4082 result->reservs = alloc_empty_reserv_sets ();
4083 else
4084 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
4086 return result;
4089 /* The function frees node STATE. */
4090 static void
4091 free_state (state_t state)
4093 free_alt_states (state->component_states);
4094 VLA_PTR_ADD (free_states, state);
4097 /* Hash value of STATE. If STATE represents deterministic state it is
4098 simply hash value of the corresponding reservation set. Otherwise
4099 it is formed from hash values of the component deterministic
4100 states. One more key is order number of state automaton. */
4101 static hashval_t
4102 state_hash (const void *state)
4104 unsigned int hash_value;
4105 alt_state_t alt_state;
4107 if (((state_t) state)->component_states == NULL)
4108 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4109 else
4111 hash_value = 0;
4112 for (alt_state = ((state_t) state)->component_states;
4113 alt_state != NULL;
4114 alt_state = alt_state->next_sorted_alt_state)
4115 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4116 | (hash_value << CHAR_BIT))
4117 + alt_state->state->unique_num);
4119 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4120 | (hash_value << CHAR_BIT))
4121 + ((state_t) state)->automaton->automaton_order_num);
4122 return hash_value;
4125 /* Return nonzero value if the states are the same. */
4126 static int
4127 state_eq_p (const void *state_1, const void *state_2)
4129 alt_state_t alt_state_1;
4130 alt_state_t alt_state_2;
4132 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4133 return 0;
4134 else if (((state_t) state_1)->component_states == NULL
4135 && ((state_t) state_2)->component_states == NULL)
4136 return reserv_sets_eq (((state_t) state_1)->reservs,
4137 ((state_t) state_2)->reservs);
4138 else if (((state_t) state_1)->component_states != NULL
4139 && ((state_t) state_2)->component_states != NULL)
4141 for (alt_state_1 = ((state_t) state_1)->component_states,
4142 alt_state_2 = ((state_t) state_2)->component_states;
4143 alt_state_1 != NULL && alt_state_2 != NULL;
4144 alt_state_1 = alt_state_1->next_sorted_alt_state,
4145 alt_state_2 = alt_state_2->next_sorted_alt_state)
4146 /* All state in the list must be already in the hash table.
4147 Also the lists must be sorted. */
4148 if (alt_state_1->state != alt_state_2->state)
4149 return 0;
4150 return alt_state_1 == alt_state_2;
4152 else
4153 return 0;
4156 /* Insert STATE into the state table. */
4157 static state_t
4158 insert_state (state_t state)
4160 void **entry_ptr;
4162 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4163 if (*entry_ptr == NULL)
4164 *entry_ptr = (void *) state;
4165 return (state_t) *entry_ptr;
4168 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4169 deterministic STATE. */
4170 static void
4171 set_state_reserv (state_t state, int cycle_num, int unit_num)
4173 set_unit_reserv (state->reservs, cycle_num, unit_num);
4176 /* Return nonzero value if the deterministic states contains a
4177 reservation of the same cpu unit on the same cpu cycle. */
4178 static int
4179 intersected_state_reservs_p (state_t state1, state_t state2)
4181 gcc_assert (state1->automaton == state2->automaton);
4182 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4185 /* Return deterministic state (inserted into the table) which
4186 representing the automaton state which is union of reservations of
4187 the deterministic states masked by RESERVS. */
4188 static state_t
4189 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4191 state_t result;
4192 state_t state_in_table;
4194 gcc_assert (state1->automaton == state2->automaton);
4195 result = get_free_state (1, state1->automaton);
4196 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4197 reserv_sets_and (result->reservs, result->reservs, reservs);
4198 state_in_table = insert_state (result);
4199 if (result != state_in_table)
4201 free_state (result);
4202 result = state_in_table;
4204 return result;
4207 /* Return deterministic state (inserted into the table) which
4208 represent the automaton state is obtained from deterministic STATE
4209 by advancing cpu cycle and masking by RESERVS. */
4210 static state_t
4211 state_shift (state_t state, reserv_sets_t reservs)
4213 state_t result;
4214 state_t state_in_table;
4216 result = get_free_state (1, state->automaton);
4217 reserv_sets_shift (result->reservs, state->reservs);
4218 reserv_sets_and (result->reservs, result->reservs, reservs);
4219 state_in_table = insert_state (result);
4220 if (result != state_in_table)
4222 free_state (result);
4223 result = state_in_table;
4225 return result;
4228 /* Initialization of the abstract data. */
4229 static void
4230 initiate_states (void)
4232 decl_t decl;
4233 int i;
4235 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
4236 units_array
4237 = (description->decls_num && description->units_num
4238 ? VLA_PTR_BEGIN (units_container) : NULL);
4239 for (i = 0; i < description->decls_num; i++)
4241 decl = description->decls [i];
4242 if (decl->mode == dm_unit)
4243 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4245 max_cycles_num = description->max_insn_reserv_cycles;
4246 els_in_cycle_reserv
4247 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4248 / (sizeof (set_el_t) * CHAR_BIT));
4249 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4250 curr_unique_state_num = 0;
4251 initiate_alt_states ();
4252 VLA_PTR_CREATE (free_states, 1500, "free states");
4253 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4254 temp_reserv = alloc_empty_reserv_sets ();
4257 /* Finishing work with the abstract data. */
4258 static void
4259 finish_states (void)
4261 VLA_PTR_DELETE (units_container);
4262 htab_delete (state_table);
4263 VLA_PTR_DELETE (free_states);
4264 finish_alt_states ();
4269 /* Abstract data `arcs'. */
4271 /* List of free arcs. */
4272 static arc_t first_free_arc;
4274 #ifndef NDEBUG
4275 /* The following variables is maximal number of allocated nodes
4276 `arc'. */
4277 static int allocated_arcs_num = 0;
4278 #endif
4280 /* The function frees node ARC. */
4281 static void
4282 free_arc (arc_t arc)
4284 arc->next_out_arc = first_free_arc;
4285 first_free_arc = arc;
4288 /* The function removes and frees ARC staring from FROM_STATE. */
4289 static void
4290 remove_arc (state_t from_state, arc_t arc)
4292 arc_t prev_arc;
4293 arc_t curr_arc;
4295 gcc_assert (arc);
4296 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4297 curr_arc != NULL;
4298 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4299 if (curr_arc == arc)
4300 break;
4301 gcc_assert (curr_arc);
4302 if (prev_arc == NULL)
4303 from_state->first_out_arc = arc->next_out_arc;
4304 else
4305 prev_arc->next_out_arc = arc->next_out_arc;
4306 free_arc (arc);
4309 /* The functions returns arc with given characteristics (or NULL if
4310 the arc does not exist). */
4311 static arc_t
4312 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4314 arc_t arc;
4316 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4317 if (arc->to_state == to_state && arc->insn == insn)
4318 return arc;
4319 return NULL;
4322 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4323 and with given STATE_ALTS. The function returns added arc (or
4324 already existing arc). */
4325 static arc_t
4326 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4327 int state_alts)
4329 arc_t new_arc;
4331 new_arc = find_arc (from_state, to_state, ainsn);
4332 if (new_arc != NULL)
4333 return new_arc;
4334 if (first_free_arc == NULL)
4336 #ifndef NDEBUG
4337 allocated_arcs_num++;
4338 #endif
4339 new_arc = create_node (sizeof (struct arc));
4340 new_arc->to_state = NULL;
4341 new_arc->insn = NULL;
4342 new_arc->next_out_arc = NULL;
4344 else
4346 new_arc = first_free_arc;
4347 first_free_arc = first_free_arc->next_out_arc;
4349 new_arc->to_state = to_state;
4350 new_arc->insn = ainsn;
4351 ainsn->arc_exists_p = 1;
4352 new_arc->next_out_arc = from_state->first_out_arc;
4353 from_state->first_out_arc = new_arc;
4354 new_arc->next_arc_marked_by_insn = NULL;
4355 new_arc->state_alts = state_alts;
4356 return new_arc;
4359 /* The function returns the first arc starting from STATE. */
4360 static arc_t
4361 first_out_arc (state_t state)
4363 return state->first_out_arc;
4366 /* The function returns next out arc after ARC. */
4367 static arc_t
4368 next_out_arc (arc_t arc)
4370 return arc->next_out_arc;
4373 /* Initialization of the abstract data. */
4374 static void
4375 initiate_arcs (void)
4377 first_free_arc = NULL;
4380 /* Finishing work with the abstract data. */
4381 static void
4382 finish_arcs (void)
4388 /* Abstract data `automata lists'. */
4390 /* List of free states. */
4391 static automata_list_el_t first_free_automata_list_el;
4393 /* The list being formed. */
4394 static automata_list_el_t current_automata_list;
4396 /* Hash table of automata lists. */
4397 static htab_t automata_list_table;
4399 /* The following function returns free automata list el. It may be
4400 new allocated node or node freed earlier. */
4401 static automata_list_el_t
4402 get_free_automata_list_el (void)
4404 automata_list_el_t result;
4406 if (first_free_automata_list_el != NULL)
4408 result = first_free_automata_list_el;
4409 first_free_automata_list_el
4410 = first_free_automata_list_el->next_automata_list_el;
4412 else
4413 result = create_node (sizeof (struct automata_list_el));
4414 result->automaton = NULL;
4415 result->next_automata_list_el = NULL;
4416 return result;
4419 /* The function frees node AUTOMATA_LIST_EL. */
4420 static void
4421 free_automata_list_el (automata_list_el_t automata_list_el)
4423 if (automata_list_el == NULL)
4424 return;
4425 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4426 first_free_automata_list_el = automata_list_el;
4429 /* The function frees list AUTOMATA_LIST. */
4430 static void
4431 free_automata_list (automata_list_el_t automata_list)
4433 automata_list_el_t curr_automata_list_el;
4434 automata_list_el_t next_automata_list_el;
4436 for (curr_automata_list_el = automata_list;
4437 curr_automata_list_el != NULL;
4438 curr_automata_list_el = next_automata_list_el)
4440 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4441 free_automata_list_el (curr_automata_list_el);
4445 /* Hash value of AUTOMATA_LIST. */
4446 static hashval_t
4447 automata_list_hash (const void *automata_list)
4449 unsigned int hash_value;
4450 automata_list_el_t curr_automata_list_el;
4452 hash_value = 0;
4453 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4454 curr_automata_list_el != NULL;
4455 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4456 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4457 | (hash_value << CHAR_BIT))
4458 + curr_automata_list_el->automaton->automaton_order_num);
4459 return hash_value;
4462 /* Return nonzero value if the automata_lists are the same. */
4463 static int
4464 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4466 automata_list_el_t automata_list_el_1;
4467 automata_list_el_t automata_list_el_2;
4469 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4470 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4471 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4472 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4473 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4474 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4475 return 0;
4476 return automata_list_el_1 == automata_list_el_2;
4479 /* Initialization of the abstract data. */
4480 static void
4481 initiate_automata_lists (void)
4483 first_free_automata_list_el = NULL;
4484 automata_list_table = htab_create (1500, automata_list_hash,
4485 automata_list_eq_p, (htab_del) 0);
4488 /* The following function starts new automata list and makes it the
4489 current one. */
4490 static void
4491 automata_list_start (void)
4493 current_automata_list = NULL;
4496 /* The following function adds AUTOMATON to the current list. */
4497 static void
4498 automata_list_add (automaton_t automaton)
4500 automata_list_el_t el;
4502 el = get_free_automata_list_el ();
4503 el->automaton = automaton;
4504 el->next_automata_list_el = current_automata_list;
4505 current_automata_list = el;
4508 /* The following function finishes forming the current list, inserts
4509 it into the table and returns it. */
4510 static automata_list_el_t
4511 automata_list_finish (void)
4513 void **entry_ptr;
4515 if (current_automata_list == NULL)
4516 return NULL;
4517 entry_ptr = htab_find_slot (automata_list_table,
4518 (void *) current_automata_list, 1);
4519 if (*entry_ptr == NULL)
4520 *entry_ptr = (void *) current_automata_list;
4521 else
4522 free_automata_list (current_automata_list);
4523 current_automata_list = NULL;
4524 return (automata_list_el_t) *entry_ptr;
4527 /* Finishing work with the abstract data. */
4528 static void
4529 finish_automata_lists (void)
4531 htab_delete (automata_list_table);
4536 /* The page contains abstract data for work with exclusion sets (see
4537 exclusion_set in file rtl.def). */
4539 /* The following variable refers to an exclusion set returned by
4540 get_excl_set. This is bit string of length equal to cpu units
4541 number. If exclusion set for given unit contains 1 for a unit,
4542 then simultaneous reservation of the units is prohibited. */
4543 static reserv_sets_t excl_set;
4545 /* The array contains exclusion sets for each unit. */
4546 static reserv_sets_t *unit_excl_set_table;
4548 /* The following function forms the array containing exclusion sets
4549 for each unit. */
4550 static void
4551 initiate_excl_sets (void)
4553 decl_t decl;
4554 reserv_sets_t unit_excl_set;
4555 unit_set_el_t el;
4556 int i;
4558 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4559 excl_set = (reserv_sets_t) obstack_base (&irp);
4560 obstack_finish (&irp);
4561 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4562 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4563 obstack_finish (&irp);
4564 /* Evaluate unit exclusion sets. */
4565 for (i = 0; i < description->decls_num; i++)
4567 decl = description->decls [i];
4568 if (decl->mode == dm_unit)
4570 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4571 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4572 obstack_finish (&irp);
4573 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4574 for (el = DECL_UNIT (decl)->excl_list;
4575 el != NULL;
4576 el = el->next_unit_set_el)
4578 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4579 el->unit_decl->in_set_p = TRUE;
4581 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4586 /* The function sets up and return EXCL_SET which is union of
4587 exclusion sets for each unit in IN_SET. */
4588 static reserv_sets_t
4589 get_excl_set (reserv_sets_t in_set)
4591 int excl_char_num;
4592 int chars_num;
4593 int i;
4594 int start_unit_num;
4595 int unit_num;
4597 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4598 memset (excl_set, 0, chars_num);
4599 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4600 if (((unsigned char *) in_set) [excl_char_num])
4601 for (i = CHAR_BIT - 1; i >= 0; i--)
4602 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4604 start_unit_num = excl_char_num * CHAR_BIT + i;
4605 if (start_unit_num >= description->units_num)
4606 return excl_set;
4607 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4609 excl_set [unit_num]
4610 |= unit_excl_set_table [start_unit_num] [unit_num];
4613 return excl_set;
4618 /* The page contains abstract data for work with presence/absence
4619 pattern sets (see presence_set/absence_set in file rtl.def). */
4621 /* The following arrays contain correspondingly presence, final
4622 presence, absence, and final absence patterns for each unit. */
4623 static pattern_reserv_t *unit_presence_set_table;
4624 static pattern_reserv_t *unit_final_presence_set_table;
4625 static pattern_reserv_t *unit_absence_set_table;
4626 static pattern_reserv_t *unit_final_absence_set_table;
4628 /* The following function forms list of reservation sets for given
4629 PATTERN_LIST. */
4630 static pattern_reserv_t
4631 form_reserv_sets_list (pattern_set_el_t pattern_list)
4633 pattern_set_el_t el;
4634 pattern_reserv_t first, curr, prev;
4635 int i;
4637 prev = first = NULL;
4638 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4640 curr = create_node (sizeof (struct pattern_reserv));
4641 curr->reserv = alloc_empty_reserv_sets ();
4642 curr->next_pattern_reserv = NULL;
4643 for (i = 0; i < el->units_num; i++)
4645 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4646 el->unit_decls [i]->in_set_p = TRUE;
4648 if (prev != NULL)
4649 prev->next_pattern_reserv = curr;
4650 else
4651 first = curr;
4652 prev = curr;
4654 return first;
4657 /* The following function forms the array containing presence and
4658 absence pattern sets for each unit. */
4659 static void
4660 initiate_presence_absence_pattern_sets (void)
4662 decl_t decl;
4663 int i;
4665 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4666 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4667 obstack_finish (&irp);
4668 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4669 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4670 obstack_finish (&irp);
4671 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4672 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4673 obstack_finish (&irp);
4674 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4675 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4676 obstack_finish (&irp);
4677 /* Evaluate unit presence/absence sets. */
4678 for (i = 0; i < description->decls_num; i++)
4680 decl = description->decls [i];
4681 if (decl->mode == dm_unit)
4683 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4684 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4685 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4686 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4687 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4688 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4689 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4690 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4695 /* The function checks that CHECKED_SET satisfies all presence pattern
4696 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4697 is ok. */
4698 static int
4699 check_presence_pattern_sets (reserv_sets_t checked_set,
4700 reserv_sets_t origional_set,
4701 int final_p)
4703 int char_num;
4704 int chars_num;
4705 int i;
4706 int start_unit_num;
4707 int unit_num;
4708 int presence_p;
4709 pattern_reserv_t pat_reserv;
4711 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4712 for (char_num = 0; char_num < chars_num; char_num++)
4713 if (((unsigned char *) origional_set) [char_num])
4714 for (i = CHAR_BIT - 1; i >= 0; i--)
4715 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4717 start_unit_num = char_num * CHAR_BIT + i;
4718 if (start_unit_num >= description->units_num)
4719 break;
4720 if ((final_p
4721 && unit_final_presence_set_table [start_unit_num] == NULL)
4722 || (!final_p
4723 && unit_presence_set_table [start_unit_num] == NULL))
4724 continue;
4725 presence_p = FALSE;
4726 for (pat_reserv = (final_p
4727 ? unit_final_presence_set_table [start_unit_num]
4728 : unit_presence_set_table [start_unit_num]);
4729 pat_reserv != NULL;
4730 pat_reserv = pat_reserv->next_pattern_reserv)
4732 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4733 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4734 != pat_reserv->reserv [unit_num])
4735 break;
4736 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4738 if (!presence_p)
4739 return FALSE;
4741 return TRUE;
4744 /* The function checks that CHECKED_SET satisfies all absence pattern
4745 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4746 is ok. */
4747 static int
4748 check_absence_pattern_sets (reserv_sets_t checked_set,
4749 reserv_sets_t origional_set,
4750 int final_p)
4752 int char_num;
4753 int chars_num;
4754 int i;
4755 int start_unit_num;
4756 int unit_num;
4757 pattern_reserv_t pat_reserv;
4759 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4760 for (char_num = 0; char_num < chars_num; char_num++)
4761 if (((unsigned char *) origional_set) [char_num])
4762 for (i = CHAR_BIT - 1; i >= 0; i--)
4763 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4765 start_unit_num = char_num * CHAR_BIT + i;
4766 if (start_unit_num >= description->units_num)
4767 break;
4768 for (pat_reserv = (final_p
4769 ? unit_final_absence_set_table [start_unit_num]
4770 : unit_absence_set_table [start_unit_num]);
4771 pat_reserv != NULL;
4772 pat_reserv = pat_reserv->next_pattern_reserv)
4774 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4775 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4776 != pat_reserv->reserv [unit_num]
4777 && pat_reserv->reserv [unit_num])
4778 break;
4779 if (unit_num >= els_in_cycle_reserv)
4780 return FALSE;
4783 return TRUE;
4788 /* This page contains code for transformation of original reservations
4789 described in .md file. The main goal of transformations is
4790 simplifying reservation and lifting up all `|' on the top of IR
4791 reservation representation. */
4794 /* The following function makes copy of IR representation of
4795 reservation. The function also substitutes all reservations
4796 defined by define_reservation by corresponding value during making
4797 the copy. */
4798 static regexp_t
4799 copy_insn_regexp (regexp_t regexp)
4801 regexp_t result;
4802 int i;
4804 switch (regexp->mode)
4806 case rm_reserv:
4807 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4808 break;
4810 case rm_unit:
4811 result = copy_node (regexp, sizeof (struct regexp));
4812 break;
4814 case rm_repeat:
4815 result = copy_node (regexp, sizeof (struct regexp));
4816 REGEXP_REPEAT (result)->regexp
4817 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4818 break;
4820 case rm_sequence:
4821 result = copy_node (regexp,
4822 sizeof (struct regexp) + sizeof (regexp_t)
4823 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4824 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4825 REGEXP_SEQUENCE (result)->regexps [i]
4826 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4827 break;
4829 case rm_allof:
4830 result = copy_node (regexp,
4831 sizeof (struct regexp) + sizeof (regexp_t)
4832 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4833 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4834 REGEXP_ALLOF (result)->regexps [i]
4835 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4836 break;
4838 case rm_oneof:
4839 result = copy_node (regexp,
4840 sizeof (struct regexp) + sizeof (regexp_t)
4841 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4842 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4843 REGEXP_ONEOF (result)->regexps [i]
4844 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4845 break;
4847 case rm_nothing:
4848 result = copy_node (regexp, sizeof (struct regexp));
4849 break;
4851 default:
4852 gcc_unreachable ();
4854 return result;
4857 /* The following variable is set up 1 if a transformation has been
4858 applied. */
4859 static int regexp_transformed_p;
4861 /* The function makes transformation
4862 A*N -> A, A, ... */
4863 static regexp_t
4864 transform_1 (regexp_t regexp)
4866 int i;
4867 int repeat_num;
4868 regexp_t operand;
4869 pos_t pos;
4871 if (regexp->mode == rm_repeat)
4873 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4874 gcc_assert (repeat_num > 1);
4875 operand = REGEXP_REPEAT (regexp)->regexp;
4876 pos = regexp->mode;
4877 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4878 * (repeat_num - 1));
4879 regexp->mode = rm_sequence;
4880 regexp->pos = pos;
4881 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4882 for (i = 0; i < repeat_num; i++)
4883 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4884 regexp_transformed_p = 1;
4886 return regexp;
4889 /* The function makes transformations
4890 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4891 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4892 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4893 static regexp_t
4894 transform_2 (regexp_t regexp)
4896 if (regexp->mode == rm_sequence)
4898 regexp_t sequence = NULL;
4899 regexp_t result;
4900 int sequence_index = 0;
4901 int i, j;
4903 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4904 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4906 sequence_index = i;
4907 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4908 break;
4910 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4912 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4913 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4914 result = create_node (sizeof (struct regexp)
4915 + sizeof (regexp_t)
4916 * (REGEXP_SEQUENCE (regexp)->regexps_num
4917 + REGEXP_SEQUENCE (sequence)->regexps_num
4918 - 2));
4919 result->mode = rm_sequence;
4920 result->pos = regexp->pos;
4921 REGEXP_SEQUENCE (result)->regexps_num
4922 = (REGEXP_SEQUENCE (regexp)->regexps_num
4923 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4924 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4925 if (i < sequence_index)
4926 REGEXP_SEQUENCE (result)->regexps [i]
4927 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4928 else if (i > sequence_index)
4929 REGEXP_SEQUENCE (result)->regexps
4930 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4931 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4932 else
4933 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4934 REGEXP_SEQUENCE (result)->regexps [i + j]
4935 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4936 regexp_transformed_p = 1;
4937 regexp = result;
4940 else if (regexp->mode == rm_allof)
4942 regexp_t allof = NULL;
4943 regexp_t result;
4944 int allof_index = 0;
4945 int i, j;
4947 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4948 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4950 allof_index = i;
4951 allof = REGEXP_ALLOF (regexp)->regexps [i];
4952 break;
4954 if (i < REGEXP_ALLOF (regexp)->regexps_num)
4956 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4957 && REGEXP_ALLOF (regexp)->regexps_num > 1);
4958 result = create_node (sizeof (struct regexp)
4959 + sizeof (regexp_t)
4960 * (REGEXP_ALLOF (regexp)->regexps_num
4961 + REGEXP_ALLOF (allof)->regexps_num - 2));
4962 result->mode = rm_allof;
4963 result->pos = regexp->pos;
4964 REGEXP_ALLOF (result)->regexps_num
4965 = (REGEXP_ALLOF (regexp)->regexps_num
4966 + REGEXP_ALLOF (allof)->regexps_num - 1);
4967 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4968 if (i < allof_index)
4969 REGEXP_ALLOF (result)->regexps [i]
4970 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4971 else if (i > allof_index)
4972 REGEXP_ALLOF (result)->regexps
4973 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4974 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4975 else
4976 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4977 REGEXP_ALLOF (result)->regexps [i + j]
4978 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4979 regexp_transformed_p = 1;
4980 regexp = result;
4983 else if (regexp->mode == rm_oneof)
4985 regexp_t oneof = NULL;
4986 regexp_t result;
4987 int oneof_index = 0;
4988 int i, j;
4990 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4991 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4993 oneof_index = i;
4994 oneof = REGEXP_ONEOF (regexp)->regexps [i];
4995 break;
4997 if (i < REGEXP_ONEOF (regexp)->regexps_num)
4999 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5000 && REGEXP_ONEOF (regexp)->regexps_num > 1);
5001 result = create_node (sizeof (struct regexp)
5002 + sizeof (regexp_t)
5003 * (REGEXP_ONEOF (regexp)->regexps_num
5004 + REGEXP_ONEOF (oneof)->regexps_num - 2));
5005 result->mode = rm_oneof;
5006 result->pos = regexp->pos;
5007 REGEXP_ONEOF (result)->regexps_num
5008 = (REGEXP_ONEOF (regexp)->regexps_num
5009 + REGEXP_ONEOF (oneof)->regexps_num - 1);
5010 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5011 if (i < oneof_index)
5012 REGEXP_ONEOF (result)->regexps [i]
5013 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5014 else if (i > oneof_index)
5015 REGEXP_ONEOF (result)->regexps
5016 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
5017 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5018 else
5019 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
5020 REGEXP_ONEOF (result)->regexps [i + j]
5021 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
5022 regexp_transformed_p = 1;
5023 regexp = result;
5026 return regexp;
5029 /* The function makes transformations
5030 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
5031 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
5032 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
5033 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
5034 static regexp_t
5035 transform_3 (regexp_t regexp)
5037 if (regexp->mode == rm_sequence)
5039 regexp_t oneof = NULL;
5040 int oneof_index = 0;
5041 regexp_t result;
5042 regexp_t sequence;
5043 int i, j;
5045 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5046 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
5048 oneof_index = i;
5049 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
5050 break;
5052 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
5054 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5055 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
5056 result = create_node (sizeof (struct regexp)
5057 + sizeof (regexp_t)
5058 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5059 result->mode = rm_oneof;
5060 result->pos = regexp->pos;
5061 REGEXP_ONEOF (result)->regexps_num
5062 = REGEXP_ONEOF (oneof)->regexps_num;
5063 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5065 sequence
5066 = create_node (sizeof (struct regexp)
5067 + sizeof (regexp_t)
5068 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
5069 sequence->mode = rm_sequence;
5070 sequence->pos = regexp->pos;
5071 REGEXP_SEQUENCE (sequence)->regexps_num
5072 = REGEXP_SEQUENCE (regexp)->regexps_num;
5073 REGEXP_ONEOF (result)->regexps [i] = sequence;
5074 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
5075 if (j != oneof_index)
5076 REGEXP_SEQUENCE (sequence)->regexps [j]
5077 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
5078 else
5079 REGEXP_SEQUENCE (sequence)->regexps [j]
5080 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5082 regexp_transformed_p = 1;
5083 regexp = result;
5086 else if (regexp->mode == rm_allof)
5088 regexp_t oneof = NULL;
5089 regexp_t seq;
5090 int oneof_index = 0;
5091 int max_seq_length, allof_length;
5092 regexp_t result;
5093 regexp_t allof = NULL;
5094 regexp_t allof_op = NULL;
5095 int i, j;
5097 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5098 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
5100 oneof_index = i;
5101 oneof = REGEXP_ALLOF (regexp)->regexps [i];
5102 break;
5104 if (i < REGEXP_ALLOF (regexp)->regexps_num)
5106 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5107 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5108 result = create_node (sizeof (struct regexp)
5109 + sizeof (regexp_t)
5110 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5111 result->mode = rm_oneof;
5112 result->pos = regexp->pos;
5113 REGEXP_ONEOF (result)->regexps_num
5114 = REGEXP_ONEOF (oneof)->regexps_num;
5115 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5117 allof
5118 = create_node (sizeof (struct regexp)
5119 + sizeof (regexp_t)
5120 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5121 allof->mode = rm_allof;
5122 allof->pos = regexp->pos;
5123 REGEXP_ALLOF (allof)->regexps_num
5124 = REGEXP_ALLOF (regexp)->regexps_num;
5125 REGEXP_ONEOF (result)->regexps [i] = allof;
5126 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5127 if (j != oneof_index)
5128 REGEXP_ALLOF (allof)->regexps [j]
5129 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5130 else
5131 REGEXP_ALLOF (allof)->regexps [j]
5132 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5134 regexp_transformed_p = 1;
5135 regexp = result;
5137 max_seq_length = 0;
5138 if (regexp->mode == rm_allof)
5139 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5141 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
5143 case rm_sequence:
5144 seq = REGEXP_ALLOF (regexp)->regexps [i];
5145 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5146 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5147 break;
5149 case rm_unit:
5150 case rm_nothing:
5151 break;
5153 default:
5154 max_seq_length = 0;
5155 goto break_for;
5158 break_for:
5159 if (max_seq_length != 0)
5161 gcc_assert (max_seq_length != 1
5162 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5163 result = create_node (sizeof (struct regexp)
5164 + sizeof (regexp_t) * (max_seq_length - 1));
5165 result->mode = rm_sequence;
5166 result->pos = regexp->pos;
5167 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5168 for (i = 0; i < max_seq_length; i++)
5170 allof_length = 0;
5171 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5172 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
5174 case rm_sequence:
5175 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5176 ->regexps [j])->regexps_num))
5178 allof_op
5179 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5180 ->regexps [j])
5181 ->regexps [i]);
5182 allof_length++;
5184 break;
5185 case rm_unit:
5186 case rm_nothing:
5187 if (i == 0)
5189 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5190 allof_length++;
5192 break;
5193 default:
5194 break;
5197 if (allof_length == 1)
5198 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5199 else
5201 allof = create_node (sizeof (struct regexp)
5202 + sizeof (regexp_t)
5203 * (allof_length - 1));
5204 allof->mode = rm_allof;
5205 allof->pos = regexp->pos;
5206 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5207 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5208 allof_length = 0;
5209 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5210 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5211 && (i <
5212 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5213 ->regexps [j])->regexps_num)))
5215 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5216 ->regexps [j])
5217 ->regexps [i]);
5218 REGEXP_ALLOF (allof)->regexps [allof_length]
5219 = allof_op;
5220 allof_length++;
5222 else if (i == 0
5223 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5224 == rm_unit
5225 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5226 == rm_nothing)))
5228 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5229 REGEXP_ALLOF (allof)->regexps [allof_length]
5230 = allof_op;
5231 allof_length++;
5235 regexp_transformed_p = 1;
5236 regexp = result;
5239 return regexp;
5242 /* The function traverses IR of reservation and applies transformations
5243 implemented by FUNC. */
5244 static regexp_t
5245 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5247 int i;
5249 switch (regexp->mode)
5251 case rm_sequence:
5252 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5253 REGEXP_SEQUENCE (regexp)->regexps [i]
5254 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
5255 func);
5256 break;
5258 case rm_allof:
5259 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5260 REGEXP_ALLOF (regexp)->regexps [i]
5261 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5262 break;
5264 case rm_oneof:
5265 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5266 REGEXP_ONEOF (regexp)->regexps [i]
5267 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5268 break;
5270 case rm_repeat:
5271 REGEXP_REPEAT (regexp)->regexp
5272 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5273 break;
5275 case rm_nothing:
5276 case rm_unit:
5277 break;
5279 default:
5280 gcc_unreachable ();
5282 return (*func) (regexp);
5285 /* The function applies all transformations for IR representation of
5286 reservation REGEXP. */
5287 static regexp_t
5288 transform_regexp (regexp_t regexp)
5290 regexp = regexp_transform_func (regexp, transform_1);
5293 regexp_transformed_p = 0;
5294 regexp = regexp_transform_func (regexp, transform_2);
5295 regexp = regexp_transform_func (regexp, transform_3);
5297 while (regexp_transformed_p);
5298 return regexp;
5301 /* The function applies all transformations for reservations of all
5302 insn declarations. */
5303 static void
5304 transform_insn_regexps (void)
5306 decl_t decl;
5307 int i;
5309 transform_time = create_ticker ();
5310 add_advance_cycle_insn_decl ();
5311 if (progress_flag)
5312 fprintf (stderr, "Reservation transformation...");
5313 for (i = 0; i < description->decls_num; i++)
5315 decl = description->decls [i];
5316 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5317 DECL_INSN_RESERV (decl)->transformed_regexp
5318 = transform_regexp (copy_insn_regexp
5319 (DECL_INSN_RESERV (decl)->regexp));
5321 if (progress_flag)
5322 fprintf (stderr, "done\n");
5323 ticker_off (&transform_time);
5328 /* The following variable value is TRUE if the first annotated message
5329 about units to automata distribution has been output. */
5330 static int annotation_message_reported_p;
5332 /* The following structure describes usage of a unit in a reservation. */
5333 struct unit_usage
5335 unit_decl_t unit_decl;
5336 /* The following forms a list of units used on the same cycle in the
5337 same alternative. */
5338 struct unit_usage *next;
5341 /* Obstack for unit_usage structures. */
5342 static struct obstack unit_usages;
5344 /* VLA for representation of array of pointers to unit usage
5345 structures. There is an element for each combination of
5346 (alternative number, cycle). Unit usages on given cycle in
5347 alternative with given number are referred through element with
5348 index equals to the cycle * number of all alternatives in the regexp
5349 + the alternative number. */
5350 static vla_ptr_t cycle_alt_unit_usages;
5352 /* The following function creates the structure unit_usage for UNIT on
5353 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5354 accessed through cycle_alt_unit_usages. */
5355 static void
5356 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5357 int alt_num)
5359 size_t i, length, old_length;
5360 unit_decl_t unit_decl;
5361 struct unit_usage *unit_usage_ptr;
5362 int index;
5364 gcc_assert (regexp && regexp->mode == rm_oneof
5365 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
5366 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5367 old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
5368 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5369 if (old_length < length)
5371 VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
5372 for (i = old_length; i < length; i++)
5373 VLA_PTR (cycle_alt_unit_usages, i) = NULL;
5375 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5376 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5377 obstack_finish (&unit_usages);
5378 unit_usage_ptr->unit_decl = unit_decl;
5379 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5380 unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
5381 VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
5382 unit_decl->last_distribution_check_cycle = -1; /* undefined */
5385 /* The function processes given REGEXP to find units with the wrong
5386 distribution. */
5387 static void
5388 check_regexp_units_distribution (const char *insn_reserv_name,
5389 regexp_t regexp)
5391 int i, j, k, cycle;
5392 regexp_t seq, allof, unit;
5393 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5395 if (regexp == NULL || regexp->mode != rm_oneof)
5396 return;
5397 /* Store all unit usages in the regexp: */
5398 obstack_init (&unit_usages);
5399 VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
5400 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5402 seq = REGEXP_ONEOF (regexp)->regexps [i];
5403 switch (seq->mode)
5405 case rm_sequence:
5406 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5408 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5409 switch (allof->mode)
5411 case rm_allof:
5412 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5414 unit = REGEXP_ALLOF (allof)->regexps [k];
5415 if (unit->mode == rm_unit)
5416 store_alt_unit_usage (regexp, unit, j, i);
5417 else
5418 gcc_assert (unit->mode == rm_nothing);
5420 break;
5422 case rm_unit:
5423 store_alt_unit_usage (regexp, allof, j, i);
5424 break;
5426 case rm_nothing:
5427 break;
5429 default:
5430 gcc_unreachable ();
5433 break;
5435 case rm_allof:
5436 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5438 unit = REGEXP_ALLOF (seq)->regexps [k];
5439 switch (unit->mode)
5441 case rm_unit:
5442 store_alt_unit_usage (regexp, unit, 0, i);
5443 break;
5445 case rm_nothing:
5446 break;
5448 default:
5449 gcc_unreachable ();
5452 break;
5454 case rm_unit:
5455 store_alt_unit_usage (regexp, seq, 0, i);
5456 break;
5458 case rm_nothing:
5459 break;
5461 default:
5462 gcc_unreachable ();
5465 /* Check distribution: */
5466 for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
5468 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5469 for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
5470 unit_usage_ptr != NULL;
5471 unit_usage_ptr = unit_usage_ptr->next)
5472 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5474 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5475 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5476 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5477 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5478 k++)
5480 for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
5481 other_unit_usage_ptr != NULL;
5482 other_unit_usage_ptr = other_unit_usage_ptr->next)
5483 if (unit_usage_ptr->unit_decl->automaton_decl
5484 == other_unit_usage_ptr->unit_decl->automaton_decl)
5485 break;
5486 if (other_unit_usage_ptr == NULL
5487 && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
5488 break;
5490 if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5491 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5493 if (!annotation_message_reported_p)
5495 fprintf (stderr, "\n");
5496 error ("The following units do not satisfy units-automata distribution rule");
5497 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5498 annotation_message_reported_p = TRUE;
5500 error ("Unit %s, reserv. %s, cycle %d",
5501 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5502 cycle);
5506 VLA_PTR_DELETE (cycle_alt_unit_usages);
5507 obstack_free (&unit_usages, NULL);
5510 /* The function finds units which violates units to automata
5511 distribution rule. If the units exist, report about them. */
5512 static void
5513 check_unit_distributions_to_automata (void)
5515 decl_t decl;
5516 int i;
5518 if (progress_flag)
5519 fprintf (stderr, "Check unit distributions to automata...");
5520 annotation_message_reported_p = FALSE;
5521 for (i = 0; i < description->decls_num; i++)
5523 decl = description->decls [i];
5524 if (decl->mode == dm_insn_reserv)
5525 check_regexp_units_distribution
5526 (DECL_INSN_RESERV (decl)->name,
5527 DECL_INSN_RESERV (decl)->transformed_regexp);
5529 if (progress_flag)
5530 fprintf (stderr, "done\n");
5535 /* The page contains code for building alt_states (see comments for
5536 IR) describing all possible insns reservations of an automaton. */
5538 /* Current state being formed for which the current alt_state
5539 refers. */
5540 static state_t state_being_formed;
5542 /* Current alt_state being formed. */
5543 static alt_state_t alt_state_being_formed;
5545 /* This recursive function processes `,' and units in reservation
5546 REGEXP for forming alt_states of AUTOMATON. It is believed that
5547 CURR_CYCLE is start cycle of all reservation REGEXP. */
5548 static int
5549 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5550 int curr_cycle)
5552 int i;
5554 if (regexp == NULL)
5555 return curr_cycle;
5557 switch (regexp->mode)
5559 case rm_unit:
5560 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5561 == automaton->automaton_order_num)
5562 set_state_reserv (state_being_formed, curr_cycle,
5563 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5564 return curr_cycle;
5566 case rm_sequence:
5567 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5568 curr_cycle
5569 = process_seq_for_forming_states
5570 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5571 return curr_cycle;
5573 case rm_allof:
5575 int finish_cycle = 0;
5576 int cycle;
5578 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5580 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5581 ->regexps [i],
5582 automaton, curr_cycle);
5583 if (finish_cycle < cycle)
5584 finish_cycle = cycle;
5586 return finish_cycle;
5589 case rm_nothing:
5590 return curr_cycle;
5592 default:
5593 gcc_unreachable ();
5597 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5598 inserts alt_state into the table. */
5599 static void
5600 finish_forming_alt_state (alt_state_t alt_state,
5601 automaton_t automaton ATTRIBUTE_UNUSED)
5603 state_t state_in_table;
5604 state_t corresponding_state;
5606 corresponding_state = alt_state->state;
5607 state_in_table = insert_state (corresponding_state);
5608 if (state_in_table != corresponding_state)
5610 free_state (corresponding_state);
5611 alt_state->state = state_in_table;
5615 /* The following variable value is current automaton insn for whose
5616 reservation the alt states are created. */
5617 static ainsn_t curr_ainsn;
5619 /* This recursive function processes `|' in reservation REGEXP for
5620 forming alt_states of AUTOMATON. List of the alt states should
5621 have the same order as in the description. */
5622 static void
5623 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5624 int inside_oneof_p)
5626 int i;
5628 if (regexp->mode != rm_oneof)
5630 alt_state_being_formed = get_free_alt_state ();
5631 state_being_formed = get_free_state (1, automaton);
5632 alt_state_being_formed->state = state_being_formed;
5633 /* We inserts in reverse order but we process alternatives also
5634 in reverse order. So we have the same order of alternative
5635 as in the description. */
5636 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5637 curr_ainsn->alt_states = alt_state_being_formed;
5638 (void) process_seq_for_forming_states (regexp, automaton, 0);
5639 finish_forming_alt_state (alt_state_being_formed, automaton);
5641 else
5643 gcc_assert (!inside_oneof_p);
5644 /* We processes it in reverse order to get list with the same
5645 order as in the description. See also the previous
5646 commentary. */
5647 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5648 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5649 automaton, 1);
5653 /* Create nodes alt_state for all AUTOMATON insns. */
5654 static void
5655 create_alt_states (automaton_t automaton)
5657 struct insn_reserv_decl *reserv_decl;
5659 for (curr_ainsn = automaton->ainsn_list;
5660 curr_ainsn != NULL;
5661 curr_ainsn = curr_ainsn->next_ainsn)
5663 reserv_decl = curr_ainsn->insn_reserv_decl;
5664 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5666 curr_ainsn->alt_states = NULL;
5667 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5668 automaton, 0);
5669 curr_ainsn->sorted_alt_states
5670 = uniq_sort_alt_states (curr_ainsn->alt_states);
5677 /* The page contains major code for building DFA(s) for fast pipeline
5678 hazards recognition. */
5680 /* The function forms list of ainsns of AUTOMATON with the same
5681 reservation. */
5682 static void
5683 form_ainsn_with_same_reservs (automaton_t automaton)
5685 ainsn_t curr_ainsn;
5686 size_t i;
5687 vla_ptr_t first_insns;
5688 vla_ptr_t last_insns;
5690 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5691 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5692 for (curr_ainsn = automaton->ainsn_list;
5693 curr_ainsn != NULL;
5694 curr_ainsn = curr_ainsn->next_ainsn)
5695 if (curr_ainsn->insn_reserv_decl
5696 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5698 curr_ainsn->next_same_reservs_insn = NULL;
5699 curr_ainsn->first_insn_with_same_reservs = 1;
5701 else
5703 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5704 if (alt_states_eq
5705 (curr_ainsn->sorted_alt_states,
5706 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5707 break;
5708 curr_ainsn->next_same_reservs_insn = NULL;
5709 if (i < VLA_PTR_LENGTH (first_insns))
5711 curr_ainsn->first_insn_with_same_reservs = 0;
5712 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5713 = curr_ainsn;
5714 VLA_PTR (last_insns, i) = curr_ainsn;
5716 else
5718 VLA_PTR_ADD (first_insns, curr_ainsn);
5719 VLA_PTR_ADD (last_insns, curr_ainsn);
5720 curr_ainsn->first_insn_with_same_reservs = 1;
5723 VLA_PTR_DELETE (first_insns);
5724 VLA_PTR_DELETE (last_insns);
5727 /* Forming unit reservations which can affect creating the automaton
5728 states achieved from a given state. It permits to build smaller
5729 automata in many cases. We would have the same automata after
5730 the minimization without such optimization, but the automaton
5731 right after the building could be huge. So in other words, usage
5732 of reservs_matter means some minimization during building the
5733 automaton. */
5734 static reserv_sets_t
5735 form_reservs_matter (automaton_t automaton)
5737 int cycle, unit;
5738 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5740 for (cycle = 0; cycle < max_cycles_num; cycle++)
5741 for (unit = 0; unit < description->units_num; unit++)
5742 if (units_array [unit]->automaton_decl
5743 == automaton->corresponding_automaton_decl
5744 && (cycle >= units_array [unit]->min_occ_cycle_num
5745 /* We can not remove queried unit from reservations. */
5746 || units_array [unit]->query_p
5747 /* We can not remove units which are used
5748 `exclusion_set', `presence_set',
5749 `final_presence_set', `absence_set', and
5750 `final_absence_set'. */
5751 || units_array [unit]->in_set_p))
5752 set_unit_reserv (reservs_matter, cycle, unit);
5753 return reservs_matter;
5756 /* The following function creates all states of nondeterministic (if
5757 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5758 static void
5759 make_automaton (automaton_t automaton)
5761 ainsn_t ainsn;
5762 struct insn_reserv_decl *insn_reserv_decl;
5763 alt_state_t alt_state;
5764 state_t state;
5765 state_t start_state;
5766 state_t state2;
5767 ainsn_t advance_cycle_ainsn;
5768 arc_t added_arc;
5769 vla_ptr_t state_stack;
5770 int states_n;
5771 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5773 VLA_PTR_CREATE (state_stack, 150, "state stack");
5774 /* Create the start state (empty state). */
5775 start_state = insert_state (get_free_state (1, automaton));
5776 automaton->start_state = start_state;
5777 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5778 VLA_PTR_ADD (state_stack, start_state);
5779 states_n = 1;
5780 while (VLA_PTR_LENGTH (state_stack) != 0)
5782 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5783 VLA_PTR_SHORTEN (state_stack, 1);
5784 advance_cycle_ainsn = NULL;
5785 for (ainsn = automaton->ainsn_list;
5786 ainsn != NULL;
5787 ainsn = ainsn->next_ainsn)
5788 if (ainsn->first_insn_with_same_reservs)
5790 insn_reserv_decl = ainsn->insn_reserv_decl;
5791 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5793 /* We process alt_states in the same order as they are
5794 present in the description. */
5795 added_arc = NULL;
5796 for (alt_state = ainsn->alt_states;
5797 alt_state != NULL;
5798 alt_state = alt_state->next_alt_state)
5800 state2 = alt_state->state;
5801 if (!intersected_state_reservs_p (state, state2))
5803 state2 = states_union (state, state2, reservs_matter);
5804 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5806 state2->it_was_placed_in_stack_for_NDFA_forming
5807 = 1;
5808 VLA_PTR_ADD (state_stack, state2);
5809 states_n++;
5810 if (progress_flag && states_n % 100 == 0)
5811 fprintf (stderr, ".");
5813 added_arc = add_arc (state, state2, ainsn, 1);
5814 if (!ndfa_flag)
5815 break;
5818 if (!ndfa_flag && added_arc != NULL)
5820 added_arc->state_alts = 0;
5821 for (alt_state = ainsn->alt_states;
5822 alt_state != NULL;
5823 alt_state = alt_state->next_alt_state)
5825 state2 = alt_state->state;
5826 if (!intersected_state_reservs_p (state, state2))
5827 added_arc->state_alts++;
5831 else
5832 advance_cycle_ainsn = ainsn;
5834 /* Add transition to advance cycle. */
5835 state2 = state_shift (state, reservs_matter);
5836 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5838 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5839 VLA_PTR_ADD (state_stack, state2);
5840 states_n++;
5841 if (progress_flag && states_n % 100 == 0)
5842 fprintf (stderr, ".");
5844 gcc_assert (advance_cycle_ainsn);
5845 add_arc (state, state2, advance_cycle_ainsn, 1);
5847 VLA_PTR_DELETE (state_stack);
5850 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5851 static void
5852 form_arcs_marked_by_insn (state_t state)
5854 decl_t decl;
5855 arc_t arc;
5856 int i;
5858 for (i = 0; i < description->decls_num; i++)
5860 decl = description->decls [i];
5861 if (decl->mode == dm_insn_reserv)
5862 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5864 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5866 gcc_assert (arc->insn);
5867 arc->next_arc_marked_by_insn
5868 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5869 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5873 /* The function creates composed state (see comments for IR) from
5874 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5875 same insn. If the composed state is not in STATE_STACK yet, it is
5876 pushed into STATE_STACK. */
5877 static int
5878 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5879 vla_ptr_t *state_stack)
5881 state_t state;
5882 alt_state_t alt_state, curr_alt_state;
5883 alt_state_t new_alt_state;
5884 arc_t curr_arc;
5885 arc_t next_arc;
5886 state_t state_in_table;
5887 state_t temp_state;
5888 alt_state_t canonical_alt_states_list;
5889 int alts_number;
5890 int new_state_p = 0;
5892 if (arcs_marked_by_insn == NULL)
5893 return new_state_p;
5894 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5895 state = arcs_marked_by_insn->to_state;
5896 else
5898 gcc_assert (ndfa_flag);
5899 /* Create composed state. */
5900 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5901 curr_alt_state = NULL;
5902 for (curr_arc = arcs_marked_by_insn;
5903 curr_arc != NULL;
5904 curr_arc = curr_arc->next_arc_marked_by_insn)
5905 if (curr_arc->to_state->component_states == NULL)
5907 new_alt_state = get_free_alt_state ();
5908 new_alt_state->next_alt_state = curr_alt_state;
5909 new_alt_state->state = curr_arc->to_state;
5910 curr_alt_state = new_alt_state;
5912 else
5913 for (alt_state = curr_arc->to_state->component_states;
5914 alt_state != NULL;
5915 alt_state = alt_state->next_sorted_alt_state)
5917 new_alt_state = get_free_alt_state ();
5918 new_alt_state->next_alt_state = curr_alt_state;
5919 new_alt_state->state = alt_state->state;
5920 gcc_assert (!alt_state->state->component_states);
5921 curr_alt_state = new_alt_state;
5923 /* There are not identical sets in the alt state list. */
5924 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5925 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5927 temp_state = state;
5928 state = canonical_alt_states_list->state;
5929 free_state (temp_state);
5931 else
5933 state->component_states = canonical_alt_states_list;
5934 state_in_table = insert_state (state);
5935 if (state_in_table != state)
5937 gcc_assert
5938 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5939 free_state (state);
5940 state = state_in_table;
5942 else
5944 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5945 new_state_p = 1;
5946 for (curr_alt_state = state->component_states;
5947 curr_alt_state != NULL;
5948 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5949 for (curr_arc = first_out_arc (curr_alt_state->state);
5950 curr_arc != NULL;
5951 curr_arc = next_out_arc (curr_arc))
5952 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5954 arcs_marked_by_insn->to_state = state;
5955 for (alts_number = 0,
5956 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5957 curr_arc != NULL;
5958 curr_arc = next_arc)
5960 next_arc = curr_arc->next_arc_marked_by_insn;
5961 remove_arc (original_state, curr_arc);
5962 alts_number++;
5964 arcs_marked_by_insn->state_alts = alts_number;
5967 if (!state->it_was_placed_in_stack_for_DFA_forming)
5969 state->it_was_placed_in_stack_for_DFA_forming = 1;
5970 VLA_PTR_ADD (*state_stack, state);
5972 return new_state_p;
5975 /* The function transforms nondeterministic AUTOMATON into
5976 deterministic. */
5977 static void
5978 NDFA_to_DFA (automaton_t automaton)
5980 state_t start_state;
5981 state_t state;
5982 decl_t decl;
5983 vla_ptr_t state_stack;
5984 int i;
5985 int states_n;
5987 VLA_PTR_CREATE (state_stack, 150, "state stack");
5988 /* Create the start state (empty state). */
5989 start_state = automaton->start_state;
5990 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5991 VLA_PTR_ADD (state_stack, start_state);
5992 states_n = 1;
5993 while (VLA_PTR_LENGTH (state_stack) != 0)
5995 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5996 VLA_PTR_SHORTEN (state_stack, 1);
5997 form_arcs_marked_by_insn (state);
5998 for (i = 0; i < description->decls_num; i++)
6000 decl = description->decls [i];
6001 if (decl->mode == dm_insn_reserv
6002 && create_composed_state
6003 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
6004 &state_stack))
6006 states_n++;
6007 if (progress_flag && states_n % 100 == 0)
6008 fprintf (stderr, ".");
6012 VLA_PTR_DELETE (state_stack);
6015 /* The following variable value is current number (1, 2, ...) of passing
6016 graph of states. */
6017 static int curr_state_graph_pass_num;
6019 /* This recursive function passes all states achieved from START_STATE
6020 and applies APPLIED_FUNC to them. */
6021 static void
6022 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
6024 arc_t arc;
6026 if (start_state->pass_num == curr_state_graph_pass_num)
6027 return;
6028 start_state->pass_num = curr_state_graph_pass_num;
6029 (*applied_func) (start_state);
6030 for (arc = first_out_arc (start_state);
6031 arc != NULL;
6032 arc = next_out_arc (arc))
6033 pass_state_graph (arc->to_state, applied_func);
6036 /* This recursive function passes all states of AUTOMATON and applies
6037 APPLIED_FUNC to them. */
6038 static void
6039 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
6041 curr_state_graph_pass_num++;
6042 pass_state_graph (automaton->start_state, applied_func);
6045 /* The function initializes code for passing of all states. */
6046 static void
6047 initiate_pass_states (void)
6049 curr_state_graph_pass_num = 0;
6052 /* The following vla is used for storing pointers to all achieved
6053 states. */
6054 static vla_ptr_t all_achieved_states;
6056 /* This function is called by function pass_states to add an achieved
6057 STATE. */
6058 static void
6059 add_achieved_state (state_t state)
6061 VLA_PTR_ADD (all_achieved_states, state);
6064 /* The function sets up equivalence numbers of insns which mark all
6065 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6066 nonzero value) or by equiv_class_num_2 of the destination state.
6067 The function returns number of out arcs of STATE. */
6068 static int
6069 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
6071 int state_out_arcs_num;
6072 arc_t arc;
6074 state_out_arcs_num = 0;
6075 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6077 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
6078 && !arc->insn->insn_reserv_decl->state_alts);
6079 state_out_arcs_num++;
6080 arc->insn->insn_reserv_decl->equiv_class_num
6081 = (odd_iteration_flag
6082 ? arc->to_state->equiv_class_num_1
6083 : arc->to_state->equiv_class_num_2);
6084 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6085 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
6086 && arc->insn->insn_reserv_decl->state_alts > 0);
6088 return state_out_arcs_num;
6091 /* The function clears equivalence numbers and alt_states in all insns
6092 which mark all out arcs of STATE. */
6093 static void
6094 clear_arc_insns_equiv_num (state_t state)
6096 arc_t arc;
6098 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6100 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6101 arc->insn->insn_reserv_decl->state_alts = 0;
6105 /* The function copies pointers to equivalent states from vla FROM
6106 into vla TO. */
6107 static void
6108 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
6110 state_t *class_ptr;
6112 VLA_PTR_NULLIFY (*to);
6113 for (class_ptr = VLA_PTR_BEGIN (*from);
6114 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6115 class_ptr++)
6116 VLA_PTR_ADD (*to, *class_ptr);
6119 /* The following function returns TRUE if STATE reserves the unit with
6120 UNIT_NUM on the first cycle. */
6121 static int
6122 first_cycle_unit_presence (state_t state, int unit_num)
6124 alt_state_t alt_state;
6126 if (state->component_states == NULL)
6127 return test_unit_reserv (state->reservs, 0, unit_num);
6128 else
6130 for (alt_state = state->component_states;
6131 alt_state != NULL;
6132 alt_state = alt_state->next_sorted_alt_state)
6133 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
6134 return true;
6136 return false;
6139 /* The function returns nonzero value if STATE is not equivalent to
6140 ANOTHER_STATE from the same current partition on equivalence
6141 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6142 output arcs. Iteration of making equivalence partition is defined
6143 by ODD_ITERATION_FLAG. */
6144 static int
6145 state_is_differed (state_t state, state_t another_state,
6146 int another_state_out_arcs_num, int odd_iteration_flag)
6148 arc_t arc;
6149 int state_out_arcs_num;
6150 int i, presence1_p, presence2_p;
6152 state_out_arcs_num = 0;
6153 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6155 state_out_arcs_num++;
6156 if ((odd_iteration_flag
6157 ? arc->to_state->equiv_class_num_1
6158 : arc->to_state->equiv_class_num_2)
6159 != arc->insn->insn_reserv_decl->equiv_class_num
6160 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6161 return 1;
6163 if (state_out_arcs_num != another_state_out_arcs_num)
6164 return 1;
6165 /* Now we are looking at the states with the point of view of query
6166 units. */
6167 for (i = 0; i < description->units_num; i++)
6168 if (units_array [i]->query_p)
6170 presence1_p = first_cycle_unit_presence (state, i);
6171 presence2_p = first_cycle_unit_presence (another_state, i);
6172 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6173 return 1;
6175 return 0;
6178 /* The function makes initial partition of STATES on equivalent
6179 classes. */
6180 static state_t
6181 init_equiv_class (state_t *states, int states_num)
6183 state_t *state_ptr;
6184 state_t result_equiv_class;
6186 result_equiv_class = NULL;
6187 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6189 (*state_ptr)->equiv_class_num_1 = 1;
6190 (*state_ptr)->next_equiv_class_state = result_equiv_class;
6191 result_equiv_class = *state_ptr;
6193 return result_equiv_class;
6196 /* The function processes equivalence class given by its pointer
6197 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6198 are not equivalent states, the function partitions the class
6199 removing nonequivalent states and placing them in
6200 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6201 assigns it to the state equivalence number. If the class has been
6202 partitioned, the function returns nonzero value. */
6203 static int
6204 partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
6205 vla_ptr_t *next_iteration_classes,
6206 int *new_equiv_class_num_ptr)
6208 state_t new_equiv_class;
6209 int partition_p;
6210 state_t first_state;
6211 state_t curr_state;
6212 state_t prev_state;
6213 state_t next_state;
6214 int out_arcs_num;
6216 partition_p = 0;
6217 gcc_assert (*equiv_class_ptr);
6218 for (first_state = *equiv_class_ptr;
6219 first_state != NULL;
6220 first_state = new_equiv_class)
6222 new_equiv_class = NULL;
6223 if (first_state->next_equiv_class_state != NULL)
6225 /* There are more one states in the class equivalence. */
6226 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6227 odd_iteration_flag);
6228 for (prev_state = first_state,
6229 curr_state = first_state->next_equiv_class_state;
6230 curr_state != NULL;
6231 curr_state = next_state)
6233 next_state = curr_state->next_equiv_class_state;
6234 if (state_is_differed (curr_state, first_state, out_arcs_num,
6235 odd_iteration_flag))
6237 /* Remove curr state from the class equivalence. */
6238 prev_state->next_equiv_class_state = next_state;
6239 /* Add curr state to the new class equivalence. */
6240 curr_state->next_equiv_class_state = new_equiv_class;
6241 if (new_equiv_class == NULL)
6242 (*new_equiv_class_num_ptr)++;
6243 if (odd_iteration_flag)
6244 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6245 else
6246 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6247 new_equiv_class = curr_state;
6248 partition_p = 1;
6250 else
6251 prev_state = curr_state;
6253 clear_arc_insns_equiv_num (first_state);
6255 if (new_equiv_class != NULL)
6256 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
6258 return partition_p;
6261 /* The function finds equivalent states of AUTOMATON. */
6262 static void
6263 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
6265 state_t new_equiv_class;
6266 int new_equiv_class_num;
6267 int odd_iteration_flag;
6268 int finish_flag;
6269 vla_ptr_t next_iteration_classes;
6270 state_t *equiv_class_ptr;
6271 state_t *state_ptr;
6273 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6274 pass_states (automaton, add_achieved_state);
6275 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6276 VLA_PTR_LENGTH (all_achieved_states));
6277 odd_iteration_flag = 0;
6278 new_equiv_class_num = 1;
6279 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6280 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6283 odd_iteration_flag = !odd_iteration_flag;
6284 finish_flag = 1;
6285 copy_equiv_class (equiv_classes, &next_iteration_classes);
6286 /* Transfer equiv numbers for the next iteration. */
6287 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6288 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6289 state_ptr++)
6290 if (odd_iteration_flag)
6291 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6292 else
6293 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6294 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6295 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6296 equiv_class_ptr++)
6297 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6298 &next_iteration_classes,
6299 &new_equiv_class_num))
6300 finish_flag = 0;
6302 while (!finish_flag);
6303 VLA_PTR_DELETE (next_iteration_classes);
6304 VLA_PTR_DELETE (all_achieved_states);
6307 /* The function merges equivalent states of AUTOMATON. */
6308 static void
6309 merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
6311 state_t *equiv_class_ptr;
6312 state_t curr_state;
6313 state_t new_state;
6314 state_t first_class_state;
6315 alt_state_t alt_states;
6316 alt_state_t alt_state, new_alt_state;
6317 arc_t curr_arc;
6318 arc_t next_arc;
6320 /* Create states corresponding to equivalence classes containing two
6321 or more states. */
6322 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6323 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6324 equiv_class_ptr++)
6325 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6327 /* There are more one states in the class equivalence. */
6328 /* Create new compound state. */
6329 new_state = get_free_state (0, automaton);
6330 alt_states = NULL;
6331 first_class_state = *equiv_class_ptr;
6332 for (curr_state = first_class_state;
6333 curr_state != NULL;
6334 curr_state = curr_state->next_equiv_class_state)
6336 curr_state->equiv_class_state = new_state;
6337 if (curr_state->component_states == NULL)
6339 new_alt_state = get_free_alt_state ();
6340 new_alt_state->state = curr_state;
6341 new_alt_state->next_alt_state = alt_states;
6342 alt_states = new_alt_state;
6344 else
6345 for (alt_state = curr_state->component_states;
6346 alt_state != NULL;
6347 alt_state = alt_state->next_sorted_alt_state)
6349 new_alt_state = get_free_alt_state ();
6350 new_alt_state->state = alt_state->state;
6351 new_alt_state->next_alt_state = alt_states;
6352 alt_states = new_alt_state;
6355 /* Its is important that alt states were sorted before and
6356 after merging to have the same querying results. */
6357 new_state->component_states = uniq_sort_alt_states (alt_states);
6359 else
6360 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6361 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6362 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6363 equiv_class_ptr++)
6364 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6366 first_class_state = *equiv_class_ptr;
6367 /* Create new arcs output from the state corresponding to
6368 equiv class. */
6369 for (curr_arc = first_out_arc (first_class_state);
6370 curr_arc != NULL;
6371 curr_arc = next_out_arc (curr_arc))
6372 add_arc (first_class_state->equiv_class_state,
6373 curr_arc->to_state->equiv_class_state,
6374 curr_arc->insn, curr_arc->state_alts);
6375 /* Delete output arcs from states of given class equivalence. */
6376 for (curr_state = first_class_state;
6377 curr_state != NULL;
6378 curr_state = curr_state->next_equiv_class_state)
6380 if (automaton->start_state == curr_state)
6381 automaton->start_state = curr_state->equiv_class_state;
6382 /* Delete the state and its output arcs. */
6383 for (curr_arc = first_out_arc (curr_state);
6384 curr_arc != NULL;
6385 curr_arc = next_arc)
6387 next_arc = next_out_arc (curr_arc);
6388 free_arc (curr_arc);
6392 else
6394 /* Change `to_state' of arcs output from the state of given
6395 equivalence class. */
6396 for (curr_arc = first_out_arc (*equiv_class_ptr);
6397 curr_arc != NULL;
6398 curr_arc = next_out_arc (curr_arc))
6399 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6403 /* The function sets up new_cycle_p for states if there is arc to the
6404 state marked by advance_cycle_insn_decl. */
6405 static void
6406 set_new_cycle_flags (state_t state)
6408 arc_t arc;
6410 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6411 if (arc->insn->insn_reserv_decl
6412 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6413 arc->to_state->new_cycle_p = 1;
6416 /* The top level function for minimization of deterministic
6417 AUTOMATON. */
6418 static void
6419 minimize_DFA (automaton_t automaton)
6421 vla_ptr_t equiv_classes;
6423 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6424 evaluate_equiv_classes (automaton, &equiv_classes);
6425 merge_states (automaton, &equiv_classes);
6426 pass_states (automaton, set_new_cycle_flags);
6427 VLA_PTR_DELETE (equiv_classes);
6430 /* Values of two variables are counted number of states and arcs in an
6431 automaton. */
6432 static int curr_counted_states_num;
6433 static int curr_counted_arcs_num;
6435 /* The function is called by function `pass_states' to count states
6436 and arcs of an automaton. */
6437 static void
6438 incr_states_and_arcs_nums (state_t state)
6440 arc_t arc;
6442 curr_counted_states_num++;
6443 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6444 curr_counted_arcs_num++;
6447 /* The function counts states and arcs of AUTOMATON. */
6448 static void
6449 count_states_and_arcs (automaton_t automaton, int *states_num,
6450 int *arcs_num)
6452 curr_counted_states_num = 0;
6453 curr_counted_arcs_num = 0;
6454 pass_states (automaton, incr_states_and_arcs_nums);
6455 *states_num = curr_counted_states_num;
6456 *arcs_num = curr_counted_arcs_num;
6459 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6460 recognition after checking and simplifying IR of the
6461 description. */
6462 static void
6463 build_automaton (automaton_t automaton)
6465 int states_num;
6466 int arcs_num;
6468 ticker_on (&NDFA_time);
6469 if (progress_flag)
6471 if (automaton->corresponding_automaton_decl == NULL)
6472 fprintf (stderr, "Create anonymous automaton");
6473 else
6474 fprintf (stderr, "Create automaton `%s'",
6475 automaton->corresponding_automaton_decl->name);
6476 fprintf (stderr, " (1 dot is 100 new states):");
6478 make_automaton (automaton);
6479 if (progress_flag)
6480 fprintf (stderr, " done\n");
6481 ticker_off (&NDFA_time);
6482 count_states_and_arcs (automaton, &states_num, &arcs_num);
6483 automaton->NDFA_states_num = states_num;
6484 automaton->NDFA_arcs_num = arcs_num;
6485 ticker_on (&NDFA_to_DFA_time);
6486 if (progress_flag)
6488 if (automaton->corresponding_automaton_decl == NULL)
6489 fprintf (stderr, "Make anonymous DFA");
6490 else
6491 fprintf (stderr, "Make DFA `%s'",
6492 automaton->corresponding_automaton_decl->name);
6493 fprintf (stderr, " (1 dot is 100 new states):");
6495 NDFA_to_DFA (automaton);
6496 if (progress_flag)
6497 fprintf (stderr, " done\n");
6498 ticker_off (&NDFA_to_DFA_time);
6499 count_states_and_arcs (automaton, &states_num, &arcs_num);
6500 automaton->DFA_states_num = states_num;
6501 automaton->DFA_arcs_num = arcs_num;
6502 if (!no_minimization_flag)
6504 ticker_on (&minimize_time);
6505 if (progress_flag)
6507 if (automaton->corresponding_automaton_decl == NULL)
6508 fprintf (stderr, "Minimize anonymous DFA...");
6509 else
6510 fprintf (stderr, "Minimize DFA `%s'...",
6511 automaton->corresponding_automaton_decl->name);
6513 minimize_DFA (automaton);
6514 if (progress_flag)
6515 fprintf (stderr, "done\n");
6516 ticker_off (&minimize_time);
6517 count_states_and_arcs (automaton, &states_num, &arcs_num);
6518 automaton->minimal_DFA_states_num = states_num;
6519 automaton->minimal_DFA_arcs_num = arcs_num;
6525 /* The page contains code for enumeration of all states of an automaton. */
6527 /* Variable used for enumeration of all states of an automaton. Its
6528 value is current number of automaton states. */
6529 static int curr_state_order_num;
6531 /* The function is called by function `pass_states' for enumerating
6532 states. */
6533 static void
6534 set_order_state_num (state_t state)
6536 state->order_state_num = curr_state_order_num;
6537 curr_state_order_num++;
6540 /* The function enumerates all states of AUTOMATON. */
6541 static void
6542 enumerate_states (automaton_t automaton)
6544 curr_state_order_num = 0;
6545 pass_states (automaton, set_order_state_num);
6546 automaton->achieved_states_num = curr_state_order_num;
6551 /* The page contains code for finding equivalent automaton insns
6552 (ainsns). */
6554 /* The function inserts AINSN into cyclic list
6555 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6556 static ainsn_t
6557 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6558 ainsn_t cyclic_equiv_class_insn_list)
6560 if (cyclic_equiv_class_insn_list == NULL)
6561 ainsn->next_equiv_class_insn = ainsn;
6562 else
6564 ainsn->next_equiv_class_insn
6565 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6566 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6568 return ainsn;
6571 /* The function deletes equiv_class_insn into cyclic list of
6572 equivalent ainsns. */
6573 static void
6574 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6576 ainsn_t curr_equiv_class_insn;
6577 ainsn_t prev_equiv_class_insn;
6579 prev_equiv_class_insn = equiv_class_insn;
6580 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6581 curr_equiv_class_insn != equiv_class_insn;
6582 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6583 prev_equiv_class_insn = curr_equiv_class_insn;
6584 if (prev_equiv_class_insn != equiv_class_insn)
6585 prev_equiv_class_insn->next_equiv_class_insn
6586 = equiv_class_insn->next_equiv_class_insn;
6589 /* The function processes AINSN of a state in order to find equivalent
6590 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6591 state. */
6592 static void
6593 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6595 ainsn_t next_insn;
6596 ainsn_t curr_insn;
6597 ainsn_t cyclic_insn_list;
6598 arc_t arc;
6600 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6601 curr_insn = ainsn;
6602 /* New class of ainsns which are not equivalent to given ainsn. */
6603 cyclic_insn_list = NULL;
6606 next_insn = curr_insn->next_equiv_class_insn;
6607 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6608 if (arc == NULL
6609 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6610 != arc->to_state))
6612 delete_ainsn_from_equiv_class (curr_insn);
6613 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6614 cyclic_insn_list);
6616 curr_insn = next_insn;
6618 while (curr_insn != ainsn);
6621 /* The function processes STATE in order to find equivalent ainsns. */
6622 static void
6623 process_state_for_insn_equiv_partition (state_t state)
6625 arc_t arc;
6626 arc_t *insn_arcs_array;
6627 int i;
6628 vla_ptr_t insn_arcs_vect;
6630 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6631 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6632 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6633 /* Process insns of the arcs. */
6634 for (i = 0; i < description->insns_num; i++)
6635 insn_arcs_array [i] = NULL;
6636 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6637 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6638 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6639 process_insn_equiv_class (arc->insn, insn_arcs_array);
6640 VLA_PTR_DELETE (insn_arcs_vect);
6643 /* The function searches for equivalent ainsns of AUTOMATON. */
6644 static void
6645 set_insn_equiv_classes (automaton_t automaton)
6647 ainsn_t ainsn;
6648 ainsn_t first_insn;
6649 ainsn_t curr_insn;
6650 ainsn_t cyclic_insn_list;
6651 ainsn_t insn_with_same_reservs;
6652 int equiv_classes_num;
6654 /* All insns are included in one equivalence class. */
6655 cyclic_insn_list = NULL;
6656 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6657 if (ainsn->first_insn_with_same_reservs)
6658 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6659 cyclic_insn_list);
6660 /* Process insns in order to make equivalence partition. */
6661 pass_states (automaton, process_state_for_insn_equiv_partition);
6662 /* Enumerate equiv classes. */
6663 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6664 /* Set undefined value. */
6665 ainsn->insn_equiv_class_num = -1;
6666 equiv_classes_num = 0;
6667 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6668 if (ainsn->insn_equiv_class_num < 0)
6670 first_insn = ainsn;
6671 gcc_assert (first_insn->first_insn_with_same_reservs);
6672 first_insn->first_ainsn_with_given_equivalence_num = 1;
6673 curr_insn = first_insn;
6676 for (insn_with_same_reservs = curr_insn;
6677 insn_with_same_reservs != NULL;
6678 insn_with_same_reservs
6679 = insn_with_same_reservs->next_same_reservs_insn)
6680 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6681 curr_insn = curr_insn->next_equiv_class_insn;
6683 while (curr_insn != first_insn);
6684 equiv_classes_num++;
6686 automaton->insn_equiv_classes_num = equiv_classes_num;
6691 /* This page contains code for creating DFA(s) and calls functions
6692 building them. */
6695 /* The following value is used to prevent floating point overflow for
6696 estimating an automaton bound. The value should be less DBL_MAX on
6697 the host machine. We use here approximate minimum of maximal
6698 double floating point value required by ANSI C standard. It
6699 will work for non ANSI sun compiler too. */
6701 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6703 /* The function estimate size of the single DFA used by PHR (pipeline
6704 hazards recognizer). */
6705 static double
6706 estimate_one_automaton_bound (void)
6708 decl_t decl;
6709 double one_automaton_estimation_bound;
6710 double root_value;
6711 int i;
6713 one_automaton_estimation_bound = 1.0;
6714 for (i = 0; i < description->decls_num; i++)
6716 decl = description->decls [i];
6717 if (decl->mode == dm_unit)
6719 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6720 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6721 / automata_num);
6722 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6723 > one_automaton_estimation_bound)
6724 one_automaton_estimation_bound *= root_value;
6727 return one_automaton_estimation_bound;
6730 /* The function compares unit declarations according to their maximal
6731 cycle in reservations. */
6732 static int
6733 compare_max_occ_cycle_nums (const void *unit_decl_1,
6734 const void *unit_decl_2)
6736 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6737 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6738 return 1;
6739 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6740 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6741 return 0;
6742 else
6743 return -1;
6746 /* The function makes heuristic assigning automata to units. Actually
6747 efficacy of the algorithm has been checked yet??? */
6748 static void
6749 units_to_automata_heuristic_distr (void)
6751 double estimation_bound;
6752 decl_t decl;
6753 decl_t *unit_decl_ptr;
6754 int automaton_num;
6755 int rest_units_num;
6756 double bound_value;
6757 vla_ptr_t unit_decls;
6758 int i;
6760 if (description->units_num == 0)
6761 return;
6762 estimation_bound = estimate_one_automaton_bound ();
6763 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6764 for (i = 0; i < description->decls_num; i++)
6766 decl = description->decls [i];
6767 if (decl->mode == dm_unit)
6768 VLA_PTR_ADD (unit_decls, decl);
6770 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6771 sizeof (decl_t), compare_max_occ_cycle_nums);
6772 automaton_num = 0;
6773 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6774 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6775 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6776 for (unit_decl_ptr++;
6777 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6778 unit_decl_ptr++)
6780 rest_units_num
6781 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6782 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6783 if (automaton_num < automata_num - 1
6784 && ((automata_num - automaton_num - 1 == rest_units_num)
6785 || (bound_value
6786 > (estimation_bound
6787 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6789 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6790 automaton_num++;
6792 else
6793 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6794 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6796 gcc_assert (automaton_num == automata_num - 1);
6797 VLA_PTR_DELETE (unit_decls);
6800 /* The functions creates automaton insns for each automata. Automaton
6801 insn is simply insn for given automaton which makes reservation
6802 only of units of the automaton. */
6803 static ainsn_t
6804 create_ainsns (void)
6806 decl_t decl;
6807 ainsn_t first_ainsn;
6808 ainsn_t curr_ainsn;
6809 ainsn_t prev_ainsn;
6810 int i;
6812 first_ainsn = NULL;
6813 prev_ainsn = NULL;
6814 for (i = 0; i < description->decls_num; i++)
6816 decl = description->decls [i];
6817 if (decl->mode == dm_insn_reserv)
6819 curr_ainsn = create_node (sizeof (struct ainsn));
6820 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6821 curr_ainsn->important_p = FALSE;
6822 curr_ainsn->next_ainsn = NULL;
6823 if (prev_ainsn == NULL)
6824 first_ainsn = curr_ainsn;
6825 else
6826 prev_ainsn->next_ainsn = curr_ainsn;
6827 prev_ainsn = curr_ainsn;
6830 return first_ainsn;
6833 /* The function assigns automata to units according to constructions
6834 `define_automaton' in the description. */
6835 static void
6836 units_to_automata_distr (void)
6838 decl_t decl;
6839 int i;
6841 for (i = 0; i < description->decls_num; i++)
6843 decl = description->decls [i];
6844 if (decl->mode == dm_unit)
6846 if (DECL_UNIT (decl)->automaton_decl == NULL
6847 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6848 == NULL))
6849 /* Distribute to the first automaton. */
6850 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6851 else
6852 DECL_UNIT (decl)->corresponding_automaton_num
6853 = (DECL_UNIT (decl)->automaton_decl
6854 ->corresponding_automaton->automaton_order_num);
6859 /* The function creates DFA(s) for fast pipeline hazards recognition
6860 after checking and simplifying IR of the description. */
6861 static void
6862 create_automata (void)
6864 automaton_t curr_automaton;
6865 automaton_t prev_automaton;
6866 decl_t decl;
6867 int curr_automaton_num;
6868 int i;
6870 if (automata_num != 0)
6872 units_to_automata_heuristic_distr ();
6873 for (prev_automaton = NULL, curr_automaton_num = 0;
6874 curr_automaton_num < automata_num;
6875 curr_automaton_num++, prev_automaton = curr_automaton)
6877 curr_automaton = create_node (sizeof (struct automaton));
6878 curr_automaton->ainsn_list = create_ainsns ();
6879 curr_automaton->corresponding_automaton_decl = NULL;
6880 curr_automaton->next_automaton = NULL;
6881 curr_automaton->automaton_order_num = curr_automaton_num;
6882 if (prev_automaton == NULL)
6883 description->first_automaton = curr_automaton;
6884 else
6885 prev_automaton->next_automaton = curr_automaton;
6888 else
6890 curr_automaton_num = 0;
6891 prev_automaton = NULL;
6892 for (i = 0; i < description->decls_num; i++)
6894 decl = description->decls [i];
6895 if (decl->mode == dm_automaton
6896 && DECL_AUTOMATON (decl)->automaton_is_used)
6898 curr_automaton = create_node (sizeof (struct automaton));
6899 curr_automaton->ainsn_list = create_ainsns ();
6900 curr_automaton->corresponding_automaton_decl
6901 = DECL_AUTOMATON (decl);
6902 curr_automaton->next_automaton = NULL;
6903 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6904 curr_automaton->automaton_order_num = curr_automaton_num;
6905 if (prev_automaton == NULL)
6906 description->first_automaton = curr_automaton;
6907 else
6908 prev_automaton->next_automaton = curr_automaton;
6909 curr_automaton_num++;
6910 prev_automaton = curr_automaton;
6913 if (curr_automaton_num == 0)
6915 curr_automaton = create_node (sizeof (struct automaton));
6916 curr_automaton->ainsn_list = create_ainsns ();
6917 curr_automaton->corresponding_automaton_decl = NULL;
6918 curr_automaton->next_automaton = NULL;
6919 description->first_automaton = curr_automaton;
6921 units_to_automata_distr ();
6923 NDFA_time = create_ticker ();
6924 ticker_off (&NDFA_time);
6925 NDFA_to_DFA_time = create_ticker ();
6926 ticker_off (&NDFA_to_DFA_time);
6927 minimize_time = create_ticker ();
6928 ticker_off (&minimize_time);
6929 equiv_time = create_ticker ();
6930 ticker_off (&equiv_time);
6931 for (curr_automaton = description->first_automaton;
6932 curr_automaton != NULL;
6933 curr_automaton = curr_automaton->next_automaton)
6935 if (progress_flag)
6937 if (curr_automaton->corresponding_automaton_decl == NULL)
6938 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6939 else
6940 fprintf (stderr, "Prepare automaton `%s' creation...",
6941 curr_automaton->corresponding_automaton_decl->name);
6943 create_alt_states (curr_automaton);
6944 form_ainsn_with_same_reservs (curr_automaton);
6945 if (progress_flag)
6946 fprintf (stderr, "done\n");
6947 build_automaton (curr_automaton);
6948 enumerate_states (curr_automaton);
6949 ticker_on (&equiv_time);
6950 set_insn_equiv_classes (curr_automaton);
6951 ticker_off (&equiv_time);
6957 /* This page contains code for forming string representation of
6958 regexp. The representation is formed on IR obstack. So you should
6959 not work with IR obstack between regexp_representation and
6960 finish_regexp_representation calls. */
6962 /* This recursive function forms string representation of regexp
6963 (without tailing '\0'). */
6964 static void
6965 form_regexp (regexp_t regexp)
6967 int i;
6969 switch (regexp->mode)
6971 case rm_unit: case rm_reserv:
6973 const char *name = (regexp->mode == rm_unit
6974 ? REGEXP_UNIT (regexp)->name
6975 : REGEXP_RESERV (regexp)->name);
6977 obstack_grow (&irp, name, strlen (name));
6978 break;
6981 case rm_sequence:
6982 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6984 if (i != 0)
6985 obstack_1grow (&irp, ',');
6986 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6988 break;
6990 case rm_allof:
6991 obstack_1grow (&irp, '(');
6992 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6994 if (i != 0)
6995 obstack_1grow (&irp, '+');
6996 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6997 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6998 obstack_1grow (&irp, '(');
6999 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
7000 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
7001 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
7002 obstack_1grow (&irp, ')');
7004 obstack_1grow (&irp, ')');
7005 break;
7007 case rm_oneof:
7008 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
7010 if (i != 0)
7011 obstack_1grow (&irp, '|');
7012 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7013 obstack_1grow (&irp, '(');
7014 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
7015 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7016 obstack_1grow (&irp, ')');
7018 break;
7020 case rm_repeat:
7022 char digits [30];
7024 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7025 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7026 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7027 obstack_1grow (&irp, '(');
7028 form_regexp (REGEXP_REPEAT (regexp)->regexp);
7029 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7030 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7031 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7032 obstack_1grow (&irp, ')');
7033 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
7034 obstack_grow (&irp, digits, strlen (digits));
7035 break;
7038 case rm_nothing:
7039 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
7040 break;
7042 default:
7043 gcc_unreachable ();
7047 /* The function returns string representation of REGEXP on IR
7048 obstack. */
7049 static const char *
7050 regexp_representation (regexp_t regexp)
7052 form_regexp (regexp);
7053 obstack_1grow (&irp, '\0');
7054 return obstack_base (&irp);
7057 /* The function frees memory allocated for last formed string
7058 representation of regexp. */
7059 static void
7060 finish_regexp_representation (void)
7062 int length = obstack_object_size (&irp);
7064 obstack_blank_fast (&irp, -length);
7069 /* This page contains code for output PHR (pipeline hazards recognizer). */
7071 /* The function outputs minimal C type which is sufficient for
7072 representation numbers in range min_range_value and
7073 max_range_value. Because host machine and build machine may be
7074 different, we use here minimal values required by ANSI C standard
7075 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7076 approximation. */
7078 static void
7079 output_range_type (FILE *f, long int min_range_value,
7080 long int max_range_value)
7082 if (min_range_value >= 0 && max_range_value <= 255)
7083 fprintf (f, "unsigned char");
7084 else if (min_range_value >= -127 && max_range_value <= 127)
7085 fprintf (f, "signed char");
7086 else if (min_range_value >= 0 && max_range_value <= 65535)
7087 fprintf (f, "unsigned short");
7088 else if (min_range_value >= -32767 && max_range_value <= 32767)
7089 fprintf (f, "short");
7090 else
7091 fprintf (f, "int");
7094 /* The following macro value is used as value of member
7095 `longest_path_length' of state when we are processing path and the
7096 state on the path. */
7098 #define ON_THE_PATH -2
7100 /* The following recursive function searches for the length of the
7101 longest path starting from STATE which does not contain cycles and
7102 `cycle advance' arcs. */
7104 static int
7105 longest_path_length (state_t state)
7107 arc_t arc;
7108 int length, result;
7110 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7112 /* We don't expect the path cycle here. Our graph may contain
7113 only cycles with one state on the path not containing `cycle
7114 advance' arcs -- see comment below. */
7115 gcc_assert (state->longest_path_length != ON_THE_PATH);
7117 /* We already visited the state. */
7118 return state->longest_path_length;
7121 result = 0;
7122 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7123 /* Ignore cycles containing one state and `cycle advance' arcs. */
7124 if (arc->to_state != state
7125 && (arc->insn->insn_reserv_decl
7126 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7128 length = longest_path_length (arc->to_state);
7129 if (length > result)
7130 result = length;
7132 state->longest_path_length = result + 1;
7133 return result;
7136 /* The following variable value is value of the corresponding global
7137 variable in the automaton based pipeline interface. */
7139 static int max_dfa_issue_rate;
7141 /* The following function processes the longest path length staring
7142 from STATE to find MAX_DFA_ISSUE_RATE. */
7144 static void
7145 process_state_longest_path_length (state_t state)
7147 int value;
7149 value = longest_path_length (state);
7150 if (value > max_dfa_issue_rate)
7151 max_dfa_issue_rate = value;
7154 /* The following macro value is name of the corresponding global
7155 variable in the automaton based pipeline interface. */
7157 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7159 /* The following function calculates value of the corresponding
7160 global variable and outputs its declaration. */
7162 static void
7163 output_dfa_max_issue_rate (void)
7165 automaton_t automaton;
7167 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
7168 max_dfa_issue_rate = 0;
7169 for (automaton = description->first_automaton;
7170 automaton != NULL;
7171 automaton = automaton->next_automaton)
7172 pass_states (automaton, process_state_longest_path_length);
7173 fprintf (output_file, "\nint %s = %d;\n",
7174 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7177 /* The function outputs all initialization values of VECT with length
7178 vect_length. */
7179 static void
7180 output_vect (vect_el_t *vect, int vect_length)
7182 int els_on_line;
7184 els_on_line = 1;
7185 if (vect_length == 0)
7186 fprintf (output_file,
7187 "0 /* This is dummy el because the vect is empty */");
7188 else
7192 fprintf (output_file, "%5ld", (long) *vect);
7193 vect_length--;
7194 if (els_on_line == 10)
7196 els_on_line = 0;
7197 fprintf (output_file, ",\n");
7199 else if (vect_length != 0)
7200 fprintf (output_file, ", ");
7201 els_on_line++;
7202 vect++;
7204 while (vect_length != 0);
7208 /* The following is name of the structure which represents DFA(s) for
7209 PHR. */
7210 #define CHIP_NAME "DFA_chip"
7212 /* The following is name of member which represents state of a DFA for
7213 PHR. */
7214 static void
7215 output_chip_member_name (FILE *f, automaton_t automaton)
7217 if (automaton->corresponding_automaton_decl == NULL)
7218 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7219 else
7220 fprintf (f, "%s_automaton_state",
7221 automaton->corresponding_automaton_decl->name);
7224 /* The following is name of temporary variable which stores state of a
7225 DFA for PHR. */
7226 static void
7227 output_temp_chip_member_name (FILE *f, automaton_t automaton)
7229 fprintf (f, "_");
7230 output_chip_member_name (f, automaton);
7233 /* This is name of macro value which is code of pseudo_insn
7234 representing advancing cpu cycle. Its value is used as internal
7235 code unknown insn. */
7236 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7238 /* Output name of translate vector for given automaton. */
7239 static void
7240 output_translate_vect_name (FILE *f, automaton_t automaton)
7242 if (automaton->corresponding_automaton_decl == NULL)
7243 fprintf (f, "translate_%d", automaton->automaton_order_num);
7244 else
7245 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7248 /* Output name for simple transition table representation. */
7249 static void
7250 output_trans_full_vect_name (FILE *f, automaton_t automaton)
7252 if (automaton->corresponding_automaton_decl == NULL)
7253 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7254 else
7255 fprintf (f, "%s_transitions",
7256 automaton->corresponding_automaton_decl->name);
7259 /* Output name of comb vector of the transition table for given
7260 automaton. */
7261 static void
7262 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7264 if (automaton->corresponding_automaton_decl == NULL)
7265 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7266 else
7267 fprintf (f, "%s_transitions",
7268 automaton->corresponding_automaton_decl->name);
7271 /* Output name of check vector of the transition table for given
7272 automaton. */
7273 static void
7274 output_trans_check_vect_name (FILE *f, automaton_t automaton)
7276 if (automaton->corresponding_automaton_decl == NULL)
7277 fprintf (f, "check_%d", automaton->automaton_order_num);
7278 else
7279 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7282 /* Output name of base vector of the transition table for given
7283 automaton. */
7284 static void
7285 output_trans_base_vect_name (FILE *f, automaton_t automaton)
7287 if (automaton->corresponding_automaton_decl == NULL)
7288 fprintf (f, "base_%d", automaton->automaton_order_num);
7289 else
7290 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7293 /* Output name for simple alternatives number representation. */
7294 static void
7295 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7297 if (automaton->corresponding_automaton_decl == NULL)
7298 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7299 else
7300 fprintf (f, "%s_state_alts",
7301 automaton->corresponding_automaton_decl->name);
7304 /* Output name of comb vector of the alternatives number table for given
7305 automaton. */
7306 static void
7307 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7309 if (automaton->corresponding_automaton_decl == NULL)
7310 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7311 else
7312 fprintf (f, "%s_state_alts",
7313 automaton->corresponding_automaton_decl->name);
7316 /* Output name of check vector of the alternatives number table for given
7317 automaton. */
7318 static void
7319 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7321 if (automaton->corresponding_automaton_decl == NULL)
7322 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7323 else
7324 fprintf (f, "%s_check_state_alts",
7325 automaton->corresponding_automaton_decl->name);
7328 /* Output name of base vector of the alternatives number table for given
7329 automaton. */
7330 static void
7331 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7333 if (automaton->corresponding_automaton_decl == NULL)
7334 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7335 else
7336 fprintf (f, "%s_base_state_alts",
7337 automaton->corresponding_automaton_decl->name);
7340 /* Output name of simple min issue delay table representation. */
7341 static void
7342 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7344 if (automaton->corresponding_automaton_decl == NULL)
7345 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7346 else
7347 fprintf (f, "%s_min_issue_delay",
7348 automaton->corresponding_automaton_decl->name);
7351 /* Output name of deadlock vector for given automaton. */
7352 static void
7353 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7355 if (automaton->corresponding_automaton_decl == NULL)
7356 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7357 else
7358 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7361 /* Output name of reserved units table for AUTOMATON into file F. */
7362 static void
7363 output_reserved_units_table_name (FILE *f, automaton_t automaton)
7365 if (automaton->corresponding_automaton_decl == NULL)
7366 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7367 else
7368 fprintf (f, "%s_reserved_units",
7369 automaton->corresponding_automaton_decl->name);
7372 /* Name of the PHR interface macro. */
7373 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7375 /* Name of the PHR interface macro. */
7376 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7378 /* Names of an internal functions: */
7379 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7381 /* This is external type of DFA(s) state. */
7382 #define STATE_TYPE_NAME "state_t"
7384 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7386 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7388 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7390 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7392 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7394 /* Name of cache of insn dfa codes. */
7395 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7397 /* Name of length of cache of insn dfa codes. */
7398 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7400 /* Names of the PHR interface functions: */
7401 #define SIZE_FUNC_NAME "state_size"
7403 #define TRANSITION_FUNC_NAME "state_transition"
7405 #define STATE_ALTS_FUNC_NAME "state_alts"
7407 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7409 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7411 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7413 #define RESET_FUNC_NAME "state_reset"
7415 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7417 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7419 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7421 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7423 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7425 #define DFA_START_FUNC_NAME "dfa_start"
7427 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7429 /* Names of parameters of the PHR interface functions. */
7430 #define STATE_NAME "state"
7432 #define INSN_PARAMETER_NAME "insn"
7434 #define INSN2_PARAMETER_NAME "insn2"
7436 #define CHIP_PARAMETER_NAME "chip"
7438 #define FILE_PARAMETER_NAME "f"
7440 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7442 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7444 /* Names of the variables whose values are internal insn code of rtx
7445 insn. */
7446 #define INTERNAL_INSN_CODE_NAME "insn_code"
7448 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7450 /* Names of temporary variables in some functions. */
7451 #define TEMPORARY_VARIABLE_NAME "temp"
7453 #define I_VARIABLE_NAME "i"
7455 /* Name of result variable in some functions. */
7456 #define RESULT_VARIABLE_NAME "res"
7458 /* Name of function (attribute) to translate insn into internal insn
7459 code. */
7460 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7462 /* Name of function (attribute) to translate insn into internal insn
7463 code with caching. */
7464 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7466 /* Name of function (attribute) to translate insn into internal insn
7467 code. */
7468 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7470 /* Name of function (attribute) to translate insn into internal insn
7471 code. */
7472 #define BYPASS_P_FUNC_NAME "bypass_p"
7474 /* Output C type which is used for representation of codes of states
7475 of AUTOMATON. */
7476 static void
7477 output_state_member_type (FILE *f, automaton_t automaton)
7479 output_range_type (f, 0, automaton->achieved_states_num);
7482 /* Output definition of the structure representing current DFA(s)
7483 state(s). */
7484 static void
7485 output_chip_definitions (void)
7487 automaton_t automaton;
7489 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7490 for (automaton = description->first_automaton;
7491 automaton != NULL;
7492 automaton = automaton->next_automaton)
7494 fprintf (output_file, " ");
7495 output_state_member_type (output_file, automaton);
7496 fprintf (output_file, " ");
7497 output_chip_member_name (output_file, automaton);
7498 fprintf (output_file, ";\n");
7500 fprintf (output_file, "};\n\n");
7501 #if 0
7502 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7503 #endif
7507 /* The function outputs translate vector of internal insn code into
7508 insn equivalence class number. The equivalence class number is
7509 used to access to table and vectors representing DFA(s). */
7510 static void
7511 output_translate_vect (automaton_t automaton)
7513 ainsn_t ainsn;
7514 int insn_value;
7515 vla_hwint_t translate_vect;
7517 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7518 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7519 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7520 /* Undefined value */
7521 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7522 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7523 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7524 = ainsn->insn_equiv_class_num;
7525 fprintf (output_file,
7526 "/* Vector translating external insn codes to internal ones.*/\n");
7527 fprintf (output_file, "static const ");
7528 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7529 fprintf (output_file, " ");
7530 output_translate_vect_name (output_file, automaton);
7531 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7532 output_vect (VLA_HWINT_BEGIN (translate_vect),
7533 VLA_HWINT_LENGTH (translate_vect));
7534 fprintf (output_file, "};\n\n");
7535 VLA_HWINT_DELETE (translate_vect);
7538 /* The value in a table state x ainsn -> something which represents
7539 undefined value. */
7540 static int undefined_vect_el_value;
7542 /* The following function returns nonzero value if the best
7543 representation of the table is comb vector. */
7544 static int
7545 comb_vect_p (state_ainsn_table_t tab)
7547 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7548 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7551 /* The following function creates new table for AUTOMATON. */
7552 static state_ainsn_table_t
7553 create_state_ainsn_table (automaton_t automaton)
7555 state_ainsn_table_t tab;
7556 int full_vect_length;
7557 int i;
7559 tab = create_node (sizeof (struct state_ainsn_table));
7560 tab->automaton = automaton;
7561 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7562 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7563 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7564 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7565 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7566 full_vect_length = (automaton->insn_equiv_classes_num
7567 * automaton->achieved_states_num);
7568 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7569 for (i = 0; i < full_vect_length; i++)
7570 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7571 tab->min_base_vect_el_value = 0;
7572 tab->max_base_vect_el_value = 0;
7573 tab->min_comb_vect_el_value = 0;
7574 tab->max_comb_vect_el_value = 0;
7575 return tab;
7578 /* The following function outputs the best C representation of the
7579 table TAB of given TABLE_NAME. */
7580 static void
7581 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
7582 void (*output_full_vect_name_func) (FILE *, automaton_t),
7583 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7584 void (*output_check_vect_name_func) (FILE *, automaton_t),
7585 void (*output_base_vect_name_func) (FILE *, automaton_t))
7587 if (!comb_vect_p (tab))
7589 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7590 fprintf (output_file, "static const ");
7591 output_range_type (output_file, tab->min_comb_vect_el_value,
7592 tab->max_comb_vect_el_value);
7593 fprintf (output_file, " ");
7594 (*output_full_vect_name_func) (output_file, tab->automaton);
7595 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7596 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7597 VLA_HWINT_LENGTH (tab->full_vect));
7598 fprintf (output_file, "};\n\n");
7600 else
7602 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7603 fprintf (output_file, "static const ");
7604 output_range_type (output_file, tab->min_comb_vect_el_value,
7605 tab->max_comb_vect_el_value);
7606 fprintf (output_file, " ");
7607 (*output_comb_vect_name_func) (output_file, tab->automaton);
7608 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7609 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7610 VLA_HWINT_LENGTH (tab->comb_vect));
7611 fprintf (output_file, "};\n\n");
7612 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7613 fprintf (output_file, "static const ");
7614 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7615 fprintf (output_file, " ");
7616 (*output_check_vect_name_func) (output_file, tab->automaton);
7617 fprintf (output_file, "[] = {\n");
7618 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7619 VLA_HWINT_LENGTH (tab->check_vect));
7620 fprintf (output_file, "};\n\n");
7621 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7622 fprintf (output_file, "static const ");
7623 output_range_type (output_file, tab->min_base_vect_el_value,
7624 tab->max_base_vect_el_value);
7625 fprintf (output_file, " ");
7626 (*output_base_vect_name_func) (output_file, tab->automaton);
7627 fprintf (output_file, "[] = {\n");
7628 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7629 VLA_HWINT_LENGTH (tab->base_vect));
7630 fprintf (output_file, "};\n\n");
7634 /* The following function adds vector with length VECT_LENGTH and
7635 elements pointed to by VECT to table TAB as its line with number
7636 VECT_NUM. */
7637 static void
7638 add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
7639 int vect_length)
7641 int real_vect_length;
7642 vect_el_t *comb_vect_start;
7643 vect_el_t *check_vect_start;
7644 int comb_vect_index;
7645 int comb_vect_els_num;
7646 int vect_index;
7647 int first_unempty_vect_index;
7648 int additional_els_num;
7649 int no_state_value;
7650 vect_el_t vect_el;
7651 int i;
7652 unsigned long vect_mask, comb_vect_mask;
7654 gcc_assert (vect_length);
7655 real_vect_length = tab->automaton->insn_equiv_classes_num;
7656 gcc_assert (vect [vect_length - 1] != undefined_vect_el_value);
7657 /* Form full vector in the table: */
7658 for (i = 0; i < vect_length; i++)
7659 VLA_HWINT (tab->full_vect,
7660 i + tab->automaton->insn_equiv_classes_num * vect_num)
7661 = vect [i];
7662 /* Form comb vector in the table: */
7663 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7664 == VLA_HWINT_LENGTH (tab->check_vect));
7665 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7666 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7667 for (first_unempty_vect_index = 0;
7668 first_unempty_vect_index < vect_length;
7669 first_unempty_vect_index++)
7670 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7671 break;
7673 /* Search for the place in comb vect for the inserted vect. */
7675 /* Slow case. */
7676 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7678 for (comb_vect_index = 0;
7679 comb_vect_index < comb_vect_els_num;
7680 comb_vect_index++)
7682 for (vect_index = first_unempty_vect_index;
7683 vect_index < vect_length
7684 && vect_index + comb_vect_index < comb_vect_els_num;
7685 vect_index++)
7686 if (vect [vect_index] != undefined_vect_el_value
7687 && (comb_vect_start [vect_index + comb_vect_index]
7688 != undefined_vect_el_value))
7689 break;
7690 if (vect_index >= vect_length
7691 || vect_index + comb_vect_index >= comb_vect_els_num)
7692 break;
7694 goto found;
7697 /* Fast case. */
7698 vect_mask = 0;
7699 for (vect_index = first_unempty_vect_index;
7700 vect_index < vect_length;
7701 vect_index++)
7703 vect_mask = vect_mask << 1;
7704 if (vect [vect_index] != undefined_vect_el_value)
7705 vect_mask |= 1;
7708 /* Search for the place in comb vect for the inserted vect. */
7709 comb_vect_index = 0;
7710 if (comb_vect_els_num == 0)
7711 goto found;
7713 comb_vect_mask = 0;
7714 for (vect_index = first_unempty_vect_index;
7715 vect_index < vect_length && vect_index < comb_vect_els_num;
7716 vect_index++)
7718 comb_vect_mask <<= 1;
7719 if (vect_index + comb_vect_index < comb_vect_els_num
7720 && comb_vect_start [vect_index + comb_vect_index]
7721 != undefined_vect_el_value)
7722 comb_vect_mask |= 1;
7724 if ((vect_mask & comb_vect_mask) == 0)
7725 goto found;
7727 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7728 comb_vect_index++, i++)
7730 comb_vect_mask = (comb_vect_mask << 1) | 1;
7731 comb_vect_mask ^= comb_vect_start [i] == undefined_vect_el_value;
7732 if ((vect_mask & comb_vect_mask) == 0)
7733 goto found;
7735 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7737 comb_vect_mask <<= 1;
7738 if ((vect_mask & comb_vect_mask) == 0)
7739 goto found;
7742 found:
7743 /* Slot was found. */
7744 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7745 if (additional_els_num < 0)
7746 additional_els_num = 0;
7747 /* Expand comb and check vectors. */
7748 vect_el = undefined_vect_el_value;
7749 no_state_value = tab->automaton->achieved_states_num;
7750 while (additional_els_num > 0)
7752 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7753 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7754 additional_els_num--;
7756 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7757 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7758 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7759 >= (size_t) (comb_vect_index + real_vect_length));
7760 /* Fill comb and check vectors. */
7761 for (vect_index = 0; vect_index < vect_length; vect_index++)
7762 if (vect [vect_index] != undefined_vect_el_value)
7764 gcc_assert (comb_vect_start [comb_vect_index + vect_index]
7765 == undefined_vect_el_value);
7766 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7767 gcc_assert (vect [vect_index] >= 0);
7768 if (tab->max_comb_vect_el_value < vect [vect_index])
7769 tab->max_comb_vect_el_value = vect [vect_index];
7770 if (tab->min_comb_vect_el_value > vect [vect_index])
7771 tab->min_comb_vect_el_value = vect [vect_index];
7772 check_vect_start [comb_vect_index + vect_index] = vect_num;
7774 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7775 tab->max_comb_vect_el_value = undefined_vect_el_value;
7776 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7777 tab->min_comb_vect_el_value = undefined_vect_el_value;
7778 if (tab->max_base_vect_el_value < comb_vect_index)
7779 tab->max_base_vect_el_value = comb_vect_index;
7780 if (tab->min_base_vect_el_value > comb_vect_index)
7781 tab->min_base_vect_el_value = comb_vect_index;
7782 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7785 /* Return number of out arcs of STATE. */
7786 static int
7787 out_state_arcs_num (state_t state)
7789 int result;
7790 arc_t arc;
7792 result = 0;
7793 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7795 gcc_assert (arc->insn);
7796 if (arc->insn->first_ainsn_with_given_equivalence_num)
7797 result++;
7799 return result;
7802 /* Compare number of possible transitions from the states. */
7803 static int
7804 compare_transition_els_num (const void *state_ptr_1,
7805 const void *state_ptr_2)
7807 int transition_els_num_1;
7808 int transition_els_num_2;
7810 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7811 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7812 if (transition_els_num_1 < transition_els_num_2)
7813 return 1;
7814 else if (transition_els_num_1 == transition_els_num_2)
7815 return 0;
7816 else
7817 return -1;
7820 /* The function adds element EL_VALUE to vector VECT for a table state
7821 x AINSN. */
7822 static void
7823 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7825 int equiv_class_num;
7826 int vect_index;
7828 gcc_assert (ainsn);
7829 equiv_class_num = ainsn->insn_equiv_class_num;
7830 for (vect_index = VLA_HWINT_LENGTH (*vect);
7831 vect_index <= equiv_class_num;
7832 vect_index++)
7833 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7834 VLA_HWINT (*vect, equiv_class_num) = el_value;
7837 /* This is for forming vector of states of an automaton. */
7838 static vla_ptr_t output_states_vect;
7840 /* The function is called by function pass_states. The function adds
7841 STATE to `output_states_vect'. */
7842 static void
7843 add_states_vect_el (state_t state)
7845 VLA_PTR_ADD (output_states_vect, state);
7848 /* Form and output vectors (comb, check, base or full vector)
7849 representing transition table of AUTOMATON. */
7850 static void
7851 output_trans_table (automaton_t automaton)
7853 state_t *state_ptr;
7854 arc_t arc;
7855 vla_hwint_t transition_vect;
7857 undefined_vect_el_value = automaton->achieved_states_num;
7858 automaton->trans_table = create_state_ainsn_table (automaton);
7859 /* Create vect of pointers to states ordered by num of transitions
7860 from the state (state with the maximum num is the first). */
7861 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7862 pass_states (automaton, add_states_vect_el);
7863 qsort (VLA_PTR_BEGIN (output_states_vect),
7864 VLA_PTR_LENGTH (output_states_vect),
7865 sizeof (state_t), compare_transition_els_num);
7866 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7867 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7868 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7869 state_ptr++)
7871 VLA_HWINT_NULLIFY (transition_vect);
7872 for (arc = first_out_arc (*state_ptr);
7873 arc != NULL;
7874 arc = next_out_arc (arc))
7876 gcc_assert (arc->insn);
7877 if (arc->insn->first_ainsn_with_given_equivalence_num)
7878 add_vect_el (&transition_vect, arc->insn,
7879 arc->to_state->order_state_num);
7881 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7882 VLA_HWINT_BEGIN (transition_vect),
7883 VLA_HWINT_LENGTH (transition_vect));
7885 output_state_ainsn_table
7886 (automaton->trans_table, (char *) "state transitions",
7887 output_trans_full_vect_name, output_trans_comb_vect_name,
7888 output_trans_check_vect_name, output_trans_base_vect_name);
7889 VLA_PTR_DELETE (output_states_vect);
7890 VLA_HWINT_DELETE (transition_vect);
7893 /* Form and output vectors (comb, check, base or simple vect)
7894 representing alts number table of AUTOMATON. The table is state x
7895 ainsn -> number of possible alternative reservations by the
7896 ainsn. */
7897 static void
7898 output_state_alts_table (automaton_t automaton)
7900 state_t *state_ptr;
7901 arc_t arc;
7902 vla_hwint_t state_alts_vect;
7904 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7905 automaton->state_alts_table = create_state_ainsn_table (automaton);
7906 /* Create vect of pointers to states ordered by num of transitions
7907 from the state (state with the maximum num is the first). */
7908 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7909 pass_states (automaton, add_states_vect_el);
7910 qsort (VLA_PTR_BEGIN (output_states_vect),
7911 VLA_PTR_LENGTH (output_states_vect),
7912 sizeof (state_t), compare_transition_els_num);
7913 /* Create base, comb, and check vectors. */
7914 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7915 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7916 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7917 state_ptr++)
7919 VLA_HWINT_NULLIFY (state_alts_vect);
7920 for (arc = first_out_arc (*state_ptr);
7921 arc != NULL;
7922 arc = next_out_arc (arc))
7924 gcc_assert (arc->insn);
7925 if (arc->insn->first_ainsn_with_given_equivalence_num)
7926 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7928 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7929 VLA_HWINT_BEGIN (state_alts_vect),
7930 VLA_HWINT_LENGTH (state_alts_vect));
7932 output_state_ainsn_table
7933 (automaton->state_alts_table, (char *) "state insn alternatives",
7934 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7935 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7936 VLA_PTR_DELETE (output_states_vect);
7937 VLA_HWINT_DELETE (state_alts_vect);
7940 /* The current number of passing states to find minimal issue delay
7941 value for an ainsn and state. */
7942 static int curr_state_pass_num;
7944 /* This recursive function passes states to find minimal issue delay
7945 value for AINSN. The state being visited is STATE. The function
7946 returns minimal issue delay value for AINSN in STATE or -1 if we
7947 enter into a loop. */
7948 static int
7949 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7951 arc_t arc;
7952 int min_insn_issue_delay, insn_issue_delay;
7954 if (state->state_pass_num == curr_state_pass_num
7955 || state->min_insn_issue_delay != -1)
7956 /* We've entered into a loop or already have the correct value for
7957 given state and ainsn. */
7958 return state->min_insn_issue_delay;
7959 state->state_pass_num = curr_state_pass_num;
7960 min_insn_issue_delay = -1;
7961 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7962 if (arc->insn == ainsn)
7964 min_insn_issue_delay = 0;
7965 break;
7967 else
7969 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7970 if (insn_issue_delay != -1)
7972 if (arc->insn->insn_reserv_decl
7973 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7974 insn_issue_delay++;
7975 if (min_insn_issue_delay == -1
7976 || min_insn_issue_delay > insn_issue_delay)
7978 min_insn_issue_delay = insn_issue_delay;
7979 if (insn_issue_delay == 0)
7980 break;
7984 return min_insn_issue_delay;
7987 /* The function searches minimal issue delay value for AINSN in STATE.
7988 The function can return negative value if we can not issue AINSN. We
7989 will report about it later. */
7990 static int
7991 min_issue_delay (state_t state, ainsn_t ainsn)
7993 curr_state_pass_num++;
7994 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7995 return state->min_insn_issue_delay;
7998 /* The function initiates code for finding minimal issue delay values.
7999 It should be called only once. */
8000 static void
8001 initiate_min_issue_delay_pass_states (void)
8003 curr_state_pass_num = 0;
8006 /* Form and output vectors representing minimal issue delay table of
8007 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8008 the ainsn. */
8009 static void
8010 output_min_issue_delay_table (automaton_t automaton)
8012 vla_hwint_t min_issue_delay_vect;
8013 vla_hwint_t compressed_min_issue_delay_vect;
8014 vect_el_t min_delay;
8015 ainsn_t ainsn;
8016 state_t *state_ptr;
8017 int i;
8019 /* Create vect of pointers to states ordered by num of transitions
8020 from the state (state with the maximum num is the first). */
8021 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8022 pass_states (automaton, add_states_vect_el);
8023 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
8024 VLA_HWINT_EXPAND (min_issue_delay_vect,
8025 VLA_HWINT_LENGTH (output_states_vect)
8026 * automaton->insn_equiv_classes_num);
8027 for (i = 0;
8028 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
8029 * automaton->insn_equiv_classes_num);
8030 i++)
8031 VLA_HWINT (min_issue_delay_vect, i) = 0;
8032 automaton->max_min_delay = 0;
8033 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
8034 if (ainsn->first_ainsn_with_given_equivalence_num)
8036 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8037 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8038 state_ptr++)
8039 (*state_ptr)->min_insn_issue_delay = -1;
8040 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8041 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8042 state_ptr++)
8044 min_delay = min_issue_delay (*state_ptr, ainsn);
8045 if (automaton->max_min_delay < min_delay)
8046 automaton->max_min_delay = min_delay;
8047 VLA_HWINT (min_issue_delay_vect,
8048 (*state_ptr)->order_state_num
8049 * automaton->insn_equiv_classes_num
8050 + ainsn->insn_equiv_class_num) = min_delay;
8053 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
8054 fprintf (output_file, "static const ");
8055 output_range_type (output_file, 0, automaton->max_min_delay);
8056 fprintf (output_file, " ");
8057 output_min_issue_delay_vect_name (output_file, automaton);
8058 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
8059 /* Compress the vector. */
8060 if (automaton->max_min_delay < 2)
8061 automaton->min_issue_delay_table_compression_factor = 8;
8062 else if (automaton->max_min_delay < 4)
8063 automaton->min_issue_delay_table_compression_factor = 4;
8064 else if (automaton->max_min_delay < 16)
8065 automaton->min_issue_delay_table_compression_factor = 2;
8066 else
8067 automaton->min_issue_delay_table_compression_factor = 1;
8068 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
8069 "compressed min issue delay vector");
8070 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
8071 (VLA_HWINT_LENGTH (min_issue_delay_vect)
8072 + automaton->min_issue_delay_table_compression_factor
8073 - 1)
8074 / automaton->min_issue_delay_table_compression_factor);
8075 for (i = 0;
8076 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
8077 i++)
8078 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
8079 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
8080 VLA_HWINT (compressed_min_issue_delay_vect,
8081 i / automaton->min_issue_delay_table_compression_factor)
8082 |= (VLA_HWINT (min_issue_delay_vect, i)
8083 << (8 - (i % automaton->min_issue_delay_table_compression_factor
8084 + 1)
8085 * (8 / automaton->min_issue_delay_table_compression_factor)));
8086 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
8087 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
8088 fprintf (output_file, "};\n\n");
8089 VLA_PTR_DELETE (output_states_vect);
8090 VLA_HWINT_DELETE (min_issue_delay_vect);
8091 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
8094 #ifndef NDEBUG
8095 /* Number of states which contains transition only by advancing cpu
8096 cycle. */
8097 static int locked_states_num;
8098 #endif
8100 /* Form and output vector representing the locked states of
8101 AUTOMATON. */
8102 static void
8103 output_dead_lock_vect (automaton_t automaton)
8105 state_t *state_ptr;
8106 arc_t arc;
8107 vla_hwint_t dead_lock_vect;
8109 /* Create vect of pointers to states ordered by num of
8110 transitions from the state (state with the maximum num is the
8111 first). */
8112 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8113 pass_states (automaton, add_states_vect_el);
8114 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
8115 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
8116 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8117 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8118 state_ptr++)
8120 arc = first_out_arc (*state_ptr);
8121 gcc_assert (arc);
8122 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8123 = (next_out_arc (arc) == NULL
8124 && (arc->insn->insn_reserv_decl
8125 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8126 #ifndef NDEBUG
8127 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8128 locked_states_num++;
8129 #endif
8131 fprintf (output_file, "/* Vector for locked state flags. */\n");
8132 fprintf (output_file, "static const ");
8133 output_range_type (output_file, 0, 1);
8134 fprintf (output_file, " ");
8135 output_dead_lock_vect_name (output_file, automaton);
8136 fprintf (output_file, "[] = {\n");
8137 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8138 VLA_HWINT_LENGTH (dead_lock_vect));
8139 fprintf (output_file, "};\n\n");
8140 VLA_HWINT_DELETE (dead_lock_vect);
8141 VLA_PTR_DELETE (output_states_vect);
8144 /* Form and output vector representing reserved units of the states of
8145 AUTOMATON. */
8146 static void
8147 output_reserved_units_table (automaton_t automaton)
8149 state_t *curr_state_ptr;
8150 vla_hwint_t reserved_units_table;
8151 size_t state_byte_size;
8152 int i;
8154 /* Create vect of pointers to states. */
8155 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8156 pass_states (automaton, add_states_vect_el);
8157 /* Create vector. */
8158 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8159 state_byte_size = (description->query_units_num + 7) / 8;
8160 VLA_HWINT_EXPAND (reserved_units_table,
8161 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8162 for (i = 0;
8163 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8164 i++)
8165 VLA_HWINT (reserved_units_table, i) = 0;
8166 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8167 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8168 curr_state_ptr++)
8170 for (i = 0; i < description->units_num; i++)
8171 if (units_array [i]->query_p
8172 && first_cycle_unit_presence (*curr_state_ptr, i))
8173 VLA_HWINT (reserved_units_table,
8174 (*curr_state_ptr)->order_state_num * state_byte_size
8175 + units_array [i]->query_num / 8)
8176 += (1 << (units_array [i]->query_num % 8));
8178 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8179 fprintf (output_file, "static const ");
8180 output_range_type (output_file, 0, 255);
8181 fprintf (output_file, " ");
8182 output_reserved_units_table_name (output_file, automaton);
8183 fprintf (output_file, "[] = {\n");
8184 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8185 VLA_HWINT_LENGTH (reserved_units_table));
8186 fprintf (output_file, "};\n\n");
8187 VLA_HWINT_DELETE (reserved_units_table);
8188 VLA_PTR_DELETE (output_states_vect);
8191 /* The function outputs all tables representing DFA(s) used for fast
8192 pipeline hazards recognition. */
8193 static void
8194 output_tables (void)
8196 automaton_t automaton;
8198 #ifndef NDEBUG
8199 locked_states_num = 0;
8200 #endif
8201 initiate_min_issue_delay_pass_states ();
8202 for (automaton = description->first_automaton;
8203 automaton != NULL;
8204 automaton = automaton->next_automaton)
8206 output_translate_vect (automaton);
8207 output_trans_table (automaton);
8208 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8209 output_state_alts_table (automaton);
8210 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8211 AUTOMATON_STATE_ALTS_MACRO_NAME);
8212 output_min_issue_delay_table (automaton);
8213 output_dead_lock_vect (automaton);
8214 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8215 output_reserved_units_table (automaton);
8216 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8217 CPU_UNITS_QUERY_MACRO_NAME);
8219 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8220 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8223 /* The function outputs definition and value of PHR interface variable
8224 `max_insn_queue_index'. Its value is not less than maximal queue
8225 length needed for the insn scheduler. */
8226 static void
8227 output_max_insn_queue_index_def (void)
8229 int i, max, latency;
8230 decl_t decl;
8232 max = description->max_insn_reserv_cycles;
8233 for (i = 0; i < description->decls_num; i++)
8235 decl = description->decls [i];
8236 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8238 latency = DECL_INSN_RESERV (decl)->default_latency;
8239 if (latency > max)
8240 max = latency;
8242 else if (decl->mode == dm_bypass)
8244 latency = DECL_BYPASS (decl)->latency;
8245 if (latency > max)
8246 max = latency;
8249 for (i = 0; (1 << i) <= max; i++)
8251 gcc_assert (i >= 0);
8252 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8256 /* The function outputs switch cases for insn reservations using
8257 function *output_automata_list_code. */
8258 static void
8259 output_insn_code_cases (void (*output_automata_list_code)
8260 (automata_list_el_t))
8262 decl_t decl, decl2;
8263 int i, j;
8265 for (i = 0; i < description->decls_num; i++)
8267 decl = description->decls [i];
8268 if (decl->mode == dm_insn_reserv)
8269 DECL_INSN_RESERV (decl)->processed_p = FALSE;
8271 for (i = 0; i < description->decls_num; i++)
8273 decl = description->decls [i];
8274 if (decl->mode == dm_insn_reserv
8275 && !DECL_INSN_RESERV (decl)->processed_p)
8277 for (j = i; j < description->decls_num; j++)
8279 decl2 = description->decls [j];
8280 if (decl2->mode == dm_insn_reserv
8281 && (DECL_INSN_RESERV (decl2)->important_automata_list
8282 == DECL_INSN_RESERV (decl)->important_automata_list))
8284 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8285 fprintf (output_file, " case %d: /* %s */\n",
8286 DECL_INSN_RESERV (decl2)->insn_num,
8287 DECL_INSN_RESERV (decl2)->name);
8290 (*output_automata_list_code)
8291 (DECL_INSN_RESERV (decl)->important_automata_list);
8297 /* The function outputs a code for evaluation of a minimal delay of
8298 issue of insns which have reservations in given AUTOMATA_LIST. */
8299 static void
8300 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8302 automata_list_el_t el;
8303 automaton_t automaton;
8305 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8307 automaton = el->automaton;
8308 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8309 output_min_issue_delay_vect_name (output_file, automaton);
8310 fprintf (output_file,
8311 (automaton->min_issue_delay_table_compression_factor != 1
8312 ? " [(" : " ["));
8313 output_translate_vect_name (output_file, automaton);
8314 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8315 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8316 output_chip_member_name (output_file, automaton);
8317 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8318 if (automaton->min_issue_delay_table_compression_factor == 1)
8319 fprintf (output_file, "];\n");
8320 else
8322 fprintf (output_file, ") / %d];\n",
8323 automaton->min_issue_delay_table_compression_factor);
8324 fprintf (output_file, " %s = (%s >> (8 - (",
8325 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8326 output_translate_vect_name (output_file, automaton);
8327 fprintf
8328 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8329 INTERNAL_INSN_CODE_NAME,
8330 automaton->min_issue_delay_table_compression_factor,
8331 8 / automaton->min_issue_delay_table_compression_factor,
8332 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8333 - 1);
8335 if (el == automata_list)
8336 fprintf (output_file, " %s = %s;\n",
8337 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8338 else
8340 fprintf (output_file, " if (%s > %s)\n",
8341 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8342 fprintf (output_file, " %s = %s;\n",
8343 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8346 fprintf (output_file, " break;\n\n");
8349 /* Output function `internal_min_issue_delay'. */
8350 static void
8351 output_internal_min_issue_delay_func (void)
8353 fprintf (output_file,
8354 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8355 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8356 CHIP_NAME, CHIP_PARAMETER_NAME);
8357 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8358 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8359 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8360 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8361 fprintf (output_file,
8362 "\n default:\n %s = -1;\n break;\n }\n",
8363 RESULT_VARIABLE_NAME);
8364 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8365 fprintf (output_file, "}\n\n");
8368 /* The function outputs a code changing state after issue of insns
8369 which have reservations in given AUTOMATA_LIST. */
8370 static void
8371 output_automata_list_transition_code (automata_list_el_t automata_list)
8373 automata_list_el_t el, next_el;
8375 fprintf (output_file, " {\n");
8376 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8377 for (el = automata_list;; el = next_el)
8379 next_el = el->next_automata_list_el;
8380 if (next_el == NULL)
8381 break;
8382 fprintf (output_file, " ");
8383 output_state_member_type (output_file, el->automaton);
8384 fprintf (output_file, " ");
8385 output_temp_chip_member_name (output_file, el->automaton);
8386 fprintf (output_file, ";\n");
8388 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8389 if (comb_vect_p (el->automaton->trans_table))
8391 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8392 output_trans_base_vect_name (output_file, el->automaton);
8393 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8394 output_chip_member_name (output_file, el->automaton);
8395 fprintf (output_file, "] + ");
8396 output_translate_vect_name (output_file, el->automaton);
8397 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8398 fprintf (output_file, " if (");
8399 output_trans_check_vect_name (output_file, el->automaton);
8400 fprintf (output_file, " [%s] != %s->",
8401 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8402 output_chip_member_name (output_file, el->automaton);
8403 fprintf (output_file, ")\n");
8404 fprintf (output_file, " return %s (%s, %s);\n",
8405 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8406 CHIP_PARAMETER_NAME);
8407 fprintf (output_file, " else\n");
8408 fprintf (output_file, " ");
8409 if (el->next_automata_list_el != NULL)
8410 output_temp_chip_member_name (output_file, el->automaton);
8411 else
8413 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8414 output_chip_member_name (output_file, el->automaton);
8416 fprintf (output_file, " = ");
8417 output_trans_comb_vect_name (output_file, el->automaton);
8418 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8420 else
8422 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8423 output_trans_full_vect_name (output_file, el->automaton);
8424 fprintf (output_file, " [");
8425 output_translate_vect_name (output_file, el->automaton);
8426 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8427 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8428 output_chip_member_name (output_file, el->automaton);
8429 fprintf (output_file, " * %d];\n",
8430 el->automaton->insn_equiv_classes_num);
8431 fprintf (output_file, " if (%s >= %d)\n",
8432 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8433 fprintf (output_file, " return %s (%s, %s);\n",
8434 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8435 CHIP_PARAMETER_NAME);
8436 fprintf (output_file, " else\n ");
8437 if (el->next_automata_list_el != NULL)
8438 output_temp_chip_member_name (output_file, el->automaton);
8439 else
8441 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8442 output_chip_member_name (output_file, el->automaton);
8444 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8446 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8447 for (el = automata_list;; el = next_el)
8449 next_el = el->next_automata_list_el;
8450 if (next_el == NULL)
8451 break;
8452 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8453 output_chip_member_name (output_file, el->automaton);
8454 fprintf (output_file, " = ");
8455 output_temp_chip_member_name (output_file, el->automaton);
8456 fprintf (output_file, ";\n");
8458 fprintf (output_file, " return -1;\n");
8459 fprintf (output_file, " }\n");
8462 /* Output function `internal_state_transition'. */
8463 static void
8464 output_internal_trans_func (void)
8466 fprintf (output_file,
8467 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8468 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8469 CHIP_NAME, CHIP_PARAMETER_NAME);
8470 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8471 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8472 output_insn_code_cases (output_automata_list_transition_code);
8473 fprintf (output_file, "\n default:\n return -1;\n }\n");
8474 fprintf (output_file, "}\n\n");
8477 /* Output code
8479 if (insn != 0)
8481 insn_code = dfa_insn_code (insn);
8482 if (insn_code > DFA__ADVANCE_CYCLE)
8483 return code;
8485 else
8486 insn_code = DFA__ADVANCE_CYCLE;
8488 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8489 code denotes CODE. */
8490 static void
8491 output_internal_insn_code_evaluation (const char *insn_name,
8492 const char *insn_code_name,
8493 int code)
8495 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8496 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8497 DFA_INSN_CODE_FUNC_NAME, insn_name);
8498 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8499 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8500 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8501 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8505 /* This function outputs `dfa_insn_code' and its helper function
8506 `dfa_insn_code_enlarge'. */
8507 static void
8508 output_dfa_insn_code_func (void)
8510 /* Emacs c-mode gets really confused if there's a { or } in column 0
8511 inside a string, so don't do that. */
8512 fprintf (output_file, "\
8513 static void\n\
8514 dfa_insn_code_enlarge (int uid)\n\
8515 {\n\
8516 int i = %s;\n\
8517 %s = 2 * uid;\n\
8518 %s = xrealloc (%s,\n\
8519 %s * sizeof(int));\n\
8520 for (; i < %s; i++)\n\
8521 %s[i] = -1;\n}\n\n",
8522 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8523 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8524 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8525 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8526 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8527 DFA_INSN_CODES_VARIABLE_NAME);
8528 fprintf (output_file, "\
8529 static inline int\n%s (rtx %s)\n\
8530 {\n\
8531 int uid = INSN_UID (%s);\n\
8532 int %s;\n\n",
8533 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8534 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8536 fprintf (output_file,
8537 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8538 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8539 fprintf (output_file, " %s = %s[uid];\n",
8540 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8541 fprintf (output_file, "\
8542 if (%s < 0)\n\
8543 {\n\
8544 %s = %s (%s);\n\
8545 %s[uid] = %s;\n\
8546 }\n",
8547 INTERNAL_INSN_CODE_NAME,
8548 INTERNAL_INSN_CODE_NAME,
8549 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8550 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8551 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8554 /* The function outputs PHR interface function `state_transition'. */
8555 static void
8556 output_trans_func (void)
8558 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8559 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8560 INSN_PARAMETER_NAME);
8561 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8562 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8563 INTERNAL_INSN_CODE_NAME, -1);
8564 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8565 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8568 /* The function outputs a code for evaluation of alternative states
8569 number for insns which have reservations in given AUTOMATA_LIST. */
8570 static void
8571 output_automata_list_state_alts_code (automata_list_el_t automata_list)
8573 automata_list_el_t el;
8574 automaton_t automaton;
8576 fprintf (output_file, " {\n");
8577 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8578 if (comb_vect_p (el->automaton->state_alts_table))
8580 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8581 break;
8583 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8585 automaton = el->automaton;
8586 if (comb_vect_p (automaton->state_alts_table))
8588 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8589 output_state_alts_base_vect_name (output_file, automaton);
8590 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8591 output_chip_member_name (output_file, automaton);
8592 fprintf (output_file, "] + ");
8593 output_translate_vect_name (output_file, automaton);
8594 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8595 fprintf (output_file, " if (");
8596 output_state_alts_check_vect_name (output_file, automaton);
8597 fprintf (output_file, " [%s] != %s->",
8598 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8599 output_chip_member_name (output_file, automaton);
8600 fprintf (output_file, ")\n");
8601 fprintf (output_file, " return 0;\n");
8602 fprintf (output_file, " else\n");
8603 fprintf (output_file,
8604 (el == automata_list
8605 ? " %s = " : " %s += "),
8606 RESULT_VARIABLE_NAME);
8607 output_state_alts_comb_vect_name (output_file, automaton);
8608 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8610 else
8612 fprintf (output_file,
8613 (el == automata_list
8614 ? "\n %s = " : " %s += "),
8615 RESULT_VARIABLE_NAME);
8616 output_state_alts_full_vect_name (output_file, automaton);
8617 fprintf (output_file, " [");
8618 output_translate_vect_name (output_file, automaton);
8619 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8620 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8621 output_chip_member_name (output_file, automaton);
8622 fprintf (output_file, " * %d];\n",
8623 automaton->insn_equiv_classes_num);
8626 fprintf (output_file, " break;\n }\n\n");
8629 /* Output function `internal_state_alts'. */
8630 static void
8631 output_internal_state_alts_func (void)
8633 fprintf (output_file,
8634 "static int\n%s (int %s, struct %s *%s)\n",
8635 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8636 CHIP_NAME, CHIP_PARAMETER_NAME);
8637 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8638 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8639 output_insn_code_cases (output_automata_list_state_alts_code);
8640 fprintf (output_file,
8641 "\n default:\n %s = 0;\n break;\n }\n",
8642 RESULT_VARIABLE_NAME);
8643 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8644 fprintf (output_file, "}\n\n");
8647 /* The function outputs PHR interface function `state_alts'. */
8648 static void
8649 output_state_alts_func (void)
8651 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8652 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8653 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8654 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8655 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8656 INTERNAL_INSN_CODE_NAME, 0);
8657 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8658 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8661 /* Output function `min_issue_delay'. */
8662 static void
8663 output_min_issue_delay_func (void)
8665 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8666 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8667 INSN_PARAMETER_NAME);
8668 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8669 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8670 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8671 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8672 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8673 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8674 fprintf (output_file, " }\n else\n %s = %s;\n",
8675 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8676 fprintf (output_file, "\n return %s (%s, %s);\n",
8677 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8678 STATE_NAME);
8679 fprintf (output_file, "}\n\n");
8682 /* Output function `internal_dead_lock'. */
8683 static void
8684 output_internal_dead_lock_func (void)
8686 automaton_t automaton;
8688 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8689 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8690 fprintf (output_file, "{\n");
8691 for (automaton = description->first_automaton;
8692 automaton != NULL;
8693 automaton = automaton->next_automaton)
8695 fprintf (output_file, " if (");
8696 output_dead_lock_vect_name (output_file, automaton);
8697 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8698 output_chip_member_name (output_file, automaton);
8699 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8701 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8704 /* The function outputs PHR interface function `state_dead_lock_p'. */
8705 static void
8706 output_dead_lock_func (void)
8708 fprintf (output_file, "int\n%s (%s %s)\n",
8709 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8710 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8711 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8714 /* Output function `internal_reset'. */
8715 static void
8716 output_internal_reset_func (void)
8718 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8719 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8720 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8721 CHIP_PARAMETER_NAME, CHIP_NAME);
8724 /* The function outputs PHR interface function `state_size'. */
8725 static void
8726 output_size_func (void)
8728 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8729 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8732 /* The function outputs PHR interface function `state_reset'. */
8733 static void
8734 output_reset_func (void)
8736 fprintf (output_file, "void\n%s (%s %s)\n",
8737 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8738 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8739 STATE_NAME);
8742 /* Output function `min_insn_conflict_delay'. */
8743 static void
8744 output_min_insn_conflict_delay_func (void)
8746 fprintf (output_file,
8747 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8748 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8749 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8750 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
8751 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8752 INTERNAL_INSN2_CODE_NAME);
8753 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8754 INTERNAL_INSN_CODE_NAME, 0);
8755 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8756 INTERNAL_INSN2_CODE_NAME, 0);
8757 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8758 CHIP_NAME, STATE_NAME, CHIP_NAME);
8759 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8760 fprintf (output_file, " transition = %s (%s, &%s);\n",
8761 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8762 fprintf (output_file, " gcc_assert (transition <= 0);\n");
8763 fprintf (output_file, " return %s (%s, &%s);\n",
8764 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8765 CHIP_NAME);
8766 fprintf (output_file, "}\n\n");
8769 /* Output function `internal_insn_latency'. */
8770 static void
8771 output_internal_insn_latency_func (void)
8773 decl_t decl;
8774 struct bypass_decl *bypass;
8775 int i, j, col;
8776 const char *tabletype = "unsigned char";
8778 /* Find the smallest integer type that can hold all the default
8779 latency values. */
8780 for (i = 0; i < description->decls_num; i++)
8781 if (description->decls[i]->mode == dm_insn_reserv)
8783 decl = description->decls[i];
8784 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8785 && tabletype[0] != 'i') /* Don't shrink it. */
8786 tabletype = "unsigned short";
8787 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8788 tabletype = "int";
8791 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",
8792 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8793 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8794 INSN2_PARAMETER_NAME);
8795 fprintf (output_file, "{\n");
8797 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8799 fputs (" return 0;\n}\n\n", output_file);
8800 return;
8803 fprintf (output_file, " static const %s default_latencies[] =\n {",
8804 tabletype);
8806 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8807 if (description->decls[i]->mode == dm_insn_reserv
8808 && description->decls[i] != advance_cycle_insn_decl)
8810 if ((col = (col+1) % 8) == 0)
8811 fputs ("\n ", output_file);
8812 decl = description->decls[i];
8813 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8814 fprintf (output_file, "% 4d,",
8815 DECL_INSN_RESERV (decl)->default_latency);
8817 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8818 fputs ("\n };\n", output_file);
8820 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8821 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8822 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8824 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8825 for (i = 0; i < description->decls_num; i++)
8826 if (description->decls[i]->mode == dm_insn_reserv
8827 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8829 decl = description->decls [i];
8830 fprintf (output_file,
8831 " case %d:\n switch (%s)\n {\n",
8832 DECL_INSN_RESERV (decl)->insn_num,
8833 INTERNAL_INSN2_CODE_NAME);
8834 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8835 bypass != NULL;
8836 bypass = bypass->next)
8838 gcc_assert (bypass->in_insn_reserv->insn_num
8839 != (DECL_INSN_RESERV
8840 (advance_cycle_insn_decl)->insn_num));
8841 fprintf (output_file, " case %d:\n",
8842 bypass->in_insn_reserv->insn_num);
8843 if (bypass->bypass_guard_name == NULL)
8844 fprintf (output_file, " return %d;\n",
8845 bypass->latency);
8846 else
8848 fprintf (output_file,
8849 " if (%s (%s, %s))\n",
8850 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8851 INSN2_PARAMETER_NAME);
8852 fprintf (output_file,
8853 " return %d;\n break;\n",
8854 bypass->latency);
8857 fputs (" }\n break;\n", output_file);
8860 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8861 INTERNAL_INSN_CODE_NAME);
8864 /* The function outputs PHR interface function `insn_latency'. */
8865 static void
8866 output_insn_latency_func (void)
8868 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8869 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8870 fprintf (output_file, "{\n int %s, %s;\n",
8871 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8872 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8873 INTERNAL_INSN_CODE_NAME, 0);
8874 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8875 INTERNAL_INSN2_CODE_NAME, 0);
8876 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8877 INTERNAL_INSN_LATENCY_FUNC_NAME,
8878 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8879 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8882 /* The function outputs PHR interface function `print_reservation'. */
8883 static void
8884 output_print_reservation_func (void)
8886 decl_t decl;
8887 int i, j;
8889 fprintf (output_file,
8890 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8891 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8892 INSN_PARAMETER_NAME);
8894 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8896 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8897 NOTHING_NAME, FILE_PARAMETER_NAME);
8898 return;
8902 fputs (" static const char *const reservation_names[] =\n {",
8903 output_file);
8905 for (i = 0, j = 0; i < description->decls_num; i++)
8907 decl = description->decls [i];
8908 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8910 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8911 j++;
8913 fprintf (output_file, "\n \"%s\",",
8914 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8915 finish_regexp_representation ();
8918 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8920 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8921 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8923 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8924 INSN_PARAMETER_NAME,
8925 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8926 fprintf (output_file, " else\n\
8927 {\n\
8928 %s = %s (%s);\n\
8929 if (%s > %s)\n\
8930 %s = %s;\n\
8931 }\n",
8932 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8933 INSN_PARAMETER_NAME,
8934 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8935 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8937 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8938 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8941 /* The following function is used to sort unit declaration by their
8942 names. */
8943 static int
8944 units_cmp (const void *unit1, const void *unit2)
8946 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8947 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8949 return strcmp (u1->name, u2->name);
8952 /* The following macro value is name of struct containing unit name
8953 and unit code. */
8954 #define NAME_CODE_STRUCT_NAME "name_code"
8956 /* The following macro value is name of table of struct name_code. */
8957 #define NAME_CODE_TABLE_NAME "name_code_table"
8959 /* The following macro values are member names for struct name_code. */
8960 #define NAME_MEMBER_NAME "name"
8961 #define CODE_MEMBER_NAME "code"
8963 /* The following macro values are local variable names for function
8964 `get_cpu_unit_code'. */
8965 #define CMP_VARIABLE_NAME "cmp"
8966 #define LOW_VARIABLE_NAME "l"
8967 #define MIDDLE_VARIABLE_NAME "m"
8968 #define HIGH_VARIABLE_NAME "h"
8970 /* The following function outputs function to obtain internal cpu unit
8971 code by the cpu unit name. */
8972 static void
8973 output_get_cpu_unit_code_func (void)
8975 int i;
8976 unit_decl_t *units;
8978 fprintf (output_file, "int\n%s (const char *%s)\n",
8979 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
8980 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8981 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8982 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8983 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8984 fprintf (output_file, " static struct %s %s [] =\n {\n",
8985 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8986 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8987 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8988 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8989 for (i = 0; i < description->units_num; i++)
8990 if (units [i]->query_p)
8991 fprintf (output_file, " {\"%s\", %d},\n",
8992 units[i]->name, units[i]->query_num);
8993 fprintf (output_file, " };\n\n");
8994 fprintf (output_file, " /* The following is binary search: */\n");
8995 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8996 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8997 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8998 fprintf (output_file, " while (%s <= %s)\n {\n",
8999 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9000 fprintf (output_file, " %s = (%s + %s) / 2;\n",
9001 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9002 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
9003 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
9004 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
9005 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
9006 fprintf (output_file, " %s = %s - 1;\n",
9007 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9008 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
9009 fprintf (output_file, " %s = %s + 1;\n",
9010 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9011 fprintf (output_file, " else\n");
9012 fprintf (output_file, " return %s [%s].%s;\n }\n",
9013 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
9014 fprintf (output_file, " return -1;\n}\n\n");
9015 free (units);
9018 /* The following function outputs function to check reservation of cpu
9019 unit (its internal code will be passed as the function argument) in
9020 given cpu state. */
9021 static void
9022 output_cpu_unit_reservation_p (void)
9024 automaton_t automaton;
9026 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
9027 CPU_UNIT_RESERVATION_P_FUNC_NAME,
9028 STATE_TYPE_NAME, STATE_NAME,
9029 CPU_CODE_PARAMETER_NAME);
9030 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
9031 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
9032 description->query_units_num);
9033 for (automaton = description->first_automaton;
9034 automaton != NULL;
9035 automaton = automaton->next_automaton)
9037 fprintf (output_file, " if ((");
9038 output_reserved_units_table_name (output_file, automaton);
9039 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
9040 output_chip_member_name (output_file, automaton);
9041 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9042 (description->query_units_num + 7) / 8,
9043 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
9044 fprintf (output_file, " return 1;\n");
9046 fprintf (output_file, " return 0;\n}\n\n");
9049 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9050 static void
9051 output_dfa_clean_insn_cache_func (void)
9053 fprintf (output_file,
9054 "void\n%s (void)\n{\n int %s;\n\n",
9055 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
9056 fprintf (output_file,
9057 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9058 I_VARIABLE_NAME, I_VARIABLE_NAME,
9059 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
9060 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
9063 /* The function outputs PHR interface function `dfa_start'. */
9064 static void
9065 output_dfa_start_func (void)
9067 fprintf (output_file,
9068 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
9069 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9070 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
9071 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9072 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
9075 /* The function outputs PHR interface function `dfa_finish'. */
9076 static void
9077 output_dfa_finish_func (void)
9079 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
9080 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
9085 /* The page contains code for output description file (readable
9086 representation of original description and generated DFA(s). */
9088 /* The function outputs string representation of IR reservation. */
9089 static void
9090 output_regexp (regexp_t regexp)
9092 fprintf (output_description_file, "%s", regexp_representation (regexp));
9093 finish_regexp_representation ();
9096 /* Output names of units in LIST separated by comma. */
9097 static void
9098 output_unit_set_el_list (unit_set_el_t list)
9100 unit_set_el_t el;
9102 for (el = list; el != NULL; el = el->next_unit_set_el)
9104 if (el != list)
9105 fprintf (output_description_file, ", ");
9106 fprintf (output_description_file, "%s", el->unit_decl->name);
9110 /* Output patterns in LIST separated by comma. */
9111 static void
9112 output_pattern_set_el_list (pattern_set_el_t list)
9114 pattern_set_el_t el;
9115 int i;
9117 for (el = list; el != NULL; el = el->next_pattern_set_el)
9119 if (el != list)
9120 fprintf (output_description_file, ", ");
9121 for (i = 0; i < el->units_num; i++)
9122 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9123 el->unit_decls [i]->name);
9127 /* The function outputs string representation of IR define_reservation
9128 and define_insn_reservation. */
9129 static void
9130 output_description (void)
9132 decl_t decl;
9133 int i;
9135 for (i = 0; i < description->decls_num; i++)
9137 decl = description->decls [i];
9138 if (decl->mode == dm_unit)
9140 if (DECL_UNIT (decl)->excl_list != NULL)
9142 fprintf (output_description_file, "unit %s exlusion_set: ",
9143 DECL_UNIT (decl)->name);
9144 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9145 fprintf (output_description_file, "\n");
9147 if (DECL_UNIT (decl)->presence_list != NULL)
9149 fprintf (output_description_file, "unit %s presence_set: ",
9150 DECL_UNIT (decl)->name);
9151 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9152 fprintf (output_description_file, "\n");
9154 if (DECL_UNIT (decl)->final_presence_list != NULL)
9156 fprintf (output_description_file, "unit %s final_presence_set: ",
9157 DECL_UNIT (decl)->name);
9158 output_pattern_set_el_list
9159 (DECL_UNIT (decl)->final_presence_list);
9160 fprintf (output_description_file, "\n");
9162 if (DECL_UNIT (decl)->absence_list != NULL)
9164 fprintf (output_description_file, "unit %s absence_set: ",
9165 DECL_UNIT (decl)->name);
9166 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9167 fprintf (output_description_file, "\n");
9169 if (DECL_UNIT (decl)->final_absence_list != NULL)
9171 fprintf (output_description_file, "unit %s final_absence_set: ",
9172 DECL_UNIT (decl)->name);
9173 output_pattern_set_el_list
9174 (DECL_UNIT (decl)->final_absence_list);
9175 fprintf (output_description_file, "\n");
9179 fprintf (output_description_file, "\n");
9180 for (i = 0; i < description->decls_num; i++)
9182 decl = description->decls [i];
9183 if (decl->mode == dm_reserv)
9185 fprintf (output_description_file, "reservation %s: ",
9186 DECL_RESERV (decl)->name);
9187 output_regexp (DECL_RESERV (decl)->regexp);
9188 fprintf (output_description_file, "\n");
9190 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9192 fprintf (output_description_file, "insn reservation %s ",
9193 DECL_INSN_RESERV (decl)->name);
9194 print_rtl (output_description_file,
9195 DECL_INSN_RESERV (decl)->condexp);
9196 fprintf (output_description_file, ": ");
9197 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9198 fprintf (output_description_file, "\n");
9200 else if (decl->mode == dm_bypass)
9201 fprintf (output_description_file, "bypass %d %s %s\n",
9202 DECL_BYPASS (decl)->latency,
9203 DECL_BYPASS (decl)->out_insn_name,
9204 DECL_BYPASS (decl)->in_insn_name);
9206 fprintf (output_description_file, "\n\f\n");
9209 /* The function outputs name of AUTOMATON. */
9210 static void
9211 output_automaton_name (FILE *f, automaton_t automaton)
9213 if (automaton->corresponding_automaton_decl == NULL)
9214 fprintf (f, "#%d", automaton->automaton_order_num);
9215 else
9216 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9219 /* Maximal length of line for pretty printing into description
9220 file. */
9221 #define MAX_LINE_LENGTH 70
9223 /* The function outputs units name belonging to AUTOMATON. */
9224 static void
9225 output_automaton_units (automaton_t automaton)
9227 decl_t decl;
9228 char *name;
9229 int curr_line_length;
9230 int there_is_an_automaton_unit;
9231 int i;
9233 fprintf (output_description_file, "\n Corresponding units:\n");
9234 fprintf (output_description_file, " ");
9235 curr_line_length = 4;
9236 there_is_an_automaton_unit = 0;
9237 for (i = 0; i < description->decls_num; i++)
9239 decl = description->decls [i];
9240 if (decl->mode == dm_unit
9241 && (DECL_UNIT (decl)->corresponding_automaton_num
9242 == automaton->automaton_order_num))
9244 there_is_an_automaton_unit = 1;
9245 name = DECL_UNIT (decl)->name;
9246 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9248 curr_line_length = strlen (name) + 4;
9249 fprintf (output_description_file, "\n ");
9251 else
9253 curr_line_length += strlen (name) + 1;
9254 fprintf (output_description_file, " ");
9256 fprintf (output_description_file, "%s", name);
9259 if (!there_is_an_automaton_unit)
9260 fprintf (output_description_file, "<None>");
9261 fprintf (output_description_file, "\n\n");
9264 /* The following variable is used for forming array of all possible cpu unit
9265 reservations described by the current DFA state. */
9266 static vla_ptr_t state_reservs;
9268 /* The function forms `state_reservs' for STATE. */
9269 static void
9270 add_state_reservs (state_t state)
9272 alt_state_t curr_alt_state;
9273 reserv_sets_t reservs;
9275 if (state->component_states != NULL)
9276 for (curr_alt_state = state->component_states;
9277 curr_alt_state != NULL;
9278 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9279 add_state_reservs (curr_alt_state->state);
9280 else
9282 reservs = state->reservs;
9283 VLA_PTR_ADD (state_reservs, reservs);
9287 /* The function outputs readable representation of all out arcs of
9288 STATE. */
9289 static void
9290 output_state_arcs (state_t state)
9292 arc_t arc;
9293 ainsn_t ainsn;
9294 char *insn_name;
9295 int curr_line_length;
9297 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9299 ainsn = arc->insn;
9300 gcc_assert (ainsn->first_insn_with_same_reservs);
9301 fprintf (output_description_file, " ");
9302 curr_line_length = 7;
9303 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9306 insn_name = ainsn->insn_reserv_decl->name;
9307 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9309 if (ainsn != arc->insn)
9311 fprintf (output_description_file, ",\n ");
9312 curr_line_length = strlen (insn_name) + 6;
9314 else
9315 curr_line_length += strlen (insn_name);
9317 else
9319 curr_line_length += strlen (insn_name);
9320 if (ainsn != arc->insn)
9322 curr_line_length += 2;
9323 fprintf (output_description_file, ", ");
9326 fprintf (output_description_file, "%s", insn_name);
9327 ainsn = ainsn->next_same_reservs_insn;
9329 while (ainsn != NULL);
9330 fprintf (output_description_file, " %d (%d)\n",
9331 arc->to_state->order_state_num, arc->state_alts);
9333 fprintf (output_description_file, "\n");
9336 /* The following function is used for sorting possible cpu unit
9337 reservation of a DFA state. */
9338 static int
9339 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9341 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9342 *(reserv_sets_t *) reservs_ptr_2);
9345 /* The following function is used for sorting possible cpu unit
9346 reservation of a DFA state. */
9347 static void
9348 remove_state_duplicate_reservs (void)
9350 reserv_sets_t *reservs_ptr;
9351 reserv_sets_t *last_formed_reservs_ptr;
9353 last_formed_reservs_ptr = NULL;
9354 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9355 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9356 reservs_ptr++)
9357 if (last_formed_reservs_ptr == NULL)
9358 last_formed_reservs_ptr = reservs_ptr;
9359 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9361 ++last_formed_reservs_ptr;
9362 *last_formed_reservs_ptr = *reservs_ptr;
9364 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9367 /* The following function output readable representation of DFA(s)
9368 state used for fast recognition of pipeline hazards. State is
9369 described by possible (current and scheduled) cpu unit
9370 reservations. */
9371 static void
9372 output_state (state_t state)
9374 reserv_sets_t *reservs_ptr;
9376 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9377 fprintf (output_description_file, " State #%d", state->order_state_num);
9378 fprintf (output_description_file,
9379 state->new_cycle_p ? " (new cycle)\n" : "\n");
9380 add_state_reservs (state);
9381 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9382 sizeof (reserv_sets_t), state_reservs_cmp);
9383 remove_state_duplicate_reservs ();
9384 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9385 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9386 reservs_ptr++)
9388 fprintf (output_description_file, " ");
9389 output_reserv_sets (output_description_file, *reservs_ptr);
9390 fprintf (output_description_file, "\n");
9392 fprintf (output_description_file, "\n");
9393 output_state_arcs (state);
9394 VLA_PTR_DELETE (state_reservs);
9397 /* The following function output readable representation of
9398 DFAs used for fast recognition of pipeline hazards. */
9399 static void
9400 output_automaton_descriptions (void)
9402 automaton_t automaton;
9404 for (automaton = description->first_automaton;
9405 automaton != NULL;
9406 automaton = automaton->next_automaton)
9408 fprintf (output_description_file, "\nAutomaton ");
9409 output_automaton_name (output_description_file, automaton);
9410 fprintf (output_description_file, "\n");
9411 output_automaton_units (automaton);
9412 pass_states (automaton, output_state);
9418 /* The page contains top level function for generation DFA(s) used for
9419 PHR. */
9421 /* The function outputs statistics about work of different phases of
9422 DFA generator. */
9423 static void
9424 output_statistics (FILE *f)
9426 automaton_t automaton;
9427 int states_num;
9428 #ifndef NDEBUG
9429 int transition_comb_vect_els = 0;
9430 int transition_full_vect_els = 0;
9431 int state_alts_comb_vect_els = 0;
9432 int state_alts_full_vect_els = 0;
9433 int min_issue_delay_vect_els = 0;
9434 #endif
9436 for (automaton = description->first_automaton;
9437 automaton != NULL;
9438 automaton = automaton->next_automaton)
9440 fprintf (f, "\nAutomaton ");
9441 output_automaton_name (f, automaton);
9442 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9443 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9444 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9445 automaton->DFA_states_num, automaton->DFA_arcs_num);
9446 states_num = automaton->DFA_states_num;
9447 if (!no_minimization_flag)
9449 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9450 automaton->minimal_DFA_states_num,
9451 automaton->minimal_DFA_arcs_num);
9452 states_num = automaton->minimal_DFA_states_num;
9454 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9455 description->insns_num, automaton->insn_equiv_classes_num);
9456 #ifndef NDEBUG
9457 fprintf
9458 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9459 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9460 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9461 (comb_vect_p (automaton->trans_table)
9462 ? "use comb vect" : "use simple vect"));
9463 fprintf
9464 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9465 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9466 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9467 (comb_vect_p (automaton->state_alts_table)
9468 ? "use comb vect" : "use simple vect"));
9469 fprintf
9470 (f, "%5ld min delay table els, compression factor %d\n",
9471 (long) states_num * automaton->insn_equiv_classes_num,
9472 automaton->min_issue_delay_table_compression_factor);
9473 transition_comb_vect_els
9474 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9475 transition_full_vect_els
9476 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9477 state_alts_comb_vect_els
9478 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9479 state_alts_full_vect_els
9480 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9481 min_issue_delay_vect_els
9482 += states_num * automaton->insn_equiv_classes_num;
9483 #endif
9485 #ifndef NDEBUG
9486 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9487 allocated_states_num, allocated_arcs_num);
9488 fprintf (f, "%5d all allocated alternative states\n",
9489 allocated_alt_states_num);
9490 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9491 transition_comb_vect_els, transition_full_vect_els);
9492 fprintf
9493 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9494 state_alts_comb_vect_els, state_alts_full_vect_els);
9495 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9496 fprintf (f, "%5d locked states num\n", locked_states_num);
9497 #endif
9500 /* The function output times of work of different phases of DFA
9501 generator. */
9502 static void
9503 output_time_statistics (FILE *f)
9505 fprintf (f, "\n transformation: ");
9506 print_active_time (f, transform_time);
9507 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9508 print_active_time (f, NDFA_time);
9509 if (ndfa_flag)
9511 fprintf (f, ", NDFA -> DFA: ");
9512 print_active_time (f, NDFA_to_DFA_time);
9514 fprintf (f, "\n DFA minimization: ");
9515 print_active_time (f, minimize_time);
9516 fprintf (f, ", making insn equivalence: ");
9517 print_active_time (f, equiv_time);
9518 fprintf (f, "\n all automaton generation: ");
9519 print_active_time (f, automaton_generation_time);
9520 fprintf (f, ", output: ");
9521 print_active_time (f, output_time);
9522 fprintf (f, "\n");
9525 /* The function generates DFA (deterministic finite state automaton)
9526 for fast recognition of pipeline hazards. No errors during
9527 checking must be fixed before this function call. */
9528 static void
9529 generate (void)
9531 automata_num = split_argument;
9532 if (description->units_num < automata_num)
9533 automata_num = description->units_num;
9534 initiate_states ();
9535 initiate_arcs ();
9536 initiate_automata_lists ();
9537 initiate_pass_states ();
9538 initiate_excl_sets ();
9539 initiate_presence_absence_pattern_sets ();
9540 automaton_generation_time = create_ticker ();
9541 create_automata ();
9542 ticker_off (&automaton_generation_time);
9547 /* The following function creates insn attribute whose values are
9548 number alternatives in insn reservations. */
9549 static void
9550 make_insn_alts_attr (void)
9552 int i, insn_num;
9553 decl_t decl;
9554 rtx condexp;
9556 condexp = rtx_alloc (COND);
9557 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9558 XEXP (condexp, 1) = make_numeric_value (0);
9559 for (i = insn_num = 0; i < description->decls_num; i++)
9561 decl = description->decls [i];
9562 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9564 XVECEXP (condexp, 0, 2 * insn_num)
9565 = DECL_INSN_RESERV (decl)->condexp;
9566 XVECEXP (condexp, 0, 2 * insn_num + 1)
9567 = make_numeric_value
9568 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9569 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9570 ->transformed_regexp)->regexps_num);
9571 insn_num++;
9574 gcc_assert (description->insns_num == insn_num + 1);
9575 make_internal_attr (attr_printf (sizeof ("*")
9576 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9577 "*%s", INSN_ALTS_FUNC_NAME),
9578 condexp, ATTR_NONE);
9583 /* The following function creates attribute which is order number of
9584 insn in pipeline hazard description translator. */
9585 static void
9586 make_internal_dfa_insn_code_attr (void)
9588 int i, insn_num;
9589 decl_t decl;
9590 rtx condexp;
9592 condexp = rtx_alloc (COND);
9593 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9594 XEXP (condexp, 1)
9595 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9596 ->insn_num + 1);
9597 for (i = insn_num = 0; i < description->decls_num; i++)
9599 decl = description->decls [i];
9600 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9602 XVECEXP (condexp, 0, 2 * insn_num)
9603 = DECL_INSN_RESERV (decl)->condexp;
9604 XVECEXP (condexp, 0, 2 * insn_num + 1)
9605 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9606 insn_num++;
9609 gcc_assert (description->insns_num == insn_num + 1);
9610 make_internal_attr
9611 (attr_printf (sizeof ("*")
9612 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9613 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9614 condexp, ATTR_STATIC);
9619 /* The following function creates attribute which order number of insn
9620 in pipeline hazard description translator. */
9621 static void
9622 make_default_insn_latency_attr (void)
9624 int i, insn_num;
9625 decl_t decl;
9626 rtx condexp;
9628 condexp = rtx_alloc (COND);
9629 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9630 XEXP (condexp, 1) = make_numeric_value (0);
9631 for (i = insn_num = 0; i < description->decls_num; i++)
9633 decl = description->decls [i];
9634 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9636 XVECEXP (condexp, 0, 2 * insn_num)
9637 = DECL_INSN_RESERV (decl)->condexp;
9638 XVECEXP (condexp, 0, 2 * insn_num + 1)
9639 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9640 insn_num++;
9643 gcc_assert (description->insns_num == insn_num + 1);
9644 make_internal_attr (attr_printf (sizeof ("*")
9645 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9646 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9647 condexp, ATTR_NONE);
9652 /* The following function creates attribute which returns 1 if given
9653 output insn has bypassing and 0 otherwise. */
9654 static void
9655 make_bypass_attr (void)
9657 int i, bypass_insn;
9658 int bypass_insns_num = 0;
9659 decl_t decl;
9660 rtx result_rtx;
9662 for (i = 0; i < description->decls_num; i++)
9664 decl = description->decls [i];
9665 if (decl->mode == dm_insn_reserv
9666 && DECL_INSN_RESERV (decl)->condexp != NULL
9667 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9668 bypass_insns_num++;
9670 if (bypass_insns_num == 0)
9671 result_rtx = make_numeric_value (0);
9672 else
9674 result_rtx = rtx_alloc (COND);
9675 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9676 XEXP (result_rtx, 1) = make_numeric_value (0);
9678 for (i = bypass_insn = 0; i < description->decls_num; i++)
9680 decl = description->decls [i];
9681 if (decl->mode == dm_insn_reserv
9682 && DECL_INSN_RESERV (decl)->condexp != NULL
9683 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9685 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9686 = DECL_INSN_RESERV (decl)->condexp;
9687 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9688 = make_numeric_value (1);
9689 bypass_insn++;
9693 make_internal_attr (attr_printf (sizeof ("*")
9694 + strlen (BYPASS_P_FUNC_NAME) + 1,
9695 "*%s", BYPASS_P_FUNC_NAME),
9696 result_rtx, ATTR_NONE);
9701 /* This page mainly contains top level functions of pipeline hazards
9702 description translator. */
9704 /* The following macro value is suffix of name of description file of
9705 pipeline hazards description translator. */
9706 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9708 /* The function returns suffix of given file name. The returned
9709 string can not be changed. */
9710 static const char *
9711 file_name_suffix (const char *file_name)
9713 const char *last_period;
9715 for (last_period = NULL; *file_name != '\0'; file_name++)
9716 if (*file_name == '.')
9717 last_period = file_name;
9718 return (last_period == NULL ? file_name : last_period);
9721 /* The function returns base name of given file name, i.e. pointer to
9722 first char after last `/' (or `\' for WIN32) in given file name,
9723 given file name itself if the directory name is absent. The
9724 returned string can not be changed. */
9725 static const char *
9726 base_file_name (const char *file_name)
9728 int directory_name_length;
9730 directory_name_length = strlen (file_name);
9731 #ifdef WIN32
9732 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9733 && file_name[directory_name_length] != '\\')
9734 #else
9735 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9736 #endif
9737 directory_name_length--;
9738 return file_name + directory_name_length + 1;
9741 /* The following is top level function to initialize the work of
9742 pipeline hazards description translator. */
9743 void
9744 initiate_automaton_gen (int argc, char **argv)
9746 const char *base_name;
9747 int i;
9749 ndfa_flag = 0;
9750 split_argument = 0; /* default value */
9751 no_minimization_flag = 0;
9752 time_flag = 0;
9753 v_flag = 0;
9754 w_flag = 0;
9755 progress_flag = 0;
9756 for (i = 2; i < argc; i++)
9757 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9758 no_minimization_flag = 1;
9759 else if (strcmp (argv [i], TIME_OPTION) == 0)
9760 time_flag = 1;
9761 else if (strcmp (argv [i], V_OPTION) == 0)
9762 v_flag = 1;
9763 else if (strcmp (argv [i], W_OPTION) == 0)
9764 w_flag = 1;
9765 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9766 ndfa_flag = 1;
9767 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9768 progress_flag = 1;
9769 else if (strcmp (argv [i], "-split") == 0)
9771 if (i + 1 >= argc)
9772 fatal ("-split has no argument.");
9773 fatal ("option `-split' has not been implemented yet\n");
9774 /* split_argument = atoi (argument_vect [i + 1]); */
9776 VLA_PTR_CREATE (decls, 150, "decls");
9777 /* Initialize IR storage. */
9778 obstack_init (&irp);
9779 initiate_automaton_decl_table ();
9780 initiate_insn_decl_table ();
9781 initiate_decl_table ();
9782 output_file = stdout;
9783 output_description_file = NULL;
9784 base_name = base_file_name (argv[1]);
9785 obstack_grow (&irp, base_name,
9786 strlen (base_name) - strlen (file_name_suffix (base_name)));
9787 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9788 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9789 obstack_1grow (&irp, '\0');
9790 output_description_file_name = obstack_base (&irp);
9791 obstack_finish (&irp);
9794 /* The following function checks existence at least one arc marked by
9795 each insn. */
9796 static void
9797 check_automata_insn_issues (void)
9799 automaton_t automaton;
9800 ainsn_t ainsn, reserv_ainsn;
9802 for (automaton = description->first_automaton;
9803 automaton != NULL;
9804 automaton = automaton->next_automaton)
9806 for (ainsn = automaton->ainsn_list;
9807 ainsn != NULL;
9808 ainsn = ainsn->next_ainsn)
9809 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9811 for (reserv_ainsn = ainsn;
9812 reserv_ainsn != NULL;
9813 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9814 if (automaton->corresponding_automaton_decl != NULL)
9816 if (!w_flag)
9817 error ("Automaton `%s': Insn `%s' will never be issued",
9818 automaton->corresponding_automaton_decl->name,
9819 reserv_ainsn->insn_reserv_decl->name);
9820 else
9821 warning
9822 (0, "Automaton `%s': Insn `%s' will never be issued",
9823 automaton->corresponding_automaton_decl->name,
9824 reserv_ainsn->insn_reserv_decl->name);
9826 else
9828 if (!w_flag)
9829 error ("Insn `%s' will never be issued",
9830 reserv_ainsn->insn_reserv_decl->name);
9831 else
9832 warning (0, "Insn `%s' will never be issued",
9833 reserv_ainsn->insn_reserv_decl->name);
9839 /* The following vla is used for storing pointers to all achieved
9840 states. */
9841 static vla_ptr_t automaton_states;
9843 /* This function is called by function pass_states to add an achieved
9844 STATE. */
9845 static void
9846 add_automaton_state (state_t state)
9848 VLA_PTR_ADD (automaton_states, state);
9851 /* The following function forms list of important automata (whose
9852 states may be changed after the insn issue) for each insn. */
9853 static void
9854 form_important_insn_automata_lists (void)
9856 automaton_t automaton;
9857 state_t *state_ptr;
9858 decl_t decl;
9859 ainsn_t ainsn;
9860 arc_t arc;
9861 int i;
9863 VLA_PTR_CREATE (automaton_states, 1500,
9864 "automaton states for forming important insn automata sets");
9865 /* Mark important ainsns. */
9866 for (automaton = description->first_automaton;
9867 automaton != NULL;
9868 automaton = automaton->next_automaton)
9870 VLA_PTR_NULLIFY (automaton_states);
9871 pass_states (automaton, add_automaton_state);
9872 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9873 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9874 state_ptr++)
9876 for (arc = first_out_arc (*state_ptr);
9877 arc != NULL;
9878 arc = next_out_arc (arc))
9879 if (arc->to_state != *state_ptr)
9881 gcc_assert (arc->insn->first_insn_with_same_reservs);
9882 for (ainsn = arc->insn;
9883 ainsn != NULL;
9884 ainsn = ainsn->next_same_reservs_insn)
9885 ainsn->important_p = TRUE;
9889 VLA_PTR_DELETE (automaton_states);
9890 /* Create automata sets for the insns. */
9891 for (i = 0; i < description->decls_num; i++)
9893 decl = description->decls [i];
9894 if (decl->mode == dm_insn_reserv)
9896 automata_list_start ();
9897 for (automaton = description->first_automaton;
9898 automaton != NULL;
9899 automaton = automaton->next_automaton)
9900 for (ainsn = automaton->ainsn_list;
9901 ainsn != NULL;
9902 ainsn = ainsn->next_ainsn)
9903 if (ainsn->important_p
9904 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9906 automata_list_add (automaton);
9907 break;
9909 DECL_INSN_RESERV (decl)->important_automata_list
9910 = automata_list_finish ();
9916 /* The following is top level function to generate automat(a,on) for
9917 fast recognition of pipeline hazards. */
9918 void
9919 expand_automata (void)
9921 int i;
9923 description = create_node (sizeof (struct description)
9924 /* One entry for cycle advancing insn. */
9925 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9926 description->decls_num = VLA_PTR_LENGTH (decls);
9927 description->query_units_num = 0;
9928 for (i = 0; i < description->decls_num; i++)
9930 description->decls [i] = VLA_PTR (decls, i);
9931 if (description->decls [i]->mode == dm_unit
9932 && DECL_UNIT (description->decls [i])->query_p)
9933 DECL_UNIT (description->decls [i])->query_num
9934 = description->query_units_num++;
9936 all_time = create_ticker ();
9937 check_time = create_ticker ();
9938 if (progress_flag)
9939 fprintf (stderr, "Check description...");
9940 check_all_description ();
9941 if (progress_flag)
9942 fprintf (stderr, "done\n");
9943 ticker_off (&check_time);
9944 generation_time = create_ticker ();
9945 if (!have_error)
9947 transform_insn_regexps ();
9948 check_unit_distributions_to_automata ();
9950 if (!have_error)
9952 generate ();
9953 check_automata_insn_issues ();
9955 if (!have_error)
9957 form_important_insn_automata_lists ();
9958 if (progress_flag)
9959 fprintf (stderr, "Generation of attributes...");
9960 make_internal_dfa_insn_code_attr ();
9961 make_insn_alts_attr ();
9962 make_default_insn_latency_attr ();
9963 make_bypass_attr ();
9964 if (progress_flag)
9965 fprintf (stderr, "done\n");
9967 ticker_off (&generation_time);
9968 ticker_off (&all_time);
9969 if (progress_flag)
9970 fprintf (stderr, "All other genattrtab stuff...");
9973 /* The following is top level function to output PHR and to finish
9974 work with pipeline description translator. */
9975 void
9976 write_automata (void)
9978 if (progress_flag)
9979 fprintf (stderr, "done\n");
9980 if (have_error)
9981 fatal ("Errors in DFA description");
9982 ticker_on (&all_time);
9983 output_time = create_ticker ();
9984 if (progress_flag)
9985 fprintf (stderr, "Forming and outputting automata tables...");
9986 output_dfa_max_issue_rate ();
9987 output_tables ();
9988 if (progress_flag)
9990 fprintf (stderr, "done\n");
9991 fprintf (stderr, "Output functions to work with automata...");
9993 output_chip_definitions ();
9994 output_max_insn_queue_index_def ();
9995 output_internal_min_issue_delay_func ();
9996 output_internal_trans_func ();
9997 /* Cache of insn dfa codes: */
9998 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9999 fprintf (output_file, "\nstatic int %s;\n\n",
10000 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
10001 output_dfa_insn_code_func ();
10002 output_trans_func ();
10003 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
10004 output_internal_state_alts_func ();
10005 output_state_alts_func ();
10006 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10007 AUTOMATON_STATE_ALTS_MACRO_NAME);
10008 output_min_issue_delay_func ();
10009 output_internal_dead_lock_func ();
10010 output_dead_lock_func ();
10011 output_size_func ();
10012 output_internal_reset_func ();
10013 output_reset_func ();
10014 output_min_insn_conflict_delay_func ();
10015 output_internal_insn_latency_func ();
10016 output_insn_latency_func ();
10017 output_print_reservation_func ();
10018 /* Output function get_cpu_unit_code. */
10019 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10020 output_get_cpu_unit_code_func ();
10021 output_cpu_unit_reservation_p ();
10022 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10023 CPU_UNITS_QUERY_MACRO_NAME);
10024 output_dfa_clean_insn_cache_func ();
10025 output_dfa_start_func ();
10026 output_dfa_finish_func ();
10027 if (progress_flag)
10028 fprintf (stderr, "done\n");
10029 if (v_flag)
10031 output_description_file = fopen (output_description_file_name, "w");
10032 if (output_description_file == NULL)
10034 perror (output_description_file_name);
10035 exit (FATAL_EXIT_CODE);
10037 if (progress_flag)
10038 fprintf (stderr, "Output automata description...");
10039 output_description ();
10040 output_automaton_descriptions ();
10041 if (progress_flag)
10042 fprintf (stderr, "done\n");
10043 output_statistics (output_description_file);
10045 output_statistics (stderr);
10046 ticker_off (&output_time);
10047 output_time_statistics (stderr);
10048 finish_states ();
10049 finish_arcs ();
10050 finish_automata_lists ();
10051 if (time_flag)
10053 fprintf (stderr, "Summary:\n");
10054 fprintf (stderr, " check time ");
10055 print_active_time (stderr, check_time);
10056 fprintf (stderr, ", generation time ");
10057 print_active_time (stderr, generation_time);
10058 fprintf (stderr, ", all time ");
10059 print_active_time (stderr, all_time);
10060 fprintf (stderr, "\n");
10062 /* Finish all work. */
10063 if (output_description_file != NULL)
10065 fflush (output_description_file);
10066 if (ferror (stdout) != 0)
10067 fatal ("Error in writing DFA description file %s",
10068 output_description_file_name);
10069 fclose (output_description_file);
10071 finish_automaton_decl_table ();
10072 finish_insn_decl_table ();
10073 finish_decl_table ();
10074 obstack_free (&irp, NULL);
10075 if (have_error && output_description_file != NULL)
10076 remove (output_description_file_name);