2004-10-25 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / gcc / genautomata.c
blob64dde93ed8e9f3464fb50417f12f9e960dd1233f
1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Written by Vladimir Makarov <vmakarov@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 /* References:
25 1. Detecting pipeline structural hazards quickly. T. Proebsting,
26 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
27 Principles of Programming Languages, pages 280--286, 1994.
29 This article is a good start point to understand usage of finite
30 state automata for pipeline hazard recognizers. But I'd
31 recommend the 2nd article for more deep understanding.
33 2. Efficient Instruction Scheduling Using Finite State Automata:
34 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
35 article about usage of finite state automata for pipeline hazard
36 recognizers.
38 The current implementation is different from the 2nd article in the
39 following:
41 1. New operator `|' (alternative) is permitted in functional unit
42 reservation which can be treated deterministically and
43 non-deterministically.
45 2. Possibility of usage of nondeterministic automata too.
47 3. Possibility to query functional unit reservations for given
48 automaton state.
50 4. Several constructions to describe impossible reservations
51 (`exclusion_set', `presence_set', `final_presence_set',
52 `absence_set', and `final_absence_set').
54 5. No reverse automata are generated. Trace instruction scheduling
55 requires this. It can be easily added in the future if we
56 really need this.
58 6. Union of automaton states are not generated yet. It is planned
59 to be implemented. Such feature is needed to make more accurate
60 interlock insn scheduling to get state describing functional
61 unit reservation in a joint CFG point. */
63 /* This file code processes constructions of machine description file
64 which describes automaton used for recognition of processor pipeline
65 hazards by insn scheduler and can be used for other tasks (such as
66 VLIW insn packing.
68 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
69 `gen_bypass', `gen_excl_set', `gen_presence_set',
70 `gen_final_presence_set', `gen_absence_set',
71 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
72 `gen_reserv', `gen_insn_reserv' are called from file
73 `genattrtab.c'. They transform RTL constructions describing
74 automata in .md file into internal representation convenient for
75 further processing.
77 The translator major function `expand_automata' processes the
78 description internal representation into finite state automaton.
79 It can be divided on:
81 o checking correctness of the automaton pipeline description
82 (major function is `check_all_description').
84 o generating automaton (automata) from the description (major
85 function is `make_automaton').
87 o optional transformation of nondeterministic finite state
88 automata into deterministic ones if the alternative operator
89 `|' is treated nondeterministically in the description (major
90 function is NDFA_to_DFA).
92 o optional minimization of the finite state automata by merging
93 equivalent automaton states (major function is `minimize_DFA').
95 o forming tables (some as comb vectors) and attributes
96 representing the automata (functions output_..._table).
98 Function `write_automata' outputs the created finite state
99 automaton as different tables and functions which works with the
100 automata to inquire automaton state and to change its state. These
101 function are used by gcc instruction scheduler and may be some
102 other gcc code. */
104 #include "bconfig.h"
105 #include "system.h"
106 #include "coretypes.h"
107 #include "tm.h"
108 #include "rtl.h"
109 #include "obstack.h"
110 #include "errors.h"
112 #include <math.h>
113 #include "hashtab.h"
114 #include "varray.h"
116 #ifndef CHAR_BIT
117 #define CHAR_BIT 8
118 #endif
120 #include "genattrtab.h"
122 /* Positions in machine description file. Now they are not used. But
123 they could be used in the future for better diagnostic messages. */
124 typedef int pos_t;
126 /* The following is element of vector of current (and planned in the
127 future) functional unit reservations. */
128 typedef unsigned HOST_WIDE_INT set_el_t;
130 /* Reservations of function units are represented by value of the following
131 type. */
132 typedef set_el_t *reserv_sets_t;
134 /* The following structure represents variable length array (vla) of
135 pointers and HOST WIDE INTs. We could be use only varray. But we
136 add new lay because we add elements very frequently and this could
137 stress OS allocator when varray is used only. */
138 typedef struct {
139 size_t length; /* current size of vla. */
140 varray_type varray; /* container for vla. */
141 } vla_ptr_t;
143 typedef vla_ptr_t vla_hwint_t;
145 /* The following structure describes a ticker. */
146 struct ticker
148 /* The following member value is time of the ticker creation with
149 taking into account time when the ticker is off. Active time of
150 the ticker is current time minus the value. */
151 int modified_creation_time;
152 /* The following member value is time (incremented by one) when the
153 ticker was off. Zero value means that now the ticker is on. */
154 int incremented_off_time;
157 /* The ticker is represented by the following type. */
158 typedef struct ticker ticker_t;
160 /* The following type describes elements of output vectors. */
161 typedef HOST_WIDE_INT vect_el_t;
163 /* Forward declaration of structures of internal representation of
164 pipeline description based on NDFA. */
166 struct unit_decl;
167 struct bypass_decl;
168 struct result_decl;
169 struct automaton_decl;
170 struct unit_pattern_rel_decl;
171 struct reserv_decl;
172 struct insn_reserv_decl;
173 struct decl;
174 struct unit_regexp;
175 struct result_regexp;
176 struct reserv_regexp;
177 struct nothing_regexp;
178 struct sequence_regexp;
179 struct repeat_regexp;
180 struct allof_regexp;
181 struct oneof_regexp;
182 struct regexp;
183 struct description;
184 struct unit_set_el;
185 struct pattern_set_el;
186 struct pattern_reserv;
187 struct state;
188 struct alt_state;
189 struct arc;
190 struct ainsn;
191 struct automaton;
192 struct state_ainsn_table;
194 /* The following typedefs are for brevity. */
195 typedef struct unit_decl *unit_decl_t;
196 typedef struct decl *decl_t;
197 typedef struct regexp *regexp_t;
198 typedef struct unit_set_el *unit_set_el_t;
199 typedef struct pattern_set_el *pattern_set_el_t;
200 typedef struct pattern_reserv *pattern_reserv_t;
201 typedef struct alt_state *alt_state_t;
202 typedef struct state *state_t;
203 typedef struct arc *arc_t;
204 typedef struct ainsn *ainsn_t;
205 typedef struct automaton *automaton_t;
206 typedef struct automata_list_el *automata_list_el_t;
207 typedef struct state_ainsn_table *state_ainsn_table_t;
210 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
211 gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
212 gen_absence_set, gen_final_absence_set, gen_automaton,
213 gen_automata_option, gen_reserv, gen_insn_reserv,
214 initiate_automaton_gen, expand_automata, write_automata are
215 described on the file top because the functions are called from
216 function `main'. */
218 static void *create_node (size_t);
219 static void *copy_node (const void *, size_t);
220 static char *check_name (char *, pos_t);
221 static char *next_sep_el (char **, int, int);
222 static int n_sep_els (char *, int, int);
223 static char **get_str_vect (char *, int *, int, int);
224 static void gen_presence_absence_set (rtx, int, int);
225 static regexp_t gen_regexp_el (char *);
226 static regexp_t gen_regexp_repeat (char *);
227 static regexp_t gen_regexp_allof (char *);
228 static regexp_t gen_regexp_oneof (char *);
229 static regexp_t gen_regexp_sequence (char *);
230 static regexp_t gen_regexp (char *);
232 static unsigned string_hash (const char *);
233 static unsigned automaton_decl_hash (const void *);
234 static int automaton_decl_eq_p (const void *,
235 const void *);
236 static decl_t insert_automaton_decl (decl_t);
237 static decl_t find_automaton_decl (char *);
238 static void initiate_automaton_decl_table (void);
239 static void finish_automaton_decl_table (void);
241 static hashval_t insn_decl_hash (const void *);
242 static int insn_decl_eq_p (const void *,
243 const void *);
244 static decl_t insert_insn_decl (decl_t);
245 static decl_t find_insn_decl (char *);
246 static void initiate_insn_decl_table (void);
247 static void finish_insn_decl_table (void);
249 static hashval_t decl_hash (const void *);
250 static int decl_eq_p (const void *,
251 const void *);
252 static decl_t insert_decl (decl_t);
253 static decl_t find_decl (char *);
254 static void initiate_decl_table (void);
255 static void finish_decl_table (void);
257 static unit_set_el_t process_excls (char **, int, pos_t);
258 static void add_excls (unit_set_el_t, unit_set_el_t,
259 pos_t);
260 static unit_set_el_t process_presence_absence_names
261 (char **, int, pos_t,
262 int, int);
263 static pattern_set_el_t process_presence_absence_patterns
264 (char ***, int, pos_t,
265 int, int);
266 static void add_presence_absence (unit_set_el_t,
267 pattern_set_el_t,
268 pos_t, int, int);
269 static void process_decls (void);
270 static struct bypass_decl *find_bypass (struct bypass_decl *,
271 struct insn_reserv_decl *);
272 static void check_automaton_usage (void);
273 static regexp_t process_regexp (regexp_t);
274 static void process_regexp_decls (void);
275 static void check_usage (void);
276 static int loop_in_regexp (regexp_t, decl_t);
277 static void check_loops_in_regexps (void);
278 static void process_regexp_cycles (regexp_t, int, int,
279 int *, int *);
280 static void evaluate_max_reserv_cycles (void);
281 static void check_all_description (void);
283 static ticker_t create_ticker (void);
284 static void ticker_off (ticker_t *);
285 static void ticker_on (ticker_t *);
286 static int active_time (ticker_t);
287 static void print_active_time (FILE *, ticker_t);
289 static void add_advance_cycle_insn_decl (void);
291 static alt_state_t get_free_alt_state (void);
292 static void free_alt_state (alt_state_t);
293 static void free_alt_states (alt_state_t);
294 static int alt_state_cmp (const void *alt_state_ptr_1,
295 const void *alt_state_ptr_2);
296 static alt_state_t uniq_sort_alt_states (alt_state_t);
297 static int alt_states_eq (alt_state_t, alt_state_t);
298 static void initiate_alt_states (void);
299 static void finish_alt_states (void);
301 static reserv_sets_t alloc_empty_reserv_sets (void);
302 static unsigned reserv_sets_hash_value (reserv_sets_t);
303 static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
304 static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
305 static void set_unit_reserv (reserv_sets_t, int, int);
306 static int test_unit_reserv (reserv_sets_t, int, int);
307 static int it_is_empty_reserv_sets (reserv_sets_t)
308 ATTRIBUTE_UNUSED;
309 static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
310 static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
311 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
312 reserv_sets_t);
313 static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
314 reserv_sets_t)
315 ATTRIBUTE_UNUSED;
316 static void output_cycle_reservs (FILE *, reserv_sets_t,
317 int, int);
318 static void output_reserv_sets (FILE *, reserv_sets_t);
319 static state_t get_free_state (int, automaton_t);
320 static void free_state (state_t);
321 static hashval_t state_hash (const void *);
322 static int state_eq_p (const void *, const void *);
323 static state_t insert_state (state_t);
324 static void set_state_reserv (state_t, int, int);
325 static int intersected_state_reservs_p (state_t, state_t);
326 static state_t states_union (state_t, state_t, reserv_sets_t);
327 static state_t state_shift (state_t, reserv_sets_t);
328 static void initiate_states (void);
329 static void finish_states (void);
331 static void free_arc (arc_t);
332 static void remove_arc (state_t, arc_t);
333 static arc_t find_arc (state_t, state_t, ainsn_t);
334 static arc_t add_arc (state_t, state_t, ainsn_t, int);
335 static arc_t first_out_arc (state_t);
336 static arc_t next_out_arc (arc_t);
337 static void initiate_arcs (void);
338 static void finish_arcs (void);
340 static automata_list_el_t get_free_automata_list_el (void);
341 static void free_automata_list_el (automata_list_el_t);
342 static void free_automata_list (automata_list_el_t);
343 static hashval_t automata_list_hash (const void *);
344 static int automata_list_eq_p (const void *, const void *);
345 static void initiate_automata_lists (void);
346 static void automata_list_start (void);
347 static void automata_list_add (automaton_t);
348 static automata_list_el_t automata_list_finish (void);
349 static void finish_automata_lists (void);
351 static void initiate_excl_sets (void);
352 static reserv_sets_t get_excl_set (reserv_sets_t);
354 static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
355 static void initiate_presence_absence_pattern_sets (void);
356 static int check_presence_pattern_sets (reserv_sets_t,
357 reserv_sets_t, int);
358 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
359 int);
361 static regexp_t copy_insn_regexp (regexp_t);
362 static regexp_t transform_1 (regexp_t);
363 static regexp_t transform_2 (regexp_t);
364 static regexp_t transform_3 (regexp_t);
365 static regexp_t regexp_transform_func
366 (regexp_t, regexp_t (*) (regexp_t));
367 static regexp_t transform_regexp (regexp_t);
368 static void transform_insn_regexps (void);
370 static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
371 static void check_regexp_units_distribution (const char *, regexp_t);
372 static void check_unit_distributions_to_automata (void);
374 static int process_seq_for_forming_states (regexp_t, automaton_t,
375 int);
376 static void finish_forming_alt_state (alt_state_t,
377 automaton_t);
378 static void process_alts_for_forming_states (regexp_t,
379 automaton_t, int);
380 static void create_alt_states (automaton_t);
382 static void form_ainsn_with_same_reservs (automaton_t);
384 static reserv_sets_t form_reservs_matter (automaton_t);
385 static void make_automaton (automaton_t);
386 static void form_arcs_marked_by_insn (state_t);
387 static int create_composed_state (state_t, arc_t, vla_ptr_t *);
388 static void NDFA_to_DFA (automaton_t);
389 static void pass_state_graph (state_t, void (*) (state_t));
390 static void pass_states (automaton_t,
391 void (*) (state_t));
392 static void initiate_pass_states (void);
393 static void add_achieved_state (state_t);
394 static int set_out_arc_insns_equiv_num (state_t, int);
395 static void clear_arc_insns_equiv_num (state_t);
396 static void copy_equiv_class (vla_ptr_t *to,
397 const vla_ptr_t *from);
398 static int first_cycle_unit_presence (state_t, int);
399 static int state_is_differed (state_t, state_t, int, int);
400 static state_t init_equiv_class (state_t *states, int);
401 static int partition_equiv_class (state_t *, int,
402 vla_ptr_t *, int *);
403 static void evaluate_equiv_classes (automaton_t, vla_ptr_t *);
404 static void merge_states (automaton_t, vla_ptr_t *);
405 static void set_new_cycle_flags (state_t);
406 static void minimize_DFA (automaton_t);
407 static void incr_states_and_arcs_nums (state_t);
408 static void count_states_and_arcs (automaton_t, int *, int *);
409 static void build_automaton (automaton_t);
411 static void set_order_state_num (state_t);
412 static void enumerate_states (automaton_t);
414 static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
415 static void delete_ainsn_from_equiv_class (ainsn_t);
416 static void process_insn_equiv_class (ainsn_t, arc_t *);
417 static void process_state_for_insn_equiv_partition (state_t);
418 static void set_insn_equiv_classes (automaton_t);
420 static double estimate_one_automaton_bound (void);
421 static int compare_max_occ_cycle_nums (const void *,
422 const void *);
423 static void units_to_automata_heuristic_distr (void);
424 static ainsn_t create_ainsns (void);
425 static void units_to_automata_distr (void);
426 static void create_automata (void);
428 static void form_regexp (regexp_t);
429 static const char *regexp_representation (regexp_t);
430 static void finish_regexp_representation (void);
432 static void output_range_type (FILE *, long int, long int);
433 static int longest_path_length (state_t);
434 static void process_state_longest_path_length (state_t);
435 static void output_dfa_max_issue_rate (void);
436 static void output_vect (vect_el_t *, int);
437 static void output_chip_member_name (FILE *, automaton_t);
438 static void output_temp_chip_member_name (FILE *, automaton_t);
439 static void output_translate_vect_name (FILE *, automaton_t);
440 static void output_trans_full_vect_name (FILE *, automaton_t);
441 static void output_trans_comb_vect_name (FILE *, automaton_t);
442 static void output_trans_check_vect_name (FILE *, automaton_t);
443 static void output_trans_base_vect_name (FILE *, automaton_t);
444 static void output_state_alts_full_vect_name (FILE *, automaton_t);
445 static void output_state_alts_comb_vect_name (FILE *, automaton_t);
446 static void output_state_alts_check_vect_name (FILE *, automaton_t);
447 static void output_state_alts_base_vect_name (FILE *, automaton_t);
448 static void output_min_issue_delay_vect_name (FILE *, automaton_t);
449 static void output_dead_lock_vect_name (FILE *, automaton_t);
450 static void output_reserved_units_table_name (FILE *, automaton_t);
451 static void output_state_member_type (FILE *, automaton_t);
452 static void output_chip_definitions (void);
453 static void output_translate_vect (automaton_t);
454 static int comb_vect_p (state_ainsn_table_t);
455 static state_ainsn_table_t create_state_ainsn_table (automaton_t);
456 static void output_state_ainsn_table
457 (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
458 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
459 void (*) (FILE *, automaton_t));
460 static void add_vect (state_ainsn_table_t,
461 int, vect_el_t *, int);
462 static int out_state_arcs_num (state_t);
463 static int compare_transition_els_num (const void *, const void *);
464 static void add_vect_el (vla_hwint_t *,
465 ainsn_t, int);
466 static void add_states_vect_el (state_t);
467 static void output_trans_table (automaton_t);
468 static void output_state_alts_table (automaton_t);
469 static int min_issue_delay_pass_states (state_t, ainsn_t);
470 static int min_issue_delay (state_t, ainsn_t);
471 static void initiate_min_issue_delay_pass_states (void);
472 static void output_min_issue_delay_table (automaton_t);
473 static void output_dead_lock_vect (automaton_t);
474 static void output_reserved_units_table (automaton_t);
475 static void output_tables (void);
476 static void output_max_insn_queue_index_def (void);
477 static void output_insn_code_cases (void (*) (automata_list_el_t));
478 static void output_automata_list_min_issue_delay_code (automata_list_el_t);
479 static void output_internal_min_issue_delay_func (void);
480 static void output_automata_list_transition_code (automata_list_el_t);
481 static void output_internal_trans_func (void);
482 static void output_internal_insn_code_evaluation (const char *,
483 const char *, int);
484 static void output_dfa_insn_code_func (void);
485 static void output_trans_func (void);
486 static void output_automata_list_state_alts_code (automata_list_el_t);
487 static void output_internal_state_alts_func (void);
488 static void output_state_alts_func (void);
489 static void output_min_issue_delay_func (void);
490 static void output_internal_dead_lock_func (void);
491 static void output_dead_lock_func (void);
492 static void output_internal_reset_func (void);
493 static void output_size_func (void);
494 static void output_reset_func (void);
495 static void output_min_insn_conflict_delay_func (void);
496 static void output_internal_insn_latency_func (void);
497 static void output_insn_latency_func (void);
498 static void output_print_reservation_func (void);
499 static int units_cmp (const void *,
500 const void *);
501 static void output_get_cpu_unit_code_func (void);
502 static void output_cpu_unit_reservation_p (void);
503 static void output_dfa_clean_insn_cache_func (void);
504 static void output_dfa_start_func (void);
505 static void output_dfa_finish_func (void);
507 static void output_regexp (regexp_t );
508 static void output_unit_set_el_list (unit_set_el_t);
509 static void output_pattern_set_el_list (pattern_set_el_t);
510 static void output_description (void);
511 static void output_automaton_name (FILE *, automaton_t);
512 static void output_automaton_units (automaton_t);
513 static void add_state_reservs (state_t);
514 static void output_state_arcs (state_t);
515 static int state_reservs_cmp (const void *,
516 const void *);
517 static void remove_state_duplicate_reservs (void);
518 static void output_state (state_t);
519 static void output_automaton_descriptions (void);
520 static void output_statistics (FILE *);
521 static void output_time_statistics (FILE *);
522 static void generate (void);
524 static void make_insn_alts_attr (void);
525 static void make_internal_dfa_insn_code_attr (void);
526 static void make_default_insn_latency_attr (void);
527 static void make_bypass_attr (void);
528 static const char *file_name_suffix (const char *);
529 static const char *base_file_name (const char *);
530 static void check_automata_insn_issues (void);
531 static void add_automaton_state (state_t);
532 static void form_important_insn_automata_lists (void);
534 /* Undefined position. */
535 static pos_t no_pos = 0;
537 /* All IR is stored in the following obstack. */
538 static struct obstack irp;
542 /* This page contains code for work with variable length array (vla)
543 of pointers. We could be use only varray. But we add new lay
544 because we add elements very frequently and this could stress OS
545 allocator when varray is used only. */
547 /* Start work with vla. */
548 #define VLA_PTR_CREATE(vla, allocated_length, name) \
549 do \
551 vla_ptr_t *const _vla_ptr = &(vla); \
553 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
554 _vla_ptr->length = 0; \
556 while (0)
558 /* Finish work with the vla. */
559 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
561 /* Return start address of the vla. */
562 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
564 /* Address of the last element of the vla. Do not use side effects in
565 the macro argument. */
566 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
567 (vla).length - 1))
568 /* Nullify the vla. */
569 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
571 /* Shorten the vla on given number bytes. */
572 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
574 /* Expand the vla on N elements. The values of new elements are
575 undefined. */
576 #define VLA_PTR_EXPAND(vla, n) \
577 do { \
578 vla_ptr_t *const _expand_vla_ptr = &(vla); \
579 const size_t _new_length = (n) + _expand_vla_ptr->length; \
581 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
582 VARRAY_GROW (_expand_vla_ptr->varray, \
583 (_new_length - _expand_vla_ptr->length < 128 \
584 ? _expand_vla_ptr->length + 128 : _new_length)); \
585 _expand_vla_ptr->length = _new_length; \
586 } while (0)
588 /* Add element to the end of the vla. */
589 #define VLA_PTR_ADD(vla, ptr) \
590 do { \
591 vla_ptr_t *const _vla_ptr = &(vla); \
593 VLA_PTR_EXPAND (*_vla_ptr, 1); \
594 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
595 } while (0)
597 /* Length of the vla in elements. */
598 #define VLA_PTR_LENGTH(vla) ((vla).length)
600 /* N-th element of the vla. */
601 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
604 /* The following macros are analogous to the previous ones but for
605 VLAs of HOST WIDE INTs. */
607 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
608 do { \
609 vla_hwint_t *const _vla_ptr = &(vla); \
611 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
612 _vla_ptr->length = 0; \
613 } while (0)
615 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
617 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
619 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
621 #define VLA_HWINT_EXPAND(vla, n) \
622 do { \
623 vla_hwint_t *const _expand_vla_ptr = &(vla); \
624 const size_t _new_length = (n) + _expand_vla_ptr->length; \
626 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
627 VARRAY_GROW (_expand_vla_ptr->varray, \
628 (_new_length - _expand_vla_ptr->length < 128 \
629 ? _expand_vla_ptr->length + 128 : _new_length)); \
630 _expand_vla_ptr->length = _new_length; \
631 } while (0)
633 #define VLA_HWINT_ADD(vla, ptr) \
634 do { \
635 vla_hwint_t *const _vla_ptr = &(vla); \
637 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
638 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
639 } while (0)
641 #define VLA_HWINT_LENGTH(vla) ((vla).length)
643 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
647 /* Options with the following names can be set up in automata_option
648 construction. Because the strings occur more one time we use the
649 macros. */
651 #define NO_MINIMIZATION_OPTION "-no-minimization"
653 #define TIME_OPTION "-time"
655 #define V_OPTION "-v"
657 #define W_OPTION "-w"
659 #define NDFA_OPTION "-ndfa"
661 #define PROGRESS_OPTION "-progress"
663 /* The following flags are set up by function `initiate_automaton_gen'. */
665 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
666 static int ndfa_flag;
668 /* Do not make minimization of DFA (`-no-minimization'). */
669 static int no_minimization_flag;
671 /* Value of this variable is number of automata being generated. The
672 actual number of automata may be less this value if there is not
673 sufficient number of units. This value is defined by argument of
674 option `-split' or by constructions automaton if the value is zero
675 (it is default value of the argument). */
676 static int split_argument;
678 /* Flag of output time statistics (`-time'). */
679 static int time_flag;
681 /* Flag of creation of description file which contains description of
682 result automaton and statistics information (`-v'). */
683 static int v_flag;
685 /* Flag of output of a progress bar showing how many states were
686 generated so far for automaton being processed (`-progress'). */
687 static int progress_flag;
689 /* Flag of generating warning instead of error for non-critical errors
690 (`-w'). */
691 static int w_flag;
694 /* Output file for pipeline hazard recognizer (PHR) being generated.
695 The value is NULL if the file is not defined. */
696 static FILE *output_file;
698 /* Description file of PHR. The value is NULL if the file is not
699 created. */
700 static FILE *output_description_file;
702 /* PHR description file name. */
703 static char *output_description_file_name;
705 /* Value of the following variable is node representing description
706 being processed. This is start point of IR. */
707 static struct description *description;
711 /* This page contains description of IR structure (nodes). */
713 enum decl_mode
715 dm_unit,
716 dm_bypass,
717 dm_automaton,
718 dm_excl,
719 dm_presence,
720 dm_absence,
721 dm_reserv,
722 dm_insn_reserv
725 /* This describes define_cpu_unit and define_query_cpu_unit (see file
726 rtl.def). */
727 struct unit_decl
729 char *name;
730 /* NULL if the automaton name is absent. */
731 char *automaton_name;
732 /* If the following value is not zero, the cpu unit reservation is
733 described in define_query_cpu_unit. */
734 char query_p;
736 /* The following fields are defined by checker. */
738 /* The following field value is nonzero if the unit is used in an
739 regexp. */
740 char unit_is_used;
742 /* The following field value is order number (0, 1, ...) of given
743 unit. */
744 int unit_num;
745 /* The following field value is corresponding declaration of
746 automaton which was given in description. If the field value is
747 NULL then automaton in the unit declaration was absent. */
748 struct automaton_decl *automaton_decl;
749 /* The following field value is maximal cycle number (1, ...) on
750 which given unit occurs in insns. Zero value means that given
751 unit is not used in insns. */
752 int max_occ_cycle_num;
753 /* The following field value is minimal cycle number (0, ...) on
754 which given unit occurs in insns. -1 value means that given
755 unit is not used in insns. */
756 int min_occ_cycle_num;
757 /* The following list contains units which conflict with given
758 unit. */
759 unit_set_el_t excl_list;
760 /* The following list contains patterns which are required to
761 reservation of given unit. */
762 pattern_set_el_t presence_list;
763 pattern_set_el_t final_presence_list;
764 /* The following list contains patterns which should be not present
765 in reservation for given unit. */
766 pattern_set_el_t absence_list;
767 pattern_set_el_t final_absence_list;
768 /* The following is used only when `query_p' has nonzero value.
769 This is query number for the unit. */
770 int query_num;
771 /* The following is the last cycle on which the unit was checked for
772 correct distributions of units to automata in a regexp. */
773 int last_distribution_check_cycle;
775 /* The following fields are defined by automaton generator. */
777 /* The following field value is number of the automaton to which
778 given unit belongs. */
779 int corresponding_automaton_num;
780 /* If the following value is not zero, the cpu unit is present in a
781 `exclusion_set' or in right part of a `presence_set',
782 `final_presence_set', `absence_set', and
783 `final_absence_set'define_query_cpu_unit. */
784 char in_set_p;
787 /* This describes define_bypass (see file rtl.def). */
788 struct bypass_decl
790 int latency;
791 char *out_insn_name;
792 char *in_insn_name;
793 char *bypass_guard_name;
795 /* The following fields are defined by checker. */
797 /* output and input insns of given bypass. */
798 struct insn_reserv_decl *out_insn_reserv;
799 struct insn_reserv_decl *in_insn_reserv;
800 /* The next bypass for given output insn. */
801 struct bypass_decl *next;
804 /* This describes define_automaton (see file rtl.def). */
805 struct automaton_decl
807 char *name;
809 /* The following fields are defined by automaton generator. */
811 /* The following field value is nonzero if the automaton is used in
812 an regexp definition. */
813 char automaton_is_used;
815 /* The following fields are defined by checker. */
817 /* The following field value is the corresponding automaton. This
818 field is not NULL only if the automaton is present in unit
819 declarations and the automatic partition on automata is not
820 used. */
821 automaton_t corresponding_automaton;
824 /* This describes exclusion relations: exclusion_set (see file
825 rtl.def). */
826 struct excl_rel_decl
828 int all_names_num;
829 int first_list_length;
830 char *names [1];
833 /* This describes unit relations: [final_]presence_set or
834 [final_]absence_set (see file rtl.def). */
835 struct unit_pattern_rel_decl
837 int final_p;
838 int names_num;
839 int patterns_num;
840 char **names;
841 char ***patterns;
844 /* This describes define_reservation (see file rtl.def). */
845 struct reserv_decl
847 char *name;
848 regexp_t regexp;
850 /* The following fields are defined by checker. */
852 /* The following field value is nonzero if the unit is used in an
853 regexp. */
854 char reserv_is_used;
855 /* The following field is used to check up cycle in expression
856 definition. */
857 int loop_pass_num;
860 /* This describes define_insn_reservation (see file rtl.def). */
861 struct insn_reserv_decl
863 rtx condexp;
864 int default_latency;
865 regexp_t regexp;
866 char *name;
868 /* The following fields are defined by checker. */
870 /* The following field value is order number (0, 1, ...) of given
871 insn. */
872 int insn_num;
873 /* The following field value is list of bypasses in which given insn
874 is output insn. */
875 struct bypass_decl *bypass_list;
877 /* The following fields are defined by automaton generator. */
879 /* The following field is the insn regexp transformed that
880 the regexp has not optional regexp, repetition regexp, and an
881 reservation name (i.e. reservation identifiers are changed by the
882 corresponding regexp) and all alternations are the topest level
883 of the regexp. The value can be NULL only if it is special
884 insn `cycle advancing'. */
885 regexp_t transformed_regexp;
886 /* The following field value is list of arcs marked given
887 insn. The field is used in transformation NDFA -> DFA. */
888 arc_t arcs_marked_by_insn;
889 /* The two following fields are used during minimization of a finite state
890 automaton. */
891 /* The field value is number of equivalence class of state into
892 which arc marked by given insn enters from a state (fixed during
893 an automaton minimization). */
894 int equiv_class_num;
895 /* The field value is state_alts of arc leaving a state (fixed
896 during an automaton minimization) and marked by given insn
897 enters. */
898 int state_alts;
899 /* The following member value is the list to automata which can be
900 changed by the insn issue. */
901 automata_list_el_t important_automata_list;
902 /* The following member is used to process insn once for output. */
903 int processed_p;
906 /* This contains a declaration mentioned above. */
907 struct decl
909 /* What node in the union? */
910 enum decl_mode mode;
911 pos_t pos;
912 union
914 struct unit_decl unit;
915 struct bypass_decl bypass;
916 struct automaton_decl automaton;
917 struct excl_rel_decl excl;
918 struct unit_pattern_rel_decl presence;
919 struct unit_pattern_rel_decl absence;
920 struct reserv_decl reserv;
921 struct insn_reserv_decl insn_reserv;
922 } decl;
925 /* The following structures represent parsed reservation strings. */
926 enum regexp_mode
928 rm_unit,
929 rm_reserv,
930 rm_nothing,
931 rm_sequence,
932 rm_repeat,
933 rm_allof,
934 rm_oneof
937 /* Cpu unit in reservation. */
938 struct unit_regexp
940 char *name;
941 unit_decl_t unit_decl;
944 /* Define_reservation in a reservation. */
945 struct reserv_regexp
947 char *name;
948 struct reserv_decl *reserv_decl;
951 /* Absence of reservation (represented by string `nothing'). */
952 struct nothing_regexp
954 /* This used to be empty but ISO C doesn't allow that. */
955 char unused;
958 /* Representation of reservations separated by ',' (see file
959 rtl.def). */
960 struct sequence_regexp
962 int regexps_num;
963 regexp_t regexps [1];
966 /* Representation of construction `repeat' (see file rtl.def). */
967 struct repeat_regexp
969 int repeat_num;
970 regexp_t regexp;
973 /* Representation of reservations separated by '+' (see file
974 rtl.def). */
975 struct allof_regexp
977 int regexps_num;
978 regexp_t regexps [1];
981 /* Representation of reservations separated by '|' (see file
982 rtl.def). */
983 struct oneof_regexp
985 int regexps_num;
986 regexp_t regexps [1];
989 /* Representation of a reservation string. */
990 struct regexp
992 /* What node in the union? */
993 enum regexp_mode mode;
994 pos_t pos;
995 union
997 struct unit_regexp unit;
998 struct reserv_regexp reserv;
999 struct nothing_regexp nothing;
1000 struct sequence_regexp sequence;
1001 struct repeat_regexp repeat;
1002 struct allof_regexp allof;
1003 struct oneof_regexp oneof;
1004 } regexp;
1007 /* Represents description of pipeline hazard description based on
1008 NDFA. */
1009 struct description
1011 int decls_num;
1013 /* The following fields are defined by checker. */
1015 /* The following fields values are correspondingly number of all
1016 units, query units, and insns in the description. */
1017 int units_num;
1018 int query_units_num;
1019 int insns_num;
1020 /* The following field value is max length (in cycles) of
1021 reservations of insns. The field value is defined only for
1022 correct programs. */
1023 int max_insn_reserv_cycles;
1025 /* The following fields are defined by automaton generator. */
1027 /* The following field value is the first automaton. */
1028 automaton_t first_automaton;
1030 /* The following field is created by pipeline hazard parser and
1031 contains all declarations. We allocate additional entry for
1032 special insn "cycle advancing" which is added by the automaton
1033 generator. */
1034 decl_t decls [1];
1038 /* The following nodes are created in automaton checker. */
1040 /* The following nodes represent exclusion set for cpu units. Each
1041 element is accessed through only one excl_list. */
1042 struct unit_set_el
1044 unit_decl_t unit_decl;
1045 unit_set_el_t next_unit_set_el;
1048 /* The following nodes represent presence or absence pattern for cpu
1049 units. Each element is accessed through only one presence_list or
1050 absence_list. */
1051 struct pattern_set_el
1053 /* The number of units in unit_decls. */
1054 int units_num;
1055 /* The units forming the pattern. */
1056 struct unit_decl **unit_decls;
1057 pattern_set_el_t next_pattern_set_el;
1061 /* The following nodes are created in automaton generator. */
1064 /* The following nodes represent presence or absence pattern for cpu
1065 units. Each element is accessed through only one element of
1066 unit_presence_set_table or unit_absence_set_table. */
1067 struct pattern_reserv
1069 reserv_sets_t reserv;
1070 pattern_reserv_t next_pattern_reserv;
1073 /* The following node type describes state automaton. The state may
1074 be deterministic or non-deterministic. Non-deterministic state has
1075 several component states which represent alternative cpu units
1076 reservations. The state also is used for describing a
1077 deterministic reservation of automaton insn. */
1078 struct state
1080 /* The following member value is nonzero if there is a transition by
1081 cycle advancing. */
1082 int new_cycle_p;
1083 /* The following field is list of processor unit reservations on
1084 each cycle. */
1085 reserv_sets_t reservs;
1086 /* The following field is unique number of given state between other
1087 states. */
1088 int unique_num;
1089 /* The following field value is automaton to which given state
1090 belongs. */
1091 automaton_t automaton;
1092 /* The following field value is the first arc output from given
1093 state. */
1094 arc_t first_out_arc;
1095 /* The following field is used to form NDFA. */
1096 char it_was_placed_in_stack_for_NDFA_forming;
1097 /* The following field is used to form DFA. */
1098 char it_was_placed_in_stack_for_DFA_forming;
1099 /* The following field is used to transform NDFA to DFA and DFA
1100 minimization. The field value is not NULL if the state is a
1101 compound state. In this case the value of field `unit_sets_list'
1102 is NULL. All states in the list are in the hash table. The list
1103 is formed through field `next_sorted_alt_state'. We should
1104 support only one level of nesting state. */
1105 alt_state_t component_states;
1106 /* The following field is used for passing graph of states. */
1107 int pass_num;
1108 /* The list of states belonging to one equivalence class is formed
1109 with the aid of the following field. */
1110 state_t next_equiv_class_state;
1111 /* The two following fields are used during minimization of a finite
1112 state automaton. */
1113 int equiv_class_num_1, equiv_class_num_2;
1114 /* The following field is used during minimization of a finite state
1115 automaton. The field value is state corresponding to equivalence
1116 class to which given state belongs. */
1117 state_t equiv_class_state;
1118 /* The following field value is the order number of given state.
1119 The states in final DFA is enumerated with the aid of the
1120 following field. */
1121 int order_state_num;
1122 /* This member is used for passing states for searching minimal
1123 delay time. */
1124 int state_pass_num;
1125 /* The following member is used to evaluate min issue delay of insn
1126 for a state. */
1127 int min_insn_issue_delay;
1128 /* The following member is used to evaluate max issue rate of the
1129 processor. The value of the member is maximal length of the path
1130 from given state no containing arcs marked by special insn `cycle
1131 advancing'. */
1132 int longest_path_length;
1135 /* The following macro is an initial value of member
1136 `longest_path_length' of a state. */
1137 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1139 /* Automaton arc. */
1140 struct arc
1142 /* The following field refers for the state into which given arc
1143 enters. */
1144 state_t to_state;
1145 /* The following field describes that the insn issue (with cycle
1146 advancing for special insn `cycle advancing' and without cycle
1147 advancing for others) makes transition from given state to
1148 another given state. */
1149 ainsn_t insn;
1150 /* The following field value is the next arc output from the same
1151 state. */
1152 arc_t next_out_arc;
1153 /* List of arcs marked given insn is formed with the following
1154 field. The field is used in transformation NDFA -> DFA. */
1155 arc_t next_arc_marked_by_insn;
1156 /* The following field is defined if NDFA_FLAG is zero. The member
1157 value is number of alternative reservations which can be used for
1158 transition for given state by given insn. */
1159 int state_alts;
1162 /* The following node type describes a deterministic alternative in
1163 non-deterministic state which characterizes cpu unit reservations
1164 of automaton insn or which is part of NDFA. */
1165 struct alt_state
1167 /* The following field is a deterministic state which characterizes
1168 unit reservations of the instruction. */
1169 state_t state;
1170 /* The following field refers to the next state which characterizes
1171 unit reservations of the instruction. */
1172 alt_state_t next_alt_state;
1173 /* The following field refers to the next state in sorted list. */
1174 alt_state_t next_sorted_alt_state;
1177 /* The following node type describes insn of automaton. They are
1178 labels of FA arcs. */
1179 struct ainsn
1181 /* The following field value is the corresponding insn declaration
1182 of description. */
1183 struct insn_reserv_decl *insn_reserv_decl;
1184 /* The following field value is the next insn declaration for an
1185 automaton. */
1186 ainsn_t next_ainsn;
1187 /* The following field is states which characterize automaton unit
1188 reservations of the instruction. The value can be NULL only if it
1189 is special insn `cycle advancing'. */
1190 alt_state_t alt_states;
1191 /* The following field is sorted list of states which characterize
1192 automaton unit reservations of the instruction. The value can be
1193 NULL only if it is special insn `cycle advancing'. */
1194 alt_state_t sorted_alt_states;
1195 /* The following field refers the next automaton insn with
1196 the same reservations. */
1197 ainsn_t next_same_reservs_insn;
1198 /* The following field is flag of the first automaton insn with the
1199 same reservations in the declaration list. Only arcs marked such
1200 insn is present in the automaton. This significantly decreases
1201 memory requirements especially when several automata are
1202 formed. */
1203 char first_insn_with_same_reservs;
1204 /* The following member has nonzero value if there is arc from state of
1205 the automaton marked by the ainsn. */
1206 char arc_exists_p;
1207 /* Cyclic list of insns of an equivalence class is formed with the
1208 aid of the following field. */
1209 ainsn_t next_equiv_class_insn;
1210 /* The following field value is nonzero if the insn declaration is
1211 the first insn declaration with given equivalence number. */
1212 char first_ainsn_with_given_equivalence_num;
1213 /* The following field is number of class of equivalence of insns.
1214 It is necessary because many insns may be equivalent with the
1215 point of view of pipeline hazards. */
1216 int insn_equiv_class_num;
1217 /* The following member value is TRUE if there is an arc in the
1218 automaton marked by the insn into another state. In other
1219 words, the insn can change the state of the automaton. */
1220 int important_p;
1223 /* The following describes an automaton for PHR. */
1224 struct automaton
1226 /* The following field value is the list of insn declarations for
1227 given automaton. */
1228 ainsn_t ainsn_list;
1229 /* The following field value is the corresponding automaton
1230 declaration. This field is not NULL only if the automatic
1231 partition on automata is not used. */
1232 struct automaton_decl *corresponding_automaton_decl;
1233 /* The following field value is the next automaton. */
1234 automaton_t next_automaton;
1235 /* The following field is start state of FA. There are not unit
1236 reservations in the state. */
1237 state_t start_state;
1238 /* The following field value is number of equivalence classes of
1239 insns (see field `insn_equiv_class_num' in
1240 `insn_reserv_decl'). */
1241 int insn_equiv_classes_num;
1242 /* The following field value is number of states of final DFA. */
1243 int achieved_states_num;
1244 /* The following field value is the order number (0, 1, ...) of
1245 given automaton. */
1246 int automaton_order_num;
1247 /* The following fields contain statistics information about
1248 building automaton. */
1249 int NDFA_states_num, DFA_states_num;
1250 /* The following field value is defined only if minimization of DFA
1251 is used. */
1252 int minimal_DFA_states_num;
1253 int NDFA_arcs_num, DFA_arcs_num;
1254 /* The following field value is defined only if minimization of DFA
1255 is used. */
1256 int minimal_DFA_arcs_num;
1257 /* The following two members refer for two table state x ainsn ->
1258 int. */
1259 state_ainsn_table_t trans_table;
1260 state_ainsn_table_t state_alts_table;
1261 /* The following member value is maximal value of min issue delay
1262 for insns of the automaton. */
1263 int max_min_delay;
1264 /* Usually min issue delay is small and we can place several (2, 4,
1265 8) elements in one vector element. So the compression factor can
1266 be 1 (no compression), 2, 4, 8. */
1267 int min_issue_delay_table_compression_factor;
1270 /* The following is the element of the list of automata. */
1271 struct automata_list_el
1273 /* The automaton itself. */
1274 automaton_t automaton;
1275 /* The next automata set element. */
1276 automata_list_el_t next_automata_list_el;
1279 /* The following structure describes a table state X ainsn -> int(>= 0). */
1280 struct state_ainsn_table
1282 /* Automaton to which given table belongs. */
1283 automaton_t automaton;
1284 /* The following tree vectors for comb vector implementation of the
1285 table. */
1286 vla_hwint_t comb_vect;
1287 vla_hwint_t check_vect;
1288 vla_hwint_t base_vect;
1289 /* This is simple implementation of the table. */
1290 vla_hwint_t full_vect;
1291 /* Minimal and maximal values of the previous vectors. */
1292 int min_comb_vect_el_value, max_comb_vect_el_value;
1293 int min_base_vect_el_value, max_base_vect_el_value;
1296 /* Macros to access members of unions. Use only them for access to
1297 union members of declarations and regexps. */
1299 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1301 #define DECL_UNIT(d) __extension__ \
1302 (({ struct decl *const _decl = (d); \
1303 if (_decl->mode != dm_unit) \
1304 decl_mode_check_failed (_decl->mode, "dm_unit", \
1305 __FILE__, __LINE__, __FUNCTION__); \
1306 &(_decl)->decl.unit; }))
1308 #define DECL_BYPASS(d) __extension__ \
1309 (({ struct decl *const _decl = (d); \
1310 if (_decl->mode != dm_bypass) \
1311 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1312 __FILE__, __LINE__, __FUNCTION__); \
1313 &(_decl)->decl.bypass; }))
1315 #define DECL_AUTOMATON(d) __extension__ \
1316 (({ struct decl *const _decl = (d); \
1317 if (_decl->mode != dm_automaton) \
1318 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1319 __FILE__, __LINE__, __FUNCTION__); \
1320 &(_decl)->decl.automaton; }))
1322 #define DECL_EXCL(d) __extension__ \
1323 (({ struct decl *const _decl = (d); \
1324 if (_decl->mode != dm_excl) \
1325 decl_mode_check_failed (_decl->mode, "dm_excl", \
1326 __FILE__, __LINE__, __FUNCTION__); \
1327 &(_decl)->decl.excl; }))
1329 #define DECL_PRESENCE(d) __extension__ \
1330 (({ struct decl *const _decl = (d); \
1331 if (_decl->mode != dm_presence) \
1332 decl_mode_check_failed (_decl->mode, "dm_presence", \
1333 __FILE__, __LINE__, __FUNCTION__); \
1334 &(_decl)->decl.presence; }))
1336 #define DECL_ABSENCE(d) __extension__ \
1337 (({ struct decl *const _decl = (d); \
1338 if (_decl->mode != dm_absence) \
1339 decl_mode_check_failed (_decl->mode, "dm_absence", \
1340 __FILE__, __LINE__, __FUNCTION__); \
1341 &(_decl)->decl.absence; }))
1343 #define DECL_RESERV(d) __extension__ \
1344 (({ struct decl *const _decl = (d); \
1345 if (_decl->mode != dm_reserv) \
1346 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1347 __FILE__, __LINE__, __FUNCTION__); \
1348 &(_decl)->decl.reserv; }))
1350 #define DECL_INSN_RESERV(d) __extension__ \
1351 (({ struct decl *const _decl = (d); \
1352 if (_decl->mode != dm_insn_reserv) \
1353 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1354 __FILE__, __LINE__, __FUNCTION__); \
1355 &(_decl)->decl.insn_reserv; }))
1357 static const char *decl_name (enum decl_mode);
1358 static void decl_mode_check_failed (enum decl_mode, const char *,
1359 const char *, int, const char *);
1361 /* Return string representation of declaration mode MODE. */
1362 static const char *
1363 decl_name (enum decl_mode mode)
1365 static char str [100];
1367 if (mode == dm_unit)
1368 return "dm_unit";
1369 else if (mode == dm_bypass)
1370 return "dm_bypass";
1371 else if (mode == dm_automaton)
1372 return "dm_automaton";
1373 else if (mode == dm_excl)
1374 return "dm_excl";
1375 else if (mode == dm_presence)
1376 return "dm_presence";
1377 else if (mode == dm_absence)
1378 return "dm_absence";
1379 else if (mode == dm_reserv)
1380 return "dm_reserv";
1381 else if (mode == dm_insn_reserv)
1382 return "dm_insn_reserv";
1383 else
1384 sprintf (str, "unknown (%d)", (int) mode);
1385 return str;
1388 /* The function prints message about unexpected declaration and finish
1389 the program. */
1390 static void
1391 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1392 const char *file, int line, const char *func)
1394 fprintf
1395 (stderr,
1396 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1397 file, line, func, expected_mode_str, decl_name (mode));
1398 exit (1);
1402 #define REGEXP_UNIT(r) __extension__ \
1403 (({ struct regexp *const _regexp = (r); \
1404 if (_regexp->mode != rm_unit) \
1405 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1406 __FILE__, __LINE__, __FUNCTION__); \
1407 &(_regexp)->regexp.unit; }))
1409 #define REGEXP_RESERV(r) __extension__ \
1410 (({ struct regexp *const _regexp = (r); \
1411 if (_regexp->mode != rm_reserv) \
1412 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1413 __FILE__, __LINE__, __FUNCTION__); \
1414 &(_regexp)->regexp.reserv; }))
1416 #define REGEXP_SEQUENCE(r) __extension__ \
1417 (({ struct regexp *const _regexp = (r); \
1418 if (_regexp->mode != rm_sequence) \
1419 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1420 __FILE__, __LINE__, __FUNCTION__); \
1421 &(_regexp)->regexp.sequence; }))
1423 #define REGEXP_REPEAT(r) __extension__ \
1424 (({ struct regexp *const _regexp = (r); \
1425 if (_regexp->mode != rm_repeat) \
1426 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1427 __FILE__, __LINE__, __FUNCTION__); \
1428 &(_regexp)->regexp.repeat; }))
1430 #define REGEXP_ALLOF(r) __extension__ \
1431 (({ struct regexp *const _regexp = (r); \
1432 if (_regexp->mode != rm_allof) \
1433 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1434 __FILE__, __LINE__, __FUNCTION__); \
1435 &(_regexp)->regexp.allof; }))
1437 #define REGEXP_ONEOF(r) __extension__ \
1438 (({ struct regexp *const _regexp = (r); \
1439 if (_regexp->mode != rm_oneof) \
1440 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1441 __FILE__, __LINE__, __FUNCTION__); \
1442 &(_regexp)->regexp.oneof; }))
1444 static const char *regexp_name (enum regexp_mode);
1445 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1446 const char *, int,
1447 const char *);
1450 /* Return string representation of regexp mode MODE. */
1451 static const char *
1452 regexp_name (enum regexp_mode mode)
1454 switch (mode)
1456 case rm_unit:
1457 return "rm_unit";
1458 case rm_reserv:
1459 return "rm_reserv";
1460 case rm_nothing:
1461 return "rm_nothing";
1462 case rm_sequence:
1463 return "rm_sequence";
1464 case rm_repeat:
1465 return "rm_repeat";
1466 case rm_allof:
1467 return "rm_allof";
1468 case rm_oneof:
1469 return "rm_oneof";
1470 default:
1471 gcc_unreachable ();
1475 /* The function prints message about unexpected regexp and finish the
1476 program. */
1477 static void
1478 regexp_mode_check_failed (enum regexp_mode mode,
1479 const char *expected_mode_str,
1480 const char *file, int line, const char *func)
1482 fprintf
1483 (stderr,
1484 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1485 file, line, func, expected_mode_str, regexp_name (mode));
1486 exit (1);
1489 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1491 #define DECL_UNIT(d) (&(d)->decl.unit)
1492 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1493 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1494 #define DECL_EXCL(d) (&(d)->decl.excl)
1495 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1496 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1497 #define DECL_RESERV(d) (&(d)->decl.reserv)
1498 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1500 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1501 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1502 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1503 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1504 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1505 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1507 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1509 /* Create IR structure (node). */
1510 static void *
1511 create_node (size_t size)
1513 void *result;
1515 obstack_blank (&irp, size);
1516 result = obstack_base (&irp);
1517 obstack_finish (&irp);
1518 /* Default values of members are NULL and zero. */
1519 memset (result, 0, size);
1520 return result;
1523 /* Copy IR structure (node). */
1524 static void *
1525 copy_node (const void *from, size_t size)
1527 void *const result = create_node (size);
1528 memcpy (result, from, size);
1529 return result;
1532 /* The function checks that NAME does not contain quotes (`"'). */
1533 static char *
1534 check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
1536 const char *str;
1538 for (str = name; *str != '\0'; str++)
1539 if (*str == '\"')
1540 error ("Name `%s' contains quotes", name);
1541 return name;
1544 /* Pointers to all declarations during IR generation are stored in the
1545 following. */
1546 static vla_ptr_t decls;
1548 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1549 string containing the next separated element, taking parentheses
1550 into account if PAR_FLAG has nonzero value. Advance the pointer to
1551 after the string scanned, or the end-of-string. Return NULL if at
1552 end of string. */
1553 static char *
1554 next_sep_el (char **pstr, int sep, int par_flag)
1556 char *out_str;
1557 char *p;
1558 int pars_num;
1559 int n_spaces;
1561 /* Remove leading whitespaces. */
1562 while (ISSPACE ((int) **pstr))
1563 (*pstr)++;
1565 if (**pstr == '\0')
1566 return NULL;
1568 n_spaces = 0;
1569 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1571 if (par_flag && *p == '(')
1572 pars_num++;
1573 else if (par_flag && *p == ')')
1574 pars_num--;
1575 else if (pars_num == 0 && *p == sep)
1576 break;
1577 if (pars_num == 0 && ISSPACE ((int) *p))
1578 n_spaces++;
1579 else
1581 for (; n_spaces != 0; n_spaces--)
1582 obstack_1grow (&irp, p [-n_spaces]);
1583 obstack_1grow (&irp, *p);
1586 obstack_1grow (&irp, '\0');
1587 out_str = obstack_base (&irp);
1588 obstack_finish (&irp);
1590 *pstr = p;
1591 if (**pstr == sep)
1592 (*pstr)++;
1594 return out_str;
1597 /* Given a string and a separator, return the number of separated
1598 elements in it, taking parentheses into account if PAR_FLAG has
1599 nonzero value. Return 0 for the null string, -1 if parentheses is
1600 not balanced. */
1601 static int
1602 n_sep_els (char *s, int sep, int par_flag)
1604 int n;
1605 int pars_num;
1607 if (*s == '\0')
1608 return 0;
1610 for (pars_num = 0, n = 1; *s; s++)
1611 if (par_flag && *s == '(')
1612 pars_num++;
1613 else if (par_flag && *s == ')')
1614 pars_num--;
1615 else if (pars_num == 0 && *s == sep)
1616 n++;
1618 return (pars_num != 0 ? -1 : n);
1621 /* Given a string and a separator, return vector of strings which are
1622 elements in the string and number of elements through els_num.
1623 Take parentheses into account if PAREN_P has nonzero value. The
1624 function also inserts the end marker NULL at the end of vector.
1625 Return 0 for the null string, -1 if parentheses are not balanced. */
1626 static char **
1627 get_str_vect (char *str, int *els_num, int sep, int paren_p)
1629 int i;
1630 char **vect;
1631 char **pstr;
1632 char *trail;
1634 *els_num = n_sep_els (str, sep, paren_p);
1635 if (*els_num <= 0)
1636 return NULL;
1637 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1638 vect = (char **) obstack_base (&irp);
1639 obstack_finish (&irp);
1640 pstr = &str;
1641 for (i = 0; i < *els_num; i++)
1642 vect [i] = next_sep_el (pstr, sep, paren_p);
1643 trail = next_sep_el (pstr, sep, paren_p);
1644 gcc_assert (!trail);
1645 vect [i] = NULL;
1646 return vect;
1649 /* Process a DEFINE_CPU_UNIT.
1651 This gives information about a unit contained in CPU. We fill a
1652 struct unit_decl with information used later by `expand_automata'. */
1653 void
1654 gen_cpu_unit (rtx def)
1656 decl_t decl;
1657 char **str_cpu_units;
1658 int vect_length;
1659 int i;
1661 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1662 FALSE);
1663 if (str_cpu_units == NULL)
1664 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1665 for (i = 0; i < vect_length; i++)
1667 decl = create_node (sizeof (struct decl));
1668 decl->mode = dm_unit;
1669 decl->pos = 0;
1670 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1671 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1672 DECL_UNIT (decl)->query_p = 0;
1673 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1674 DECL_UNIT (decl)->in_set_p = 0;
1675 VLA_PTR_ADD (decls, decl);
1676 num_dfa_decls++;
1680 /* Process a DEFINE_QUERY_CPU_UNIT.
1682 This gives information about a unit contained in CPU. We fill a
1683 struct unit_decl with information used later by `expand_automata'. */
1684 void
1685 gen_query_cpu_unit (rtx def)
1687 decl_t decl;
1688 char **str_cpu_units;
1689 int vect_length;
1690 int i;
1692 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1693 FALSE);
1694 if (str_cpu_units == NULL)
1695 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1696 for (i = 0; i < vect_length; i++)
1698 decl = create_node (sizeof (struct decl));
1699 decl->mode = dm_unit;
1700 decl->pos = 0;
1701 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1702 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1703 DECL_UNIT (decl)->query_p = 1;
1704 VLA_PTR_ADD (decls, decl);
1705 num_dfa_decls++;
1709 /* Process a DEFINE_BYPASS.
1711 This gives information about a unit contained in the CPU. We fill
1712 in a struct bypass_decl with information used later by
1713 `expand_automata'. */
1714 void
1715 gen_bypass (rtx def)
1717 decl_t decl;
1718 char **out_insns;
1719 int out_length;
1720 char **in_insns;
1721 int in_length;
1722 int i, j;
1724 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1725 if (out_insns == NULL)
1726 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1727 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1728 if (in_insns == NULL)
1729 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1730 for (i = 0; i < out_length; i++)
1731 for (j = 0; j < in_length; j++)
1733 decl = create_node (sizeof (struct decl));
1734 decl->mode = dm_bypass;
1735 decl->pos = 0;
1736 DECL_BYPASS (decl)->latency = XINT (def, 0);
1737 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1738 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1739 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1740 VLA_PTR_ADD (decls, decl);
1741 num_dfa_decls++;
1745 /* Process an EXCLUSION_SET.
1747 This gives information about a cpu unit conflicts. We fill a
1748 struct excl_rel_decl (excl) with information used later by
1749 `expand_automata'. */
1750 void
1751 gen_excl_set (rtx def)
1753 decl_t decl;
1754 char **first_str_cpu_units;
1755 char **second_str_cpu_units;
1756 int first_vect_length;
1757 int length;
1758 int i;
1760 first_str_cpu_units
1761 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1762 if (first_str_cpu_units == NULL)
1763 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1764 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1765 FALSE);
1766 if (second_str_cpu_units == NULL)
1767 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1768 length += first_vect_length;
1769 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1770 decl->mode = dm_excl;
1771 decl->pos = 0;
1772 DECL_EXCL (decl)->all_names_num = length;
1773 DECL_EXCL (decl)->first_list_length = first_vect_length;
1774 for (i = 0; i < length; i++)
1775 if (i < first_vect_length)
1776 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1777 else
1778 DECL_EXCL (decl)->names [i]
1779 = second_str_cpu_units [i - first_vect_length];
1780 VLA_PTR_ADD (decls, decl);
1781 num_dfa_decls++;
1784 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1785 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1787 This gives information about a cpu unit reservation requirements.
1788 We fill a struct unit_pattern_rel_decl with information used later
1789 by `expand_automata'. */
1790 static void
1791 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1793 decl_t decl;
1794 char **str_cpu_units;
1795 char ***str_patterns;
1796 int cpu_units_length;
1797 int length;
1798 int patterns_length;
1799 int i;
1801 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1802 FALSE);
1803 if (str_cpu_units == NULL)
1804 fatal ((presence_p
1805 ? (final_p
1806 ? "invalid first string `%s' in final_presence_set"
1807 : "invalid first string `%s' in presence_set")
1808 : (final_p
1809 ? "invalid first string `%s' in final_absence_set"
1810 : "invalid first string `%s' in absence_set")),
1811 XSTR (def, 0));
1812 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1813 &patterns_length, ',', FALSE);
1814 if (str_patterns == NULL)
1815 fatal ((presence_p
1816 ? (final_p
1817 ? "invalid second string `%s' in final_presence_set"
1818 : "invalid second string `%s' in presence_set")
1819 : (final_p
1820 ? "invalid second string `%s' in final_absence_set"
1821 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1822 for (i = 0; i < patterns_length; i++)
1824 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1825 FALSE);
1826 gcc_assert (str_patterns [i]);
1828 decl = create_node (sizeof (struct decl));
1829 decl->pos = 0;
1830 if (presence_p)
1832 decl->mode = dm_presence;
1833 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1834 DECL_PRESENCE (decl)->names = str_cpu_units;
1835 DECL_PRESENCE (decl)->patterns = str_patterns;
1836 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1837 DECL_PRESENCE (decl)->final_p = final_p;
1839 else
1841 decl->mode = dm_absence;
1842 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1843 DECL_ABSENCE (decl)->names = str_cpu_units;
1844 DECL_ABSENCE (decl)->patterns = str_patterns;
1845 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1846 DECL_ABSENCE (decl)->final_p = final_p;
1848 VLA_PTR_ADD (decls, decl);
1849 num_dfa_decls++;
1852 /* Process a PRESENCE_SET.
1854 This gives information about a cpu unit reservation requirements.
1855 We fill a struct unit_pattern_rel_decl (presence) with information
1856 used later by `expand_automata'. */
1857 void
1858 gen_presence_set (rtx def)
1860 gen_presence_absence_set (def, TRUE, FALSE);
1863 /* Process a FINAL_PRESENCE_SET.
1865 This gives information about a cpu unit reservation requirements.
1866 We fill a struct unit_pattern_rel_decl (presence) with information
1867 used later by `expand_automata'. */
1868 void
1869 gen_final_presence_set (rtx def)
1871 gen_presence_absence_set (def, TRUE, TRUE);
1874 /* Process an ABSENCE_SET.
1876 This gives information about a cpu unit reservation requirements.
1877 We fill a struct unit_pattern_rel_decl (absence) with information
1878 used later by `expand_automata'. */
1879 void
1880 gen_absence_set (rtx def)
1882 gen_presence_absence_set (def, FALSE, FALSE);
1885 /* Process a FINAL_ABSENCE_SET.
1887 This gives information about a cpu unit reservation requirements.
1888 We fill a struct unit_pattern_rel_decl (absence) with information
1889 used later by `expand_automata'. */
1890 void
1891 gen_final_absence_set (rtx def)
1893 gen_presence_absence_set (def, FALSE, TRUE);
1896 /* Process a DEFINE_AUTOMATON.
1898 This gives information about a finite state automaton used for
1899 recognizing pipeline hazards. We fill a struct automaton_decl
1900 with information used later by `expand_automata'. */
1901 void
1902 gen_automaton (rtx def)
1904 decl_t decl;
1905 char **str_automata;
1906 int vect_length;
1907 int i;
1909 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1910 FALSE);
1911 if (str_automata == NULL)
1912 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1913 for (i = 0; i < vect_length; i++)
1915 decl = create_node (sizeof (struct decl));
1916 decl->mode = dm_automaton;
1917 decl->pos = 0;
1918 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1919 VLA_PTR_ADD (decls, decl);
1920 num_dfa_decls++;
1924 /* Process an AUTOMATA_OPTION.
1926 This gives information how to generate finite state automaton used
1927 for recognizing pipeline hazards. */
1928 void
1929 gen_automata_option (rtx def)
1931 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1932 no_minimization_flag = 1;
1933 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1934 time_flag = 1;
1935 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1936 v_flag = 1;
1937 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1938 w_flag = 1;
1939 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1940 ndfa_flag = 1;
1941 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1942 progress_flag = 1;
1943 else
1944 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1947 /* Name in reservation to denote absence reservation. */
1948 #define NOTHING_NAME "nothing"
1950 /* The following string contains original reservation string being
1951 parsed. */
1952 static char *reserv_str;
1954 /* Parse an element in STR. */
1955 static regexp_t
1956 gen_regexp_el (char *str)
1958 regexp_t regexp;
1959 int len;
1961 if (*str == '(')
1963 len = strlen (str);
1964 if (str [len - 1] != ')')
1965 fatal ("garbage after ) in reservation `%s'", reserv_str);
1966 str [len - 1] = '\0';
1967 regexp = gen_regexp_sequence (str + 1);
1969 else if (strcmp (str, NOTHING_NAME) == 0)
1971 regexp = create_node (sizeof (struct decl));
1972 regexp->mode = rm_nothing;
1974 else
1976 regexp = create_node (sizeof (struct decl));
1977 regexp->mode = rm_unit;
1978 REGEXP_UNIT (regexp)->name = str;
1980 return regexp;
1983 /* Parse construction `repeat' in STR. */
1984 static regexp_t
1985 gen_regexp_repeat (char *str)
1987 regexp_t regexp;
1988 regexp_t repeat;
1989 char **repeat_vect;
1990 int els_num;
1991 int i;
1993 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1994 if (repeat_vect == NULL)
1995 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1996 if (els_num > 1)
1998 regexp = gen_regexp_el (repeat_vect [0]);
1999 for (i = 1; i < els_num; i++)
2001 repeat = create_node (sizeof (struct regexp));
2002 repeat->mode = rm_repeat;
2003 REGEXP_REPEAT (repeat)->regexp = regexp;
2004 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
2005 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
2006 fatal ("repetition `%s' <= 1 in reservation `%s'",
2007 str, reserv_str);
2008 regexp = repeat;
2010 return regexp;
2012 else
2013 return gen_regexp_el (str);
2016 /* Parse reservation STR which possibly contains separator '+'. */
2017 static regexp_t
2018 gen_regexp_allof (char *str)
2020 regexp_t allof;
2021 char **allof_vect;
2022 int els_num;
2023 int i;
2025 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
2026 if (allof_vect == NULL)
2027 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2028 if (els_num > 1)
2030 allof = create_node (sizeof (struct regexp)
2031 + sizeof (regexp_t) * (els_num - 1));
2032 allof->mode = rm_allof;
2033 REGEXP_ALLOF (allof)->regexps_num = els_num;
2034 for (i = 0; i < els_num; i++)
2035 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2036 return allof;
2038 else
2039 return gen_regexp_repeat (str);
2042 /* Parse reservation STR which possibly contains separator '|'. */
2043 static regexp_t
2044 gen_regexp_oneof (char *str)
2046 regexp_t oneof;
2047 char **oneof_vect;
2048 int els_num;
2049 int i;
2051 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
2052 if (oneof_vect == NULL)
2053 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2054 if (els_num > 1)
2056 oneof = create_node (sizeof (struct regexp)
2057 + sizeof (regexp_t) * (els_num - 1));
2058 oneof->mode = rm_oneof;
2059 REGEXP_ONEOF (oneof)->regexps_num = els_num;
2060 for (i = 0; i < els_num; i++)
2061 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2062 return oneof;
2064 else
2065 return gen_regexp_allof (str);
2068 /* Parse reservation STR which possibly contains separator ','. */
2069 static regexp_t
2070 gen_regexp_sequence (char *str)
2072 regexp_t sequence;
2073 char **sequence_vect;
2074 int els_num;
2075 int i;
2077 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
2078 if (els_num > 1)
2080 sequence = create_node (sizeof (struct regexp)
2081 + sizeof (regexp_t) * (els_num - 1));
2082 sequence->mode = rm_sequence;
2083 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
2084 for (i = 0; i < els_num; i++)
2085 REGEXP_SEQUENCE (sequence)->regexps [i]
2086 = gen_regexp_oneof (sequence_vect [i]);
2087 return sequence;
2089 else
2090 return gen_regexp_oneof (str);
2093 /* Parse construction reservation STR. */
2094 static regexp_t
2095 gen_regexp (char *str)
2097 reserv_str = str;
2098 return gen_regexp_sequence (str);;
2101 /* Process a DEFINE_RESERVATION.
2103 This gives information about a reservation of cpu units. We fill
2104 in a struct reserv_decl with information used later by
2105 `expand_automata'. */
2106 void
2107 gen_reserv (rtx def)
2109 decl_t decl;
2111 decl = create_node (sizeof (struct decl));
2112 decl->mode = dm_reserv;
2113 decl->pos = 0;
2114 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
2115 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2116 VLA_PTR_ADD (decls, decl);
2117 num_dfa_decls++;
2120 /* Process a DEFINE_INSN_RESERVATION.
2122 This gives information about the reservation of cpu units by an
2123 insn. We fill a struct insn_reserv_decl with information used
2124 later by `expand_automata'. */
2125 void
2126 gen_insn_reserv (rtx def)
2128 decl_t decl;
2130 decl = create_node (sizeof (struct decl));
2131 decl->mode = dm_insn_reserv;
2132 decl->pos = 0;
2133 DECL_INSN_RESERV (decl)->name
2134 = check_name ((char *) XSTR (def, 0), decl->pos);
2135 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2136 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2137 DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
2138 VLA_PTR_ADD (decls, decl);
2139 num_dfa_decls++;
2144 /* The function evaluates hash value (0..UINT_MAX) of string. */
2145 static unsigned
2146 string_hash (const char *string)
2148 unsigned result, i;
2150 for (result = i = 0;*string++ != '\0'; i++)
2151 result += ((unsigned char) *string << (i % CHAR_BIT));
2152 return result;
2157 /* This page contains abstract data `table of automaton declarations'.
2158 Elements of the table is nodes representing automaton declarations.
2159 Key of the table elements is name of given automaton. Remember
2160 that automaton names have own space. */
2162 /* The function evaluates hash value of an automaton declaration. The
2163 function is used by abstract data `hashtab'. The function returns
2164 hash value (0..UINT_MAX) of given automaton declaration. */
2165 static hashval_t
2166 automaton_decl_hash (const void *automaton_decl)
2168 const decl_t decl = (decl_t) automaton_decl;
2170 gcc_assert (decl->mode != dm_automaton
2171 || DECL_AUTOMATON (decl)->name);
2172 return string_hash (DECL_AUTOMATON (decl)->name);
2175 /* The function tests automaton declarations on equality of their
2176 keys. The function is used by abstract data `hashtab'. The
2177 function returns 1 if the declarations have the same key, 0
2178 otherwise. */
2179 static int
2180 automaton_decl_eq_p (const void* automaton_decl_1,
2181 const void* automaton_decl_2)
2183 const decl_t decl1 = (decl_t) automaton_decl_1;
2184 const decl_t decl2 = (decl_t) automaton_decl_2;
2186 gcc_assert (decl1->mode == dm_automaton
2187 && DECL_AUTOMATON (decl1)->name
2188 && decl2->mode == dm_automaton
2189 && DECL_AUTOMATON (decl2)->name);
2190 return strcmp (DECL_AUTOMATON (decl1)->name,
2191 DECL_AUTOMATON (decl2)->name) == 0;
2194 /* The automaton declaration table itself is represented by the
2195 following variable. */
2196 static htab_t automaton_decl_table;
2198 /* The function inserts automaton declaration into the table. The
2199 function does nothing if an automaton declaration with the same key
2200 exists already in the table. The function returns automaton
2201 declaration node in the table with the same key as given automaton
2202 declaration node. */
2203 static decl_t
2204 insert_automaton_decl (decl_t automaton_decl)
2206 void **entry_ptr;
2208 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2209 if (*entry_ptr == NULL)
2210 *entry_ptr = (void *) automaton_decl;
2211 return (decl_t) *entry_ptr;
2214 /* The following variable value is node representing automaton
2215 declaration. The node used for searching automaton declaration
2216 with given name. */
2217 static struct decl work_automaton_decl;
2219 /* The function searches for automaton declaration in the table with
2220 the same key as node representing name of the automaton
2221 declaration. The function returns node found in the table, NULL if
2222 such node does not exist in the table. */
2223 static decl_t
2224 find_automaton_decl (char *name)
2226 void *entry;
2228 work_automaton_decl.mode = dm_automaton;
2229 DECL_AUTOMATON (&work_automaton_decl)->name = name;
2230 entry = htab_find (automaton_decl_table, &work_automaton_decl);
2231 return (decl_t) entry;
2234 /* The function creates empty automaton declaration table and node
2235 representing automaton declaration and used for searching automaton
2236 declaration with given name. The function must be called only once
2237 before any work with the automaton declaration table. */
2238 static void
2239 initiate_automaton_decl_table (void)
2241 work_automaton_decl.mode = dm_automaton;
2242 automaton_decl_table = htab_create (10, automaton_decl_hash,
2243 automaton_decl_eq_p, (htab_del) 0);
2246 /* The function deletes the automaton declaration table. Only call of
2247 function `initiate_automaton_decl_table' is possible immediately
2248 after this function call. */
2249 static void
2250 finish_automaton_decl_table (void)
2252 htab_delete (automaton_decl_table);
2257 /* This page contains abstract data `table of insn declarations'.
2258 Elements of the table is nodes representing insn declarations. Key
2259 of the table elements is name of given insn (in corresponding
2260 define_insn_reservation). Remember that insn names have own
2261 space. */
2263 /* The function evaluates hash value of an insn declaration. The
2264 function is used by abstract data `hashtab'. The function returns
2265 hash value (0..UINT_MAX) of given insn declaration. */
2266 static hashval_t
2267 insn_decl_hash (const void *insn_decl)
2269 const decl_t decl = (decl_t) insn_decl;
2271 gcc_assert (decl->mode == dm_insn_reserv
2272 && DECL_INSN_RESERV (decl)->name);
2273 return string_hash (DECL_INSN_RESERV (decl)->name);
2276 /* The function tests insn declarations on equality of their keys.
2277 The function is used by abstract data `hashtab'. The function
2278 returns 1 if declarations have the same key, 0 otherwise. */
2279 static int
2280 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2282 const decl_t decl1 = (decl_t) insn_decl_1;
2283 const decl_t decl2 = (decl_t) insn_decl_2;
2285 gcc_assert (decl1->mode == dm_insn_reserv
2286 && DECL_INSN_RESERV (decl1)->name
2287 && decl2->mode == dm_insn_reserv
2288 && DECL_INSN_RESERV (decl2)->name);
2289 return strcmp (DECL_INSN_RESERV (decl1)->name,
2290 DECL_INSN_RESERV (decl2)->name) == 0;
2293 /* The insn declaration table itself is represented by the following
2294 variable. The table does not contain insn reservation
2295 declarations. */
2296 static htab_t insn_decl_table;
2298 /* The function inserts insn declaration into the table. The function
2299 does nothing if an insn declaration with the same key exists
2300 already in the table. The function returns insn declaration node
2301 in the table with the same key as given insn declaration node. */
2302 static decl_t
2303 insert_insn_decl (decl_t insn_decl)
2305 void **entry_ptr;
2307 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2308 if (*entry_ptr == NULL)
2309 *entry_ptr = (void *) insn_decl;
2310 return (decl_t) *entry_ptr;
2313 /* The following variable value is node representing insn reservation
2314 declaration. The node used for searching insn reservation
2315 declaration with given name. */
2316 static struct decl work_insn_decl;
2318 /* The function searches for insn reservation declaration in the table
2319 with the same key as node representing name of the insn reservation
2320 declaration. The function returns node found in the table, NULL if
2321 such node does not exist in the table. */
2322 static decl_t
2323 find_insn_decl (char *name)
2325 void *entry;
2327 work_insn_decl.mode = dm_insn_reserv;
2328 DECL_INSN_RESERV (&work_insn_decl)->name = name;
2329 entry = htab_find (insn_decl_table, &work_insn_decl);
2330 return (decl_t) entry;
2333 /* The function creates empty insn declaration table and node
2334 representing insn declaration and used for searching insn
2335 declaration with given name. The function must be called only once
2336 before any work with the insn declaration table. */
2337 static void
2338 initiate_insn_decl_table (void)
2340 work_insn_decl.mode = dm_insn_reserv;
2341 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2342 (htab_del) 0);
2345 /* The function deletes the insn declaration table. Only call of
2346 function `initiate_insn_decl_table' is possible immediately after
2347 this function call. */
2348 static void
2349 finish_insn_decl_table (void)
2351 htab_delete (insn_decl_table);
2356 /* This page contains abstract data `table of declarations'. Elements
2357 of the table is nodes representing declarations (of units and
2358 reservations). Key of the table elements is names of given
2359 declarations. */
2361 /* The function evaluates hash value of a declaration. The function
2362 is used by abstract data `hashtab'. The function returns hash
2363 value (0..UINT_MAX) of given declaration. */
2364 static hashval_t
2365 decl_hash (const void *decl)
2367 const decl_t d = (const decl_t) decl;
2369 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
2370 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
2371 return string_hash (d->mode == dm_unit
2372 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2375 /* The function tests declarations on equality of their keys. The
2376 function is used by abstract data 'hashtab'. The function
2377 returns 1 if the declarations have the same key, 0 otherwise. */
2378 static int
2379 decl_eq_p (const void *decl_1, const void *decl_2)
2381 const decl_t d1 = (const decl_t) decl_1;
2382 const decl_t d2 = (const decl_t) decl_2;
2384 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
2385 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
2386 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
2387 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
2388 return strcmp ((d1->mode == dm_unit
2389 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2390 (d2->mode == dm_unit
2391 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2394 /* The declaration table itself is represented by the following
2395 variable. */
2396 static htab_t decl_table;
2398 /* The function inserts declaration into the table. The function does
2399 nothing if a declaration with the same key exists already in the
2400 table. The function returns declaration node in the table with the
2401 same key as given declaration node. */
2403 static decl_t
2404 insert_decl (decl_t decl)
2406 void **entry_ptr;
2408 entry_ptr = htab_find_slot (decl_table, decl, 1);
2409 if (*entry_ptr == NULL)
2410 *entry_ptr = (void *) decl;
2411 return (decl_t) *entry_ptr;
2414 /* The following variable value is node representing declaration. The
2415 node used for searching declaration with given name. */
2416 static struct decl work_decl;
2418 /* The function searches for declaration in the table with the same
2419 key as node representing name of the declaration. The function
2420 returns node found in the table, NULL if such node does not exist
2421 in the table. */
2422 static decl_t
2423 find_decl (char *name)
2425 void *entry;
2427 work_decl.mode = dm_unit;
2428 DECL_UNIT (&work_decl)->name = name;
2429 entry = htab_find (decl_table, &work_decl);
2430 return (decl_t) entry;
2433 /* The function creates empty declaration table and node representing
2434 declaration and used for searching declaration with given name.
2435 The function must be called only once before any work with the
2436 declaration table. */
2437 static void
2438 initiate_decl_table (void)
2440 work_decl.mode = dm_unit;
2441 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2444 /* The function deletes the declaration table. Only call of function
2445 `initiate_declaration_table' is possible immediately after this
2446 function call. */
2447 static void
2448 finish_decl_table (void)
2450 htab_delete (decl_table);
2455 /* This page contains checker of pipeline hazard description. */
2457 /* Checking NAMES in an exclusion clause vector and returning formed
2458 unit_set_el_list. */
2459 static unit_set_el_t
2460 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2462 unit_set_el_t el_list;
2463 unit_set_el_t last_el;
2464 unit_set_el_t new_el;
2465 decl_t decl_in_table;
2466 int i;
2468 el_list = NULL;
2469 last_el = NULL;
2470 for (i = 0; i < num; i++)
2472 decl_in_table = find_decl (names [i]);
2473 if (decl_in_table == NULL)
2474 error ("unit `%s' in exclusion is not declared", names [i]);
2475 else if (decl_in_table->mode != dm_unit)
2476 error ("`%s' in exclusion is not unit", names [i]);
2477 else
2479 new_el = create_node (sizeof (struct unit_set_el));
2480 new_el->unit_decl = DECL_UNIT (decl_in_table);
2481 new_el->next_unit_set_el = NULL;
2482 if (last_el == NULL)
2483 el_list = last_el = new_el;
2484 else
2486 last_el->next_unit_set_el = new_el;
2487 last_el = last_el->next_unit_set_el;
2491 return el_list;
2494 /* The function adds each element from SOURCE_LIST to the exclusion
2495 list of the each element from DEST_LIST. Checking situation "unit
2496 excludes itself". */
2497 static void
2498 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2499 pos_t excl_pos ATTRIBUTE_UNUSED)
2501 unit_set_el_t dst;
2502 unit_set_el_t src;
2503 unit_set_el_t curr_el;
2504 unit_set_el_t prev_el;
2505 unit_set_el_t copy;
2507 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2508 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2510 if (dst->unit_decl == src->unit_decl)
2512 error ("unit `%s' excludes itself", src->unit_decl->name);
2513 continue;
2515 if (dst->unit_decl->automaton_name != NULL
2516 && src->unit_decl->automaton_name != NULL
2517 && strcmp (dst->unit_decl->automaton_name,
2518 src->unit_decl->automaton_name) != 0)
2520 error ("units `%s' and `%s' in exclusion set belong to different automata",
2521 src->unit_decl->name, dst->unit_decl->name);
2522 continue;
2524 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2525 curr_el != NULL;
2526 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2527 if (curr_el->unit_decl == src->unit_decl)
2528 break;
2529 if (curr_el == NULL)
2531 /* Element not found - insert. */
2532 copy = copy_node (src, sizeof (*src));
2533 copy->next_unit_set_el = NULL;
2534 if (prev_el == NULL)
2535 dst->unit_decl->excl_list = copy;
2536 else
2537 prev_el->next_unit_set_el = copy;
2542 /* Checking NAMES in presence/absence clause and returning the
2543 formed unit_set_el_list. The function is called only after
2544 processing all exclusion sets. */
2545 static unit_set_el_t
2546 process_presence_absence_names (char **names, int num,
2547 pos_t req_pos ATTRIBUTE_UNUSED,
2548 int presence_p, int final_p)
2550 unit_set_el_t el_list;
2551 unit_set_el_t last_el;
2552 unit_set_el_t new_el;
2553 decl_t decl_in_table;
2554 int i;
2556 el_list = NULL;
2557 last_el = NULL;
2558 for (i = 0; i < num; i++)
2560 decl_in_table = find_decl (names [i]);
2561 if (decl_in_table == NULL)
2562 error ((presence_p
2563 ? (final_p
2564 ? "unit `%s' in final presence set is not declared"
2565 : "unit `%s' in presence set is not declared")
2566 : (final_p
2567 ? "unit `%s' in final absence set is not declared"
2568 : "unit `%s' in absence set is not declared")), names [i]);
2569 else if (decl_in_table->mode != dm_unit)
2570 error ((presence_p
2571 ? (final_p
2572 ? "`%s' in final presence set is not unit"
2573 : "`%s' in presence set is not unit")
2574 : (final_p
2575 ? "`%s' in final absence set is not unit"
2576 : "`%s' in absence set is not unit")), names [i]);
2577 else
2579 new_el = create_node (sizeof (struct unit_set_el));
2580 new_el->unit_decl = DECL_UNIT (decl_in_table);
2581 new_el->next_unit_set_el = NULL;
2582 if (last_el == NULL)
2583 el_list = last_el = new_el;
2584 else
2586 last_el->next_unit_set_el = new_el;
2587 last_el = last_el->next_unit_set_el;
2591 return el_list;
2594 /* Checking NAMES in patterns of a presence/absence clause and
2595 returning the formed pattern_set_el_list. The function is called
2596 only after processing all exclusion sets. */
2597 static pattern_set_el_t
2598 process_presence_absence_patterns (char ***patterns, int num,
2599 pos_t req_pos ATTRIBUTE_UNUSED,
2600 int presence_p, int final_p)
2602 pattern_set_el_t el_list;
2603 pattern_set_el_t last_el;
2604 pattern_set_el_t new_el;
2605 decl_t decl_in_table;
2606 int i, j;
2608 el_list = NULL;
2609 last_el = NULL;
2610 for (i = 0; i < num; i++)
2612 for (j = 0; patterns [i] [j] != NULL; j++)
2614 new_el = create_node (sizeof (struct pattern_set_el)
2615 + sizeof (struct unit_decl *) * j);
2616 new_el->unit_decls
2617 = (struct unit_decl **) ((char *) new_el
2618 + sizeof (struct pattern_set_el));
2619 new_el->next_pattern_set_el = NULL;
2620 if (last_el == NULL)
2621 el_list = last_el = new_el;
2622 else
2624 last_el->next_pattern_set_el = new_el;
2625 last_el = last_el->next_pattern_set_el;
2627 new_el->units_num = 0;
2628 for (j = 0; patterns [i] [j] != NULL; j++)
2630 decl_in_table = find_decl (patterns [i] [j]);
2631 if (decl_in_table == NULL)
2632 error ((presence_p
2633 ? (final_p
2634 ? "unit `%s' in final presence set is not declared"
2635 : "unit `%s' in presence set is not declared")
2636 : (final_p
2637 ? "unit `%s' in final absence set is not declared"
2638 : "unit `%s' in absence set is not declared")),
2639 patterns [i] [j]);
2640 else if (decl_in_table->mode != dm_unit)
2641 error ((presence_p
2642 ? (final_p
2643 ? "`%s' in final presence set is not unit"
2644 : "`%s' in presence set is not unit")
2645 : (final_p
2646 ? "`%s' in final absence set is not unit"
2647 : "`%s' in absence set is not unit")),
2648 patterns [i] [j]);
2649 else
2651 new_el->unit_decls [new_el->units_num]
2652 = DECL_UNIT (decl_in_table);
2653 new_el->units_num++;
2657 return el_list;
2660 /* The function adds each element from PATTERN_LIST to presence (if
2661 PRESENCE_P) or absence list of the each element from DEST_LIST.
2662 Checking situations "unit requires own absence", and "unit excludes
2663 and requires presence of ...", "unit requires absence and presence
2664 of ...", "units in (final) presence set belong to different
2665 automata", and "units in (final) absence set belong to different
2666 automata". Remember that we process absence sets only after all
2667 presence sets. */
2668 static void
2669 add_presence_absence (unit_set_el_t dest_list,
2670 pattern_set_el_t pattern_list,
2671 pos_t req_pos ATTRIBUTE_UNUSED,
2672 int presence_p, int final_p)
2674 unit_set_el_t dst;
2675 pattern_set_el_t pat;
2676 struct unit_decl *unit;
2677 unit_set_el_t curr_excl_el;
2678 pattern_set_el_t curr_pat_el;
2679 pattern_set_el_t prev_el;
2680 pattern_set_el_t copy;
2681 int i;
2682 int no_error_flag;
2684 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2685 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2687 for (i = 0; i < pat->units_num; i++)
2689 unit = pat->unit_decls [i];
2690 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2692 error ("unit `%s' requires own absence", unit->name);
2693 continue;
2695 if (dst->unit_decl->automaton_name != NULL
2696 && unit->automaton_name != NULL
2697 && strcmp (dst->unit_decl->automaton_name,
2698 unit->automaton_name) != 0)
2700 error ((presence_p
2701 ? (final_p
2702 ? "units `%s' and `%s' in final presence set belong to different automata"
2703 : "units `%s' and `%s' in presence set belong to different automata")
2704 : (final_p
2705 ? "units `%s' and `%s' in final absence set belong to different automata"
2706 : "units `%s' and `%s' in absence set belong to different automata")),
2707 unit->name, dst->unit_decl->name);
2708 continue;
2710 no_error_flag = 1;
2711 if (presence_p)
2712 for (curr_excl_el = dst->unit_decl->excl_list;
2713 curr_excl_el != NULL;
2714 curr_excl_el = curr_excl_el->next_unit_set_el)
2716 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2718 if (!w_flag)
2720 error ("unit `%s' excludes and requires presence of `%s'",
2721 dst->unit_decl->name, unit->name);
2722 no_error_flag = 0;
2724 else
2725 warning
2726 ("unit `%s' excludes and requires presence of `%s'",
2727 dst->unit_decl->name, unit->name);
2730 else if (pat->units_num == 1)
2731 for (curr_pat_el = dst->unit_decl->presence_list;
2732 curr_pat_el != NULL;
2733 curr_pat_el = curr_pat_el->next_pattern_set_el)
2734 if (curr_pat_el->units_num == 1
2735 && unit == curr_pat_el->unit_decls [0])
2737 if (!w_flag)
2739 error
2740 ("unit `%s' requires absence and presence of `%s'",
2741 dst->unit_decl->name, unit->name);
2742 no_error_flag = 0;
2744 else
2745 warning
2746 ("unit `%s' requires absence and presence of `%s'",
2747 dst->unit_decl->name, unit->name);
2749 if (no_error_flag)
2751 for (prev_el = (presence_p
2752 ? (final_p
2753 ? dst->unit_decl->final_presence_list
2754 : dst->unit_decl->final_presence_list)
2755 : (final_p
2756 ? dst->unit_decl->final_absence_list
2757 : dst->unit_decl->absence_list));
2758 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2759 prev_el = prev_el->next_pattern_set_el)
2761 copy = copy_node (pat, sizeof (*pat));
2762 copy->next_pattern_set_el = NULL;
2763 if (prev_el == NULL)
2765 if (presence_p)
2767 if (final_p)
2768 dst->unit_decl->final_presence_list = copy;
2769 else
2770 dst->unit_decl->presence_list = copy;
2772 else if (final_p)
2773 dst->unit_decl->final_absence_list = copy;
2774 else
2775 dst->unit_decl->absence_list = copy;
2777 else
2778 prev_el->next_pattern_set_el = copy;
2785 /* The function searches for bypass with given IN_INSN_RESERV in given
2786 BYPASS_LIST. */
2787 static struct bypass_decl *
2788 find_bypass (struct bypass_decl *bypass_list,
2789 struct insn_reserv_decl *in_insn_reserv)
2791 struct bypass_decl *bypass;
2793 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2794 if (bypass->in_insn_reserv == in_insn_reserv)
2795 break;
2796 return bypass;
2799 /* The function processes pipeline description declarations, checks
2800 their correctness, and forms exclusion/presence/absence sets. */
2801 static void
2802 process_decls (void)
2804 decl_t decl;
2805 decl_t automaton_decl;
2806 decl_t decl_in_table;
2807 decl_t out_insn_reserv;
2808 decl_t in_insn_reserv;
2809 struct bypass_decl *bypass;
2810 int automaton_presence;
2811 int i;
2813 /* Checking repeated automata declarations. */
2814 automaton_presence = 0;
2815 for (i = 0; i < description->decls_num; i++)
2817 decl = description->decls [i];
2818 if (decl->mode == dm_automaton)
2820 automaton_presence = 1;
2821 decl_in_table = insert_automaton_decl (decl);
2822 if (decl_in_table != decl)
2824 if (!w_flag)
2825 error ("repeated declaration of automaton `%s'",
2826 DECL_AUTOMATON (decl)->name);
2827 else
2828 warning ("repeated declaration of automaton `%s'",
2829 DECL_AUTOMATON (decl)->name);
2833 /* Checking undeclared automata, repeated declarations (except for
2834 automata) and correctness of their attributes (insn latency times
2835 etc.). */
2836 for (i = 0; i < description->decls_num; i++)
2838 decl = description->decls [i];
2839 if (decl->mode == dm_insn_reserv)
2841 DECL_INSN_RESERV (decl)->condexp
2842 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2843 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2844 error ("define_insn_reservation `%s' has negative latency time",
2845 DECL_INSN_RESERV (decl)->name);
2846 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2847 description->insns_num++;
2848 decl_in_table = insert_insn_decl (decl);
2849 if (decl_in_table != decl)
2850 error ("`%s' is already used as insn reservation name",
2851 DECL_INSN_RESERV (decl)->name);
2853 else if (decl->mode == dm_bypass)
2855 if (DECL_BYPASS (decl)->latency < 0)
2856 error ("define_bypass `%s - %s' has negative latency time",
2857 DECL_BYPASS (decl)->out_insn_name,
2858 DECL_BYPASS (decl)->in_insn_name);
2860 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2862 if (decl->mode == dm_unit)
2864 DECL_UNIT (decl)->automaton_decl = NULL;
2865 if (DECL_UNIT (decl)->automaton_name != NULL)
2867 automaton_decl
2868 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2869 if (automaton_decl == NULL)
2870 error ("automaton `%s' is not declared",
2871 DECL_UNIT (decl)->automaton_name);
2872 else
2874 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2875 DECL_UNIT (decl)->automaton_decl
2876 = DECL_AUTOMATON (automaton_decl);
2879 else if (automaton_presence)
2880 error ("define_unit `%s' without automaton when one defined",
2881 DECL_UNIT (decl)->name);
2882 DECL_UNIT (decl)->unit_num = description->units_num;
2883 description->units_num++;
2884 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2886 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2887 continue;
2889 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2891 else
2893 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2895 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2896 continue;
2898 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2900 if (decl_in_table == NULL)
2901 decl_in_table = insert_decl (decl);
2902 else
2904 if (decl->mode == dm_unit)
2905 error ("repeated declaration of unit `%s'",
2906 DECL_UNIT (decl)->name);
2907 else
2908 error ("repeated declaration of reservation `%s'",
2909 DECL_RESERV (decl)->name);
2913 /* Check bypasses and form list of bypasses for each (output)
2914 insn. */
2915 for (i = 0; i < description->decls_num; i++)
2917 decl = description->decls [i];
2918 if (decl->mode == dm_bypass)
2920 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2921 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2922 if (out_insn_reserv == NULL)
2923 error ("there is no insn reservation `%s'",
2924 DECL_BYPASS (decl)->out_insn_name);
2925 else if (in_insn_reserv == NULL)
2926 error ("there is no insn reservation `%s'",
2927 DECL_BYPASS (decl)->in_insn_name);
2928 else
2930 DECL_BYPASS (decl)->out_insn_reserv
2931 = DECL_INSN_RESERV (out_insn_reserv);
2932 DECL_BYPASS (decl)->in_insn_reserv
2933 = DECL_INSN_RESERV (in_insn_reserv);
2934 bypass
2935 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2936 DECL_BYPASS (decl)->in_insn_reserv);
2937 if (bypass != NULL)
2939 if (DECL_BYPASS (decl)->latency == bypass->latency)
2941 if (!w_flag)
2942 error
2943 ("the same bypass `%s - %s' is already defined",
2944 DECL_BYPASS (decl)->out_insn_name,
2945 DECL_BYPASS (decl)->in_insn_name);
2946 else
2947 warning
2948 ("the same bypass `%s - %s' is already defined",
2949 DECL_BYPASS (decl)->out_insn_name,
2950 DECL_BYPASS (decl)->in_insn_name);
2952 else
2953 error ("bypass `%s - %s' is already defined",
2954 DECL_BYPASS (decl)->out_insn_name,
2955 DECL_BYPASS (decl)->in_insn_name);
2957 else
2959 DECL_BYPASS (decl)->next
2960 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2961 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2962 = DECL_BYPASS (decl);
2968 /* Check exclusion set declarations and form exclusion sets. */
2969 for (i = 0; i < description->decls_num; i++)
2971 decl = description->decls [i];
2972 if (decl->mode == dm_excl)
2974 unit_set_el_t unit_set_el_list;
2975 unit_set_el_t unit_set_el_list_2;
2977 unit_set_el_list
2978 = process_excls (DECL_EXCL (decl)->names,
2979 DECL_EXCL (decl)->first_list_length, decl->pos);
2980 unit_set_el_list_2
2981 = process_excls (&DECL_EXCL (decl)->names
2982 [DECL_EXCL (decl)->first_list_length],
2983 DECL_EXCL (decl)->all_names_num
2984 - DECL_EXCL (decl)->first_list_length,
2985 decl->pos);
2986 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2987 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2991 /* Check presence set declarations and form presence sets. */
2992 for (i = 0; i < description->decls_num; i++)
2994 decl = description->decls [i];
2995 if (decl->mode == dm_presence)
2997 unit_set_el_t unit_set_el_list;
2998 pattern_set_el_t pattern_set_el_list;
3000 unit_set_el_list
3001 = process_presence_absence_names
3002 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
3003 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3004 pattern_set_el_list
3005 = process_presence_absence_patterns
3006 (DECL_PRESENCE (decl)->patterns,
3007 DECL_PRESENCE (decl)->patterns_num,
3008 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3009 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3010 decl->pos, TRUE,
3011 DECL_PRESENCE (decl)->final_p);
3015 /* Check absence set declarations and form absence sets. */
3016 for (i = 0; i < description->decls_num; i++)
3018 decl = description->decls [i];
3019 if (decl->mode == dm_absence)
3021 unit_set_el_t unit_set_el_list;
3022 pattern_set_el_t pattern_set_el_list;
3024 unit_set_el_list
3025 = process_presence_absence_names
3026 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3027 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3028 pattern_set_el_list
3029 = process_presence_absence_patterns
3030 (DECL_ABSENCE (decl)->patterns,
3031 DECL_ABSENCE (decl)->patterns_num,
3032 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3033 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3034 decl->pos, FALSE,
3035 DECL_ABSENCE (decl)->final_p);
3040 /* The following function checks that declared automaton is used. If
3041 the automaton is not used, the function fixes error/warning. The
3042 following function must be called only after `process_decls'. */
3043 static void
3044 check_automaton_usage (void)
3046 decl_t decl;
3047 int i;
3049 for (i = 0; i < description->decls_num; i++)
3051 decl = description->decls [i];
3052 if (decl->mode == dm_automaton
3053 && !DECL_AUTOMATON (decl)->automaton_is_used)
3055 if (!w_flag)
3056 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3057 else
3058 warning ("automaton `%s' is not used",
3059 DECL_AUTOMATON (decl)->name);
3064 /* The following recursive function processes all regexp in order to
3065 fix usage of units or reservations and to fix errors of undeclared
3066 name. The function may change unit_regexp onto reserv_regexp.
3067 Remember that reserv_regexp does not exist before the function
3068 call. */
3069 static regexp_t
3070 process_regexp (regexp_t regexp)
3072 decl_t decl_in_table;
3073 regexp_t new_regexp;
3074 int i;
3076 switch (regexp->mode)
3078 case rm_unit:
3079 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3080 if (decl_in_table == NULL)
3081 error ("undeclared unit or reservation `%s'",
3082 REGEXP_UNIT (regexp)->name);
3083 else
3084 switch (decl_in_table->mode)
3086 case dm_unit:
3087 DECL_UNIT (decl_in_table)->unit_is_used = 1;
3088 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3089 break;
3091 case dm_reserv:
3092 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3093 new_regexp = create_node (sizeof (struct regexp));
3094 new_regexp->mode = rm_reserv;
3095 new_regexp->pos = regexp->pos;
3096 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3097 REGEXP_RESERV (new_regexp)->reserv_decl
3098 = DECL_RESERV (decl_in_table);
3099 regexp = new_regexp;
3100 break;
3102 default:
3103 gcc_unreachable ();
3105 break;
3106 case rm_sequence:
3107 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3108 REGEXP_SEQUENCE (regexp)->regexps [i]
3109 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3110 break;
3111 case rm_allof:
3112 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3113 REGEXP_ALLOF (regexp)->regexps [i]
3114 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3115 break;
3116 case rm_oneof:
3117 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3118 REGEXP_ONEOF (regexp)->regexps [i]
3119 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3120 break;
3121 case rm_repeat:
3122 REGEXP_REPEAT (regexp)->regexp
3123 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3124 break;
3125 case rm_nothing:
3126 break;
3127 default:
3128 gcc_unreachable ();
3130 return regexp;
3133 /* The following function processes regexp of define_reservation and
3134 define_insn_reservation with the aid of function
3135 `process_regexp'. */
3136 static void
3137 process_regexp_decls (void)
3139 decl_t decl;
3140 int i;
3142 for (i = 0; i < description->decls_num; i++)
3144 decl = description->decls [i];
3145 if (decl->mode == dm_reserv)
3146 DECL_RESERV (decl)->regexp
3147 = process_regexp (DECL_RESERV (decl)->regexp);
3148 else if (decl->mode == dm_insn_reserv)
3149 DECL_INSN_RESERV (decl)->regexp
3150 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3154 /* The following function checks that declared unit is used. If the
3155 unit is not used, the function fixes errors/warnings. The
3156 following function must be called only after `process_decls',
3157 `process_regexp_decls'. */
3158 static void
3159 check_usage (void)
3161 decl_t decl;
3162 int i;
3164 for (i = 0; i < description->decls_num; i++)
3166 decl = description->decls [i];
3167 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3169 if (!w_flag)
3170 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3171 else
3172 warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
3174 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3176 if (!w_flag)
3177 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3178 else
3179 warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3184 /* The following variable value is number of reservation being
3185 processed on loop recognition. */
3186 static int curr_loop_pass_num;
3188 /* The following recursive function returns nonzero value if REGEXP
3189 contains given decl or reservations in given regexp refers for
3190 given decl. */
3191 static int
3192 loop_in_regexp (regexp_t regexp, decl_t start_decl)
3194 int i;
3196 if (regexp == NULL)
3197 return 0;
3198 switch (regexp->mode)
3200 case rm_unit:
3201 return 0;
3203 case rm_reserv:
3204 if (start_decl->mode == dm_reserv
3205 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3206 return 1;
3207 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3208 == curr_loop_pass_num)
3209 /* declaration has been processed. */
3210 return 0;
3211 else
3213 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3214 = curr_loop_pass_num;
3215 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3216 start_decl);
3219 case rm_sequence:
3220 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3221 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3222 return 1;
3223 return 0;
3225 case rm_allof:
3226 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3227 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3228 return 1;
3229 return 0;
3231 case rm_oneof:
3232 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3233 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3234 return 1;
3235 return 0;
3237 case rm_repeat:
3238 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3240 case rm_nothing:
3241 return 0;
3243 default:
3244 gcc_unreachable ();
3248 /* The following function fixes errors "cycle in definition ...". The
3249 function uses function `loop_in_regexp' for that. */
3250 static void
3251 check_loops_in_regexps (void)
3253 decl_t decl;
3254 int i;
3256 for (i = 0; i < description->decls_num; i++)
3258 decl = description->decls [i];
3259 if (decl->mode == dm_reserv)
3260 DECL_RESERV (decl)->loop_pass_num = 0;
3262 for (i = 0; i < description->decls_num; i++)
3264 decl = description->decls [i];
3265 curr_loop_pass_num = i;
3267 if (decl->mode == dm_reserv)
3269 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3270 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3272 gcc_assert (DECL_RESERV (decl)->regexp);
3273 error ("cycle in definition of reservation `%s'",
3274 DECL_RESERV (decl)->name);
3280 /* The function recursively processes IR of reservation and defines
3281 max and min cycle for reservation of unit. */
3282 static void
3283 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3284 int min_start_cycle, int *max_finish_cycle,
3285 int *min_finish_cycle)
3287 int i;
3289 switch (regexp->mode)
3291 case rm_unit:
3292 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3293 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3294 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3295 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3296 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3297 *max_finish_cycle = max_start_cycle;
3298 *min_finish_cycle = min_start_cycle;
3299 break;
3301 case rm_reserv:
3302 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3303 max_start_cycle, min_start_cycle,
3304 max_finish_cycle, min_finish_cycle);
3305 break;
3307 case rm_repeat:
3308 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3310 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3311 max_start_cycle, min_start_cycle,
3312 max_finish_cycle, min_finish_cycle);
3313 max_start_cycle = *max_finish_cycle + 1;
3314 min_start_cycle = *min_finish_cycle + 1;
3316 break;
3318 case rm_sequence:
3319 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3321 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3322 max_start_cycle, min_start_cycle,
3323 max_finish_cycle, min_finish_cycle);
3324 max_start_cycle = *max_finish_cycle + 1;
3325 min_start_cycle = *min_finish_cycle + 1;
3327 break;
3329 case rm_allof:
3331 int max_cycle = 0;
3332 int min_cycle = 0;
3334 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3336 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3337 max_start_cycle, min_start_cycle,
3338 max_finish_cycle, min_finish_cycle);
3339 if (max_cycle < *max_finish_cycle)
3340 max_cycle = *max_finish_cycle;
3341 if (i == 0 || min_cycle > *min_finish_cycle)
3342 min_cycle = *min_finish_cycle;
3344 *max_finish_cycle = max_cycle;
3345 *min_finish_cycle = min_cycle;
3347 break;
3349 case rm_oneof:
3351 int max_cycle = 0;
3352 int min_cycle = 0;
3354 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3356 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3357 max_start_cycle, min_start_cycle,
3358 max_finish_cycle, min_finish_cycle);
3359 if (max_cycle < *max_finish_cycle)
3360 max_cycle = *max_finish_cycle;
3361 if (i == 0 || min_cycle > *min_finish_cycle)
3362 min_cycle = *min_finish_cycle;
3364 *max_finish_cycle = max_cycle;
3365 *min_finish_cycle = min_cycle;
3367 break;
3369 case rm_nothing:
3370 *max_finish_cycle = max_start_cycle;
3371 *min_finish_cycle = min_start_cycle;
3372 break;
3374 default:
3375 gcc_unreachable ();
3379 /* The following function is called only for correct program. The
3380 function defines max reservation of insns in cycles. */
3381 static void
3382 evaluate_max_reserv_cycles (void)
3384 int max_insn_cycles_num;
3385 int min_insn_cycles_num;
3386 decl_t decl;
3387 int i;
3389 description->max_insn_reserv_cycles = 0;
3390 for (i = 0; i < description->decls_num; i++)
3392 decl = description->decls [i];
3393 if (decl->mode == dm_insn_reserv)
3395 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3396 &max_insn_cycles_num, &min_insn_cycles_num);
3397 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3398 description->max_insn_reserv_cycles = max_insn_cycles_num;
3401 description->max_insn_reserv_cycles++;
3404 /* The following function calls functions for checking all
3405 description. */
3406 static void
3407 check_all_description (void)
3409 process_decls ();
3410 check_automaton_usage ();
3411 process_regexp_decls ();
3412 check_usage ();
3413 check_loops_in_regexps ();
3414 if (!have_error)
3415 evaluate_max_reserv_cycles ();
3420 /* The page contains abstract data `ticker'. This data is used to
3421 report time of different phases of building automata. It is
3422 possibly to write a description for which automata will be built
3423 during several minutes even on fast machine. */
3425 /* The following function creates ticker and makes it active. */
3426 static ticker_t
3427 create_ticker (void)
3429 ticker_t ticker;
3431 ticker.modified_creation_time = get_run_time ();
3432 ticker.incremented_off_time = 0;
3433 return ticker;
3436 /* The following function switches off given ticker. */
3437 static void
3438 ticker_off (ticker_t *ticker)
3440 if (ticker->incremented_off_time == 0)
3441 ticker->incremented_off_time = get_run_time () + 1;
3444 /* The following function switches on given ticker. */
3445 static void
3446 ticker_on (ticker_t *ticker)
3448 if (ticker->incremented_off_time != 0)
3450 ticker->modified_creation_time
3451 += get_run_time () - ticker->incremented_off_time + 1;
3452 ticker->incremented_off_time = 0;
3456 /* The following function returns current time in milliseconds since
3457 the moment when given ticker was created. */
3458 static int
3459 active_time (ticker_t ticker)
3461 if (ticker.incremented_off_time != 0)
3462 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3463 else
3464 return get_run_time () - ticker.modified_creation_time;
3467 /* The following function returns string representation of active time
3468 of given ticker. The result is string representation of seconds
3469 with accuracy of 1/100 second. Only result of the last call of the
3470 function exists. Therefore the following code is not correct
3472 printf ("parser time: %s\ngeneration time: %s\n",
3473 active_time_string (parser_ticker),
3474 active_time_string (generation_ticker));
3476 Correct code has to be the following
3478 printf ("parser time: %s\n", active_time_string (parser_ticker));
3479 printf ("generation time: %s\n",
3480 active_time_string (generation_ticker));
3483 static void
3484 print_active_time (FILE *f, ticker_t ticker)
3486 int msecs;
3488 msecs = active_time (ticker);
3489 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3494 /* The following variable value is number of automaton which are
3495 really being created. This value is defined on the base of
3496 argument of option `-split'. If the variable has zero value the
3497 number of automata is defined by the constructions `%automaton'.
3498 This case occurs when option `-split' is absent or has zero
3499 argument. If constructions `define_automaton' is absent only one
3500 automaton is created. */
3501 static int automata_num;
3503 /* The following variable values are times of
3504 o transformation of regular expressions
3505 o building NDFA (DFA if !ndfa_flag)
3506 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3507 o DFA minimization
3508 o building insn equivalence classes
3509 o all previous ones
3510 o code output */
3511 static ticker_t transform_time;
3512 static ticker_t NDFA_time;
3513 static ticker_t NDFA_to_DFA_time;
3514 static ticker_t minimize_time;
3515 static ticker_t equiv_time;
3516 static ticker_t automaton_generation_time;
3517 static ticker_t output_time;
3519 /* The following variable values are times of
3520 all checking
3521 all generation
3522 all pipeline hazard translator work */
3523 static ticker_t check_time;
3524 static ticker_t generation_time;
3525 static ticker_t all_time;
3529 /* Pseudo insn decl which denotes advancing cycle. */
3530 static decl_t advance_cycle_insn_decl;
3531 static void
3532 add_advance_cycle_insn_decl (void)
3534 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3535 advance_cycle_insn_decl->mode = dm_insn_reserv;
3536 advance_cycle_insn_decl->pos = no_pos;
3537 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3538 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
3539 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3540 = description->insns_num;
3541 description->decls [description->decls_num] = advance_cycle_insn_decl;
3542 description->decls_num++;
3543 description->insns_num++;
3544 num_dfa_decls++;
3548 /* Abstract data `alternative states' which represents
3549 nondeterministic nature of the description (see comments for
3550 structures alt_state and state). */
3552 /* List of free states. */
3553 static alt_state_t first_free_alt_state;
3555 #ifndef NDEBUG
3556 /* The following variables is maximal number of allocated nodes
3557 alt_state. */
3558 static int allocated_alt_states_num = 0;
3559 #endif
3561 /* The following function returns free node alt_state. It may be new
3562 allocated node or node freed earlier. */
3563 static alt_state_t
3564 get_free_alt_state (void)
3566 alt_state_t result;
3568 if (first_free_alt_state != NULL)
3570 result = first_free_alt_state;
3571 first_free_alt_state = first_free_alt_state->next_alt_state;
3573 else
3575 #ifndef NDEBUG
3576 allocated_alt_states_num++;
3577 #endif
3578 result = create_node (sizeof (struct alt_state));
3580 result->state = NULL;
3581 result->next_alt_state = NULL;
3582 result->next_sorted_alt_state = NULL;
3583 return result;
3586 /* The function frees node ALT_STATE. */
3587 static void
3588 free_alt_state (alt_state_t alt_state)
3590 if (alt_state == NULL)
3591 return;
3592 alt_state->next_alt_state = first_free_alt_state;
3593 first_free_alt_state = alt_state;
3596 /* The function frees list started with node ALT_STATE_LIST. */
3597 static void
3598 free_alt_states (alt_state_t alt_states_list)
3600 alt_state_t curr_alt_state;
3601 alt_state_t next_alt_state;
3603 for (curr_alt_state = alt_states_list;
3604 curr_alt_state != NULL;
3605 curr_alt_state = next_alt_state)
3607 next_alt_state = curr_alt_state->next_alt_state;
3608 free_alt_state (curr_alt_state);
3612 /* The function compares unique numbers of alt states. */
3613 static int
3614 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3616 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3617 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3618 return 0;
3619 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3620 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3621 return -1;
3622 else
3623 return 1;
3626 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3627 states from the list. The comparison key is alt state unique
3628 number. */
3629 static alt_state_t
3630 uniq_sort_alt_states (alt_state_t alt_states_list)
3632 alt_state_t curr_alt_state;
3633 vla_ptr_t alt_states;
3634 size_t i;
3635 size_t prev_unique_state_ind;
3636 alt_state_t result;
3637 alt_state_t *result_ptr;
3639 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3640 for (curr_alt_state = alt_states_list;
3641 curr_alt_state != NULL;
3642 curr_alt_state = curr_alt_state->next_alt_state)
3643 VLA_PTR_ADD (alt_states, curr_alt_state);
3644 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3645 sizeof (alt_state_t), alt_state_cmp);
3646 if (VLA_PTR_LENGTH (alt_states) == 0)
3647 result = NULL;
3648 else
3650 result_ptr = VLA_PTR_BEGIN (alt_states);
3651 prev_unique_state_ind = 0;
3652 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3653 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3655 prev_unique_state_ind++;
3656 result_ptr [prev_unique_state_ind] = result_ptr [i];
3658 #if 0
3659 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3660 free_alt_state (result_ptr [i]);
3661 #endif
3662 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3663 result_ptr = VLA_PTR_BEGIN (alt_states);
3664 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3665 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3666 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3667 result = *result_ptr;
3669 VLA_PTR_DELETE (alt_states);
3670 return result;
3673 /* The function checks equality of alt state lists. Remember that the
3674 lists must be already sorted by the previous function. */
3675 static int
3676 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3678 while (alt_states_1 != NULL && alt_states_2 != NULL
3679 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3681 alt_states_1 = alt_states_1->next_sorted_alt_state;
3682 alt_states_2 = alt_states_2->next_sorted_alt_state;
3684 return alt_states_1 == alt_states_2;
3687 /* Initialization of the abstract data. */
3688 static void
3689 initiate_alt_states (void)
3691 first_free_alt_state = NULL;
3694 /* Finishing work with the abstract data. */
3695 static void
3696 finish_alt_states (void)
3702 /* The page contains macros for work with bits strings. We could use
3703 standard gcc bitmap or sbitmap but it would result in difficulties
3704 of building canadian cross. */
3706 /* Set bit number bitno in the bit string. The macro is not side
3707 effect proof. */
3708 #define SET_BIT(bitstring, bitno) \
3709 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3711 #define CLEAR_BIT(bitstring, bitno) \
3712 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3714 /* Test if bit number bitno in the bitstring is set. The macro is not
3715 side effect proof. */
3716 #define TEST_BIT(bitstring, bitno) \
3717 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3721 /* This page contains abstract data `state'. */
3723 /* Maximal length of reservations in cycles (>= 1). */
3724 static int max_cycles_num;
3726 /* Number of set elements (see type set_el_t) needed for
3727 representation of one cycle reservation. It is depended on units
3728 number. */
3729 static int els_in_cycle_reserv;
3731 /* Number of set elements (see type set_el_t) needed for
3732 representation of maximal length reservation. Deterministic
3733 reservation is stored as set (bit string) of length equal to the
3734 variable value * number of bits in set_el_t. */
3735 static int els_in_reservs;
3737 /* VLA for representation of array of pointers to unit
3738 declarations. */
3739 static vla_ptr_t units_container;
3741 /* The start address of the array. */
3742 static unit_decl_t *units_array;
3744 /* Temporary reservation of maximal length. */
3745 static reserv_sets_t temp_reserv;
3747 /* The state table itself is represented by the following variable. */
3748 static htab_t state_table;
3750 /* VLA for representation of array of pointers to free nodes
3751 `state'. */
3752 static vla_ptr_t free_states;
3754 static int curr_unique_state_num;
3756 #ifndef NDEBUG
3757 /* The following variables is maximal number of allocated nodes
3758 `state'. */
3759 static int allocated_states_num = 0;
3760 #endif
3762 /* Allocate new reservation set. */
3763 static reserv_sets_t
3764 alloc_empty_reserv_sets (void)
3766 reserv_sets_t result;
3768 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3769 result = (reserv_sets_t) obstack_base (&irp);
3770 obstack_finish (&irp);
3771 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3772 return result;
3775 /* Hash value of reservation set. */
3776 static unsigned
3777 reserv_sets_hash_value (reserv_sets_t reservs)
3779 set_el_t hash_value;
3780 unsigned result;
3781 int reservs_num, i;
3782 set_el_t *reserv_ptr;
3784 hash_value = 0;
3785 reservs_num = els_in_reservs;
3786 reserv_ptr = reservs;
3787 i = 0;
3788 while (reservs_num != 0)
3790 reservs_num--;
3791 hash_value += ((*reserv_ptr >> i)
3792 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3793 i++;
3794 if (i == sizeof (set_el_t) * CHAR_BIT)
3795 i = 0;
3796 reserv_ptr++;
3798 if (sizeof (set_el_t) <= sizeof (unsigned))
3799 return hash_value;
3800 result = 0;
3801 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3803 result += (unsigned) hash_value;
3804 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3806 return result;
3809 /* Comparison of given reservation sets. */
3810 static int
3811 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3813 int reservs_num;
3814 set_el_t *reserv_ptr_1;
3815 set_el_t *reserv_ptr_2;
3817 gcc_assert (reservs_1 && reservs_2);
3818 reservs_num = els_in_reservs;
3819 reserv_ptr_1 = reservs_1;
3820 reserv_ptr_2 = reservs_2;
3821 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3823 reservs_num--;
3824 reserv_ptr_1++;
3825 reserv_ptr_2++;
3827 if (reservs_num == 0)
3828 return 0;
3829 else if (*reserv_ptr_1 < *reserv_ptr_2)
3830 return -1;
3831 else
3832 return 1;
3835 /* The function checks equality of the reservation sets. */
3836 static int
3837 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3839 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3842 /* Set up in the reservation set that unit with UNIT_NUM is used on
3843 CYCLE_NUM. */
3844 static void
3845 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3847 gcc_assert (cycle_num < max_cycles_num);
3848 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3849 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3852 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3853 used on CYCLE_NUM. */
3854 static int
3855 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3857 gcc_assert (cycle_num < max_cycles_num);
3858 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3859 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3862 /* The function checks that the reservation set represents no one unit
3863 reservation. */
3864 static int
3865 it_is_empty_reserv_sets (reserv_sets_t operand)
3867 set_el_t *reserv_ptr;
3868 int reservs_num;
3870 gcc_assert (operand);
3871 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3872 reservs_num != 0;
3873 reserv_ptr++, reservs_num--)
3874 if (*reserv_ptr != 0)
3875 return 0;
3876 return 1;
3879 /* The function checks that the reservation sets are intersected,
3880 i.e. there is a unit reservation on a cycle in both reservation
3881 sets. */
3882 static int
3883 reserv_sets_are_intersected (reserv_sets_t operand_1,
3884 reserv_sets_t operand_2)
3886 set_el_t *el_ptr_1;
3887 set_el_t *el_ptr_2;
3888 set_el_t *cycle_ptr_1;
3889 set_el_t *cycle_ptr_2;
3891 gcc_assert (operand_1 && operand_2);
3892 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3893 el_ptr_1 < operand_1 + els_in_reservs;
3894 el_ptr_1++, el_ptr_2++)
3895 if (*el_ptr_1 & *el_ptr_2)
3896 return 1;
3897 reserv_sets_or (temp_reserv, operand_1, operand_2);
3898 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3899 cycle_ptr_1 < operand_1 + els_in_reservs;
3900 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3902 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3903 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3904 el_ptr_1++, el_ptr_2++)
3905 if (*el_ptr_1 & *el_ptr_2)
3906 return 1;
3907 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3908 return 1;
3909 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3910 - operand_2),
3911 cycle_ptr_2, TRUE))
3912 return 1;
3913 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3914 return 1;
3915 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3916 cycle_ptr_2, TRUE))
3917 return 1;
3919 return 0;
3922 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3923 cpu cycle. The remaining bits of OPERAND (representing the last
3924 cycle unit reservations) are not changed. */
3925 static void
3926 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3928 int i;
3930 gcc_assert (result && operand && result != operand);
3931 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3932 result [i - els_in_cycle_reserv] = operand [i];
3935 /* OR of the reservation sets. */
3936 static void
3937 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3938 reserv_sets_t operand_2)
3940 set_el_t *el_ptr_1;
3941 set_el_t *el_ptr_2;
3942 set_el_t *result_set_el_ptr;
3944 gcc_assert (result && operand_1 && operand_2);
3945 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3946 el_ptr_1 < operand_1 + els_in_reservs;
3947 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3948 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3951 /* AND of the reservation sets. */
3952 static void
3953 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3954 reserv_sets_t operand_2)
3956 set_el_t *el_ptr_1;
3957 set_el_t *el_ptr_2;
3958 set_el_t *result_set_el_ptr;
3960 gcc_assert (result && operand_1 && operand_2);
3961 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3962 el_ptr_1 < operand_1 + els_in_reservs;
3963 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3964 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3967 /* The function outputs string representation of units reservation on
3968 cycle START_CYCLE in the reservation set. The function uses repeat
3969 construction if REPETITION_NUM > 1. */
3970 static void
3971 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3972 int repetition_num)
3974 int unit_num;
3975 int reserved_units_num;
3977 reserved_units_num = 0;
3978 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3979 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3980 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3981 reserved_units_num++;
3982 gcc_assert (repetition_num > 0);
3983 if (repetition_num != 1 && reserved_units_num > 1)
3984 fprintf (f, "(");
3985 reserved_units_num = 0;
3986 for (unit_num = 0;
3987 unit_num < description->units_num;
3988 unit_num++)
3989 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3990 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3992 if (reserved_units_num != 0)
3993 fprintf (f, "+");
3994 reserved_units_num++;
3995 fprintf (f, "%s", units_array [unit_num]->name);
3997 if (reserved_units_num == 0)
3998 fprintf (f, NOTHING_NAME);
3999 gcc_assert (repetition_num > 0);
4000 if (repetition_num != 1 && reserved_units_num > 1)
4001 fprintf (f, ")");
4002 if (repetition_num != 1)
4003 fprintf (f, "*%d", repetition_num);
4006 /* The function outputs string representation of units reservation in
4007 the reservation set. */
4008 static void
4009 output_reserv_sets (FILE *f, reserv_sets_t reservs)
4011 int start_cycle = 0;
4012 int cycle;
4013 int repetition_num;
4015 repetition_num = 0;
4016 for (cycle = 0; cycle < max_cycles_num; cycle++)
4017 if (repetition_num == 0)
4019 repetition_num++;
4020 start_cycle = cycle;
4022 else if (memcmp
4023 ((char *) reservs + start_cycle * els_in_cycle_reserv
4024 * sizeof (set_el_t),
4025 (char *) reservs + cycle * els_in_cycle_reserv
4026 * sizeof (set_el_t),
4027 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
4028 repetition_num++;
4029 else
4031 if (start_cycle != 0)
4032 fprintf (f, ", ");
4033 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4034 repetition_num = 1;
4035 start_cycle = cycle;
4037 if (start_cycle < max_cycles_num)
4039 if (start_cycle != 0)
4040 fprintf (f, ", ");
4041 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4045 /* The following function returns free node state for AUTOMATON. It
4046 may be new allocated node or node freed earlier. The function also
4047 allocates reservation set if WITH_RESERVS has nonzero value. */
4048 static state_t
4049 get_free_state (int with_reservs, automaton_t automaton)
4051 state_t result;
4053 gcc_assert (max_cycles_num > 0 && automaton);
4054 if (VLA_PTR_LENGTH (free_states) != 0)
4056 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
4057 VLA_PTR_SHORTEN (free_states, 1);
4058 result->automaton = automaton;
4059 result->first_out_arc = NULL;
4060 result->it_was_placed_in_stack_for_NDFA_forming = 0;
4061 result->it_was_placed_in_stack_for_DFA_forming = 0;
4062 result->component_states = NULL;
4063 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4065 else
4067 #ifndef NDEBUG
4068 allocated_states_num++;
4069 #endif
4070 result = create_node (sizeof (struct state));
4071 result->automaton = automaton;
4072 result->first_out_arc = NULL;
4073 result->unique_num = curr_unique_state_num;
4074 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4075 curr_unique_state_num++;
4077 if (with_reservs)
4079 if (result->reservs == NULL)
4080 result->reservs = alloc_empty_reserv_sets ();
4081 else
4082 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
4084 return result;
4087 /* The function frees node STATE. */
4088 static void
4089 free_state (state_t state)
4091 free_alt_states (state->component_states);
4092 VLA_PTR_ADD (free_states, state);
4095 /* Hash value of STATE. If STATE represents deterministic state it is
4096 simply hash value of the corresponding reservation set. Otherwise
4097 it is formed from hash values of the component deterministic
4098 states. One more key is order number of state automaton. */
4099 static hashval_t
4100 state_hash (const void *state)
4102 unsigned int hash_value;
4103 alt_state_t alt_state;
4105 if (((state_t) state)->component_states == NULL)
4106 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4107 else
4109 hash_value = 0;
4110 for (alt_state = ((state_t) state)->component_states;
4111 alt_state != NULL;
4112 alt_state = alt_state->next_sorted_alt_state)
4113 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4114 | (hash_value << CHAR_BIT))
4115 + alt_state->state->unique_num);
4117 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4118 | (hash_value << CHAR_BIT))
4119 + ((state_t) state)->automaton->automaton_order_num);
4120 return hash_value;
4123 /* Return nonzero value if the states are the same. */
4124 static int
4125 state_eq_p (const void *state_1, const void *state_2)
4127 alt_state_t alt_state_1;
4128 alt_state_t alt_state_2;
4130 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4131 return 0;
4132 else if (((state_t) state_1)->component_states == NULL
4133 && ((state_t) state_2)->component_states == NULL)
4134 return reserv_sets_eq (((state_t) state_1)->reservs,
4135 ((state_t) state_2)->reservs);
4136 else if (((state_t) state_1)->component_states != NULL
4137 && ((state_t) state_2)->component_states != NULL)
4139 for (alt_state_1 = ((state_t) state_1)->component_states,
4140 alt_state_2 = ((state_t) state_2)->component_states;
4141 alt_state_1 != NULL && alt_state_2 != NULL;
4142 alt_state_1 = alt_state_1->next_sorted_alt_state,
4143 alt_state_2 = alt_state_2->next_sorted_alt_state)
4144 /* All state in the list must be already in the hash table.
4145 Also the lists must be sorted. */
4146 if (alt_state_1->state != alt_state_2->state)
4147 return 0;
4148 return alt_state_1 == alt_state_2;
4150 else
4151 return 0;
4154 /* Insert STATE into the state table. */
4155 static state_t
4156 insert_state (state_t state)
4158 void **entry_ptr;
4160 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4161 if (*entry_ptr == NULL)
4162 *entry_ptr = (void *) state;
4163 return (state_t) *entry_ptr;
4166 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4167 deterministic STATE. */
4168 static void
4169 set_state_reserv (state_t state, int cycle_num, int unit_num)
4171 set_unit_reserv (state->reservs, cycle_num, unit_num);
4174 /* Return nonzero value if the deterministic states contains a
4175 reservation of the same cpu unit on the same cpu cycle. */
4176 static int
4177 intersected_state_reservs_p (state_t state1, state_t state2)
4179 gcc_assert (state1->automaton == state2->automaton);
4180 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4183 /* Return deterministic state (inserted into the table) which
4184 representing the automaton state which is union of reservations of
4185 the deterministic states masked by RESERVS. */
4186 static state_t
4187 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4189 state_t result;
4190 state_t state_in_table;
4192 gcc_assert (state1->automaton == state2->automaton);
4193 result = get_free_state (1, state1->automaton);
4194 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4195 reserv_sets_and (result->reservs, result->reservs, reservs);
4196 state_in_table = insert_state (result);
4197 if (result != state_in_table)
4199 free_state (result);
4200 result = state_in_table;
4202 return result;
4205 /* Return deterministic state (inserted into the table) which
4206 represent the automaton state is obtained from deterministic STATE
4207 by advancing cpu cycle and masking by RESERVS. */
4208 static state_t
4209 state_shift (state_t state, reserv_sets_t reservs)
4211 state_t result;
4212 state_t state_in_table;
4214 result = get_free_state (1, state->automaton);
4215 reserv_sets_shift (result->reservs, state->reservs);
4216 reserv_sets_and (result->reservs, result->reservs, reservs);
4217 state_in_table = insert_state (result);
4218 if (result != state_in_table)
4220 free_state (result);
4221 result = state_in_table;
4223 return result;
4226 /* Initialization of the abstract data. */
4227 static void
4228 initiate_states (void)
4230 decl_t decl;
4231 int i;
4233 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
4234 units_array
4235 = (description->decls_num && description->units_num
4236 ? VLA_PTR_BEGIN (units_container) : NULL);
4237 for (i = 0; i < description->decls_num; i++)
4239 decl = description->decls [i];
4240 if (decl->mode == dm_unit)
4241 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4243 max_cycles_num = description->max_insn_reserv_cycles;
4244 els_in_cycle_reserv
4245 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4246 / (sizeof (set_el_t) * CHAR_BIT));
4247 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4248 curr_unique_state_num = 0;
4249 initiate_alt_states ();
4250 VLA_PTR_CREATE (free_states, 1500, "free states");
4251 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4252 temp_reserv = alloc_empty_reserv_sets ();
4255 /* Finishing work with the abstract data. */
4256 static void
4257 finish_states (void)
4259 VLA_PTR_DELETE (units_container);
4260 htab_delete (state_table);
4261 VLA_PTR_DELETE (free_states);
4262 finish_alt_states ();
4267 /* Abstract data `arcs'. */
4269 /* List of free arcs. */
4270 static arc_t first_free_arc;
4272 #ifndef NDEBUG
4273 /* The following variables is maximal number of allocated nodes
4274 `arc'. */
4275 static int allocated_arcs_num = 0;
4276 #endif
4278 /* The function frees node ARC. */
4279 static void
4280 free_arc (arc_t arc)
4282 arc->next_out_arc = first_free_arc;
4283 first_free_arc = arc;
4286 /* The function removes and frees ARC staring from FROM_STATE. */
4287 static void
4288 remove_arc (state_t from_state, arc_t arc)
4290 arc_t prev_arc;
4291 arc_t curr_arc;
4293 gcc_assert (arc);
4294 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4295 curr_arc != NULL;
4296 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4297 if (curr_arc == arc)
4298 break;
4299 gcc_assert (curr_arc);
4300 if (prev_arc == NULL)
4301 from_state->first_out_arc = arc->next_out_arc;
4302 else
4303 prev_arc->next_out_arc = arc->next_out_arc;
4304 free_arc (arc);
4307 /* The functions returns arc with given characteristics (or NULL if
4308 the arc does not exist). */
4309 static arc_t
4310 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4312 arc_t arc;
4314 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4315 if (arc->to_state == to_state && arc->insn == insn)
4316 return arc;
4317 return NULL;
4320 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4321 and with given STATE_ALTS. The function returns added arc (or
4322 already existing arc). */
4323 static arc_t
4324 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4325 int state_alts)
4327 arc_t new_arc;
4329 new_arc = find_arc (from_state, to_state, ainsn);
4330 if (new_arc != NULL)
4331 return new_arc;
4332 if (first_free_arc == NULL)
4334 #ifndef NDEBUG
4335 allocated_arcs_num++;
4336 #endif
4337 new_arc = create_node (sizeof (struct arc));
4338 new_arc->to_state = NULL;
4339 new_arc->insn = NULL;
4340 new_arc->next_out_arc = NULL;
4342 else
4344 new_arc = first_free_arc;
4345 first_free_arc = first_free_arc->next_out_arc;
4347 new_arc->to_state = to_state;
4348 new_arc->insn = ainsn;
4349 ainsn->arc_exists_p = 1;
4350 new_arc->next_out_arc = from_state->first_out_arc;
4351 from_state->first_out_arc = new_arc;
4352 new_arc->next_arc_marked_by_insn = NULL;
4353 new_arc->state_alts = state_alts;
4354 return new_arc;
4357 /* The function returns the first arc starting from STATE. */
4358 static arc_t
4359 first_out_arc (state_t state)
4361 return state->first_out_arc;
4364 /* The function returns next out arc after ARC. */
4365 static arc_t
4366 next_out_arc (arc_t arc)
4368 return arc->next_out_arc;
4371 /* Initialization of the abstract data. */
4372 static void
4373 initiate_arcs (void)
4375 first_free_arc = NULL;
4378 /* Finishing work with the abstract data. */
4379 static void
4380 finish_arcs (void)
4386 /* Abstract data `automata lists'. */
4388 /* List of free states. */
4389 static automata_list_el_t first_free_automata_list_el;
4391 /* The list being formed. */
4392 static automata_list_el_t current_automata_list;
4394 /* Hash table of automata lists. */
4395 static htab_t automata_list_table;
4397 /* The following function returns free automata list el. It may be
4398 new allocated node or node freed earlier. */
4399 static automata_list_el_t
4400 get_free_automata_list_el (void)
4402 automata_list_el_t result;
4404 if (first_free_automata_list_el != NULL)
4406 result = first_free_automata_list_el;
4407 first_free_automata_list_el
4408 = first_free_automata_list_el->next_automata_list_el;
4410 else
4411 result = create_node (sizeof (struct automata_list_el));
4412 result->automaton = NULL;
4413 result->next_automata_list_el = NULL;
4414 return result;
4417 /* The function frees node AUTOMATA_LIST_EL. */
4418 static void
4419 free_automata_list_el (automata_list_el_t automata_list_el)
4421 if (automata_list_el == NULL)
4422 return;
4423 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4424 first_free_automata_list_el = automata_list_el;
4427 /* The function frees list AUTOMATA_LIST. */
4428 static void
4429 free_automata_list (automata_list_el_t automata_list)
4431 automata_list_el_t curr_automata_list_el;
4432 automata_list_el_t next_automata_list_el;
4434 for (curr_automata_list_el = automata_list;
4435 curr_automata_list_el != NULL;
4436 curr_automata_list_el = next_automata_list_el)
4438 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4439 free_automata_list_el (curr_automata_list_el);
4443 /* Hash value of AUTOMATA_LIST. */
4444 static hashval_t
4445 automata_list_hash (const void *automata_list)
4447 unsigned int hash_value;
4448 automata_list_el_t curr_automata_list_el;
4450 hash_value = 0;
4451 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4452 curr_automata_list_el != NULL;
4453 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4454 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4455 | (hash_value << CHAR_BIT))
4456 + curr_automata_list_el->automaton->automaton_order_num);
4457 return hash_value;
4460 /* Return nonzero value if the automata_lists are the same. */
4461 static int
4462 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4464 automata_list_el_t automata_list_el_1;
4465 automata_list_el_t automata_list_el_2;
4467 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4468 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4469 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4470 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4471 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4472 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4473 return 0;
4474 return automata_list_el_1 == automata_list_el_2;
4477 /* Initialization of the abstract data. */
4478 static void
4479 initiate_automata_lists (void)
4481 first_free_automata_list_el = NULL;
4482 automata_list_table = htab_create (1500, automata_list_hash,
4483 automata_list_eq_p, (htab_del) 0);
4486 /* The following function starts new automata list and makes it the
4487 current one. */
4488 static void
4489 automata_list_start (void)
4491 current_automata_list = NULL;
4494 /* The following function adds AUTOMATON to the current list. */
4495 static void
4496 automata_list_add (automaton_t automaton)
4498 automata_list_el_t el;
4500 el = get_free_automata_list_el ();
4501 el->automaton = automaton;
4502 el->next_automata_list_el = current_automata_list;
4503 current_automata_list = el;
4506 /* The following function finishes forming the current list, inserts
4507 it into the table and returns it. */
4508 static automata_list_el_t
4509 automata_list_finish (void)
4511 void **entry_ptr;
4513 if (current_automata_list == NULL)
4514 return NULL;
4515 entry_ptr = htab_find_slot (automata_list_table,
4516 (void *) current_automata_list, 1);
4517 if (*entry_ptr == NULL)
4518 *entry_ptr = (void *) current_automata_list;
4519 else
4520 free_automata_list (current_automata_list);
4521 current_automata_list = NULL;
4522 return (automata_list_el_t) *entry_ptr;
4525 /* Finishing work with the abstract data. */
4526 static void
4527 finish_automata_lists (void)
4529 htab_delete (automata_list_table);
4534 /* The page contains abstract data for work with exclusion sets (see
4535 exclusion_set in file rtl.def). */
4537 /* The following variable refers to an exclusion set returned by
4538 get_excl_set. This is bit string of length equal to cpu units
4539 number. If exclusion set for given unit contains 1 for a unit,
4540 then simultaneous reservation of the units is prohibited. */
4541 static reserv_sets_t excl_set;
4543 /* The array contains exclusion sets for each unit. */
4544 static reserv_sets_t *unit_excl_set_table;
4546 /* The following function forms the array containing exclusion sets
4547 for each unit. */
4548 static void
4549 initiate_excl_sets (void)
4551 decl_t decl;
4552 reserv_sets_t unit_excl_set;
4553 unit_set_el_t el;
4554 int i;
4556 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4557 excl_set = (reserv_sets_t) obstack_base (&irp);
4558 obstack_finish (&irp);
4559 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4560 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4561 obstack_finish (&irp);
4562 /* Evaluate unit exclusion sets. */
4563 for (i = 0; i < description->decls_num; i++)
4565 decl = description->decls [i];
4566 if (decl->mode == dm_unit)
4568 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4569 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4570 obstack_finish (&irp);
4571 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4572 for (el = DECL_UNIT (decl)->excl_list;
4573 el != NULL;
4574 el = el->next_unit_set_el)
4576 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4577 el->unit_decl->in_set_p = TRUE;
4579 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4584 /* The function sets up and return EXCL_SET which is union of
4585 exclusion sets for each unit in IN_SET. */
4586 static reserv_sets_t
4587 get_excl_set (reserv_sets_t in_set)
4589 int excl_char_num;
4590 int chars_num;
4591 int i;
4592 int start_unit_num;
4593 int unit_num;
4595 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4596 memset (excl_set, 0, chars_num);
4597 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4598 if (((unsigned char *) in_set) [excl_char_num])
4599 for (i = CHAR_BIT - 1; i >= 0; i--)
4600 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4602 start_unit_num = excl_char_num * CHAR_BIT + i;
4603 if (start_unit_num >= description->units_num)
4604 return excl_set;
4605 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4607 excl_set [unit_num]
4608 |= unit_excl_set_table [start_unit_num] [unit_num];
4611 return excl_set;
4616 /* The page contains abstract data for work with presence/absence
4617 pattern sets (see presence_set/absence_set in file rtl.def). */
4619 /* The following arrays contain correspondingly presence, final
4620 presence, absence, and final absence patterns for each unit. */
4621 static pattern_reserv_t *unit_presence_set_table;
4622 static pattern_reserv_t *unit_final_presence_set_table;
4623 static pattern_reserv_t *unit_absence_set_table;
4624 static pattern_reserv_t *unit_final_absence_set_table;
4626 /* The following function forms list of reservation sets for given
4627 PATTERN_LIST. */
4628 static pattern_reserv_t
4629 form_reserv_sets_list (pattern_set_el_t pattern_list)
4631 pattern_set_el_t el;
4632 pattern_reserv_t first, curr, prev;
4633 int i;
4635 prev = first = NULL;
4636 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4638 curr = create_node (sizeof (struct pattern_reserv));
4639 curr->reserv = alloc_empty_reserv_sets ();
4640 curr->next_pattern_reserv = NULL;
4641 for (i = 0; i < el->units_num; i++)
4643 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4644 el->unit_decls [i]->in_set_p = TRUE;
4646 if (prev != NULL)
4647 prev->next_pattern_reserv = curr;
4648 else
4649 first = curr;
4650 prev = curr;
4652 return first;
4655 /* The following function forms the array containing presence and
4656 absence pattern sets for each unit. */
4657 static void
4658 initiate_presence_absence_pattern_sets (void)
4660 decl_t decl;
4661 int i;
4663 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4664 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4665 obstack_finish (&irp);
4666 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4667 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4668 obstack_finish (&irp);
4669 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4670 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4671 obstack_finish (&irp);
4672 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4673 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4674 obstack_finish (&irp);
4675 /* Evaluate unit presence/absence sets. */
4676 for (i = 0; i < description->decls_num; i++)
4678 decl = description->decls [i];
4679 if (decl->mode == dm_unit)
4681 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4682 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4683 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4684 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4685 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4686 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4687 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4688 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4693 /* The function checks that CHECKED_SET satisfies all presence pattern
4694 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4695 is ok. */
4696 static int
4697 check_presence_pattern_sets (reserv_sets_t checked_set,
4698 reserv_sets_t origional_set,
4699 int final_p)
4701 int char_num;
4702 int chars_num;
4703 int i;
4704 int start_unit_num;
4705 int unit_num;
4706 int presence_p;
4707 pattern_reserv_t pat_reserv;
4709 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4710 for (char_num = 0; char_num < chars_num; char_num++)
4711 if (((unsigned char *) origional_set) [char_num])
4712 for (i = CHAR_BIT - 1; i >= 0; i--)
4713 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4715 start_unit_num = char_num * CHAR_BIT + i;
4716 if (start_unit_num >= description->units_num)
4717 break;
4718 if ((final_p
4719 && unit_final_presence_set_table [start_unit_num] == NULL)
4720 || (!final_p
4721 && unit_presence_set_table [start_unit_num] == NULL))
4722 continue;
4723 presence_p = FALSE;
4724 for (pat_reserv = (final_p
4725 ? unit_final_presence_set_table [start_unit_num]
4726 : unit_presence_set_table [start_unit_num]);
4727 pat_reserv != NULL;
4728 pat_reserv = pat_reserv->next_pattern_reserv)
4730 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4731 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4732 != pat_reserv->reserv [unit_num])
4733 break;
4734 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4736 if (!presence_p)
4737 return FALSE;
4739 return TRUE;
4742 /* The function checks that CHECKED_SET satisfies all absence pattern
4743 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4744 is ok. */
4745 static int
4746 check_absence_pattern_sets (reserv_sets_t checked_set,
4747 reserv_sets_t origional_set,
4748 int final_p)
4750 int char_num;
4751 int chars_num;
4752 int i;
4753 int start_unit_num;
4754 int unit_num;
4755 pattern_reserv_t pat_reserv;
4757 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4758 for (char_num = 0; char_num < chars_num; char_num++)
4759 if (((unsigned char *) origional_set) [char_num])
4760 for (i = CHAR_BIT - 1; i >= 0; i--)
4761 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4763 start_unit_num = char_num * CHAR_BIT + i;
4764 if (start_unit_num >= description->units_num)
4765 break;
4766 for (pat_reserv = (final_p
4767 ? unit_final_absence_set_table [start_unit_num]
4768 : unit_absence_set_table [start_unit_num]);
4769 pat_reserv != NULL;
4770 pat_reserv = pat_reserv->next_pattern_reserv)
4772 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4773 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4774 != pat_reserv->reserv [unit_num]
4775 && pat_reserv->reserv [unit_num])
4776 break;
4777 if (unit_num >= els_in_cycle_reserv)
4778 return FALSE;
4781 return TRUE;
4786 /* This page contains code for transformation of original reservations
4787 described in .md file. The main goal of transformations is
4788 simplifying reservation and lifting up all `|' on the top of IR
4789 reservation representation. */
4792 /* The following function makes copy of IR representation of
4793 reservation. The function also substitutes all reservations
4794 defined by define_reservation by corresponding value during making
4795 the copy. */
4796 static regexp_t
4797 copy_insn_regexp (regexp_t regexp)
4799 regexp_t result;
4800 int i;
4802 switch (regexp->mode)
4804 case rm_reserv:
4805 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4806 break;
4808 case rm_unit:
4809 result = copy_node (regexp, sizeof (struct regexp));
4810 break;
4812 case rm_repeat:
4813 result = copy_node (regexp, sizeof (struct regexp));
4814 REGEXP_REPEAT (result)->regexp
4815 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4816 break;
4818 case rm_sequence:
4819 result = copy_node (regexp,
4820 sizeof (struct regexp) + sizeof (regexp_t)
4821 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4822 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4823 REGEXP_SEQUENCE (result)->regexps [i]
4824 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4825 break;
4827 case rm_allof:
4828 result = copy_node (regexp,
4829 sizeof (struct regexp) + sizeof (regexp_t)
4830 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4831 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4832 REGEXP_ALLOF (result)->regexps [i]
4833 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4834 break;
4836 case rm_oneof:
4837 result = copy_node (regexp,
4838 sizeof (struct regexp) + sizeof (regexp_t)
4839 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4840 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4841 REGEXP_ONEOF (result)->regexps [i]
4842 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4843 break;
4845 case rm_nothing:
4846 result = copy_node (regexp, sizeof (struct regexp));
4847 break;
4849 default:
4850 gcc_unreachable ();
4852 return result;
4855 /* The following variable is set up 1 if a transformation has been
4856 applied. */
4857 static int regexp_transformed_p;
4859 /* The function makes transformation
4860 A*N -> A, A, ... */
4861 static regexp_t
4862 transform_1 (regexp_t regexp)
4864 int i;
4865 int repeat_num;
4866 regexp_t operand;
4867 pos_t pos;
4869 if (regexp->mode == rm_repeat)
4871 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4872 gcc_assert (repeat_num > 1);
4873 operand = REGEXP_REPEAT (regexp)->regexp;
4874 pos = regexp->mode;
4875 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4876 * (repeat_num - 1));
4877 regexp->mode = rm_sequence;
4878 regexp->pos = pos;
4879 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4880 for (i = 0; i < repeat_num; i++)
4881 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4882 regexp_transformed_p = 1;
4884 return regexp;
4887 /* The function makes transformations
4888 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4889 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4890 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4891 static regexp_t
4892 transform_2 (regexp_t regexp)
4894 if (regexp->mode == rm_sequence)
4896 regexp_t sequence = NULL;
4897 regexp_t result;
4898 int sequence_index = 0;
4899 int i, j;
4901 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4902 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4904 sequence_index = i;
4905 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4906 break;
4908 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4910 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4911 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4912 result = create_node (sizeof (struct regexp)
4913 + sizeof (regexp_t)
4914 * (REGEXP_SEQUENCE (regexp)->regexps_num
4915 + REGEXP_SEQUENCE (sequence)->regexps_num
4916 - 2));
4917 result->mode = rm_sequence;
4918 result->pos = regexp->pos;
4919 REGEXP_SEQUENCE (result)->regexps_num
4920 = (REGEXP_SEQUENCE (regexp)->regexps_num
4921 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4922 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4923 if (i < sequence_index)
4924 REGEXP_SEQUENCE (result)->regexps [i]
4925 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4926 else if (i > sequence_index)
4927 REGEXP_SEQUENCE (result)->regexps
4928 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4929 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4930 else
4931 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4932 REGEXP_SEQUENCE (result)->regexps [i + j]
4933 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4934 regexp_transformed_p = 1;
4935 regexp = result;
4938 else if (regexp->mode == rm_allof)
4940 regexp_t allof = NULL;
4941 regexp_t result;
4942 int allof_index = 0;
4943 int i, j;
4945 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4946 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4948 allof_index = i;
4949 allof = REGEXP_ALLOF (regexp)->regexps [i];
4950 break;
4952 if (i < REGEXP_ALLOF (regexp)->regexps_num)
4954 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4955 && REGEXP_ALLOF (regexp)->regexps_num > 1);
4956 result = create_node (sizeof (struct regexp)
4957 + sizeof (regexp_t)
4958 * (REGEXP_ALLOF (regexp)->regexps_num
4959 + REGEXP_ALLOF (allof)->regexps_num - 2));
4960 result->mode = rm_allof;
4961 result->pos = regexp->pos;
4962 REGEXP_ALLOF (result)->regexps_num
4963 = (REGEXP_ALLOF (regexp)->regexps_num
4964 + REGEXP_ALLOF (allof)->regexps_num - 1);
4965 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4966 if (i < allof_index)
4967 REGEXP_ALLOF (result)->regexps [i]
4968 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4969 else if (i > allof_index)
4970 REGEXP_ALLOF (result)->regexps
4971 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4972 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4973 else
4974 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4975 REGEXP_ALLOF (result)->regexps [i + j]
4976 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4977 regexp_transformed_p = 1;
4978 regexp = result;
4981 else if (regexp->mode == rm_oneof)
4983 regexp_t oneof = NULL;
4984 regexp_t result;
4985 int oneof_index = 0;
4986 int i, j;
4988 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4989 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4991 oneof_index = i;
4992 oneof = REGEXP_ONEOF (regexp)->regexps [i];
4993 break;
4995 if (i < REGEXP_ONEOF (regexp)->regexps_num)
4997 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4998 && REGEXP_ONEOF (regexp)->regexps_num > 1);
4999 result = create_node (sizeof (struct regexp)
5000 + sizeof (regexp_t)
5001 * (REGEXP_ONEOF (regexp)->regexps_num
5002 + REGEXP_ONEOF (oneof)->regexps_num - 2));
5003 result->mode = rm_oneof;
5004 result->pos = regexp->pos;
5005 REGEXP_ONEOF (result)->regexps_num
5006 = (REGEXP_ONEOF (regexp)->regexps_num
5007 + REGEXP_ONEOF (oneof)->regexps_num - 1);
5008 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5009 if (i < oneof_index)
5010 REGEXP_ONEOF (result)->regexps [i]
5011 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5012 else if (i > oneof_index)
5013 REGEXP_ONEOF (result)->regexps
5014 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
5015 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5016 else
5017 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
5018 REGEXP_ONEOF (result)->regexps [i + j]
5019 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
5020 regexp_transformed_p = 1;
5021 regexp = result;
5024 return regexp;
5027 /* The function makes transformations
5028 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
5029 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
5030 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
5031 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
5032 static regexp_t
5033 transform_3 (regexp_t regexp)
5035 if (regexp->mode == rm_sequence)
5037 regexp_t oneof = NULL;
5038 int oneof_index = 0;
5039 regexp_t result;
5040 regexp_t sequence;
5041 int i, j;
5043 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5044 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
5046 oneof_index = i;
5047 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
5048 break;
5050 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
5052 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5053 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
5054 result = create_node (sizeof (struct regexp)
5055 + sizeof (regexp_t)
5056 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5057 result->mode = rm_oneof;
5058 result->pos = regexp->pos;
5059 REGEXP_ONEOF (result)->regexps_num
5060 = REGEXP_ONEOF (oneof)->regexps_num;
5061 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5063 sequence
5064 = create_node (sizeof (struct regexp)
5065 + sizeof (regexp_t)
5066 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
5067 sequence->mode = rm_sequence;
5068 sequence->pos = regexp->pos;
5069 REGEXP_SEQUENCE (sequence)->regexps_num
5070 = REGEXP_SEQUENCE (regexp)->regexps_num;
5071 REGEXP_ONEOF (result)->regexps [i] = sequence;
5072 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
5073 if (j != oneof_index)
5074 REGEXP_SEQUENCE (sequence)->regexps [j]
5075 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
5076 else
5077 REGEXP_SEQUENCE (sequence)->regexps [j]
5078 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5080 regexp_transformed_p = 1;
5081 regexp = result;
5084 else if (regexp->mode == rm_allof)
5086 regexp_t oneof = NULL;
5087 regexp_t seq;
5088 int oneof_index = 0;
5089 int max_seq_length, allof_length;
5090 regexp_t result;
5091 regexp_t allof = NULL;
5092 regexp_t allof_op = NULL;
5093 int i, j;
5095 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5096 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
5098 oneof_index = i;
5099 oneof = REGEXP_ALLOF (regexp)->regexps [i];
5100 break;
5102 if (i < REGEXP_ALLOF (regexp)->regexps_num)
5104 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5105 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5106 result = create_node (sizeof (struct regexp)
5107 + sizeof (regexp_t)
5108 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5109 result->mode = rm_oneof;
5110 result->pos = regexp->pos;
5111 REGEXP_ONEOF (result)->regexps_num
5112 = REGEXP_ONEOF (oneof)->regexps_num;
5113 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5115 allof
5116 = create_node (sizeof (struct regexp)
5117 + sizeof (regexp_t)
5118 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5119 allof->mode = rm_allof;
5120 allof->pos = regexp->pos;
5121 REGEXP_ALLOF (allof)->regexps_num
5122 = REGEXP_ALLOF (regexp)->regexps_num;
5123 REGEXP_ONEOF (result)->regexps [i] = allof;
5124 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5125 if (j != oneof_index)
5126 REGEXP_ALLOF (allof)->regexps [j]
5127 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5128 else
5129 REGEXP_ALLOF (allof)->regexps [j]
5130 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5132 regexp_transformed_p = 1;
5133 regexp = result;
5135 max_seq_length = 0;
5136 if (regexp->mode == rm_allof)
5137 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5139 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
5141 case rm_sequence:
5142 seq = REGEXP_ALLOF (regexp)->regexps [i];
5143 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5144 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5145 break;
5147 case rm_unit:
5148 case rm_nothing:
5149 break;
5151 default:
5152 max_seq_length = 0;
5153 goto break_for;
5156 break_for:
5157 if (max_seq_length != 0)
5159 gcc_assert (max_seq_length != 1
5160 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5161 result = create_node (sizeof (struct regexp)
5162 + sizeof (regexp_t) * (max_seq_length - 1));
5163 result->mode = rm_sequence;
5164 result->pos = regexp->pos;
5165 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5166 for (i = 0; i < max_seq_length; i++)
5168 allof_length = 0;
5169 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5170 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
5172 case rm_sequence:
5173 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5174 ->regexps [j])->regexps_num))
5176 allof_op
5177 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5178 ->regexps [j])
5179 ->regexps [i]);
5180 allof_length++;
5182 break;
5183 case rm_unit:
5184 case rm_nothing:
5185 if (i == 0)
5187 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5188 allof_length++;
5190 break;
5191 default:
5192 break;
5195 if (allof_length == 1)
5196 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5197 else
5199 allof = create_node (sizeof (struct regexp)
5200 + sizeof (regexp_t)
5201 * (allof_length - 1));
5202 allof->mode = rm_allof;
5203 allof->pos = regexp->pos;
5204 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5205 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5206 allof_length = 0;
5207 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5208 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5209 && (i <
5210 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5211 ->regexps [j])->regexps_num)))
5213 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5214 ->regexps [j])
5215 ->regexps [i]);
5216 REGEXP_ALLOF (allof)->regexps [allof_length]
5217 = allof_op;
5218 allof_length++;
5220 else if (i == 0
5221 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5222 == rm_unit
5223 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5224 == rm_nothing)))
5226 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5227 REGEXP_ALLOF (allof)->regexps [allof_length]
5228 = allof_op;
5229 allof_length++;
5233 regexp_transformed_p = 1;
5234 regexp = result;
5237 return regexp;
5240 /* The function traverses IR of reservation and applies transformations
5241 implemented by FUNC. */
5242 static regexp_t
5243 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5245 int i;
5247 switch (regexp->mode)
5249 case rm_sequence:
5250 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5251 REGEXP_SEQUENCE (regexp)->regexps [i]
5252 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
5253 func);
5254 break;
5256 case rm_allof:
5257 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5258 REGEXP_ALLOF (regexp)->regexps [i]
5259 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5260 break;
5262 case rm_oneof:
5263 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5264 REGEXP_ONEOF (regexp)->regexps [i]
5265 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5266 break;
5268 case rm_repeat:
5269 REGEXP_REPEAT (regexp)->regexp
5270 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5271 break;
5273 case rm_nothing:
5274 case rm_unit:
5275 break;
5277 default:
5278 gcc_unreachable ();
5280 return (*func) (regexp);
5283 /* The function applies all transformations for IR representation of
5284 reservation REGEXP. */
5285 static regexp_t
5286 transform_regexp (regexp_t regexp)
5288 regexp = regexp_transform_func (regexp, transform_1);
5291 regexp_transformed_p = 0;
5292 regexp = regexp_transform_func (regexp, transform_2);
5293 regexp = regexp_transform_func (regexp, transform_3);
5295 while (regexp_transformed_p);
5296 return regexp;
5299 /* The function applies all transformations for reservations of all
5300 insn declarations. */
5301 static void
5302 transform_insn_regexps (void)
5304 decl_t decl;
5305 int i;
5307 transform_time = create_ticker ();
5308 add_advance_cycle_insn_decl ();
5309 if (progress_flag)
5310 fprintf (stderr, "Reservation transformation...");
5311 for (i = 0; i < description->decls_num; i++)
5313 decl = description->decls [i];
5314 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5315 DECL_INSN_RESERV (decl)->transformed_regexp
5316 = transform_regexp (copy_insn_regexp
5317 (DECL_INSN_RESERV (decl)->regexp));
5319 if (progress_flag)
5320 fprintf (stderr, "done\n");
5321 ticker_off (&transform_time);
5326 /* The following variable value is TRUE if the first annotated message
5327 about units to automata distribution has been output. */
5328 static int annotation_message_reported_p;
5330 /* The following structure describes usage of a unit in a reservation. */
5331 struct unit_usage
5333 unit_decl_t unit_decl;
5334 /* The following forms a list of units used on the same cycle in the
5335 same alternative. */
5336 struct unit_usage *next;
5339 /* Obstack for unit_usage structures. */
5340 static struct obstack unit_usages;
5342 /* VLA for representation of array of pointers to unit usage
5343 structures. There is an element for each combination of
5344 (alternative number, cycle). Unit usages on given cycle in
5345 alternative with given number are referred through element with
5346 index equals to the cycle * number of all alternatives in the regexp
5347 + the alternative number. */
5348 static vla_ptr_t cycle_alt_unit_usages;
5350 /* The following function creates the structure unit_usage for UNIT on
5351 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5352 accessed through cycle_alt_unit_usages. */
5353 static void
5354 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5355 int alt_num)
5357 size_t i, length, old_length;
5358 unit_decl_t unit_decl;
5359 struct unit_usage *unit_usage_ptr;
5360 int index;
5362 gcc_assert (regexp && regexp->mode == rm_oneof
5363 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
5364 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5365 old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
5366 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5367 if (old_length < length)
5369 VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
5370 for (i = old_length; i < length; i++)
5371 VLA_PTR (cycle_alt_unit_usages, i) = NULL;
5373 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5374 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5375 obstack_finish (&unit_usages);
5376 unit_usage_ptr->unit_decl = unit_decl;
5377 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5378 unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
5379 VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
5380 unit_decl->last_distribution_check_cycle = -1; /* undefined */
5383 /* The function processes given REGEXP to find units with the wrong
5384 distribution. */
5385 static void
5386 check_regexp_units_distribution (const char *insn_reserv_name,
5387 regexp_t regexp)
5389 int i, j, k, cycle;
5390 regexp_t seq, allof, unit;
5391 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5393 if (regexp == NULL || regexp->mode != rm_oneof)
5394 return;
5395 /* Store all unit usages in the regexp: */
5396 obstack_init (&unit_usages);
5397 VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
5398 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5400 seq = REGEXP_ONEOF (regexp)->regexps [i];
5401 switch (seq->mode)
5403 case rm_sequence:
5404 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5406 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5407 switch (allof->mode)
5409 case rm_allof:
5410 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5412 unit = REGEXP_ALLOF (allof)->regexps [k];
5413 if (unit->mode == rm_unit)
5414 store_alt_unit_usage (regexp, unit, j, i);
5415 else
5416 gcc_assert (unit->mode == rm_nothing);
5418 break;
5420 case rm_unit:
5421 store_alt_unit_usage (regexp, allof, j, i);
5422 break;
5424 case rm_nothing:
5425 break;
5427 default:
5428 gcc_unreachable ();
5431 break;
5433 case rm_allof:
5434 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5436 unit = REGEXP_ALLOF (seq)->regexps [k];
5437 switch (unit->mode)
5439 case rm_unit:
5440 store_alt_unit_usage (regexp, unit, 0, i);
5441 break;
5443 case rm_nothing:
5444 break;
5446 default:
5447 gcc_unreachable ();
5450 break;
5452 case rm_unit:
5453 store_alt_unit_usage (regexp, seq, 0, i);
5454 break;
5456 case rm_nothing:
5457 break;
5459 default:
5460 gcc_unreachable ();
5463 /* Check distribution: */
5464 for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
5466 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5467 for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
5468 unit_usage_ptr != NULL;
5469 unit_usage_ptr = unit_usage_ptr->next)
5470 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5472 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5473 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5474 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5475 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5476 k++)
5478 for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
5479 other_unit_usage_ptr != NULL;
5480 other_unit_usage_ptr = other_unit_usage_ptr->next)
5481 if (unit_usage_ptr->unit_decl->automaton_decl
5482 == other_unit_usage_ptr->unit_decl->automaton_decl)
5483 break;
5484 if (other_unit_usage_ptr == NULL
5485 && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
5486 break;
5488 if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5489 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5491 if (!annotation_message_reported_p)
5493 fprintf (stderr, "\n");
5494 error ("The following units do not satisfy units-automata distribution rule");
5495 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5496 annotation_message_reported_p = TRUE;
5498 error ("Unit %s, reserv. %s, cycle %d",
5499 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5500 cycle);
5504 VLA_PTR_DELETE (cycle_alt_unit_usages);
5505 obstack_free (&unit_usages, NULL);
5508 /* The function finds units which violates units to automata
5509 distribution rule. If the units exist, report about them. */
5510 static void
5511 check_unit_distributions_to_automata (void)
5513 decl_t decl;
5514 int i;
5516 if (progress_flag)
5517 fprintf (stderr, "Check unit distributions to automata...");
5518 annotation_message_reported_p = FALSE;
5519 for (i = 0; i < description->decls_num; i++)
5521 decl = description->decls [i];
5522 if (decl->mode == dm_insn_reserv)
5523 check_regexp_units_distribution
5524 (DECL_INSN_RESERV (decl)->name,
5525 DECL_INSN_RESERV (decl)->transformed_regexp);
5527 if (progress_flag)
5528 fprintf (stderr, "done\n");
5533 /* The page contains code for building alt_states (see comments for
5534 IR) describing all possible insns reservations of an automaton. */
5536 /* Current state being formed for which the current alt_state
5537 refers. */
5538 static state_t state_being_formed;
5540 /* Current alt_state being formed. */
5541 static alt_state_t alt_state_being_formed;
5543 /* This recursive function processes `,' and units in reservation
5544 REGEXP for forming alt_states of AUTOMATON. It is believed that
5545 CURR_CYCLE is start cycle of all reservation REGEXP. */
5546 static int
5547 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5548 int curr_cycle)
5550 int i;
5552 if (regexp == NULL)
5553 return curr_cycle;
5555 switch (regexp->mode)
5557 case rm_unit:
5558 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5559 == automaton->automaton_order_num)
5560 set_state_reserv (state_being_formed, curr_cycle,
5561 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5562 return curr_cycle;
5564 case rm_sequence:
5565 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5566 curr_cycle
5567 = process_seq_for_forming_states
5568 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5569 return curr_cycle;
5571 case rm_allof:
5573 int finish_cycle = 0;
5574 int cycle;
5576 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5578 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5579 ->regexps [i],
5580 automaton, curr_cycle);
5581 if (finish_cycle < cycle)
5582 finish_cycle = cycle;
5584 return finish_cycle;
5587 case rm_nothing:
5588 return curr_cycle;
5590 default:
5591 gcc_unreachable ();
5595 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5596 inserts alt_state into the table. */
5597 static void
5598 finish_forming_alt_state (alt_state_t alt_state,
5599 automaton_t automaton ATTRIBUTE_UNUSED)
5601 state_t state_in_table;
5602 state_t corresponding_state;
5604 corresponding_state = alt_state->state;
5605 state_in_table = insert_state (corresponding_state);
5606 if (state_in_table != corresponding_state)
5608 free_state (corresponding_state);
5609 alt_state->state = state_in_table;
5613 /* The following variable value is current automaton insn for whose
5614 reservation the alt states are created. */
5615 static ainsn_t curr_ainsn;
5617 /* This recursive function processes `|' in reservation REGEXP for
5618 forming alt_states of AUTOMATON. List of the alt states should
5619 have the same order as in the description. */
5620 static void
5621 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5622 int inside_oneof_p)
5624 int i;
5626 if (regexp->mode != rm_oneof)
5628 alt_state_being_formed = get_free_alt_state ();
5629 state_being_formed = get_free_state (1, automaton);
5630 alt_state_being_formed->state = state_being_formed;
5631 /* We inserts in reverse order but we process alternatives also
5632 in reverse order. So we have the same order of alternative
5633 as in the description. */
5634 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5635 curr_ainsn->alt_states = alt_state_being_formed;
5636 (void) process_seq_for_forming_states (regexp, automaton, 0);
5637 finish_forming_alt_state (alt_state_being_formed, automaton);
5639 else
5641 gcc_assert (!inside_oneof_p);
5642 /* We processes it in reverse order to get list with the same
5643 order as in the description. See also the previous
5644 commentary. */
5645 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5646 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5647 automaton, 1);
5651 /* Create nodes alt_state for all AUTOMATON insns. */
5652 static void
5653 create_alt_states (automaton_t automaton)
5655 struct insn_reserv_decl *reserv_decl;
5657 for (curr_ainsn = automaton->ainsn_list;
5658 curr_ainsn != NULL;
5659 curr_ainsn = curr_ainsn->next_ainsn)
5661 reserv_decl = curr_ainsn->insn_reserv_decl;
5662 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5664 curr_ainsn->alt_states = NULL;
5665 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5666 automaton, 0);
5667 curr_ainsn->sorted_alt_states
5668 = uniq_sort_alt_states (curr_ainsn->alt_states);
5675 /* The page contains major code for building DFA(s) for fast pipeline
5676 hazards recognition. */
5678 /* The function forms list of ainsns of AUTOMATON with the same
5679 reservation. */
5680 static void
5681 form_ainsn_with_same_reservs (automaton_t automaton)
5683 ainsn_t curr_ainsn;
5684 size_t i;
5685 vla_ptr_t first_insns;
5686 vla_ptr_t last_insns;
5688 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5689 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5690 for (curr_ainsn = automaton->ainsn_list;
5691 curr_ainsn != NULL;
5692 curr_ainsn = curr_ainsn->next_ainsn)
5693 if (curr_ainsn->insn_reserv_decl
5694 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5696 curr_ainsn->next_same_reservs_insn = NULL;
5697 curr_ainsn->first_insn_with_same_reservs = 1;
5699 else
5701 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5702 if (alt_states_eq
5703 (curr_ainsn->sorted_alt_states,
5704 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5705 break;
5706 curr_ainsn->next_same_reservs_insn = NULL;
5707 if (i < VLA_PTR_LENGTH (first_insns))
5709 curr_ainsn->first_insn_with_same_reservs = 0;
5710 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5711 = curr_ainsn;
5712 VLA_PTR (last_insns, i) = curr_ainsn;
5714 else
5716 VLA_PTR_ADD (first_insns, curr_ainsn);
5717 VLA_PTR_ADD (last_insns, curr_ainsn);
5718 curr_ainsn->first_insn_with_same_reservs = 1;
5721 VLA_PTR_DELETE (first_insns);
5722 VLA_PTR_DELETE (last_insns);
5725 /* Forming unit reservations which can affect creating the automaton
5726 states achieved from a given state. It permits to build smaller
5727 automata in many cases. We would have the same automata after
5728 the minimization without such optimization, but the automaton
5729 right after the building could be huge. So in other words, usage
5730 of reservs_matter means some minimization during building the
5731 automaton. */
5732 static reserv_sets_t
5733 form_reservs_matter (automaton_t automaton)
5735 int cycle, unit;
5736 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5738 for (cycle = 0; cycle < max_cycles_num; cycle++)
5739 for (unit = 0; unit < description->units_num; unit++)
5740 if (units_array [unit]->automaton_decl
5741 == automaton->corresponding_automaton_decl
5742 && (cycle >= units_array [unit]->min_occ_cycle_num
5743 /* We can not remove queried unit from reservations. */
5744 || units_array [unit]->query_p
5745 /* We can not remove units which are used
5746 `exclusion_set', `presence_set',
5747 `final_presence_set', `absence_set', and
5748 `final_absence_set'. */
5749 || units_array [unit]->in_set_p))
5750 set_unit_reserv (reservs_matter, cycle, unit);
5751 return reservs_matter;
5754 /* The following function creates all states of nondeterministic (if
5755 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5756 static void
5757 make_automaton (automaton_t automaton)
5759 ainsn_t ainsn;
5760 struct insn_reserv_decl *insn_reserv_decl;
5761 alt_state_t alt_state;
5762 state_t state;
5763 state_t start_state;
5764 state_t state2;
5765 ainsn_t advance_cycle_ainsn;
5766 arc_t added_arc;
5767 vla_ptr_t state_stack;
5768 int states_n;
5769 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5771 VLA_PTR_CREATE (state_stack, 150, "state stack");
5772 /* Create the start state (empty state). */
5773 start_state = insert_state (get_free_state (1, automaton));
5774 automaton->start_state = start_state;
5775 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5776 VLA_PTR_ADD (state_stack, start_state);
5777 states_n = 1;
5778 while (VLA_PTR_LENGTH (state_stack) != 0)
5780 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5781 VLA_PTR_SHORTEN (state_stack, 1);
5782 advance_cycle_ainsn = NULL;
5783 for (ainsn = automaton->ainsn_list;
5784 ainsn != NULL;
5785 ainsn = ainsn->next_ainsn)
5786 if (ainsn->first_insn_with_same_reservs)
5788 insn_reserv_decl = ainsn->insn_reserv_decl;
5789 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5791 /* We process alt_states in the same order as they are
5792 present in the description. */
5793 added_arc = NULL;
5794 for (alt_state = ainsn->alt_states;
5795 alt_state != NULL;
5796 alt_state = alt_state->next_alt_state)
5798 state2 = alt_state->state;
5799 if (!intersected_state_reservs_p (state, state2))
5801 state2 = states_union (state, state2, reservs_matter);
5802 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5804 state2->it_was_placed_in_stack_for_NDFA_forming
5805 = 1;
5806 VLA_PTR_ADD (state_stack, state2);
5807 states_n++;
5808 if (progress_flag && states_n % 100 == 0)
5809 fprintf (stderr, ".");
5811 added_arc = add_arc (state, state2, ainsn, 1);
5812 if (!ndfa_flag)
5813 break;
5816 if (!ndfa_flag && added_arc != NULL)
5818 added_arc->state_alts = 0;
5819 for (alt_state = ainsn->alt_states;
5820 alt_state != NULL;
5821 alt_state = alt_state->next_alt_state)
5823 state2 = alt_state->state;
5824 if (!intersected_state_reservs_p (state, state2))
5825 added_arc->state_alts++;
5829 else
5830 advance_cycle_ainsn = ainsn;
5832 /* Add transition to advance cycle. */
5833 state2 = state_shift (state, reservs_matter);
5834 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5836 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5837 VLA_PTR_ADD (state_stack, state2);
5838 states_n++;
5839 if (progress_flag && states_n % 100 == 0)
5840 fprintf (stderr, ".");
5842 gcc_assert (advance_cycle_ainsn);
5843 add_arc (state, state2, advance_cycle_ainsn, 1);
5845 VLA_PTR_DELETE (state_stack);
5848 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5849 static void
5850 form_arcs_marked_by_insn (state_t state)
5852 decl_t decl;
5853 arc_t arc;
5854 int i;
5856 for (i = 0; i < description->decls_num; i++)
5858 decl = description->decls [i];
5859 if (decl->mode == dm_insn_reserv)
5860 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5862 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5864 gcc_assert (arc->insn);
5865 arc->next_arc_marked_by_insn
5866 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5867 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5871 /* The function creates composed state (see comments for IR) from
5872 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5873 same insn. If the composed state is not in STATE_STACK yet, it is
5874 pushed into STATE_STACK. */
5875 static int
5876 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5877 vla_ptr_t *state_stack)
5879 state_t state;
5880 alt_state_t alt_state, curr_alt_state;
5881 alt_state_t new_alt_state;
5882 arc_t curr_arc;
5883 arc_t next_arc;
5884 state_t state_in_table;
5885 state_t temp_state;
5886 alt_state_t canonical_alt_states_list;
5887 int alts_number;
5888 int new_state_p = 0;
5890 if (arcs_marked_by_insn == NULL)
5891 return new_state_p;
5892 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5893 state = arcs_marked_by_insn->to_state;
5894 else
5896 gcc_assert (ndfa_flag);
5897 /* Create composed state. */
5898 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5899 curr_alt_state = NULL;
5900 for (curr_arc = arcs_marked_by_insn;
5901 curr_arc != NULL;
5902 curr_arc = curr_arc->next_arc_marked_by_insn)
5903 if (curr_arc->to_state->component_states == NULL)
5905 new_alt_state = get_free_alt_state ();
5906 new_alt_state->next_alt_state = curr_alt_state;
5907 new_alt_state->state = curr_arc->to_state;
5908 curr_alt_state = new_alt_state;
5910 else
5911 for (alt_state = curr_arc->to_state->component_states;
5912 alt_state != NULL;
5913 alt_state = alt_state->next_sorted_alt_state)
5915 new_alt_state = get_free_alt_state ();
5916 new_alt_state->next_alt_state = curr_alt_state;
5917 new_alt_state->state = alt_state->state;
5918 gcc_assert (!alt_state->state->component_states);
5919 curr_alt_state = new_alt_state;
5921 /* There are not identical sets in the alt state list. */
5922 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5923 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5925 temp_state = state;
5926 state = canonical_alt_states_list->state;
5927 free_state (temp_state);
5929 else
5931 state->component_states = canonical_alt_states_list;
5932 state_in_table = insert_state (state);
5933 if (state_in_table != state)
5935 gcc_assert
5936 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5937 free_state (state);
5938 state = state_in_table;
5940 else
5942 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5943 new_state_p = 1;
5944 for (curr_alt_state = state->component_states;
5945 curr_alt_state != NULL;
5946 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5947 for (curr_arc = first_out_arc (curr_alt_state->state);
5948 curr_arc != NULL;
5949 curr_arc = next_out_arc (curr_arc))
5950 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5952 arcs_marked_by_insn->to_state = state;
5953 for (alts_number = 0,
5954 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5955 curr_arc != NULL;
5956 curr_arc = next_arc)
5958 next_arc = curr_arc->next_arc_marked_by_insn;
5959 remove_arc (original_state, curr_arc);
5960 alts_number++;
5962 arcs_marked_by_insn->state_alts = alts_number;
5965 if (!state->it_was_placed_in_stack_for_DFA_forming)
5967 state->it_was_placed_in_stack_for_DFA_forming = 1;
5968 VLA_PTR_ADD (*state_stack, state);
5970 return new_state_p;
5973 /* The function transforms nondeterministic AUTOMATON into
5974 deterministic. */
5975 static void
5976 NDFA_to_DFA (automaton_t automaton)
5978 state_t start_state;
5979 state_t state;
5980 decl_t decl;
5981 vla_ptr_t state_stack;
5982 int i;
5983 int states_n;
5985 VLA_PTR_CREATE (state_stack, 150, "state stack");
5986 /* Create the start state (empty state). */
5987 start_state = automaton->start_state;
5988 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5989 VLA_PTR_ADD (state_stack, start_state);
5990 states_n = 1;
5991 while (VLA_PTR_LENGTH (state_stack) != 0)
5993 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5994 VLA_PTR_SHORTEN (state_stack, 1);
5995 form_arcs_marked_by_insn (state);
5996 for (i = 0; i < description->decls_num; i++)
5998 decl = description->decls [i];
5999 if (decl->mode == dm_insn_reserv
6000 && create_composed_state
6001 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
6002 &state_stack))
6004 states_n++;
6005 if (progress_flag && states_n % 100 == 0)
6006 fprintf (stderr, ".");
6010 VLA_PTR_DELETE (state_stack);
6013 /* The following variable value is current number (1, 2, ...) of passing
6014 graph of states. */
6015 static int curr_state_graph_pass_num;
6017 /* This recursive function passes all states achieved from START_STATE
6018 and applies APPLIED_FUNC to them. */
6019 static void
6020 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
6022 arc_t arc;
6024 if (start_state->pass_num == curr_state_graph_pass_num)
6025 return;
6026 start_state->pass_num = curr_state_graph_pass_num;
6027 (*applied_func) (start_state);
6028 for (arc = first_out_arc (start_state);
6029 arc != NULL;
6030 arc = next_out_arc (arc))
6031 pass_state_graph (arc->to_state, applied_func);
6034 /* This recursive function passes all states of AUTOMATON and applies
6035 APPLIED_FUNC to them. */
6036 static void
6037 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
6039 curr_state_graph_pass_num++;
6040 pass_state_graph (automaton->start_state, applied_func);
6043 /* The function initializes code for passing of all states. */
6044 static void
6045 initiate_pass_states (void)
6047 curr_state_graph_pass_num = 0;
6050 /* The following vla is used for storing pointers to all achieved
6051 states. */
6052 static vla_ptr_t all_achieved_states;
6054 /* This function is called by function pass_states to add an achieved
6055 STATE. */
6056 static void
6057 add_achieved_state (state_t state)
6059 VLA_PTR_ADD (all_achieved_states, state);
6062 /* The function sets up equivalence numbers of insns which mark all
6063 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6064 nonzero value) or by equiv_class_num_2 of the destination state.
6065 The function returns number of out arcs of STATE. */
6066 static int
6067 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
6069 int state_out_arcs_num;
6070 arc_t arc;
6072 state_out_arcs_num = 0;
6073 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6075 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
6076 && !arc->insn->insn_reserv_decl->state_alts);
6077 state_out_arcs_num++;
6078 arc->insn->insn_reserv_decl->equiv_class_num
6079 = (odd_iteration_flag
6080 ? arc->to_state->equiv_class_num_1
6081 : arc->to_state->equiv_class_num_2);
6082 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6083 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
6084 && arc->insn->insn_reserv_decl->state_alts > 0);
6086 return state_out_arcs_num;
6089 /* The function clears equivalence numbers and alt_states in all insns
6090 which mark all out arcs of STATE. */
6091 static void
6092 clear_arc_insns_equiv_num (state_t state)
6094 arc_t arc;
6096 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6098 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6099 arc->insn->insn_reserv_decl->state_alts = 0;
6103 /* The function copies pointers to equivalent states from vla FROM
6104 into vla TO. */
6105 static void
6106 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
6108 state_t *class_ptr;
6110 VLA_PTR_NULLIFY (*to);
6111 for (class_ptr = VLA_PTR_BEGIN (*from);
6112 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6113 class_ptr++)
6114 VLA_PTR_ADD (*to, *class_ptr);
6117 /* The following function returns TRUE if STATE reserves the unit with
6118 UNIT_NUM on the first cycle. */
6119 static int
6120 first_cycle_unit_presence (state_t state, int unit_num)
6122 int presence_p;
6124 if (state->component_states == NULL)
6125 presence_p = test_unit_reserv (state->reservs, 0, unit_num);
6126 else
6127 presence_p
6128 = test_unit_reserv (state->component_states->state->reservs,
6129 0, unit_num);
6130 return presence_p;
6133 /* The function returns nonzero value if STATE is not equivalent to
6134 ANOTHER_STATE from the same current partition on equivalence
6135 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6136 output arcs. Iteration of making equivalence partition is defined
6137 by ODD_ITERATION_FLAG. */
6138 static int
6139 state_is_differed (state_t state, state_t another_state,
6140 int another_state_out_arcs_num, int odd_iteration_flag)
6142 arc_t arc;
6143 int state_out_arcs_num;
6144 int i, presence1_p, presence2_p;
6146 state_out_arcs_num = 0;
6147 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6149 state_out_arcs_num++;
6150 if ((odd_iteration_flag
6151 ? arc->to_state->equiv_class_num_1
6152 : arc->to_state->equiv_class_num_2)
6153 != arc->insn->insn_reserv_decl->equiv_class_num
6154 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6155 return 1;
6157 if (state_out_arcs_num != another_state_out_arcs_num)
6158 return 1;
6159 /* Now we are looking at the states with the point of view of query
6160 units. */
6161 for (i = 0; i < description->units_num; i++)
6162 if (units_array [i]->query_p)
6164 presence1_p = first_cycle_unit_presence (state, i);
6165 presence2_p = first_cycle_unit_presence (another_state, i);
6166 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6167 return 1;
6169 return 0;
6172 /* The function makes initial partition of STATES on equivalent
6173 classes. */
6174 static state_t
6175 init_equiv_class (state_t *states, int states_num)
6177 state_t *state_ptr;
6178 state_t result_equiv_class;
6180 result_equiv_class = NULL;
6181 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6183 (*state_ptr)->equiv_class_num_1 = 1;
6184 (*state_ptr)->next_equiv_class_state = result_equiv_class;
6185 result_equiv_class = *state_ptr;
6187 return result_equiv_class;
6190 /* The function processes equivalence class given by its pointer
6191 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6192 are not equivalent states, the function partitions the class
6193 removing nonequivalent states and placing them in
6194 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6195 assigns it to the state equivalence number. If the class has been
6196 partitioned, the function returns nonzero value. */
6197 static int
6198 partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
6199 vla_ptr_t *next_iteration_classes,
6200 int *new_equiv_class_num_ptr)
6202 state_t new_equiv_class;
6203 int partition_p;
6204 state_t first_state;
6205 state_t curr_state;
6206 state_t prev_state;
6207 state_t next_state;
6208 int out_arcs_num;
6210 partition_p = 0;
6211 gcc_assert (*equiv_class_ptr);
6212 for (first_state = *equiv_class_ptr;
6213 first_state != NULL;
6214 first_state = new_equiv_class)
6216 new_equiv_class = NULL;
6217 if (first_state->next_equiv_class_state != NULL)
6219 /* There are more one states in the class equivalence. */
6220 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6221 odd_iteration_flag);
6222 for (prev_state = first_state,
6223 curr_state = first_state->next_equiv_class_state;
6224 curr_state != NULL;
6225 curr_state = next_state)
6227 next_state = curr_state->next_equiv_class_state;
6228 if (state_is_differed (curr_state, first_state, out_arcs_num,
6229 odd_iteration_flag))
6231 /* Remove curr state from the class equivalence. */
6232 prev_state->next_equiv_class_state = next_state;
6233 /* Add curr state to the new class equivalence. */
6234 curr_state->next_equiv_class_state = new_equiv_class;
6235 if (new_equiv_class == NULL)
6236 (*new_equiv_class_num_ptr)++;
6237 if (odd_iteration_flag)
6238 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6239 else
6240 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6241 new_equiv_class = curr_state;
6242 partition_p = 1;
6244 else
6245 prev_state = curr_state;
6247 clear_arc_insns_equiv_num (first_state);
6249 if (new_equiv_class != NULL)
6250 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
6252 return partition_p;
6255 /* The function finds equivalent states of AUTOMATON. */
6256 static void
6257 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
6259 state_t new_equiv_class;
6260 int new_equiv_class_num;
6261 int odd_iteration_flag;
6262 int finish_flag;
6263 vla_ptr_t next_iteration_classes;
6264 state_t *equiv_class_ptr;
6265 state_t *state_ptr;
6267 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6268 pass_states (automaton, add_achieved_state);
6269 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6270 VLA_PTR_LENGTH (all_achieved_states));
6271 odd_iteration_flag = 0;
6272 new_equiv_class_num = 1;
6273 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6274 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6277 odd_iteration_flag = !odd_iteration_flag;
6278 finish_flag = 1;
6279 copy_equiv_class (equiv_classes, &next_iteration_classes);
6280 /* Transfer equiv numbers for the next iteration. */
6281 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6282 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6283 state_ptr++)
6284 if (odd_iteration_flag)
6285 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6286 else
6287 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6288 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6289 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6290 equiv_class_ptr++)
6291 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6292 &next_iteration_classes,
6293 &new_equiv_class_num))
6294 finish_flag = 0;
6296 while (!finish_flag);
6297 VLA_PTR_DELETE (next_iteration_classes);
6298 VLA_PTR_DELETE (all_achieved_states);
6301 /* The function merges equivalent states of AUTOMATON. */
6302 static void
6303 merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
6305 state_t *equiv_class_ptr;
6306 state_t curr_state;
6307 state_t new_state;
6308 state_t first_class_state;
6309 alt_state_t alt_states;
6310 alt_state_t alt_state, new_alt_state;
6311 arc_t curr_arc;
6312 arc_t next_arc;
6314 /* Create states corresponding to equivalence classes containing two
6315 or more states. */
6316 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6317 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6318 equiv_class_ptr++)
6319 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6321 /* There are more one states in the class equivalence. */
6322 /* Create new compound state. */
6323 new_state = get_free_state (0, automaton);
6324 alt_states = NULL;
6325 first_class_state = *equiv_class_ptr;
6326 for (curr_state = first_class_state;
6327 curr_state != NULL;
6328 curr_state = curr_state->next_equiv_class_state)
6330 curr_state->equiv_class_state = new_state;
6331 if (curr_state->component_states == NULL)
6333 new_alt_state = get_free_alt_state ();
6334 new_alt_state->state = curr_state;
6335 new_alt_state->next_alt_state = alt_states;
6336 alt_states = new_alt_state;
6338 else
6339 for (alt_state = curr_state->component_states;
6340 alt_state != NULL;
6341 alt_state = alt_state->next_sorted_alt_state)
6343 new_alt_state = get_free_alt_state ();
6344 new_alt_state->state = alt_state->state;
6345 new_alt_state->next_alt_state = alt_states;
6346 alt_states = new_alt_state;
6349 /* Its is important that alt states were sorted before and
6350 after merging to have the same querying results. */
6351 new_state->component_states = uniq_sort_alt_states (alt_states);
6353 else
6354 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6355 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6356 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6357 equiv_class_ptr++)
6358 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6360 first_class_state = *equiv_class_ptr;
6361 /* Create new arcs output from the state corresponding to
6362 equiv class. */
6363 for (curr_arc = first_out_arc (first_class_state);
6364 curr_arc != NULL;
6365 curr_arc = next_out_arc (curr_arc))
6366 add_arc (first_class_state->equiv_class_state,
6367 curr_arc->to_state->equiv_class_state,
6368 curr_arc->insn, curr_arc->state_alts);
6369 /* Delete output arcs from states of given class equivalence. */
6370 for (curr_state = first_class_state;
6371 curr_state != NULL;
6372 curr_state = curr_state->next_equiv_class_state)
6374 if (automaton->start_state == curr_state)
6375 automaton->start_state = curr_state->equiv_class_state;
6376 /* Delete the state and its output arcs. */
6377 for (curr_arc = first_out_arc (curr_state);
6378 curr_arc != NULL;
6379 curr_arc = next_arc)
6381 next_arc = next_out_arc (curr_arc);
6382 free_arc (curr_arc);
6386 else
6388 /* Change `to_state' of arcs output from the state of given
6389 equivalence class. */
6390 for (curr_arc = first_out_arc (*equiv_class_ptr);
6391 curr_arc != NULL;
6392 curr_arc = next_out_arc (curr_arc))
6393 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6397 /* The function sets up new_cycle_p for states if there is arc to the
6398 state marked by advance_cycle_insn_decl. */
6399 static void
6400 set_new_cycle_flags (state_t state)
6402 arc_t arc;
6404 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6405 if (arc->insn->insn_reserv_decl
6406 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6407 arc->to_state->new_cycle_p = 1;
6410 /* The top level function for minimization of deterministic
6411 AUTOMATON. */
6412 static void
6413 minimize_DFA (automaton_t automaton)
6415 vla_ptr_t equiv_classes;
6417 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6418 evaluate_equiv_classes (automaton, &equiv_classes);
6419 merge_states (automaton, &equiv_classes);
6420 pass_states (automaton, set_new_cycle_flags);
6421 VLA_PTR_DELETE (equiv_classes);
6424 /* Values of two variables are counted number of states and arcs in an
6425 automaton. */
6426 static int curr_counted_states_num;
6427 static int curr_counted_arcs_num;
6429 /* The function is called by function `pass_states' to count states
6430 and arcs of an automaton. */
6431 static void
6432 incr_states_and_arcs_nums (state_t state)
6434 arc_t arc;
6436 curr_counted_states_num++;
6437 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6438 curr_counted_arcs_num++;
6441 /* The function counts states and arcs of AUTOMATON. */
6442 static void
6443 count_states_and_arcs (automaton_t automaton, int *states_num,
6444 int *arcs_num)
6446 curr_counted_states_num = 0;
6447 curr_counted_arcs_num = 0;
6448 pass_states (automaton, incr_states_and_arcs_nums);
6449 *states_num = curr_counted_states_num;
6450 *arcs_num = curr_counted_arcs_num;
6453 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6454 recognition after checking and simplifying IR of the
6455 description. */
6456 static void
6457 build_automaton (automaton_t automaton)
6459 int states_num;
6460 int arcs_num;
6462 ticker_on (&NDFA_time);
6463 if (progress_flag)
6465 if (automaton->corresponding_automaton_decl == NULL)
6466 fprintf (stderr, "Create anonymous automaton");
6467 else
6468 fprintf (stderr, "Create automaton `%s'",
6469 automaton->corresponding_automaton_decl->name);
6470 fprintf (stderr, " (1 dot is 100 new states):");
6472 make_automaton (automaton);
6473 if (progress_flag)
6474 fprintf (stderr, " done\n");
6475 ticker_off (&NDFA_time);
6476 count_states_and_arcs (automaton, &states_num, &arcs_num);
6477 automaton->NDFA_states_num = states_num;
6478 automaton->NDFA_arcs_num = arcs_num;
6479 ticker_on (&NDFA_to_DFA_time);
6480 if (progress_flag)
6482 if (automaton->corresponding_automaton_decl == NULL)
6483 fprintf (stderr, "Make anonymous DFA");
6484 else
6485 fprintf (stderr, "Make DFA `%s'",
6486 automaton->corresponding_automaton_decl->name);
6487 fprintf (stderr, " (1 dot is 100 new states):");
6489 NDFA_to_DFA (automaton);
6490 if (progress_flag)
6491 fprintf (stderr, " done\n");
6492 ticker_off (&NDFA_to_DFA_time);
6493 count_states_and_arcs (automaton, &states_num, &arcs_num);
6494 automaton->DFA_states_num = states_num;
6495 automaton->DFA_arcs_num = arcs_num;
6496 if (!no_minimization_flag)
6498 ticker_on (&minimize_time);
6499 if (progress_flag)
6501 if (automaton->corresponding_automaton_decl == NULL)
6502 fprintf (stderr, "Minimize anonymous DFA...");
6503 else
6504 fprintf (stderr, "Minimize DFA `%s'...",
6505 automaton->corresponding_automaton_decl->name);
6507 minimize_DFA (automaton);
6508 if (progress_flag)
6509 fprintf (stderr, "done\n");
6510 ticker_off (&minimize_time);
6511 count_states_and_arcs (automaton, &states_num, &arcs_num);
6512 automaton->minimal_DFA_states_num = states_num;
6513 automaton->minimal_DFA_arcs_num = arcs_num;
6519 /* The page contains code for enumeration of all states of an automaton. */
6521 /* Variable used for enumeration of all states of an automaton. Its
6522 value is current number of automaton states. */
6523 static int curr_state_order_num;
6525 /* The function is called by function `pass_states' for enumerating
6526 states. */
6527 static void
6528 set_order_state_num (state_t state)
6530 state->order_state_num = curr_state_order_num;
6531 curr_state_order_num++;
6534 /* The function enumerates all states of AUTOMATON. */
6535 static void
6536 enumerate_states (automaton_t automaton)
6538 curr_state_order_num = 0;
6539 pass_states (automaton, set_order_state_num);
6540 automaton->achieved_states_num = curr_state_order_num;
6545 /* The page contains code for finding equivalent automaton insns
6546 (ainsns). */
6548 /* The function inserts AINSN into cyclic list
6549 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6550 static ainsn_t
6551 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6552 ainsn_t cyclic_equiv_class_insn_list)
6554 if (cyclic_equiv_class_insn_list == NULL)
6555 ainsn->next_equiv_class_insn = ainsn;
6556 else
6558 ainsn->next_equiv_class_insn
6559 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6560 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6562 return ainsn;
6565 /* The function deletes equiv_class_insn into cyclic list of
6566 equivalent ainsns. */
6567 static void
6568 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6570 ainsn_t curr_equiv_class_insn;
6571 ainsn_t prev_equiv_class_insn;
6573 prev_equiv_class_insn = equiv_class_insn;
6574 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6575 curr_equiv_class_insn != equiv_class_insn;
6576 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6577 prev_equiv_class_insn = curr_equiv_class_insn;
6578 if (prev_equiv_class_insn != equiv_class_insn)
6579 prev_equiv_class_insn->next_equiv_class_insn
6580 = equiv_class_insn->next_equiv_class_insn;
6583 /* The function processes AINSN of a state in order to find equivalent
6584 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6585 state. */
6586 static void
6587 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6589 ainsn_t next_insn;
6590 ainsn_t curr_insn;
6591 ainsn_t cyclic_insn_list;
6592 arc_t arc;
6594 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6595 curr_insn = ainsn;
6596 /* New class of ainsns which are not equivalent to given ainsn. */
6597 cyclic_insn_list = NULL;
6600 next_insn = curr_insn->next_equiv_class_insn;
6601 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6602 if (arc == NULL
6603 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6604 != arc->to_state))
6606 delete_ainsn_from_equiv_class (curr_insn);
6607 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6608 cyclic_insn_list);
6610 curr_insn = next_insn;
6612 while (curr_insn != ainsn);
6615 /* The function processes STATE in order to find equivalent ainsns. */
6616 static void
6617 process_state_for_insn_equiv_partition (state_t state)
6619 arc_t arc;
6620 arc_t *insn_arcs_array;
6621 int i;
6622 vla_ptr_t insn_arcs_vect;
6624 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6625 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6626 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6627 /* Process insns of the arcs. */
6628 for (i = 0; i < description->insns_num; i++)
6629 insn_arcs_array [i] = NULL;
6630 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6631 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6632 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6633 process_insn_equiv_class (arc->insn, insn_arcs_array);
6634 VLA_PTR_DELETE (insn_arcs_vect);
6637 /* The function searches for equivalent ainsns of AUTOMATON. */
6638 static void
6639 set_insn_equiv_classes (automaton_t automaton)
6641 ainsn_t ainsn;
6642 ainsn_t first_insn;
6643 ainsn_t curr_insn;
6644 ainsn_t cyclic_insn_list;
6645 ainsn_t insn_with_same_reservs;
6646 int equiv_classes_num;
6648 /* All insns are included in one equivalence class. */
6649 cyclic_insn_list = NULL;
6650 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6651 if (ainsn->first_insn_with_same_reservs)
6652 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6653 cyclic_insn_list);
6654 /* Process insns in order to make equivalence partition. */
6655 pass_states (automaton, process_state_for_insn_equiv_partition);
6656 /* Enumerate equiv classes. */
6657 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6658 /* Set undefined value. */
6659 ainsn->insn_equiv_class_num = -1;
6660 equiv_classes_num = 0;
6661 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6662 if (ainsn->insn_equiv_class_num < 0)
6664 first_insn = ainsn;
6665 gcc_assert (first_insn->first_insn_with_same_reservs);
6666 first_insn->first_ainsn_with_given_equivalence_num = 1;
6667 curr_insn = first_insn;
6670 for (insn_with_same_reservs = curr_insn;
6671 insn_with_same_reservs != NULL;
6672 insn_with_same_reservs
6673 = insn_with_same_reservs->next_same_reservs_insn)
6674 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6675 curr_insn = curr_insn->next_equiv_class_insn;
6677 while (curr_insn != first_insn);
6678 equiv_classes_num++;
6680 automaton->insn_equiv_classes_num = equiv_classes_num;
6685 /* This page contains code for creating DFA(s) and calls functions
6686 building them. */
6689 /* The following value is used to prevent floating point overflow for
6690 estimating an automaton bound. The value should be less DBL_MAX on
6691 the host machine. We use here approximate minimum of maximal
6692 double floating point value required by ANSI C standard. It
6693 will work for non ANSI sun compiler too. */
6695 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6697 /* The function estimate size of the single DFA used by PHR (pipeline
6698 hazards recognizer). */
6699 static double
6700 estimate_one_automaton_bound (void)
6702 decl_t decl;
6703 double one_automaton_estimation_bound;
6704 double root_value;
6705 int i;
6707 one_automaton_estimation_bound = 1.0;
6708 for (i = 0; i < description->decls_num; i++)
6710 decl = description->decls [i];
6711 if (decl->mode == dm_unit)
6713 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6714 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6715 / automata_num);
6716 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6717 > one_automaton_estimation_bound)
6718 one_automaton_estimation_bound *= root_value;
6721 return one_automaton_estimation_bound;
6724 /* The function compares unit declarations according to their maximal
6725 cycle in reservations. */
6726 static int
6727 compare_max_occ_cycle_nums (const void *unit_decl_1,
6728 const void *unit_decl_2)
6730 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6731 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6732 return 1;
6733 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6734 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6735 return 0;
6736 else
6737 return -1;
6740 /* The function makes heuristic assigning automata to units. Actually
6741 efficacy of the algorithm has been checked yet??? */
6742 static void
6743 units_to_automata_heuristic_distr (void)
6745 double estimation_bound;
6746 decl_t decl;
6747 decl_t *unit_decl_ptr;
6748 int automaton_num;
6749 int rest_units_num;
6750 double bound_value;
6751 vla_ptr_t unit_decls;
6752 int i;
6754 if (description->units_num == 0)
6755 return;
6756 estimation_bound = estimate_one_automaton_bound ();
6757 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6758 for (i = 0; i < description->decls_num; i++)
6760 decl = description->decls [i];
6761 if (decl->mode == dm_unit)
6762 VLA_PTR_ADD (unit_decls, decl);
6764 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6765 sizeof (decl_t), compare_max_occ_cycle_nums);
6766 automaton_num = 0;
6767 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6768 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6769 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6770 for (unit_decl_ptr++;
6771 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6772 unit_decl_ptr++)
6774 rest_units_num
6775 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6776 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6777 if (automaton_num < automata_num - 1
6778 && ((automata_num - automaton_num - 1 == rest_units_num)
6779 || (bound_value
6780 > (estimation_bound
6781 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6783 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6784 automaton_num++;
6786 else
6787 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6788 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6790 gcc_assert (automaton_num == automata_num - 1);
6791 VLA_PTR_DELETE (unit_decls);
6794 /* The functions creates automaton insns for each automata. Automaton
6795 insn is simply insn for given automaton which makes reservation
6796 only of units of the automaton. */
6797 static ainsn_t
6798 create_ainsns (void)
6800 decl_t decl;
6801 ainsn_t first_ainsn;
6802 ainsn_t curr_ainsn;
6803 ainsn_t prev_ainsn;
6804 int i;
6806 first_ainsn = NULL;
6807 prev_ainsn = NULL;
6808 for (i = 0; i < description->decls_num; i++)
6810 decl = description->decls [i];
6811 if (decl->mode == dm_insn_reserv)
6813 curr_ainsn = create_node (sizeof (struct ainsn));
6814 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6815 curr_ainsn->important_p = FALSE;
6816 curr_ainsn->next_ainsn = NULL;
6817 if (prev_ainsn == NULL)
6818 first_ainsn = curr_ainsn;
6819 else
6820 prev_ainsn->next_ainsn = curr_ainsn;
6821 prev_ainsn = curr_ainsn;
6824 return first_ainsn;
6827 /* The function assigns automata to units according to constructions
6828 `define_automaton' in the description. */
6829 static void
6830 units_to_automata_distr (void)
6832 decl_t decl;
6833 int i;
6835 for (i = 0; i < description->decls_num; i++)
6837 decl = description->decls [i];
6838 if (decl->mode == dm_unit)
6840 if (DECL_UNIT (decl)->automaton_decl == NULL
6841 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6842 == NULL))
6843 /* Distribute to the first automaton. */
6844 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6845 else
6846 DECL_UNIT (decl)->corresponding_automaton_num
6847 = (DECL_UNIT (decl)->automaton_decl
6848 ->corresponding_automaton->automaton_order_num);
6853 /* The function creates DFA(s) for fast pipeline hazards recognition
6854 after checking and simplifying IR of the description. */
6855 static void
6856 create_automata (void)
6858 automaton_t curr_automaton;
6859 automaton_t prev_automaton;
6860 decl_t decl;
6861 int curr_automaton_num;
6862 int i;
6864 if (automata_num != 0)
6866 units_to_automata_heuristic_distr ();
6867 for (prev_automaton = NULL, curr_automaton_num = 0;
6868 curr_automaton_num < automata_num;
6869 curr_automaton_num++, prev_automaton = curr_automaton)
6871 curr_automaton = create_node (sizeof (struct automaton));
6872 curr_automaton->ainsn_list = create_ainsns ();
6873 curr_automaton->corresponding_automaton_decl = NULL;
6874 curr_automaton->next_automaton = NULL;
6875 curr_automaton->automaton_order_num = curr_automaton_num;
6876 if (prev_automaton == NULL)
6877 description->first_automaton = curr_automaton;
6878 else
6879 prev_automaton->next_automaton = curr_automaton;
6882 else
6884 curr_automaton_num = 0;
6885 prev_automaton = NULL;
6886 for (i = 0; i < description->decls_num; i++)
6888 decl = description->decls [i];
6889 if (decl->mode == dm_automaton
6890 && DECL_AUTOMATON (decl)->automaton_is_used)
6892 curr_automaton = create_node (sizeof (struct automaton));
6893 curr_automaton->ainsn_list = create_ainsns ();
6894 curr_automaton->corresponding_automaton_decl
6895 = DECL_AUTOMATON (decl);
6896 curr_automaton->next_automaton = NULL;
6897 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6898 curr_automaton->automaton_order_num = curr_automaton_num;
6899 if (prev_automaton == NULL)
6900 description->first_automaton = curr_automaton;
6901 else
6902 prev_automaton->next_automaton = curr_automaton;
6903 curr_automaton_num++;
6904 prev_automaton = curr_automaton;
6907 if (curr_automaton_num == 0)
6909 curr_automaton = create_node (sizeof (struct automaton));
6910 curr_automaton->ainsn_list = create_ainsns ();
6911 curr_automaton->corresponding_automaton_decl = NULL;
6912 curr_automaton->next_automaton = NULL;
6913 description->first_automaton = curr_automaton;
6915 units_to_automata_distr ();
6917 NDFA_time = create_ticker ();
6918 ticker_off (&NDFA_time);
6919 NDFA_to_DFA_time = create_ticker ();
6920 ticker_off (&NDFA_to_DFA_time);
6921 minimize_time = create_ticker ();
6922 ticker_off (&minimize_time);
6923 equiv_time = create_ticker ();
6924 ticker_off (&equiv_time);
6925 for (curr_automaton = description->first_automaton;
6926 curr_automaton != NULL;
6927 curr_automaton = curr_automaton->next_automaton)
6929 if (progress_flag)
6931 if (curr_automaton->corresponding_automaton_decl == NULL)
6932 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6933 else
6934 fprintf (stderr, "Prepare automaton `%s' creation...",
6935 curr_automaton->corresponding_automaton_decl->name);
6937 create_alt_states (curr_automaton);
6938 form_ainsn_with_same_reservs (curr_automaton);
6939 if (progress_flag)
6940 fprintf (stderr, "done\n");
6941 build_automaton (curr_automaton);
6942 enumerate_states (curr_automaton);
6943 ticker_on (&equiv_time);
6944 set_insn_equiv_classes (curr_automaton);
6945 ticker_off (&equiv_time);
6951 /* This page contains code for forming string representation of
6952 regexp. The representation is formed on IR obstack. So you should
6953 not work with IR obstack between regexp_representation and
6954 finish_regexp_representation calls. */
6956 /* This recursive function forms string representation of regexp
6957 (without tailing '\0'). */
6958 static void
6959 form_regexp (regexp_t regexp)
6961 int i;
6963 switch (regexp->mode)
6965 case rm_unit: case rm_reserv:
6967 const char *name = (regexp->mode == rm_unit
6968 ? REGEXP_UNIT (regexp)->name
6969 : REGEXP_RESERV (regexp)->name);
6971 obstack_grow (&irp, name, strlen (name));
6972 break;
6975 case rm_sequence:
6976 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6978 if (i != 0)
6979 obstack_1grow (&irp, ',');
6980 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6982 break;
6984 case rm_allof:
6985 obstack_1grow (&irp, '(');
6986 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6988 if (i != 0)
6989 obstack_1grow (&irp, '+');
6990 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6991 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6992 obstack_1grow (&irp, '(');
6993 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6994 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6995 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6996 obstack_1grow (&irp, ')');
6998 obstack_1grow (&irp, ')');
6999 break;
7001 case rm_oneof:
7002 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
7004 if (i != 0)
7005 obstack_1grow (&irp, '|');
7006 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7007 obstack_1grow (&irp, '(');
7008 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
7009 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7010 obstack_1grow (&irp, ')');
7012 break;
7014 case rm_repeat:
7016 char digits [30];
7018 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7019 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7020 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7021 obstack_1grow (&irp, '(');
7022 form_regexp (REGEXP_REPEAT (regexp)->regexp);
7023 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7024 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7025 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7026 obstack_1grow (&irp, ')');
7027 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
7028 obstack_grow (&irp, digits, strlen (digits));
7029 break;
7032 case rm_nothing:
7033 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
7034 break;
7036 default:
7037 gcc_unreachable ();
7041 /* The function returns string representation of REGEXP on IR
7042 obstack. */
7043 static const char *
7044 regexp_representation (regexp_t regexp)
7046 form_regexp (regexp);
7047 obstack_1grow (&irp, '\0');
7048 return obstack_base (&irp);
7051 /* The function frees memory allocated for last formed string
7052 representation of regexp. */
7053 static void
7054 finish_regexp_representation (void)
7056 int length = obstack_object_size (&irp);
7058 obstack_blank_fast (&irp, -length);
7063 /* This page contains code for output PHR (pipeline hazards recognizer). */
7065 /* The function outputs minimal C type which is sufficient for
7066 representation numbers in range min_range_value and
7067 max_range_value. Because host machine and build machine may be
7068 different, we use here minimal values required by ANSI C standard
7069 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7070 approximation. */
7072 static void
7073 output_range_type (FILE *f, long int min_range_value,
7074 long int max_range_value)
7076 if (min_range_value >= 0 && max_range_value <= 255)
7077 fprintf (f, "unsigned char");
7078 else if (min_range_value >= -127 && max_range_value <= 127)
7079 fprintf (f, "signed char");
7080 else if (min_range_value >= 0 && max_range_value <= 65535)
7081 fprintf (f, "unsigned short");
7082 else if (min_range_value >= -32767 && max_range_value <= 32767)
7083 fprintf (f, "short");
7084 else
7085 fprintf (f, "int");
7088 /* The following macro value is used as value of member
7089 `longest_path_length' of state when we are processing path and the
7090 state on the path. */
7092 #define ON_THE_PATH -2
7094 /* The following recursive function searches for the length of the
7095 longest path starting from STATE which does not contain cycles and
7096 `cycle advance' arcs. */
7098 static int
7099 longest_path_length (state_t state)
7101 arc_t arc;
7102 int length, result;
7104 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7106 /* We don't expect the path cycle here. Our graph may contain
7107 only cycles with one state on the path not containing `cycle
7108 advance' arcs -- see comment below. */
7109 gcc_assert (state->longest_path_length != ON_THE_PATH);
7111 /* We already visited the state. */
7112 return state->longest_path_length;
7115 result = 0;
7116 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7117 /* Ignore cycles containing one state and `cycle advance' arcs. */
7118 if (arc->to_state != state
7119 && (arc->insn->insn_reserv_decl
7120 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7122 length = longest_path_length (arc->to_state);
7123 if (length > result)
7124 result = length;
7126 state->longest_path_length = result + 1;
7127 return result;
7130 /* The following variable value is value of the corresponding global
7131 variable in the automaton based pipeline interface. */
7133 static int max_dfa_issue_rate;
7135 /* The following function processes the longest path length staring
7136 from STATE to find MAX_DFA_ISSUE_RATE. */
7138 static void
7139 process_state_longest_path_length (state_t state)
7141 int value;
7143 value = longest_path_length (state);
7144 if (value > max_dfa_issue_rate)
7145 max_dfa_issue_rate = value;
7148 /* The following macro value is name of the corresponding global
7149 variable in the automaton based pipeline interface. */
7151 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7153 /* The following function calculates value of the corresponding
7154 global variable and outputs its declaration. */
7156 static void
7157 output_dfa_max_issue_rate (void)
7159 automaton_t automaton;
7161 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
7162 max_dfa_issue_rate = 0;
7163 for (automaton = description->first_automaton;
7164 automaton != NULL;
7165 automaton = automaton->next_automaton)
7166 pass_states (automaton, process_state_longest_path_length);
7167 fprintf (output_file, "\nint %s = %d;\n",
7168 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7171 /* The function outputs all initialization values of VECT with length
7172 vect_length. */
7173 static void
7174 output_vect (vect_el_t *vect, int vect_length)
7176 int els_on_line;
7178 els_on_line = 1;
7179 if (vect_length == 0)
7180 fprintf (output_file,
7181 "0 /* This is dummy el because the vect is empty */");
7182 else
7186 fprintf (output_file, "%5ld", (long) *vect);
7187 vect_length--;
7188 if (els_on_line == 10)
7190 els_on_line = 0;
7191 fprintf (output_file, ",\n");
7193 else if (vect_length != 0)
7194 fprintf (output_file, ", ");
7195 els_on_line++;
7196 vect++;
7198 while (vect_length != 0);
7202 /* The following is name of the structure which represents DFA(s) for
7203 PHR. */
7204 #define CHIP_NAME "DFA_chip"
7206 /* The following is name of member which represents state of a DFA for
7207 PHR. */
7208 static void
7209 output_chip_member_name (FILE *f, automaton_t automaton)
7211 if (automaton->corresponding_automaton_decl == NULL)
7212 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7213 else
7214 fprintf (f, "%s_automaton_state",
7215 automaton->corresponding_automaton_decl->name);
7218 /* The following is name of temporary variable which stores state of a
7219 DFA for PHR. */
7220 static void
7221 output_temp_chip_member_name (FILE *f, automaton_t automaton)
7223 fprintf (f, "_");
7224 output_chip_member_name (f, automaton);
7227 /* This is name of macro value which is code of pseudo_insn
7228 representing advancing cpu cycle. Its value is used as internal
7229 code unknown insn. */
7230 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7232 /* Output name of translate vector for given automaton. */
7233 static void
7234 output_translate_vect_name (FILE *f, automaton_t automaton)
7236 if (automaton->corresponding_automaton_decl == NULL)
7237 fprintf (f, "translate_%d", automaton->automaton_order_num);
7238 else
7239 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7242 /* Output name for simple transition table representation. */
7243 static void
7244 output_trans_full_vect_name (FILE *f, automaton_t automaton)
7246 if (automaton->corresponding_automaton_decl == NULL)
7247 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7248 else
7249 fprintf (f, "%s_transitions",
7250 automaton->corresponding_automaton_decl->name);
7253 /* Output name of comb vector of the transition table for given
7254 automaton. */
7255 static void
7256 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7258 if (automaton->corresponding_automaton_decl == NULL)
7259 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7260 else
7261 fprintf (f, "%s_transitions",
7262 automaton->corresponding_automaton_decl->name);
7265 /* Output name of check vector of the transition table for given
7266 automaton. */
7267 static void
7268 output_trans_check_vect_name (FILE *f, automaton_t automaton)
7270 if (automaton->corresponding_automaton_decl == NULL)
7271 fprintf (f, "check_%d", automaton->automaton_order_num);
7272 else
7273 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7276 /* Output name of base vector of the transition table for given
7277 automaton. */
7278 static void
7279 output_trans_base_vect_name (FILE *f, automaton_t automaton)
7281 if (automaton->corresponding_automaton_decl == NULL)
7282 fprintf (f, "base_%d", automaton->automaton_order_num);
7283 else
7284 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7287 /* Output name for simple alternatives number representation. */
7288 static void
7289 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7291 if (automaton->corresponding_automaton_decl == NULL)
7292 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7293 else
7294 fprintf (f, "%s_state_alts",
7295 automaton->corresponding_automaton_decl->name);
7298 /* Output name of comb vector of the alternatives number table for given
7299 automaton. */
7300 static void
7301 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7303 if (automaton->corresponding_automaton_decl == NULL)
7304 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7305 else
7306 fprintf (f, "%s_state_alts",
7307 automaton->corresponding_automaton_decl->name);
7310 /* Output name of check vector of the alternatives number table for given
7311 automaton. */
7312 static void
7313 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7315 if (automaton->corresponding_automaton_decl == NULL)
7316 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7317 else
7318 fprintf (f, "%s_check_state_alts",
7319 automaton->corresponding_automaton_decl->name);
7322 /* Output name of base vector of the alternatives number table for given
7323 automaton. */
7324 static void
7325 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7327 if (automaton->corresponding_automaton_decl == NULL)
7328 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7329 else
7330 fprintf (f, "%s_base_state_alts",
7331 automaton->corresponding_automaton_decl->name);
7334 /* Output name of simple min issue delay table representation. */
7335 static void
7336 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7338 if (automaton->corresponding_automaton_decl == NULL)
7339 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7340 else
7341 fprintf (f, "%s_min_issue_delay",
7342 automaton->corresponding_automaton_decl->name);
7345 /* Output name of deadlock vector for given automaton. */
7346 static void
7347 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7349 if (automaton->corresponding_automaton_decl == NULL)
7350 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7351 else
7352 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7355 /* Output name of reserved units table for AUTOMATON into file F. */
7356 static void
7357 output_reserved_units_table_name (FILE *f, automaton_t automaton)
7359 if (automaton->corresponding_automaton_decl == NULL)
7360 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7361 else
7362 fprintf (f, "%s_reserved_units",
7363 automaton->corresponding_automaton_decl->name);
7366 /* Name of the PHR interface macro. */
7367 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7369 /* Name of the PHR interface macro. */
7370 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7372 /* Names of an internal functions: */
7373 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7375 /* This is external type of DFA(s) state. */
7376 #define STATE_TYPE_NAME "state_t"
7378 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7380 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7382 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7384 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7386 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7388 /* Name of cache of insn dfa codes. */
7389 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7391 /* Name of length of cache of insn dfa codes. */
7392 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7394 /* Names of the PHR interface functions: */
7395 #define SIZE_FUNC_NAME "state_size"
7397 #define TRANSITION_FUNC_NAME "state_transition"
7399 #define STATE_ALTS_FUNC_NAME "state_alts"
7401 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7403 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7405 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7407 #define RESET_FUNC_NAME "state_reset"
7409 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7411 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7413 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7415 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7417 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7419 #define DFA_START_FUNC_NAME "dfa_start"
7421 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7423 /* Names of parameters of the PHR interface functions. */
7424 #define STATE_NAME "state"
7426 #define INSN_PARAMETER_NAME "insn"
7428 #define INSN2_PARAMETER_NAME "insn2"
7430 #define CHIP_PARAMETER_NAME "chip"
7432 #define FILE_PARAMETER_NAME "f"
7434 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7436 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7438 /* Names of the variables whose values are internal insn code of rtx
7439 insn. */
7440 #define INTERNAL_INSN_CODE_NAME "insn_code"
7442 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7444 /* Names of temporary variables in some functions. */
7445 #define TEMPORARY_VARIABLE_NAME "temp"
7447 #define I_VARIABLE_NAME "i"
7449 /* Name of result variable in some functions. */
7450 #define RESULT_VARIABLE_NAME "res"
7452 /* Name of function (attribute) to translate insn into internal insn
7453 code. */
7454 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7456 /* Name of function (attribute) to translate insn into internal insn
7457 code with caching. */
7458 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7460 /* Name of function (attribute) to translate insn into internal insn
7461 code. */
7462 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7464 /* Name of function (attribute) to translate insn into internal insn
7465 code. */
7466 #define BYPASS_P_FUNC_NAME "bypass_p"
7468 /* Output C type which is used for representation of codes of states
7469 of AUTOMATON. */
7470 static void
7471 output_state_member_type (FILE *f, automaton_t automaton)
7473 output_range_type (f, 0, automaton->achieved_states_num);
7476 /* Output definition of the structure representing current DFA(s)
7477 state(s). */
7478 static void
7479 output_chip_definitions (void)
7481 automaton_t automaton;
7483 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7484 for (automaton = description->first_automaton;
7485 automaton != NULL;
7486 automaton = automaton->next_automaton)
7488 fprintf (output_file, " ");
7489 output_state_member_type (output_file, automaton);
7490 fprintf (output_file, " ");
7491 output_chip_member_name (output_file, automaton);
7492 fprintf (output_file, ";\n");
7494 fprintf (output_file, "};\n\n");
7495 #if 0
7496 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7497 #endif
7501 /* The function outputs translate vector of internal insn code into
7502 insn equivalence class number. The equivalence class number is
7503 used to access to table and vectors representing DFA(s). */
7504 static void
7505 output_translate_vect (automaton_t automaton)
7507 ainsn_t ainsn;
7508 int insn_value;
7509 vla_hwint_t translate_vect;
7511 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7512 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7513 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7514 /* Undefined value */
7515 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7516 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7517 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7518 = ainsn->insn_equiv_class_num;
7519 fprintf (output_file,
7520 "/* Vector translating external insn codes to internal ones.*/\n");
7521 fprintf (output_file, "static const ");
7522 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7523 fprintf (output_file, " ");
7524 output_translate_vect_name (output_file, automaton);
7525 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7526 output_vect (VLA_HWINT_BEGIN (translate_vect),
7527 VLA_HWINT_LENGTH (translate_vect));
7528 fprintf (output_file, "};\n\n");
7529 VLA_HWINT_DELETE (translate_vect);
7532 /* The value in a table state x ainsn -> something which represents
7533 undefined value. */
7534 static int undefined_vect_el_value;
7536 /* The following function returns nonzero value if the best
7537 representation of the table is comb vector. */
7538 static int
7539 comb_vect_p (state_ainsn_table_t tab)
7541 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7542 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7545 /* The following function creates new table for AUTOMATON. */
7546 static state_ainsn_table_t
7547 create_state_ainsn_table (automaton_t automaton)
7549 state_ainsn_table_t tab;
7550 int full_vect_length;
7551 int i;
7553 tab = create_node (sizeof (struct state_ainsn_table));
7554 tab->automaton = automaton;
7555 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7556 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7557 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7558 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7559 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7560 full_vect_length = (automaton->insn_equiv_classes_num
7561 * automaton->achieved_states_num);
7562 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7563 for (i = 0; i < full_vect_length; i++)
7564 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7565 tab->min_base_vect_el_value = 0;
7566 tab->max_base_vect_el_value = 0;
7567 tab->min_comb_vect_el_value = 0;
7568 tab->max_comb_vect_el_value = 0;
7569 return tab;
7572 /* The following function outputs the best C representation of the
7573 table TAB of given TABLE_NAME. */
7574 static void
7575 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
7576 void (*output_full_vect_name_func) (FILE *, automaton_t),
7577 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7578 void (*output_check_vect_name_func) (FILE *, automaton_t),
7579 void (*output_base_vect_name_func) (FILE *, automaton_t))
7581 if (!comb_vect_p (tab))
7583 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7584 fprintf (output_file, "static const ");
7585 output_range_type (output_file, tab->min_comb_vect_el_value,
7586 tab->max_comb_vect_el_value);
7587 fprintf (output_file, " ");
7588 (*output_full_vect_name_func) (output_file, tab->automaton);
7589 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7590 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7591 VLA_HWINT_LENGTH (tab->full_vect));
7592 fprintf (output_file, "};\n\n");
7594 else
7596 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7597 fprintf (output_file, "static const ");
7598 output_range_type (output_file, tab->min_comb_vect_el_value,
7599 tab->max_comb_vect_el_value);
7600 fprintf (output_file, " ");
7601 (*output_comb_vect_name_func) (output_file, tab->automaton);
7602 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7603 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7604 VLA_HWINT_LENGTH (tab->comb_vect));
7605 fprintf (output_file, "};\n\n");
7606 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7607 fprintf (output_file, "static const ");
7608 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7609 fprintf (output_file, " ");
7610 (*output_check_vect_name_func) (output_file, tab->automaton);
7611 fprintf (output_file, "[] = {\n");
7612 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7613 VLA_HWINT_LENGTH (tab->check_vect));
7614 fprintf (output_file, "};\n\n");
7615 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7616 fprintf (output_file, "static const ");
7617 output_range_type (output_file, tab->min_base_vect_el_value,
7618 tab->max_base_vect_el_value);
7619 fprintf (output_file, " ");
7620 (*output_base_vect_name_func) (output_file, tab->automaton);
7621 fprintf (output_file, "[] = {\n");
7622 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7623 VLA_HWINT_LENGTH (tab->base_vect));
7624 fprintf (output_file, "};\n\n");
7628 /* The following function adds vector with length VECT_LENGTH and
7629 elements pointed by VECT to table TAB as its line with number
7630 VECT_NUM. */
7631 static void
7632 add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
7633 int vect_length)
7635 int real_vect_length;
7636 vect_el_t *comb_vect_start;
7637 vect_el_t *check_vect_start;
7638 int comb_vect_index;
7639 int comb_vect_els_num;
7640 int vect_index;
7641 int first_unempty_vect_index;
7642 int additional_els_num;
7643 int no_state_value;
7644 vect_el_t vect_el;
7645 int i;
7646 unsigned long vect_mask, comb_vect_mask;
7648 gcc_assert (vect_length);
7649 real_vect_length = tab->automaton->insn_equiv_classes_num;
7650 gcc_assert (vect [vect_length - 1] != undefined_vect_el_value);
7651 /* Form full vector in the table: */
7652 for (i = 0; i < vect_length; i++)
7653 VLA_HWINT (tab->full_vect,
7654 i + tab->automaton->insn_equiv_classes_num * vect_num)
7655 = vect [i];
7656 /* Form comb vector in the table: */
7657 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7658 == VLA_HWINT_LENGTH (tab->check_vect));
7659 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7660 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7661 for (first_unempty_vect_index = 0;
7662 first_unempty_vect_index < vect_length;
7663 first_unempty_vect_index++)
7664 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7665 break;
7667 /* Search for the place in comb vect for the inserted vect. */
7669 /* Slow case. */
7670 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7672 for (comb_vect_index = 0;
7673 comb_vect_index < comb_vect_els_num;
7674 comb_vect_index++)
7676 for (vect_index = first_unempty_vect_index;
7677 vect_index < vect_length
7678 && vect_index + comb_vect_index < comb_vect_els_num;
7679 vect_index++)
7680 if (vect [vect_index] != undefined_vect_el_value
7681 && (comb_vect_start [vect_index + comb_vect_index]
7682 != undefined_vect_el_value))
7683 break;
7684 if (vect_index >= vect_length
7685 || vect_index + comb_vect_index >= comb_vect_els_num)
7686 break;
7688 goto found;
7691 /* Fast case. */
7692 vect_mask = 0;
7693 for (vect_index = first_unempty_vect_index;
7694 vect_index < vect_length;
7695 vect_index++)
7697 vect_mask = vect_mask << 1;
7698 if (vect [vect_index] != undefined_vect_el_value)
7699 vect_mask |= 1;
7702 /* Search for the place in comb vect for the inserted vect. */
7703 comb_vect_index = 0;
7704 if (comb_vect_els_num == 0)
7705 goto found;
7707 comb_vect_mask = 0;
7708 for (vect_index = first_unempty_vect_index;
7709 vect_index < vect_length && vect_index < comb_vect_els_num;
7710 vect_index++)
7712 comb_vect_mask <<= 1;
7713 if (vect_index + comb_vect_index < comb_vect_els_num
7714 && comb_vect_start [vect_index + comb_vect_index]
7715 != undefined_vect_el_value)
7716 comb_vect_mask |= 1;
7718 if ((vect_mask & comb_vect_mask) == 0)
7719 goto found;
7721 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7722 comb_vect_index++, i++)
7724 comb_vect_mask = (comb_vect_mask << 1) | 1;
7725 comb_vect_mask ^= comb_vect_start [i] == undefined_vect_el_value;
7726 if ((vect_mask & comb_vect_mask) == 0)
7727 goto found;
7729 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7731 comb_vect_mask <<= 1;
7732 if ((vect_mask & comb_vect_mask) == 0)
7733 goto found;
7736 found:
7737 /* Slot was found. */
7738 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7739 if (additional_els_num < 0)
7740 additional_els_num = 0;
7741 /* Expand comb and check vectors. */
7742 vect_el = undefined_vect_el_value;
7743 no_state_value = tab->automaton->achieved_states_num;
7744 while (additional_els_num > 0)
7746 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7747 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7748 additional_els_num--;
7750 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7751 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7752 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7753 >= (size_t) (comb_vect_index + real_vect_length));
7754 /* Fill comb and check vectors. */
7755 for (vect_index = 0; vect_index < vect_length; vect_index++)
7756 if (vect [vect_index] != undefined_vect_el_value)
7758 gcc_assert (comb_vect_start [comb_vect_index + vect_index]
7759 == undefined_vect_el_value);
7760 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7761 gcc_assert (vect [vect_index] >= 0);
7762 if (tab->max_comb_vect_el_value < vect [vect_index])
7763 tab->max_comb_vect_el_value = vect [vect_index];
7764 if (tab->min_comb_vect_el_value > vect [vect_index])
7765 tab->min_comb_vect_el_value = vect [vect_index];
7766 check_vect_start [comb_vect_index + vect_index] = vect_num;
7768 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7769 tab->max_comb_vect_el_value = undefined_vect_el_value;
7770 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7771 tab->min_comb_vect_el_value = undefined_vect_el_value;
7772 if (tab->max_base_vect_el_value < comb_vect_index)
7773 tab->max_base_vect_el_value = comb_vect_index;
7774 if (tab->min_base_vect_el_value > comb_vect_index)
7775 tab->min_base_vect_el_value = comb_vect_index;
7776 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7779 /* Return number of out arcs of STATE. */
7780 static int
7781 out_state_arcs_num (state_t state)
7783 int result;
7784 arc_t arc;
7786 result = 0;
7787 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7789 gcc_assert (arc->insn);
7790 if (arc->insn->first_ainsn_with_given_equivalence_num)
7791 result++;
7793 return result;
7796 /* Compare number of possible transitions from the states. */
7797 static int
7798 compare_transition_els_num (const void *state_ptr_1,
7799 const void *state_ptr_2)
7801 int transition_els_num_1;
7802 int transition_els_num_2;
7804 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7805 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7806 if (transition_els_num_1 < transition_els_num_2)
7807 return 1;
7808 else if (transition_els_num_1 == transition_els_num_2)
7809 return 0;
7810 else
7811 return -1;
7814 /* The function adds element EL_VALUE to vector VECT for a table state
7815 x AINSN. */
7816 static void
7817 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7819 int equiv_class_num;
7820 int vect_index;
7822 gcc_assert (ainsn);
7823 equiv_class_num = ainsn->insn_equiv_class_num;
7824 for (vect_index = VLA_HWINT_LENGTH (*vect);
7825 vect_index <= equiv_class_num;
7826 vect_index++)
7827 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7828 VLA_HWINT (*vect, equiv_class_num) = el_value;
7831 /* This is for forming vector of states of an automaton. */
7832 static vla_ptr_t output_states_vect;
7834 /* The function is called by function pass_states. The function adds
7835 STATE to `output_states_vect'. */
7836 static void
7837 add_states_vect_el (state_t state)
7839 VLA_PTR_ADD (output_states_vect, state);
7842 /* Form and output vectors (comb, check, base or full vector)
7843 representing transition table of AUTOMATON. */
7844 static void
7845 output_trans_table (automaton_t automaton)
7847 state_t *state_ptr;
7848 arc_t arc;
7849 vla_hwint_t transition_vect;
7851 undefined_vect_el_value = automaton->achieved_states_num;
7852 automaton->trans_table = create_state_ainsn_table (automaton);
7853 /* Create vect of pointers to states ordered by num of transitions
7854 from the state (state with the maximum num is the first). */
7855 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7856 pass_states (automaton, add_states_vect_el);
7857 qsort (VLA_PTR_BEGIN (output_states_vect),
7858 VLA_PTR_LENGTH (output_states_vect),
7859 sizeof (state_t), compare_transition_els_num);
7860 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7861 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7862 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7863 state_ptr++)
7865 VLA_HWINT_NULLIFY (transition_vect);
7866 for (arc = first_out_arc (*state_ptr);
7867 arc != NULL;
7868 arc = next_out_arc (arc))
7870 gcc_assert (arc->insn);
7871 if (arc->insn->first_ainsn_with_given_equivalence_num)
7872 add_vect_el (&transition_vect, arc->insn,
7873 arc->to_state->order_state_num);
7875 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7876 VLA_HWINT_BEGIN (transition_vect),
7877 VLA_HWINT_LENGTH (transition_vect));
7879 output_state_ainsn_table
7880 (automaton->trans_table, (char *) "state transitions",
7881 output_trans_full_vect_name, output_trans_comb_vect_name,
7882 output_trans_check_vect_name, output_trans_base_vect_name);
7883 VLA_PTR_DELETE (output_states_vect);
7884 VLA_HWINT_DELETE (transition_vect);
7887 /* Form and output vectors (comb, check, base or simple vect)
7888 representing alts number table of AUTOMATON. The table is state x
7889 ainsn -> number of possible alternative reservations by the
7890 ainsn. */
7891 static void
7892 output_state_alts_table (automaton_t automaton)
7894 state_t *state_ptr;
7895 arc_t arc;
7896 vla_hwint_t state_alts_vect;
7898 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7899 automaton->state_alts_table = create_state_ainsn_table (automaton);
7900 /* Create vect of pointers to states ordered by num of transitions
7901 from the state (state with the maximum num is the first). */
7902 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7903 pass_states (automaton, add_states_vect_el);
7904 qsort (VLA_PTR_BEGIN (output_states_vect),
7905 VLA_PTR_LENGTH (output_states_vect),
7906 sizeof (state_t), compare_transition_els_num);
7907 /* Create base, comb, and check vectors. */
7908 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7909 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7910 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7911 state_ptr++)
7913 VLA_HWINT_NULLIFY (state_alts_vect);
7914 for (arc = first_out_arc (*state_ptr);
7915 arc != NULL;
7916 arc = next_out_arc (arc))
7918 gcc_assert (arc->insn);
7919 if (arc->insn->first_ainsn_with_given_equivalence_num)
7920 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7922 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7923 VLA_HWINT_BEGIN (state_alts_vect),
7924 VLA_HWINT_LENGTH (state_alts_vect));
7926 output_state_ainsn_table
7927 (automaton->state_alts_table, (char *) "state insn alternatives",
7928 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7929 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7930 VLA_PTR_DELETE (output_states_vect);
7931 VLA_HWINT_DELETE (state_alts_vect);
7934 /* The current number of passing states to find minimal issue delay
7935 value for an ainsn and state. */
7936 static int curr_state_pass_num;
7938 /* This recursive function passes states to find minimal issue delay
7939 value for AINSN. The state being visited is STATE. The function
7940 returns minimal issue delay value for AINSN in STATE or -1 if we
7941 enter into a loop. */
7942 static int
7943 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7945 arc_t arc;
7946 int min_insn_issue_delay, insn_issue_delay;
7948 if (state->state_pass_num == curr_state_pass_num
7949 || state->min_insn_issue_delay != -1)
7950 /* We've entered into a loop or already have the correct value for
7951 given state and ainsn. */
7952 return state->min_insn_issue_delay;
7953 state->state_pass_num = curr_state_pass_num;
7954 min_insn_issue_delay = -1;
7955 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7956 if (arc->insn == ainsn)
7958 min_insn_issue_delay = 0;
7959 break;
7961 else
7963 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7964 if (insn_issue_delay != -1)
7966 if (arc->insn->insn_reserv_decl
7967 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7968 insn_issue_delay++;
7969 if (min_insn_issue_delay == -1
7970 || min_insn_issue_delay > insn_issue_delay)
7972 min_insn_issue_delay = insn_issue_delay;
7973 if (insn_issue_delay == 0)
7974 break;
7978 return min_insn_issue_delay;
7981 /* The function searches minimal issue delay value for AINSN in STATE.
7982 The function can return negative value if we can not issue AINSN. We
7983 will report about it later. */
7984 static int
7985 min_issue_delay (state_t state, ainsn_t ainsn)
7987 curr_state_pass_num++;
7988 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7989 return state->min_insn_issue_delay;
7992 /* The function initiates code for finding minimal issue delay values.
7993 It should be called only once. */
7994 static void
7995 initiate_min_issue_delay_pass_states (void)
7997 curr_state_pass_num = 0;
8000 /* Form and output vectors representing minimal issue delay table of
8001 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8002 the ainsn. */
8003 static void
8004 output_min_issue_delay_table (automaton_t automaton)
8006 vla_hwint_t min_issue_delay_vect;
8007 vla_hwint_t compressed_min_issue_delay_vect;
8008 vect_el_t min_delay;
8009 ainsn_t ainsn;
8010 state_t *state_ptr;
8011 int i;
8013 /* Create vect of pointers to states ordered by num of transitions
8014 from the state (state with the maximum num is the first). */
8015 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8016 pass_states (automaton, add_states_vect_el);
8017 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
8018 VLA_HWINT_EXPAND (min_issue_delay_vect,
8019 VLA_HWINT_LENGTH (output_states_vect)
8020 * automaton->insn_equiv_classes_num);
8021 for (i = 0;
8022 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
8023 * automaton->insn_equiv_classes_num);
8024 i++)
8025 VLA_HWINT (min_issue_delay_vect, i) = 0;
8026 automaton->max_min_delay = 0;
8027 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
8028 if (ainsn->first_ainsn_with_given_equivalence_num)
8030 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8031 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8032 state_ptr++)
8033 (*state_ptr)->min_insn_issue_delay = -1;
8034 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8035 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8036 state_ptr++)
8038 min_delay = min_issue_delay (*state_ptr, ainsn);
8039 if (automaton->max_min_delay < min_delay)
8040 automaton->max_min_delay = min_delay;
8041 VLA_HWINT (min_issue_delay_vect,
8042 (*state_ptr)->order_state_num
8043 * automaton->insn_equiv_classes_num
8044 + ainsn->insn_equiv_class_num) = min_delay;
8047 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
8048 fprintf (output_file, "static const ");
8049 output_range_type (output_file, 0, automaton->max_min_delay);
8050 fprintf (output_file, " ");
8051 output_min_issue_delay_vect_name (output_file, automaton);
8052 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
8053 /* Compress the vector. */
8054 if (automaton->max_min_delay < 2)
8055 automaton->min_issue_delay_table_compression_factor = 8;
8056 else if (automaton->max_min_delay < 4)
8057 automaton->min_issue_delay_table_compression_factor = 4;
8058 else if (automaton->max_min_delay < 16)
8059 automaton->min_issue_delay_table_compression_factor = 2;
8060 else
8061 automaton->min_issue_delay_table_compression_factor = 1;
8062 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
8063 "compressed min issue delay vector");
8064 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
8065 (VLA_HWINT_LENGTH (min_issue_delay_vect)
8066 + automaton->min_issue_delay_table_compression_factor
8067 - 1)
8068 / automaton->min_issue_delay_table_compression_factor);
8069 for (i = 0;
8070 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
8071 i++)
8072 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
8073 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
8074 VLA_HWINT (compressed_min_issue_delay_vect,
8075 i / automaton->min_issue_delay_table_compression_factor)
8076 |= (VLA_HWINT (min_issue_delay_vect, i)
8077 << (8 - (i % automaton->min_issue_delay_table_compression_factor
8078 + 1)
8079 * (8 / automaton->min_issue_delay_table_compression_factor)));
8080 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
8081 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
8082 fprintf (output_file, "};\n\n");
8083 VLA_PTR_DELETE (output_states_vect);
8084 VLA_HWINT_DELETE (min_issue_delay_vect);
8085 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
8088 #ifndef NDEBUG
8089 /* Number of states which contains transition only by advancing cpu
8090 cycle. */
8091 static int locked_states_num;
8092 #endif
8094 /* Form and output vector representing the locked states of
8095 AUTOMATON. */
8096 static void
8097 output_dead_lock_vect (automaton_t automaton)
8099 state_t *state_ptr;
8100 arc_t arc;
8101 vla_hwint_t dead_lock_vect;
8103 /* Create vect of pointers to states ordered by num of
8104 transitions from the state (state with the maximum num is the
8105 first). */
8106 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8107 pass_states (automaton, add_states_vect_el);
8108 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
8109 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
8110 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8111 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8112 state_ptr++)
8114 arc = first_out_arc (*state_ptr);
8115 gcc_assert (arc);
8116 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8117 = (next_out_arc (arc) == NULL
8118 && (arc->insn->insn_reserv_decl
8119 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8120 #ifndef NDEBUG
8121 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8122 locked_states_num++;
8123 #endif
8125 fprintf (output_file, "/* Vector for locked state flags. */\n");
8126 fprintf (output_file, "static const ");
8127 output_range_type (output_file, 0, 1);
8128 fprintf (output_file, " ");
8129 output_dead_lock_vect_name (output_file, automaton);
8130 fprintf (output_file, "[] = {\n");
8131 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8132 VLA_HWINT_LENGTH (dead_lock_vect));
8133 fprintf (output_file, "};\n\n");
8134 VLA_HWINT_DELETE (dead_lock_vect);
8135 VLA_PTR_DELETE (output_states_vect);
8138 /* Form and output vector representing reserved units of the states of
8139 AUTOMATON. */
8140 static void
8141 output_reserved_units_table (automaton_t automaton)
8143 state_t *curr_state_ptr;
8144 vla_hwint_t reserved_units_table;
8145 size_t state_byte_size;
8146 int i;
8148 /* Create vect of pointers to states. */
8149 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8150 pass_states (automaton, add_states_vect_el);
8151 /* Create vector. */
8152 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8153 state_byte_size = (description->query_units_num + 7) / 8;
8154 VLA_HWINT_EXPAND (reserved_units_table,
8155 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8156 for (i = 0;
8157 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8158 i++)
8159 VLA_HWINT (reserved_units_table, i) = 0;
8160 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8161 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8162 curr_state_ptr++)
8164 for (i = 0; i < description->units_num; i++)
8165 if (units_array [i]->query_p
8166 && first_cycle_unit_presence (*curr_state_ptr, i))
8167 VLA_HWINT (reserved_units_table,
8168 (*curr_state_ptr)->order_state_num * state_byte_size
8169 + units_array [i]->query_num / 8)
8170 += (1 << (units_array [i]->query_num % 8));
8172 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8173 fprintf (output_file, "static const ");
8174 output_range_type (output_file, 0, 255);
8175 fprintf (output_file, " ");
8176 output_reserved_units_table_name (output_file, automaton);
8177 fprintf (output_file, "[] = {\n");
8178 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8179 VLA_HWINT_LENGTH (reserved_units_table));
8180 fprintf (output_file, "};\n\n");
8181 VLA_HWINT_DELETE (reserved_units_table);
8182 VLA_PTR_DELETE (output_states_vect);
8185 /* The function outputs all tables representing DFA(s) used for fast
8186 pipeline hazards recognition. */
8187 static void
8188 output_tables (void)
8190 automaton_t automaton;
8192 #ifndef NDEBUG
8193 locked_states_num = 0;
8194 #endif
8195 initiate_min_issue_delay_pass_states ();
8196 for (automaton = description->first_automaton;
8197 automaton != NULL;
8198 automaton = automaton->next_automaton)
8200 output_translate_vect (automaton);
8201 output_trans_table (automaton);
8202 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8203 output_state_alts_table (automaton);
8204 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8205 AUTOMATON_STATE_ALTS_MACRO_NAME);
8206 output_min_issue_delay_table (automaton);
8207 output_dead_lock_vect (automaton);
8208 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8209 output_reserved_units_table (automaton);
8210 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8211 CPU_UNITS_QUERY_MACRO_NAME);
8213 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8214 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8217 /* The function outputs definition and value of PHR interface variable
8218 `max_insn_queue_index'. Its value is not less than maximal queue
8219 length needed for the insn scheduler. */
8220 static void
8221 output_max_insn_queue_index_def (void)
8223 int i, max, latency;
8224 decl_t decl;
8226 max = description->max_insn_reserv_cycles;
8227 for (i = 0; i < description->decls_num; i++)
8229 decl = description->decls [i];
8230 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8232 latency = DECL_INSN_RESERV (decl)->default_latency;
8233 if (latency > max)
8234 max = latency;
8236 else if (decl->mode == dm_bypass)
8238 latency = DECL_BYPASS (decl)->latency;
8239 if (latency > max)
8240 max = latency;
8243 for (i = 0; (1 << i) <= max; i++)
8245 gcc_assert (i >= 0);
8246 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8250 /* The function outputs switch cases for insn reservations using
8251 function *output_automata_list_code. */
8252 static void
8253 output_insn_code_cases (void (*output_automata_list_code)
8254 (automata_list_el_t))
8256 decl_t decl, decl2;
8257 int i, j;
8259 for (i = 0; i < description->decls_num; i++)
8261 decl = description->decls [i];
8262 if (decl->mode == dm_insn_reserv)
8263 DECL_INSN_RESERV (decl)->processed_p = FALSE;
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)
8271 for (j = i; j < description->decls_num; j++)
8273 decl2 = description->decls [j];
8274 if (decl2->mode == dm_insn_reserv
8275 && (DECL_INSN_RESERV (decl2)->important_automata_list
8276 == DECL_INSN_RESERV (decl)->important_automata_list))
8278 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8279 fprintf (output_file, " case %d: /* %s */\n",
8280 DECL_INSN_RESERV (decl2)->insn_num,
8281 DECL_INSN_RESERV (decl2)->name);
8284 (*output_automata_list_code)
8285 (DECL_INSN_RESERV (decl)->important_automata_list);
8291 /* The function outputs a code for evaluation of a minimal delay of
8292 issue of insns which have reservations in given AUTOMATA_LIST. */
8293 static void
8294 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8296 automata_list_el_t el;
8297 automaton_t automaton;
8299 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8301 automaton = el->automaton;
8302 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8303 output_min_issue_delay_vect_name (output_file, automaton);
8304 fprintf (output_file,
8305 (automaton->min_issue_delay_table_compression_factor != 1
8306 ? " [(" : " ["));
8307 output_translate_vect_name (output_file, automaton);
8308 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8309 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8310 output_chip_member_name (output_file, automaton);
8311 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8312 if (automaton->min_issue_delay_table_compression_factor == 1)
8313 fprintf (output_file, "];\n");
8314 else
8316 fprintf (output_file, ") / %d];\n",
8317 automaton->min_issue_delay_table_compression_factor);
8318 fprintf (output_file, " %s = (%s >> (8 - (",
8319 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8320 output_translate_vect_name (output_file, automaton);
8321 fprintf
8322 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8323 INTERNAL_INSN_CODE_NAME,
8324 automaton->min_issue_delay_table_compression_factor,
8325 8 / automaton->min_issue_delay_table_compression_factor,
8326 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8327 - 1);
8329 if (el == automata_list)
8330 fprintf (output_file, " %s = %s;\n",
8331 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8332 else
8334 fprintf (output_file, " if (%s > %s)\n",
8335 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8336 fprintf (output_file, " %s = %s;\n",
8337 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8340 fprintf (output_file, " break;\n\n");
8343 /* Output function `internal_min_issue_delay'. */
8344 static void
8345 output_internal_min_issue_delay_func (void)
8347 fprintf (output_file,
8348 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8349 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8350 CHIP_NAME, CHIP_PARAMETER_NAME);
8351 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8352 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8353 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8354 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8355 fprintf (output_file,
8356 "\n default:\n %s = -1;\n break;\n }\n",
8357 RESULT_VARIABLE_NAME);
8358 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8359 fprintf (output_file, "}\n\n");
8362 /* The function outputs a code changing state after issue of insns
8363 which have reservations in given AUTOMATA_LIST. */
8364 static void
8365 output_automata_list_transition_code (automata_list_el_t automata_list)
8367 automata_list_el_t el, next_el;
8369 fprintf (output_file, " {\n");
8370 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8371 for (el = automata_list;; el = next_el)
8373 next_el = el->next_automata_list_el;
8374 if (next_el == NULL)
8375 break;
8376 fprintf (output_file, " ");
8377 output_state_member_type (output_file, el->automaton);
8378 fprintf (output_file, " ");
8379 output_temp_chip_member_name (output_file, el->automaton);
8380 fprintf (output_file, ";\n");
8382 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8383 if (comb_vect_p (el->automaton->trans_table))
8385 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8386 output_trans_base_vect_name (output_file, el->automaton);
8387 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8388 output_chip_member_name (output_file, el->automaton);
8389 fprintf (output_file, "] + ");
8390 output_translate_vect_name (output_file, el->automaton);
8391 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8392 fprintf (output_file, " if (");
8393 output_trans_check_vect_name (output_file, el->automaton);
8394 fprintf (output_file, " [%s] != %s->",
8395 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8396 output_chip_member_name (output_file, el->automaton);
8397 fprintf (output_file, ")\n");
8398 fprintf (output_file, " return %s (%s, %s);\n",
8399 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8400 CHIP_PARAMETER_NAME);
8401 fprintf (output_file, " else\n");
8402 fprintf (output_file, " ");
8403 if (el->next_automata_list_el != NULL)
8404 output_temp_chip_member_name (output_file, el->automaton);
8405 else
8407 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8408 output_chip_member_name (output_file, el->automaton);
8410 fprintf (output_file, " = ");
8411 output_trans_comb_vect_name (output_file, el->automaton);
8412 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8414 else
8416 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8417 output_trans_full_vect_name (output_file, el->automaton);
8418 fprintf (output_file, " [");
8419 output_translate_vect_name (output_file, el->automaton);
8420 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8421 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8422 output_chip_member_name (output_file, el->automaton);
8423 fprintf (output_file, " * %d];\n",
8424 el->automaton->insn_equiv_classes_num);
8425 fprintf (output_file, " if (%s >= %d)\n",
8426 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8427 fprintf (output_file, " return %s (%s, %s);\n",
8428 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8429 CHIP_PARAMETER_NAME);
8430 fprintf (output_file, " else\n ");
8431 if (el->next_automata_list_el != NULL)
8432 output_temp_chip_member_name (output_file, el->automaton);
8433 else
8435 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8436 output_chip_member_name (output_file, el->automaton);
8438 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8440 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8441 for (el = automata_list;; el = next_el)
8443 next_el = el->next_automata_list_el;
8444 if (next_el == NULL)
8445 break;
8446 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8447 output_chip_member_name (output_file, el->automaton);
8448 fprintf (output_file, " = ");
8449 output_temp_chip_member_name (output_file, el->automaton);
8450 fprintf (output_file, ";\n");
8452 fprintf (output_file, " return -1;\n");
8453 fprintf (output_file, " }\n");
8456 /* Output function `internal_state_transition'. */
8457 static void
8458 output_internal_trans_func (void)
8460 fprintf (output_file,
8461 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8462 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8463 CHIP_NAME, CHIP_PARAMETER_NAME);
8464 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8465 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8466 output_insn_code_cases (output_automata_list_transition_code);
8467 fprintf (output_file, "\n default:\n return -1;\n }\n");
8468 fprintf (output_file, "}\n\n");
8471 /* Output code
8473 if (insn != 0)
8475 insn_code = dfa_insn_code (insn);
8476 if (insn_code > DFA__ADVANCE_CYCLE)
8477 return code;
8479 else
8480 insn_code = DFA__ADVANCE_CYCLE;
8482 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8483 code denotes CODE. */
8484 static void
8485 output_internal_insn_code_evaluation (const char *insn_name,
8486 const char *insn_code_name,
8487 int code)
8489 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8490 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8491 DFA_INSN_CODE_FUNC_NAME, insn_name);
8492 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8493 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8494 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8495 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8499 /* This function outputs `dfa_insn_code' and its helper function
8500 `dfa_insn_code_enlarge'. */
8501 static void
8502 output_dfa_insn_code_func (void)
8504 /* Emacs c-mode gets really confused if there's a { or } in column 0
8505 inside a string, so don't do that. */
8506 fprintf (output_file, "\
8507 static void\n\
8508 dfa_insn_code_enlarge (int uid)\n\
8509 {\n\
8510 int i = %s;\n\
8511 %s = 2 * uid;\n\
8512 %s = xrealloc (%s,\n\
8513 %s * sizeof(int));\n\
8514 for (; i < %s; i++)\n\
8515 %s[i] = -1;\n}\n\n",
8516 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8517 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8518 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8519 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8520 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8521 DFA_INSN_CODES_VARIABLE_NAME);
8522 fprintf (output_file, "\
8523 static inline int\n%s (rtx %s)\n\
8524 {\n\
8525 int uid = INSN_UID (%s);\n\
8526 int %s;\n\n",
8527 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8528 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8530 fprintf (output_file,
8531 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8532 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8533 fprintf (output_file, " %s = %s[uid];\n",
8534 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8535 fprintf (output_file, "\
8536 if (%s < 0)\n\
8537 {\n\
8538 %s = %s (%s);\n\
8539 %s[uid] = %s;\n\
8540 }\n",
8541 INTERNAL_INSN_CODE_NAME,
8542 INTERNAL_INSN_CODE_NAME,
8543 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8544 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8545 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8548 /* The function outputs PHR interface function `state_transition'. */
8549 static void
8550 output_trans_func (void)
8552 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8553 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8554 INSN_PARAMETER_NAME);
8555 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8556 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8557 INTERNAL_INSN_CODE_NAME, -1);
8558 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8559 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8562 /* The function outputs a code for evaluation of alternative states
8563 number for insns which have reservations in given AUTOMATA_LIST. */
8564 static void
8565 output_automata_list_state_alts_code (automata_list_el_t automata_list)
8567 automata_list_el_t el;
8568 automaton_t automaton;
8570 fprintf (output_file, " {\n");
8571 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8572 if (comb_vect_p (el->automaton->state_alts_table))
8574 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8575 break;
8577 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8579 automaton = el->automaton;
8580 if (comb_vect_p (automaton->state_alts_table))
8582 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8583 output_state_alts_base_vect_name (output_file, automaton);
8584 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8585 output_chip_member_name (output_file, automaton);
8586 fprintf (output_file, "] + ");
8587 output_translate_vect_name (output_file, automaton);
8588 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8589 fprintf (output_file, " if (");
8590 output_state_alts_check_vect_name (output_file, automaton);
8591 fprintf (output_file, " [%s] != %s->",
8592 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8593 output_chip_member_name (output_file, automaton);
8594 fprintf (output_file, ")\n");
8595 fprintf (output_file, " return 0;\n");
8596 fprintf (output_file, " else\n");
8597 fprintf (output_file,
8598 (el == automata_list
8599 ? " %s = " : " %s += "),
8600 RESULT_VARIABLE_NAME);
8601 output_state_alts_comb_vect_name (output_file, automaton);
8602 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8604 else
8606 fprintf (output_file,
8607 (el == automata_list
8608 ? "\n %s = " : " %s += "),
8609 RESULT_VARIABLE_NAME);
8610 output_state_alts_full_vect_name (output_file, automaton);
8611 fprintf (output_file, " [");
8612 output_translate_vect_name (output_file, automaton);
8613 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8614 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8615 output_chip_member_name (output_file, automaton);
8616 fprintf (output_file, " * %d];\n",
8617 automaton->insn_equiv_classes_num);
8620 fprintf (output_file, " break;\n }\n\n");
8623 /* Output function `internal_state_alts'. */
8624 static void
8625 output_internal_state_alts_func (void)
8627 fprintf (output_file,
8628 "static int\n%s (int %s, struct %s *%s)\n",
8629 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8630 CHIP_NAME, CHIP_PARAMETER_NAME);
8631 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8632 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8633 output_insn_code_cases (output_automata_list_state_alts_code);
8634 fprintf (output_file,
8635 "\n default:\n %s = 0;\n break;\n }\n",
8636 RESULT_VARIABLE_NAME);
8637 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8638 fprintf (output_file, "}\n\n");
8641 /* The function outputs PHR interface function `state_alts'. */
8642 static void
8643 output_state_alts_func (void)
8645 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8646 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8647 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8648 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8649 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8650 INTERNAL_INSN_CODE_NAME, 0);
8651 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8652 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8655 /* Output function `min_issue_delay'. */
8656 static void
8657 output_min_issue_delay_func (void)
8659 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8660 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8661 INSN_PARAMETER_NAME);
8662 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8663 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8664 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8665 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8666 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8667 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8668 fprintf (output_file, " }\n else\n %s = %s;\n",
8669 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8670 fprintf (output_file, "\n return %s (%s, %s);\n",
8671 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8672 STATE_NAME);
8673 fprintf (output_file, "}\n\n");
8676 /* Output function `internal_dead_lock'. */
8677 static void
8678 output_internal_dead_lock_func (void)
8680 automaton_t automaton;
8682 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8683 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8684 fprintf (output_file, "{\n");
8685 for (automaton = description->first_automaton;
8686 automaton != NULL;
8687 automaton = automaton->next_automaton)
8689 fprintf (output_file, " if (");
8690 output_dead_lock_vect_name (output_file, automaton);
8691 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8692 output_chip_member_name (output_file, automaton);
8693 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8695 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8698 /* The function outputs PHR interface function `state_dead_lock_p'. */
8699 static void
8700 output_dead_lock_func (void)
8702 fprintf (output_file, "int\n%s (%s %s)\n",
8703 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8704 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8705 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8708 /* Output function `internal_reset'. */
8709 static void
8710 output_internal_reset_func (void)
8712 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8713 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8714 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8715 CHIP_PARAMETER_NAME, CHIP_NAME);
8718 /* The function outputs PHR interface function `state_size'. */
8719 static void
8720 output_size_func (void)
8722 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8723 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8726 /* The function outputs PHR interface function `state_reset'. */
8727 static void
8728 output_reset_func (void)
8730 fprintf (output_file, "void\n%s (%s %s)\n",
8731 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8732 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8733 STATE_NAME);
8736 /* Output function `min_insn_conflict_delay'. */
8737 static void
8738 output_min_insn_conflict_delay_func (void)
8740 fprintf (output_file,
8741 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8742 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8743 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8744 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
8745 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8746 INTERNAL_INSN2_CODE_NAME);
8747 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8748 INTERNAL_INSN_CODE_NAME, 0);
8749 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8750 INTERNAL_INSN2_CODE_NAME, 0);
8751 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8752 CHIP_NAME, STATE_NAME, CHIP_NAME);
8753 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8754 fprintf (output_file, " transition = %s (%s, &%s);\n",
8755 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8756 fprintf (output_file, " gcc_assert (transition <= 0);\n");
8757 fprintf (output_file, " return %s (%s, &%s);\n",
8758 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8759 CHIP_NAME);
8760 fprintf (output_file, "}\n\n");
8763 /* Output function `internal_insn_latency'. */
8764 static void
8765 output_internal_insn_latency_func (void)
8767 decl_t decl;
8768 struct bypass_decl *bypass;
8769 int i, j, col;
8770 const char *tabletype = "unsigned char";
8772 /* Find the smallest integer type that can hold all the default
8773 latency values. */
8774 for (i = 0; i < description->decls_num; i++)
8775 if (description->decls[i]->mode == dm_insn_reserv)
8777 decl = description->decls[i];
8778 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8779 && tabletype[0] != 'i') /* Don't shrink it. */
8780 tabletype = "unsigned short";
8781 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8782 tabletype = "int";
8785 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",
8786 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8787 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8788 INSN2_PARAMETER_NAME);
8789 fprintf (output_file, "{\n");
8791 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8793 fputs (" return 0;\n}\n\n", output_file);
8794 return;
8797 fprintf (output_file, " static const %s default_latencies[] =\n {",
8798 tabletype);
8800 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8801 if (description->decls[i]->mode == dm_insn_reserv
8802 && description->decls[i] != advance_cycle_insn_decl)
8804 if ((col = (col+1) % 8) == 0)
8805 fputs ("\n ", output_file);
8806 decl = description->decls[i];
8807 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8808 fprintf (output_file, "% 4d,",
8809 DECL_INSN_RESERV (decl)->default_latency);
8811 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8812 fputs ("\n };\n", output_file);
8814 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8815 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8816 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8818 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8819 for (i = 0; i < description->decls_num; i++)
8820 if (description->decls[i]->mode == dm_insn_reserv
8821 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8823 decl = description->decls [i];
8824 fprintf (output_file,
8825 " case %d:\n switch (%s)\n {\n",
8826 DECL_INSN_RESERV (decl)->insn_num,
8827 INTERNAL_INSN2_CODE_NAME);
8828 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8829 bypass != NULL;
8830 bypass = bypass->next)
8832 gcc_assert (bypass->in_insn_reserv->insn_num
8833 != (DECL_INSN_RESERV
8834 (advance_cycle_insn_decl)->insn_num));
8835 fprintf (output_file, " case %d:\n",
8836 bypass->in_insn_reserv->insn_num);
8837 if (bypass->bypass_guard_name == NULL)
8838 fprintf (output_file, " return %d;\n",
8839 bypass->latency);
8840 else
8842 fprintf (output_file,
8843 " if (%s (%s, %s))\n",
8844 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8845 INSN2_PARAMETER_NAME);
8846 fprintf (output_file,
8847 " return %d;\n break;\n",
8848 bypass->latency);
8851 fputs (" }\n break;\n", output_file);
8854 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8855 INTERNAL_INSN_CODE_NAME);
8858 /* The function outputs PHR interface function `insn_latency'. */
8859 static void
8860 output_insn_latency_func (void)
8862 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8863 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8864 fprintf (output_file, "{\n int %s, %s;\n",
8865 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8866 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8867 INTERNAL_INSN_CODE_NAME, 0);
8868 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8869 INTERNAL_INSN2_CODE_NAME, 0);
8870 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8871 INTERNAL_INSN_LATENCY_FUNC_NAME,
8872 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8873 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8876 /* The function outputs PHR interface function `print_reservation'. */
8877 static void
8878 output_print_reservation_func (void)
8880 decl_t decl;
8881 int i, j;
8883 fprintf (output_file,
8884 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8885 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8886 INSN_PARAMETER_NAME);
8888 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8890 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8891 NOTHING_NAME, FILE_PARAMETER_NAME);
8892 return;
8896 fputs (" static const char *const reservation_names[] =\n {",
8897 output_file);
8899 for (i = 0, j = 0; i < description->decls_num; i++)
8901 decl = description->decls [i];
8902 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8904 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8905 j++;
8907 fprintf (output_file, "\n \"%s\",",
8908 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8909 finish_regexp_representation ();
8912 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8914 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8915 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8917 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8918 INSN_PARAMETER_NAME,
8919 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8920 fprintf (output_file, " else\n\
8921 {\n\
8922 %s = %s (%s);\n\
8923 if (%s > %s)\n\
8924 %s = %s;\n\
8925 }\n",
8926 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8927 INSN_PARAMETER_NAME,
8928 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8929 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8931 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8932 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8935 /* The following function is used to sort unit declaration by their
8936 names. */
8937 static int
8938 units_cmp (const void *unit1, const void *unit2)
8940 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8941 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8943 return strcmp (u1->name, u2->name);
8946 /* The following macro value is name of struct containing unit name
8947 and unit code. */
8948 #define NAME_CODE_STRUCT_NAME "name_code"
8950 /* The following macro value is name of table of struct name_code. */
8951 #define NAME_CODE_TABLE_NAME "name_code_table"
8953 /* The following macro values are member names for struct name_code. */
8954 #define NAME_MEMBER_NAME "name"
8955 #define CODE_MEMBER_NAME "code"
8957 /* The following macro values are local variable names for function
8958 `get_cpu_unit_code'. */
8959 #define CMP_VARIABLE_NAME "cmp"
8960 #define LOW_VARIABLE_NAME "l"
8961 #define MIDDLE_VARIABLE_NAME "m"
8962 #define HIGH_VARIABLE_NAME "h"
8964 /* The following function outputs function to obtain internal cpu unit
8965 code by the cpu unit name. */
8966 static void
8967 output_get_cpu_unit_code_func (void)
8969 int i;
8970 unit_decl_t *units;
8972 fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8973 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8974 CPU_UNIT_NAME_PARAMETER_NAME);
8975 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8976 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8977 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8978 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8979 fprintf (output_file, " static struct %s %s [] =\n {\n",
8980 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8981 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8982 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8983 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8984 for (i = 0; i < description->units_num; i++)
8985 if (units [i]->query_p)
8986 fprintf (output_file, " {\"%s\", %d},\n",
8987 units[i]->name, units[i]->query_num);
8988 fprintf (output_file, " };\n\n");
8989 fprintf (output_file, " /* The following is binary search: */\n");
8990 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8991 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8992 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8993 fprintf (output_file, " while (%s <= %s)\n {\n",
8994 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8995 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8996 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8997 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8998 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8999 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
9000 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
9001 fprintf (output_file, " %s = %s - 1;\n",
9002 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9003 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
9004 fprintf (output_file, " %s = %s + 1;\n",
9005 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9006 fprintf (output_file, " else\n");
9007 fprintf (output_file, " return %s [%s].%s;\n }\n",
9008 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
9009 fprintf (output_file, " return -1;\n}\n\n");
9010 free (units);
9013 /* The following function outputs function to check reservation of cpu
9014 unit (its internal code will be passed as the function argument) in
9015 given cpu state. */
9016 static void
9017 output_cpu_unit_reservation_p (void)
9019 automaton_t automaton;
9021 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
9022 CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
9023 CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
9024 CPU_CODE_PARAMETER_NAME);
9025 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
9026 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
9027 description->query_units_num);
9028 for (automaton = description->first_automaton;
9029 automaton != NULL;
9030 automaton = automaton->next_automaton)
9032 fprintf (output_file, " if ((");
9033 output_reserved_units_table_name (output_file, automaton);
9034 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
9035 output_chip_member_name (output_file, automaton);
9036 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9037 (description->query_units_num + 7) / 8,
9038 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
9039 fprintf (output_file, " return 1;\n");
9041 fprintf (output_file, " return 0;\n}\n\n");
9044 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9045 static void
9046 output_dfa_clean_insn_cache_func (void)
9048 fprintf (output_file,
9049 "void\n%s (void)\n{\n int %s;\n\n",
9050 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
9051 fprintf (output_file,
9052 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9053 I_VARIABLE_NAME, I_VARIABLE_NAME,
9054 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
9055 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
9058 /* The function outputs PHR interface function `dfa_start'. */
9059 static void
9060 output_dfa_start_func (void)
9062 fprintf (output_file,
9063 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
9064 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9065 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
9066 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9067 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
9070 /* The function outputs PHR interface function `dfa_finish'. */
9071 static void
9072 output_dfa_finish_func (void)
9074 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
9075 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
9080 /* The page contains code for output description file (readable
9081 representation of original description and generated DFA(s). */
9083 /* The function outputs string representation of IR reservation. */
9084 static void
9085 output_regexp (regexp_t regexp)
9087 fprintf (output_description_file, "%s", regexp_representation (regexp));
9088 finish_regexp_representation ();
9091 /* Output names of units in LIST separated by comma. */
9092 static void
9093 output_unit_set_el_list (unit_set_el_t list)
9095 unit_set_el_t el;
9097 for (el = list; el != NULL; el = el->next_unit_set_el)
9099 if (el != list)
9100 fprintf (output_description_file, ", ");
9101 fprintf (output_description_file, "%s", el->unit_decl->name);
9105 /* Output patterns in LIST separated by comma. */
9106 static void
9107 output_pattern_set_el_list (pattern_set_el_t list)
9109 pattern_set_el_t el;
9110 int i;
9112 for (el = list; el != NULL; el = el->next_pattern_set_el)
9114 if (el != list)
9115 fprintf (output_description_file, ", ");
9116 for (i = 0; i < el->units_num; i++)
9117 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9118 el->unit_decls [i]->name);
9122 /* The function outputs string representation of IR define_reservation
9123 and define_insn_reservation. */
9124 static void
9125 output_description (void)
9127 decl_t decl;
9128 int i;
9130 for (i = 0; i < description->decls_num; i++)
9132 decl = description->decls [i];
9133 if (decl->mode == dm_unit)
9135 if (DECL_UNIT (decl)->excl_list != NULL)
9137 fprintf (output_description_file, "unit %s exlusion_set: ",
9138 DECL_UNIT (decl)->name);
9139 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9140 fprintf (output_description_file, "\n");
9142 if (DECL_UNIT (decl)->presence_list != NULL)
9144 fprintf (output_description_file, "unit %s presence_set: ",
9145 DECL_UNIT (decl)->name);
9146 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9147 fprintf (output_description_file, "\n");
9149 if (DECL_UNIT (decl)->final_presence_list != NULL)
9151 fprintf (output_description_file, "unit %s final_presence_set: ",
9152 DECL_UNIT (decl)->name);
9153 output_pattern_set_el_list
9154 (DECL_UNIT (decl)->final_presence_list);
9155 fprintf (output_description_file, "\n");
9157 if (DECL_UNIT (decl)->absence_list != NULL)
9159 fprintf (output_description_file, "unit %s absence_set: ",
9160 DECL_UNIT (decl)->name);
9161 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9162 fprintf (output_description_file, "\n");
9164 if (DECL_UNIT (decl)->final_absence_list != NULL)
9166 fprintf (output_description_file, "unit %s final_absence_set: ",
9167 DECL_UNIT (decl)->name);
9168 output_pattern_set_el_list
9169 (DECL_UNIT (decl)->final_absence_list);
9170 fprintf (output_description_file, "\n");
9174 fprintf (output_description_file, "\n");
9175 for (i = 0; i < description->decls_num; i++)
9177 decl = description->decls [i];
9178 if (decl->mode == dm_reserv)
9180 fprintf (output_description_file, "reservation %s: ",
9181 DECL_RESERV (decl)->name);
9182 output_regexp (DECL_RESERV (decl)->regexp);
9183 fprintf (output_description_file, "\n");
9185 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9187 fprintf (output_description_file, "insn reservation %s ",
9188 DECL_INSN_RESERV (decl)->name);
9189 print_rtl (output_description_file,
9190 DECL_INSN_RESERV (decl)->condexp);
9191 fprintf (output_description_file, ": ");
9192 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9193 fprintf (output_description_file, "\n");
9195 else if (decl->mode == dm_bypass)
9196 fprintf (output_description_file, "bypass %d %s %s\n",
9197 DECL_BYPASS (decl)->latency,
9198 DECL_BYPASS (decl)->out_insn_name,
9199 DECL_BYPASS (decl)->in_insn_name);
9201 fprintf (output_description_file, "\n\f\n");
9204 /* The function outputs name of AUTOMATON. */
9205 static void
9206 output_automaton_name (FILE *f, automaton_t automaton)
9208 if (automaton->corresponding_automaton_decl == NULL)
9209 fprintf (f, "#%d", automaton->automaton_order_num);
9210 else
9211 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9214 /* Maximal length of line for pretty printing into description
9215 file. */
9216 #define MAX_LINE_LENGTH 70
9218 /* The function outputs units name belonging to AUTOMATON. */
9219 static void
9220 output_automaton_units (automaton_t automaton)
9222 decl_t decl;
9223 char *name;
9224 int curr_line_length;
9225 int there_is_an_automaton_unit;
9226 int i;
9228 fprintf (output_description_file, "\n Corresponding units:\n");
9229 fprintf (output_description_file, " ");
9230 curr_line_length = 4;
9231 there_is_an_automaton_unit = 0;
9232 for (i = 0; i < description->decls_num; i++)
9234 decl = description->decls [i];
9235 if (decl->mode == dm_unit
9236 && (DECL_UNIT (decl)->corresponding_automaton_num
9237 == automaton->automaton_order_num))
9239 there_is_an_automaton_unit = 1;
9240 name = DECL_UNIT (decl)->name;
9241 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9243 curr_line_length = strlen (name) + 4;
9244 fprintf (output_description_file, "\n ");
9246 else
9248 curr_line_length += strlen (name) + 1;
9249 fprintf (output_description_file, " ");
9251 fprintf (output_description_file, "%s", name);
9254 if (!there_is_an_automaton_unit)
9255 fprintf (output_description_file, "<None>");
9256 fprintf (output_description_file, "\n\n");
9259 /* The following variable is used for forming array of all possible cpu unit
9260 reservations described by the current DFA state. */
9261 static vla_ptr_t state_reservs;
9263 /* The function forms `state_reservs' for STATE. */
9264 static void
9265 add_state_reservs (state_t state)
9267 alt_state_t curr_alt_state;
9268 reserv_sets_t reservs;
9270 if (state->component_states != NULL)
9271 for (curr_alt_state = state->component_states;
9272 curr_alt_state != NULL;
9273 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9274 add_state_reservs (curr_alt_state->state);
9275 else
9277 reservs = state->reservs;
9278 VLA_PTR_ADD (state_reservs, reservs);
9282 /* The function outputs readable representation of all out arcs of
9283 STATE. */
9284 static void
9285 output_state_arcs (state_t state)
9287 arc_t arc;
9288 ainsn_t ainsn;
9289 char *insn_name;
9290 int curr_line_length;
9292 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9294 ainsn = arc->insn;
9295 gcc_assert (ainsn->first_insn_with_same_reservs);
9296 fprintf (output_description_file, " ");
9297 curr_line_length = 7;
9298 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9301 insn_name = ainsn->insn_reserv_decl->name;
9302 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9304 if (ainsn != arc->insn)
9306 fprintf (output_description_file, ",\n ");
9307 curr_line_length = strlen (insn_name) + 6;
9309 else
9310 curr_line_length += strlen (insn_name);
9312 else
9314 curr_line_length += strlen (insn_name);
9315 if (ainsn != arc->insn)
9317 curr_line_length += 2;
9318 fprintf (output_description_file, ", ");
9321 fprintf (output_description_file, "%s", insn_name);
9322 ainsn = ainsn->next_same_reservs_insn;
9324 while (ainsn != NULL);
9325 fprintf (output_description_file, " %d (%d)\n",
9326 arc->to_state->order_state_num, arc->state_alts);
9328 fprintf (output_description_file, "\n");
9331 /* The following function is used for sorting possible cpu unit
9332 reservation of a DFA state. */
9333 static int
9334 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9336 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9337 *(reserv_sets_t *) reservs_ptr_2);
9340 /* The following function is used for sorting possible cpu unit
9341 reservation of a DFA state. */
9342 static void
9343 remove_state_duplicate_reservs (void)
9345 reserv_sets_t *reservs_ptr;
9346 reserv_sets_t *last_formed_reservs_ptr;
9348 last_formed_reservs_ptr = NULL;
9349 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9350 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9351 reservs_ptr++)
9352 if (last_formed_reservs_ptr == NULL)
9353 last_formed_reservs_ptr = reservs_ptr;
9354 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9356 ++last_formed_reservs_ptr;
9357 *last_formed_reservs_ptr = *reservs_ptr;
9359 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9362 /* The following function output readable representation of DFA(s)
9363 state used for fast recognition of pipeline hazards. State is
9364 described by possible (current and scheduled) cpu unit
9365 reservations. */
9366 static void
9367 output_state (state_t state)
9369 reserv_sets_t *reservs_ptr;
9371 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9372 fprintf (output_description_file, " State #%d", state->order_state_num);
9373 fprintf (output_description_file,
9374 state->new_cycle_p ? " (new cycle)\n" : "\n");
9375 add_state_reservs (state);
9376 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9377 sizeof (reserv_sets_t), state_reservs_cmp);
9378 remove_state_duplicate_reservs ();
9379 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9380 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9381 reservs_ptr++)
9383 fprintf (output_description_file, " ");
9384 output_reserv_sets (output_description_file, *reservs_ptr);
9385 fprintf (output_description_file, "\n");
9387 fprintf (output_description_file, "\n");
9388 output_state_arcs (state);
9389 VLA_PTR_DELETE (state_reservs);
9392 /* The following function output readable representation of
9393 DFAs used for fast recognition of pipeline hazards. */
9394 static void
9395 output_automaton_descriptions (void)
9397 automaton_t automaton;
9399 for (automaton = description->first_automaton;
9400 automaton != NULL;
9401 automaton = automaton->next_automaton)
9403 fprintf (output_description_file, "\nAutomaton ");
9404 output_automaton_name (output_description_file, automaton);
9405 fprintf (output_description_file, "\n");
9406 output_automaton_units (automaton);
9407 pass_states (automaton, output_state);
9413 /* The page contains top level function for generation DFA(s) used for
9414 PHR. */
9416 /* The function outputs statistics about work of different phases of
9417 DFA generator. */
9418 static void
9419 output_statistics (FILE *f)
9421 automaton_t automaton;
9422 int states_num;
9423 #ifndef NDEBUG
9424 int transition_comb_vect_els = 0;
9425 int transition_full_vect_els = 0;
9426 int state_alts_comb_vect_els = 0;
9427 int state_alts_full_vect_els = 0;
9428 int min_issue_delay_vect_els = 0;
9429 #endif
9431 for (automaton = description->first_automaton;
9432 automaton != NULL;
9433 automaton = automaton->next_automaton)
9435 fprintf (f, "\nAutomaton ");
9436 output_automaton_name (f, automaton);
9437 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9438 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9439 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9440 automaton->DFA_states_num, automaton->DFA_arcs_num);
9441 states_num = automaton->DFA_states_num;
9442 if (!no_minimization_flag)
9444 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9445 automaton->minimal_DFA_states_num,
9446 automaton->minimal_DFA_arcs_num);
9447 states_num = automaton->minimal_DFA_states_num;
9449 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9450 description->insns_num, automaton->insn_equiv_classes_num);
9451 #ifndef NDEBUG
9452 fprintf
9453 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9454 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9455 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9456 (comb_vect_p (automaton->trans_table)
9457 ? "use comb vect" : "use simple vect"));
9458 fprintf
9459 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9460 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9461 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9462 (comb_vect_p (automaton->state_alts_table)
9463 ? "use comb vect" : "use simple vect"));
9464 fprintf
9465 (f, "%5ld min delay table els, compression factor %d\n",
9466 (long) states_num * automaton->insn_equiv_classes_num,
9467 automaton->min_issue_delay_table_compression_factor);
9468 transition_comb_vect_els
9469 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9470 transition_full_vect_els
9471 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9472 state_alts_comb_vect_els
9473 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9474 state_alts_full_vect_els
9475 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9476 min_issue_delay_vect_els
9477 += states_num * automaton->insn_equiv_classes_num;
9478 #endif
9480 #ifndef NDEBUG
9481 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9482 allocated_states_num, allocated_arcs_num);
9483 fprintf (f, "%5d all allocated alternative states\n",
9484 allocated_alt_states_num);
9485 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9486 transition_comb_vect_els, transition_full_vect_els);
9487 fprintf
9488 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9489 state_alts_comb_vect_els, state_alts_full_vect_els);
9490 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9491 fprintf (f, "%5d locked states num\n", locked_states_num);
9492 #endif
9495 /* The function output times of work of different phases of DFA
9496 generator. */
9497 static void
9498 output_time_statistics (FILE *f)
9500 fprintf (f, "\n transformation: ");
9501 print_active_time (f, transform_time);
9502 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9503 print_active_time (f, NDFA_time);
9504 if (ndfa_flag)
9506 fprintf (f, ", NDFA -> DFA: ");
9507 print_active_time (f, NDFA_to_DFA_time);
9509 fprintf (f, "\n DFA minimization: ");
9510 print_active_time (f, minimize_time);
9511 fprintf (f, ", making insn equivalence: ");
9512 print_active_time (f, equiv_time);
9513 fprintf (f, "\n all automaton generation: ");
9514 print_active_time (f, automaton_generation_time);
9515 fprintf (f, ", output: ");
9516 print_active_time (f, output_time);
9517 fprintf (f, "\n");
9520 /* The function generates DFA (deterministic finite state automaton)
9521 for fast recognition of pipeline hazards. No errors during
9522 checking must be fixed before this function call. */
9523 static void
9524 generate (void)
9526 automata_num = split_argument;
9527 if (description->units_num < automata_num)
9528 automata_num = description->units_num;
9529 initiate_states ();
9530 initiate_arcs ();
9531 initiate_automata_lists ();
9532 initiate_pass_states ();
9533 initiate_excl_sets ();
9534 initiate_presence_absence_pattern_sets ();
9535 automaton_generation_time = create_ticker ();
9536 create_automata ();
9537 ticker_off (&automaton_generation_time);
9542 /* The following function creates insn attribute whose values are
9543 number alternatives in insn reservations. */
9544 static void
9545 make_insn_alts_attr (void)
9547 int i, insn_num;
9548 decl_t decl;
9549 rtx condexp;
9551 condexp = rtx_alloc (COND);
9552 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9553 XEXP (condexp, 1) = make_numeric_value (0);
9554 for (i = insn_num = 0; i < description->decls_num; i++)
9556 decl = description->decls [i];
9557 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9559 XVECEXP (condexp, 0, 2 * insn_num)
9560 = DECL_INSN_RESERV (decl)->condexp;
9561 XVECEXP (condexp, 0, 2 * insn_num + 1)
9562 = make_numeric_value
9563 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9564 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9565 ->transformed_regexp)->regexps_num);
9566 insn_num++;
9569 gcc_assert (description->insns_num == insn_num + 1);
9570 make_internal_attr (attr_printf (sizeof ("*")
9571 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9572 "*%s", INSN_ALTS_FUNC_NAME),
9573 condexp, ATTR_NONE);
9578 /* The following function creates attribute which is order number of
9579 insn in pipeline hazard description translator. */
9580 static void
9581 make_internal_dfa_insn_code_attr (void)
9583 int i, insn_num;
9584 decl_t decl;
9585 rtx condexp;
9587 condexp = rtx_alloc (COND);
9588 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9589 XEXP (condexp, 1)
9590 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9591 ->insn_num + 1);
9592 for (i = insn_num = 0; i < description->decls_num; i++)
9594 decl = description->decls [i];
9595 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9597 XVECEXP (condexp, 0, 2 * insn_num)
9598 = DECL_INSN_RESERV (decl)->condexp;
9599 XVECEXP (condexp, 0, 2 * insn_num + 1)
9600 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9601 insn_num++;
9604 gcc_assert (description->insns_num == insn_num + 1);
9605 make_internal_attr
9606 (attr_printf (sizeof ("*")
9607 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9608 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9609 condexp, ATTR_STATIC);
9614 /* The following function creates attribute which order number of insn
9615 in pipeline hazard description translator. */
9616 static void
9617 make_default_insn_latency_attr (void)
9619 int i, insn_num;
9620 decl_t decl;
9621 rtx condexp;
9623 condexp = rtx_alloc (COND);
9624 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9625 XEXP (condexp, 1) = make_numeric_value (0);
9626 for (i = insn_num = 0; i < description->decls_num; i++)
9628 decl = description->decls [i];
9629 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9631 XVECEXP (condexp, 0, 2 * insn_num)
9632 = DECL_INSN_RESERV (decl)->condexp;
9633 XVECEXP (condexp, 0, 2 * insn_num + 1)
9634 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9635 insn_num++;
9638 gcc_assert (description->insns_num == insn_num + 1);
9639 make_internal_attr (attr_printf (sizeof ("*")
9640 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9641 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9642 condexp, ATTR_NONE);
9647 /* The following function creates attribute which returns 1 if given
9648 output insn has bypassing and 0 otherwise. */
9649 static void
9650 make_bypass_attr (void)
9652 int i, bypass_insn;
9653 int bypass_insns_num = 0;
9654 decl_t decl;
9655 rtx result_rtx;
9657 for (i = 0; i < description->decls_num; i++)
9659 decl = description->decls [i];
9660 if (decl->mode == dm_insn_reserv
9661 && DECL_INSN_RESERV (decl)->condexp != NULL
9662 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9663 bypass_insns_num++;
9665 if (bypass_insns_num == 0)
9666 result_rtx = make_numeric_value (0);
9667 else
9669 result_rtx = rtx_alloc (COND);
9670 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9671 XEXP (result_rtx, 1) = make_numeric_value (0);
9673 for (i = bypass_insn = 0; i < description->decls_num; i++)
9675 decl = description->decls [i];
9676 if (decl->mode == dm_insn_reserv
9677 && DECL_INSN_RESERV (decl)->condexp != NULL
9678 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9680 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9681 = DECL_INSN_RESERV (decl)->condexp;
9682 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9683 = make_numeric_value (1);
9684 bypass_insn++;
9688 make_internal_attr (attr_printf (sizeof ("*")
9689 + strlen (BYPASS_P_FUNC_NAME) + 1,
9690 "*%s", BYPASS_P_FUNC_NAME),
9691 result_rtx, ATTR_NONE);
9696 /* This page mainly contains top level functions of pipeline hazards
9697 description translator. */
9699 /* The following macro value is suffix of name of description file of
9700 pipeline hazards description translator. */
9701 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9703 /* The function returns suffix of given file name. The returned
9704 string can not be changed. */
9705 static const char *
9706 file_name_suffix (const char *file_name)
9708 const char *last_period;
9710 for (last_period = NULL; *file_name != '\0'; file_name++)
9711 if (*file_name == '.')
9712 last_period = file_name;
9713 return (last_period == NULL ? file_name : last_period);
9716 /* The function returns base name of given file name, i.e. pointer to
9717 first char after last `/' (or `\' for WIN32) in given file name,
9718 given file name itself if the directory name is absent. The
9719 returned string can not be changed. */
9720 static const char *
9721 base_file_name (const char *file_name)
9723 int directory_name_length;
9725 directory_name_length = strlen (file_name);
9726 #ifdef WIN32
9727 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9728 && file_name[directory_name_length] != '\\')
9729 #else
9730 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9731 #endif
9732 directory_name_length--;
9733 return file_name + directory_name_length + 1;
9736 /* The following is top level function to initialize the work of
9737 pipeline hazards description translator. */
9738 void
9739 initiate_automaton_gen (int argc, char **argv)
9741 const char *base_name;
9742 int i;
9744 ndfa_flag = 0;
9745 split_argument = 0; /* default value */
9746 no_minimization_flag = 0;
9747 time_flag = 0;
9748 v_flag = 0;
9749 w_flag = 0;
9750 progress_flag = 0;
9751 for (i = 2; i < argc; i++)
9752 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9753 no_minimization_flag = 1;
9754 else if (strcmp (argv [i], TIME_OPTION) == 0)
9755 time_flag = 1;
9756 else if (strcmp (argv [i], V_OPTION) == 0)
9757 v_flag = 1;
9758 else if (strcmp (argv [i], W_OPTION) == 0)
9759 w_flag = 1;
9760 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9761 ndfa_flag = 1;
9762 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9763 progress_flag = 1;
9764 else if (strcmp (argv [i], "-split") == 0)
9766 if (i + 1 >= argc)
9767 fatal ("-split has no argument.");
9768 fatal ("option `-split' has not been implemented yet\n");
9769 /* split_argument = atoi (argument_vect [i + 1]); */
9771 VLA_PTR_CREATE (decls, 150, "decls");
9772 /* Initialize IR storage. */
9773 obstack_init (&irp);
9774 initiate_automaton_decl_table ();
9775 initiate_insn_decl_table ();
9776 initiate_decl_table ();
9777 output_file = stdout;
9778 output_description_file = NULL;
9779 base_name = base_file_name (argv[1]);
9780 obstack_grow (&irp, base_name,
9781 strlen (base_name) - strlen (file_name_suffix (base_name)));
9782 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9783 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9784 obstack_1grow (&irp, '\0');
9785 output_description_file_name = obstack_base (&irp);
9786 obstack_finish (&irp);
9789 /* The following function checks existence at least one arc marked by
9790 each insn. */
9791 static void
9792 check_automata_insn_issues (void)
9794 automaton_t automaton;
9795 ainsn_t ainsn, reserv_ainsn;
9797 for (automaton = description->first_automaton;
9798 automaton != NULL;
9799 automaton = automaton->next_automaton)
9801 for (ainsn = automaton->ainsn_list;
9802 ainsn != NULL;
9803 ainsn = ainsn->next_ainsn)
9804 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9806 for (reserv_ainsn = ainsn;
9807 reserv_ainsn != NULL;
9808 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9809 if (automaton->corresponding_automaton_decl != NULL)
9811 if (!w_flag)
9812 error ("Automaton `%s': Insn `%s' will never be issued",
9813 automaton->corresponding_automaton_decl->name,
9814 reserv_ainsn->insn_reserv_decl->name);
9815 else
9816 warning
9817 ("Automaton `%s': Insn `%s' will never be issued",
9818 automaton->corresponding_automaton_decl->name,
9819 reserv_ainsn->insn_reserv_decl->name);
9821 else
9823 if (!w_flag)
9824 error ("Insn `%s' will never be issued",
9825 reserv_ainsn->insn_reserv_decl->name);
9826 else
9827 warning ("Insn `%s' will never be issued",
9828 reserv_ainsn->insn_reserv_decl->name);
9834 /* The following vla is used for storing pointers to all achieved
9835 states. */
9836 static vla_ptr_t automaton_states;
9838 /* This function is called by function pass_states to add an achieved
9839 STATE. */
9840 static void
9841 add_automaton_state (state_t state)
9843 VLA_PTR_ADD (automaton_states, state);
9846 /* The following function forms list of important automata (whose
9847 states may be changed after the insn issue) for each insn. */
9848 static void
9849 form_important_insn_automata_lists (void)
9851 automaton_t automaton;
9852 state_t *state_ptr;
9853 decl_t decl;
9854 ainsn_t ainsn;
9855 arc_t arc;
9856 int i;
9858 VLA_PTR_CREATE (automaton_states, 1500,
9859 "automaton states for forming important insn automata sets");
9860 /* Mark important ainsns. */
9861 for (automaton = description->first_automaton;
9862 automaton != NULL;
9863 automaton = automaton->next_automaton)
9865 VLA_PTR_NULLIFY (automaton_states);
9866 pass_states (automaton, add_automaton_state);
9867 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9868 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9869 state_ptr++)
9871 for (arc = first_out_arc (*state_ptr);
9872 arc != NULL;
9873 arc = next_out_arc (arc))
9874 if (arc->to_state != *state_ptr)
9876 gcc_assert (arc->insn->first_insn_with_same_reservs);
9877 for (ainsn = arc->insn;
9878 ainsn != NULL;
9879 ainsn = ainsn->next_same_reservs_insn)
9880 ainsn->important_p = TRUE;
9884 VLA_PTR_DELETE (automaton_states);
9885 /* Create automata sets for the insns. */
9886 for (i = 0; i < description->decls_num; i++)
9888 decl = description->decls [i];
9889 if (decl->mode == dm_insn_reserv)
9891 automata_list_start ();
9892 for (automaton = description->first_automaton;
9893 automaton != NULL;
9894 automaton = automaton->next_automaton)
9895 for (ainsn = automaton->ainsn_list;
9896 ainsn != NULL;
9897 ainsn = ainsn->next_ainsn)
9898 if (ainsn->important_p
9899 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9901 automata_list_add (automaton);
9902 break;
9904 DECL_INSN_RESERV (decl)->important_automata_list
9905 = automata_list_finish ();
9911 /* The following is top level function to generate automat(a,on) for
9912 fast recognition of pipeline hazards. */
9913 void
9914 expand_automata (void)
9916 int i;
9918 description = create_node (sizeof (struct description)
9919 /* One entry for cycle advancing insn. */
9920 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9921 description->decls_num = VLA_PTR_LENGTH (decls);
9922 description->query_units_num = 0;
9923 for (i = 0; i < description->decls_num; i++)
9925 description->decls [i] = VLA_PTR (decls, i);
9926 if (description->decls [i]->mode == dm_unit
9927 && DECL_UNIT (description->decls [i])->query_p)
9928 DECL_UNIT (description->decls [i])->query_num
9929 = description->query_units_num++;
9931 all_time = create_ticker ();
9932 check_time = create_ticker ();
9933 if (progress_flag)
9934 fprintf (stderr, "Check description...");
9935 check_all_description ();
9936 if (progress_flag)
9937 fprintf (stderr, "done\n");
9938 ticker_off (&check_time);
9939 generation_time = create_ticker ();
9940 if (!have_error)
9942 transform_insn_regexps ();
9943 check_unit_distributions_to_automata ();
9945 if (!have_error)
9947 generate ();
9948 check_automata_insn_issues ();
9950 if (!have_error)
9952 form_important_insn_automata_lists ();
9953 if (progress_flag)
9954 fprintf (stderr, "Generation of attributes...");
9955 make_internal_dfa_insn_code_attr ();
9956 make_insn_alts_attr ();
9957 make_default_insn_latency_attr ();
9958 make_bypass_attr ();
9959 if (progress_flag)
9960 fprintf (stderr, "done\n");
9962 ticker_off (&generation_time);
9963 ticker_off (&all_time);
9964 if (progress_flag)
9965 fprintf (stderr, "All other genattrtab stuff...");
9968 /* The following is top level function to output PHR and to finish
9969 work with pipeline description translator. */
9970 void
9971 write_automata (void)
9973 if (progress_flag)
9974 fprintf (stderr, "done\n");
9975 if (have_error)
9976 fatal ("Errors in DFA description");
9977 ticker_on (&all_time);
9978 output_time = create_ticker ();
9979 if (progress_flag)
9980 fprintf (stderr, "Forming and outputting automata tables...");
9981 output_dfa_max_issue_rate ();
9982 output_tables ();
9983 if (progress_flag)
9985 fprintf (stderr, "done\n");
9986 fprintf (stderr, "Output functions to work with automata...");
9988 output_chip_definitions ();
9989 output_max_insn_queue_index_def ();
9990 output_internal_min_issue_delay_func ();
9991 output_internal_trans_func ();
9992 /* Cache of insn dfa codes: */
9993 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9994 fprintf (output_file, "\nstatic int %s;\n\n",
9995 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9996 output_dfa_insn_code_func ();
9997 output_trans_func ();
9998 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9999 output_internal_state_alts_func ();
10000 output_state_alts_func ();
10001 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10002 AUTOMATON_STATE_ALTS_MACRO_NAME);
10003 output_min_issue_delay_func ();
10004 output_internal_dead_lock_func ();
10005 output_dead_lock_func ();
10006 output_size_func ();
10007 output_internal_reset_func ();
10008 output_reset_func ();
10009 output_min_insn_conflict_delay_func ();
10010 output_internal_insn_latency_func ();
10011 output_insn_latency_func ();
10012 output_print_reservation_func ();
10013 /* Output function get_cpu_unit_code. */
10014 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10015 output_get_cpu_unit_code_func ();
10016 output_cpu_unit_reservation_p ();
10017 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10018 CPU_UNITS_QUERY_MACRO_NAME);
10019 output_dfa_clean_insn_cache_func ();
10020 output_dfa_start_func ();
10021 output_dfa_finish_func ();
10022 if (progress_flag)
10023 fprintf (stderr, "done\n");
10024 if (v_flag)
10026 output_description_file = fopen (output_description_file_name, "w");
10027 if (output_description_file == NULL)
10029 perror (output_description_file_name);
10030 exit (FATAL_EXIT_CODE);
10032 if (progress_flag)
10033 fprintf (stderr, "Output automata description...");
10034 output_description ();
10035 output_automaton_descriptions ();
10036 if (progress_flag)
10037 fprintf (stderr, "done\n");
10038 output_statistics (output_description_file);
10040 output_statistics (stderr);
10041 ticker_off (&output_time);
10042 output_time_statistics (stderr);
10043 finish_states ();
10044 finish_arcs ();
10045 finish_automata_lists ();
10046 if (time_flag)
10048 fprintf (stderr, "Summary:\n");
10049 fprintf (stderr, " check time ");
10050 print_active_time (stderr, check_time);
10051 fprintf (stderr, ", generation time ");
10052 print_active_time (stderr, generation_time);
10053 fprintf (stderr, ", all time ");
10054 print_active_time (stderr, all_time);
10055 fprintf (stderr, "\n");
10057 /* Finish all work. */
10058 if (output_description_file != NULL)
10060 fflush (output_description_file);
10061 if (ferror (stdout) != 0)
10062 fatal ("Error in writing DFA description file %s",
10063 output_description_file_name);
10064 fclose (output_description_file);
10066 finish_automaton_decl_table ();
10067 finish_insn_decl_table ();
10068 finish_decl_table ();
10069 obstack_free (&irp, NULL);
10070 if (have_error && output_description_file != NULL)
10071 remove (output_description_file_name);