2005-06-07 Adrian Straetling <straetling@de.ibm.com>
[official-gcc.git] / gcc / genautomata.c
blob51e2f416a3a33129fa7f930f808f47bca275470e
1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 Written by Vladimir Makarov <vmakarov@redhat.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
24 /* References:
26 1. Detecting pipeline structural hazards quickly. T. Proebsting,
27 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
28 Principles of Programming Languages, pages 280--286, 1994.
30 This article is a good start point to understand usage of finite
31 state automata for pipeline hazard recognizers. But I'd
32 recommend the 2nd article for more deep understanding.
34 2. Efficient Instruction Scheduling Using Finite State Automata:
35 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
36 article about usage of finite state automata for pipeline hazard
37 recognizers.
39 The current implementation is different from the 2nd article in the
40 following:
42 1. New operator `|' (alternative) is permitted in functional unit
43 reservation which can be treated deterministically and
44 non-deterministically.
46 2. Possibility of usage of nondeterministic automata too.
48 3. Possibility to query functional unit reservations for given
49 automaton state.
51 4. Several constructions to describe impossible reservations
52 (`exclusion_set', `presence_set', `final_presence_set',
53 `absence_set', and `final_absence_set').
55 5. No reverse automata are generated. Trace instruction scheduling
56 requires this. It can be easily added in the future if we
57 really need this.
59 6. Union of automaton states are not generated yet. It is planned
60 to be implemented. Such feature is needed to make more accurate
61 interlock insn scheduling to get state describing functional
62 unit reservation in a joint CFG point. */
64 /* This file code processes constructions of machine description file
65 which describes automaton used for recognition of processor pipeline
66 hazards by insn scheduler and can be used for other tasks (such as
67 VLIW insn packing.
69 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
70 `gen_bypass', `gen_excl_set', `gen_presence_set',
71 `gen_final_presence_set', `gen_absence_set',
72 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
73 `gen_reserv', `gen_insn_reserv' are called from file
74 `genattrtab.c'. They transform RTL constructions describing
75 automata in .md file into internal representation convenient for
76 further processing.
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
80 It can be divided on:
82 o checking correctness of the automaton pipeline description
83 (major function is `check_all_description').
85 o generating automaton (automata) from the description (major
86 function is `make_automaton').
88 o optional transformation of nondeterministic finite state
89 automata into deterministic ones if the alternative operator
90 `|' is treated nondeterministically in the description (major
91 function is NDFA_to_DFA).
93 o optional minimization of the finite state automata by merging
94 equivalent automaton states (major function is `minimize_DFA').
96 o forming tables (some as comb vectors) and attributes
97 representing the automata (functions output_..._table).
99 Function `write_automata' outputs the created finite state
100 automaton as different tables and functions which works with the
101 automata to inquire automaton state and to change its state. These
102 function are used by gcc instruction scheduler and may be some
103 other gcc code. */
105 #include "bconfig.h"
106 #include "system.h"
107 #include "coretypes.h"
108 #include "tm.h"
109 #include "rtl.h"
110 #include "obstack.h"
111 #include "errors.h"
113 #include <math.h>
114 #include "hashtab.h"
115 #include "varray.h"
117 #ifndef CHAR_BIT
118 #define CHAR_BIT 8
119 #endif
121 #include "genattrtab.h"
123 /* Positions in machine description file. Now they are not used. But
124 they could be used in the future for better diagnostic messages. */
125 typedef int pos_t;
127 /* The following is element of vector of current (and planned in the
128 future) functional unit reservations. */
129 typedef unsigned HOST_WIDE_INT set_el_t;
131 /* Reservations of function units are represented by value of the following
132 type. */
133 typedef set_el_t *reserv_sets_t;
135 /* The following structure represents variable length array (vla) of
136 pointers and HOST WIDE INTs. We could be use only varray. But we
137 add new lay because we add elements very frequently and this could
138 stress OS allocator when varray is used only. */
139 typedef struct {
140 size_t length; /* current size of vla. */
141 varray_type varray; /* container for vla. */
142 } vla_ptr_t;
144 typedef vla_ptr_t vla_hwint_t;
146 /* The following structure describes a ticker. */
147 struct ticker
149 /* The following member value is time of the ticker creation with
150 taking into account time when the ticker is off. Active time of
151 the ticker is current time minus the value. */
152 int modified_creation_time;
153 /* The following member value is time (incremented by one) when the
154 ticker was off. Zero value means that now the ticker is on. */
155 int incremented_off_time;
158 /* The ticker is represented by the following type. */
159 typedef struct ticker ticker_t;
161 /* The following type describes elements of output vectors. */
162 typedef HOST_WIDE_INT vect_el_t;
164 /* Forward declaration of structures of internal representation of
165 pipeline description based on NDFA. */
167 struct unit_decl;
168 struct bypass_decl;
169 struct result_decl;
170 struct automaton_decl;
171 struct unit_pattern_rel_decl;
172 struct reserv_decl;
173 struct insn_reserv_decl;
174 struct decl;
175 struct unit_regexp;
176 struct result_regexp;
177 struct reserv_regexp;
178 struct nothing_regexp;
179 struct sequence_regexp;
180 struct repeat_regexp;
181 struct allof_regexp;
182 struct oneof_regexp;
183 struct regexp;
184 struct description;
185 struct unit_set_el;
186 struct pattern_set_el;
187 struct pattern_reserv;
188 struct state;
189 struct alt_state;
190 struct arc;
191 struct ainsn;
192 struct automaton;
193 struct state_ainsn_table;
195 /* The following typedefs are for brevity. */
196 typedef struct unit_decl *unit_decl_t;
197 typedef struct decl *decl_t;
198 typedef struct regexp *regexp_t;
199 typedef struct unit_set_el *unit_set_el_t;
200 typedef struct pattern_set_el *pattern_set_el_t;
201 typedef struct pattern_reserv *pattern_reserv_t;
202 typedef struct alt_state *alt_state_t;
203 typedef struct state *state_t;
204 typedef struct arc *arc_t;
205 typedef struct ainsn *ainsn_t;
206 typedef struct automaton *automaton_t;
207 typedef struct automata_list_el *automata_list_el_t;
208 typedef struct state_ainsn_table *state_ainsn_table_t;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
213 gen_absence_set, gen_final_absence_set, gen_automaton,
214 gen_automata_option, gen_reserv, gen_insn_reserv,
215 initiate_automaton_gen, expand_automata, write_automata are
216 described on the file top because the functions are called from
217 function `main'. */
219 static void *create_node (size_t);
220 static void *copy_node (const void *, size_t);
221 static char *check_name (char *, pos_t);
222 static char *next_sep_el (char **, int, int);
223 static int n_sep_els (char *, int, int);
224 static char **get_str_vect (char *, int *, int, int);
225 static void gen_presence_absence_set (rtx, int, int);
226 static regexp_t gen_regexp_el (char *);
227 static regexp_t gen_regexp_repeat (char *);
228 static regexp_t gen_regexp_allof (char *);
229 static regexp_t gen_regexp_oneof (char *);
230 static regexp_t gen_regexp_sequence (char *);
231 static regexp_t gen_regexp (char *);
233 static unsigned string_hash (const char *);
234 static unsigned automaton_decl_hash (const void *);
235 static int automaton_decl_eq_p (const void *,
236 const void *);
237 static decl_t insert_automaton_decl (decl_t);
238 static decl_t find_automaton_decl (char *);
239 static void initiate_automaton_decl_table (void);
240 static void finish_automaton_decl_table (void);
242 static hashval_t insn_decl_hash (const void *);
243 static int insn_decl_eq_p (const void *,
244 const void *);
245 static decl_t insert_insn_decl (decl_t);
246 static decl_t find_insn_decl (char *);
247 static void initiate_insn_decl_table (void);
248 static void finish_insn_decl_table (void);
250 static hashval_t decl_hash (const void *);
251 static int decl_eq_p (const void *,
252 const void *);
253 static decl_t insert_decl (decl_t);
254 static decl_t find_decl (char *);
255 static void initiate_decl_table (void);
256 static void finish_decl_table (void);
258 static unit_set_el_t process_excls (char **, int, pos_t);
259 static void add_excls (unit_set_el_t, unit_set_el_t,
260 pos_t);
261 static unit_set_el_t process_presence_absence_names
262 (char **, int, pos_t,
263 int, int);
264 static pattern_set_el_t process_presence_absence_patterns
265 (char ***, int, pos_t,
266 int, int);
267 static void add_presence_absence (unit_set_el_t,
268 pattern_set_el_t,
269 pos_t, int, int);
270 static void process_decls (void);
271 static struct bypass_decl *find_bypass (struct bypass_decl *,
272 struct insn_reserv_decl *);
273 static void check_automaton_usage (void);
274 static regexp_t process_regexp (regexp_t);
275 static void process_regexp_decls (void);
276 static void check_usage (void);
277 static int loop_in_regexp (regexp_t, decl_t);
278 static void check_loops_in_regexps (void);
279 static void process_regexp_cycles (regexp_t, int, int,
280 int *, int *);
281 static void evaluate_max_reserv_cycles (void);
282 static void check_all_description (void);
284 static ticker_t create_ticker (void);
285 static void ticker_off (ticker_t *);
286 static void ticker_on (ticker_t *);
287 static int active_time (ticker_t);
288 static void print_active_time (FILE *, ticker_t);
290 static void add_advance_cycle_insn_decl (void);
292 static alt_state_t get_free_alt_state (void);
293 static void free_alt_state (alt_state_t);
294 static void free_alt_states (alt_state_t);
295 static int alt_state_cmp (const void *alt_state_ptr_1,
296 const void *alt_state_ptr_2);
297 static alt_state_t uniq_sort_alt_states (alt_state_t);
298 static int alt_states_eq (alt_state_t, alt_state_t);
299 static void initiate_alt_states (void);
300 static void finish_alt_states (void);
302 static reserv_sets_t alloc_empty_reserv_sets (void);
303 static unsigned reserv_sets_hash_value (reserv_sets_t);
304 static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
305 static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
306 static void set_unit_reserv (reserv_sets_t, int, int);
307 static int test_unit_reserv (reserv_sets_t, int, int);
308 static int it_is_empty_reserv_sets (reserv_sets_t)
309 ATTRIBUTE_UNUSED;
310 static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
311 static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
312 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
313 reserv_sets_t);
314 static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
315 reserv_sets_t)
316 ATTRIBUTE_UNUSED;
317 static void output_cycle_reservs (FILE *, reserv_sets_t,
318 int, int);
319 static void output_reserv_sets (FILE *, reserv_sets_t);
320 static state_t get_free_state (int, automaton_t);
321 static void free_state (state_t);
322 static hashval_t state_hash (const void *);
323 static int state_eq_p (const void *, const void *);
324 static state_t insert_state (state_t);
325 static void set_state_reserv (state_t, int, int);
326 static int intersected_state_reservs_p (state_t, state_t);
327 static state_t states_union (state_t, state_t, reserv_sets_t);
328 static state_t state_shift (state_t, reserv_sets_t);
329 static void initiate_states (void);
330 static void finish_states (void);
332 static void free_arc (arc_t);
333 static void remove_arc (state_t, arc_t);
334 static arc_t find_arc (state_t, state_t, ainsn_t);
335 static arc_t add_arc (state_t, state_t, ainsn_t, int);
336 static arc_t first_out_arc (state_t);
337 static arc_t next_out_arc (arc_t);
338 static void initiate_arcs (void);
339 static void finish_arcs (void);
341 static automata_list_el_t get_free_automata_list_el (void);
342 static void free_automata_list_el (automata_list_el_t);
343 static void free_automata_list (automata_list_el_t);
344 static hashval_t automata_list_hash (const void *);
345 static int automata_list_eq_p (const void *, const void *);
346 static void initiate_automata_lists (void);
347 static void automata_list_start (void);
348 static void automata_list_add (automaton_t);
349 static automata_list_el_t automata_list_finish (void);
350 static void finish_automata_lists (void);
352 static void initiate_excl_sets (void);
353 static reserv_sets_t get_excl_set (reserv_sets_t);
355 static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
356 static void initiate_presence_absence_pattern_sets (void);
357 static int check_presence_pattern_sets (reserv_sets_t,
358 reserv_sets_t, int);
359 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
360 int);
362 static regexp_t copy_insn_regexp (regexp_t);
363 static regexp_t transform_1 (regexp_t);
364 static regexp_t transform_2 (regexp_t);
365 static regexp_t transform_3 (regexp_t);
366 static regexp_t regexp_transform_func
367 (regexp_t, regexp_t (*) (regexp_t));
368 static regexp_t transform_regexp (regexp_t);
369 static void transform_insn_regexps (void);
371 static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
372 static void check_regexp_units_distribution (const char *, regexp_t);
373 static void check_unit_distributions_to_automata (void);
375 static int process_seq_for_forming_states (regexp_t, automaton_t,
376 int);
377 static void finish_forming_alt_state (alt_state_t,
378 automaton_t);
379 static void process_alts_for_forming_states (regexp_t,
380 automaton_t, int);
381 static void create_alt_states (automaton_t);
383 static void form_ainsn_with_same_reservs (automaton_t);
385 static reserv_sets_t form_reservs_matter (automaton_t);
386 static void make_automaton (automaton_t);
387 static void form_arcs_marked_by_insn (state_t);
388 static int create_composed_state (state_t, arc_t, vla_ptr_t *);
389 static void NDFA_to_DFA (automaton_t);
390 static void pass_state_graph (state_t, void (*) (state_t));
391 static void pass_states (automaton_t,
392 void (*) (state_t));
393 static void initiate_pass_states (void);
394 static void add_achieved_state (state_t);
395 static int set_out_arc_insns_equiv_num (state_t, int);
396 static void clear_arc_insns_equiv_num (state_t);
397 static void copy_equiv_class (vla_ptr_t *to,
398 const vla_ptr_t *from);
399 static int first_cycle_unit_presence (state_t, int);
400 static int state_is_differed (state_t, state_t, int, int);
401 static state_t init_equiv_class (state_t *states, int);
402 static int partition_equiv_class (state_t *, int,
403 vla_ptr_t *, int *);
404 static void evaluate_equiv_classes (automaton_t, vla_ptr_t *);
405 static void merge_states (automaton_t, vla_ptr_t *);
406 static void set_new_cycle_flags (state_t);
407 static void minimize_DFA (automaton_t);
408 static void incr_states_and_arcs_nums (state_t);
409 static void count_states_and_arcs (automaton_t, int *, int *);
410 static void build_automaton (automaton_t);
412 static void set_order_state_num (state_t);
413 static void enumerate_states (automaton_t);
415 static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
416 static void delete_ainsn_from_equiv_class (ainsn_t);
417 static void process_insn_equiv_class (ainsn_t, arc_t *);
418 static void process_state_for_insn_equiv_partition (state_t);
419 static void set_insn_equiv_classes (automaton_t);
421 static double estimate_one_automaton_bound (void);
422 static int compare_max_occ_cycle_nums (const void *,
423 const void *);
424 static void units_to_automata_heuristic_distr (void);
425 static ainsn_t create_ainsns (void);
426 static void units_to_automata_distr (void);
427 static void create_automata (void);
429 static void form_regexp (regexp_t);
430 static const char *regexp_representation (regexp_t);
431 static void finish_regexp_representation (void);
433 static void output_range_type (FILE *, long int, long int);
434 static int longest_path_length (state_t);
435 static void process_state_longest_path_length (state_t);
436 static void output_dfa_max_issue_rate (void);
437 static void output_vect (vect_el_t *, int);
438 static void output_chip_member_name (FILE *, automaton_t);
439 static void output_temp_chip_member_name (FILE *, automaton_t);
440 static void output_translate_vect_name (FILE *, automaton_t);
441 static void output_trans_full_vect_name (FILE *, automaton_t);
442 static void output_trans_comb_vect_name (FILE *, automaton_t);
443 static void output_trans_check_vect_name (FILE *, automaton_t);
444 static void output_trans_base_vect_name (FILE *, automaton_t);
445 static void output_state_alts_full_vect_name (FILE *, automaton_t);
446 static void output_state_alts_comb_vect_name (FILE *, automaton_t);
447 static void output_state_alts_check_vect_name (FILE *, automaton_t);
448 static void output_state_alts_base_vect_name (FILE *, automaton_t);
449 static void output_min_issue_delay_vect_name (FILE *, automaton_t);
450 static void output_dead_lock_vect_name (FILE *, automaton_t);
451 static void output_reserved_units_table_name (FILE *, automaton_t);
452 static void output_state_member_type (FILE *, automaton_t);
453 static void output_chip_definitions (void);
454 static void output_translate_vect (automaton_t);
455 static int comb_vect_p (state_ainsn_table_t);
456 static state_ainsn_table_t create_state_ainsn_table (automaton_t);
457 static void output_state_ainsn_table
458 (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
459 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
460 void (*) (FILE *, automaton_t));
461 static void add_vect (state_ainsn_table_t,
462 int, vect_el_t *, int);
463 static int out_state_arcs_num (state_t);
464 static int compare_transition_els_num (const void *, const void *);
465 static void add_vect_el (vla_hwint_t *,
466 ainsn_t, int);
467 static void add_states_vect_el (state_t);
468 static void output_trans_table (automaton_t);
469 static void output_state_alts_table (automaton_t);
470 static int min_issue_delay_pass_states (state_t, ainsn_t);
471 static int min_issue_delay (state_t, ainsn_t);
472 static void initiate_min_issue_delay_pass_states (void);
473 static void output_min_issue_delay_table (automaton_t);
474 static void output_dead_lock_vect (automaton_t);
475 static void output_reserved_units_table (automaton_t);
476 static void output_tables (void);
477 static void output_max_insn_queue_index_def (void);
478 static void output_insn_code_cases (void (*) (automata_list_el_t));
479 static void output_automata_list_min_issue_delay_code (automata_list_el_t);
480 static void output_internal_min_issue_delay_func (void);
481 static void output_automata_list_transition_code (automata_list_el_t);
482 static void output_internal_trans_func (void);
483 static void output_internal_insn_code_evaluation (const char *,
484 const char *, int);
485 static void output_dfa_insn_code_func (void);
486 static void output_trans_func (void);
487 static void output_automata_list_state_alts_code (automata_list_el_t);
488 static void output_internal_state_alts_func (void);
489 static void output_state_alts_func (void);
490 static void output_min_issue_delay_func (void);
491 static void output_internal_dead_lock_func (void);
492 static void output_dead_lock_func (void);
493 static void output_internal_reset_func (void);
494 static void output_size_func (void);
495 static void output_reset_func (void);
496 static void output_min_insn_conflict_delay_func (void);
497 static void output_internal_insn_latency_func (void);
498 static void output_insn_latency_func (void);
499 static void output_print_reservation_func (void);
500 static int units_cmp (const void *,
501 const void *);
502 static void output_get_cpu_unit_code_func (void);
503 static void output_cpu_unit_reservation_p (void);
504 static void output_dfa_clean_insn_cache_func (void);
505 static void output_dfa_start_func (void);
506 static void output_dfa_finish_func (void);
508 static void output_regexp (regexp_t );
509 static void output_unit_set_el_list (unit_set_el_t);
510 static void output_pattern_set_el_list (pattern_set_el_t);
511 static void output_description (void);
512 static void output_automaton_name (FILE *, automaton_t);
513 static void output_automaton_units (automaton_t);
514 static void add_state_reservs (state_t);
515 static void output_state_arcs (state_t);
516 static int state_reservs_cmp (const void *,
517 const void *);
518 static void remove_state_duplicate_reservs (void);
519 static void output_state (state_t);
520 static void output_automaton_descriptions (void);
521 static void output_statistics (FILE *);
522 static void output_time_statistics (FILE *);
523 static void generate (void);
525 static void make_insn_alts_attr (void);
526 static void make_internal_dfa_insn_code_attr (void);
527 static void make_default_insn_latency_attr (void);
528 static void make_bypass_attr (void);
529 static const char *file_name_suffix (const char *);
530 static const char *base_file_name (const char *);
531 static void check_automata_insn_issues (void);
532 static void add_automaton_state (state_t);
533 static void form_important_insn_automata_lists (void);
535 /* Undefined position. */
536 static pos_t no_pos = 0;
538 /* All IR is stored in the following obstack. */
539 static struct obstack irp;
543 /* This page contains code for work with variable length array (vla)
544 of pointers. We could be use only varray. But we add new lay
545 because we add elements very frequently and this could stress OS
546 allocator when varray is used only. */
548 /* Start work with vla. */
549 #define VLA_PTR_CREATE(vla, allocated_length, name) \
550 do \
552 vla_ptr_t *const _vla_ptr = &(vla); \
554 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
555 _vla_ptr->length = 0; \
557 while (0)
559 /* Finish work with the vla. */
560 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
562 /* Return start address of the vla. */
563 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
565 /* Address of the last element of the vla. Do not use side effects in
566 the macro argument. */
567 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
568 (vla).length - 1))
569 /* Nullify the vla. */
570 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
572 /* Shorten the vla on given number bytes. */
573 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
575 /* Expand the vla on N elements. The values of new elements are
576 undefined. */
577 #define VLA_PTR_EXPAND(vla, n) \
578 do { \
579 vla_ptr_t *const _expand_vla_ptr = &(vla); \
580 const size_t _new_length = (n) + _expand_vla_ptr->length; \
582 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
583 VARRAY_GROW (_expand_vla_ptr->varray, \
584 (_new_length - _expand_vla_ptr->length < 128 \
585 ? _expand_vla_ptr->length + 128 : _new_length)); \
586 _expand_vla_ptr->length = _new_length; \
587 } while (0)
589 /* Add element to the end of the vla. */
590 #define VLA_PTR_ADD(vla, ptr) \
591 do { \
592 vla_ptr_t *const _vla_ptr = &(vla); \
594 VLA_PTR_EXPAND (*_vla_ptr, 1); \
595 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
596 } while (0)
598 /* Length of the vla in elements. */
599 #define VLA_PTR_LENGTH(vla) ((vla).length)
601 /* N-th element of the vla. */
602 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
605 /* The following macros are analogous to the previous ones but for
606 VLAs of HOST WIDE INTs. */
608 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
609 do { \
610 vla_hwint_t *const _vla_ptr = &(vla); \
612 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
613 _vla_ptr->length = 0; \
614 } while (0)
616 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
618 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
620 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
622 #define VLA_HWINT_EXPAND(vla, n) \
623 do { \
624 vla_hwint_t *const _expand_vla_ptr = &(vla); \
625 const size_t _new_length = (n) + _expand_vla_ptr->length; \
627 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
628 VARRAY_GROW (_expand_vla_ptr->varray, \
629 (_new_length - _expand_vla_ptr->length < 128 \
630 ? _expand_vla_ptr->length + 128 : _new_length)); \
631 _expand_vla_ptr->length = _new_length; \
632 } while (0)
634 #define VLA_HWINT_ADD(vla, ptr) \
635 do { \
636 vla_hwint_t *const _vla_ptr = &(vla); \
638 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
639 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
640 } while (0)
642 #define VLA_HWINT_LENGTH(vla) ((vla).length)
644 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
648 /* Options with the following names can be set up in automata_option
649 construction. Because the strings occur more one time we use the
650 macros. */
652 #define NO_MINIMIZATION_OPTION "-no-minimization"
654 #define TIME_OPTION "-time"
656 #define V_OPTION "-v"
658 #define W_OPTION "-w"
660 #define NDFA_OPTION "-ndfa"
662 #define PROGRESS_OPTION "-progress"
664 /* The following flags are set up by function `initiate_automaton_gen'. */
666 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
667 static int ndfa_flag;
669 /* Do not make minimization of DFA (`-no-minimization'). */
670 static int no_minimization_flag;
672 /* Value of this variable is number of automata being generated. The
673 actual number of automata may be less this value if there is not
674 sufficient number of units. This value is defined by argument of
675 option `-split' or by constructions automaton if the value is zero
676 (it is default value of the argument). */
677 static int split_argument;
679 /* Flag of output time statistics (`-time'). */
680 static int time_flag;
682 /* Flag of creation of description file which contains description of
683 result automaton and statistics information (`-v'). */
684 static int v_flag;
686 /* Flag of output of a progress bar showing how many states were
687 generated so far for automaton being processed (`-progress'). */
688 static int progress_flag;
690 /* Flag of generating warning instead of error for non-critical errors
691 (`-w'). */
692 static int w_flag;
695 /* Output file for pipeline hazard recognizer (PHR) being generated.
696 The value is NULL if the file is not defined. */
697 static FILE *output_file;
699 /* Description file of PHR. The value is NULL if the file is not
700 created. */
701 static FILE *output_description_file;
703 /* PHR description file name. */
704 static char *output_description_file_name;
706 /* Value of the following variable is node representing description
707 being processed. This is start point of IR. */
708 static struct description *description;
712 /* This page contains description of IR structure (nodes). */
714 enum decl_mode
716 dm_unit,
717 dm_bypass,
718 dm_automaton,
719 dm_excl,
720 dm_presence,
721 dm_absence,
722 dm_reserv,
723 dm_insn_reserv
726 /* This describes define_cpu_unit and define_query_cpu_unit (see file
727 rtl.def). */
728 struct unit_decl
730 char *name;
731 /* NULL if the automaton name is absent. */
732 char *automaton_name;
733 /* If the following value is not zero, the cpu unit reservation is
734 described in define_query_cpu_unit. */
735 char query_p;
737 /* The following fields are defined by checker. */
739 /* The following field value is nonzero if the unit is used in an
740 regexp. */
741 char unit_is_used;
743 /* The following field value is order number (0, 1, ...) of given
744 unit. */
745 int unit_num;
746 /* The following field value is corresponding declaration of
747 automaton which was given in description. If the field value is
748 NULL then automaton in the unit declaration was absent. */
749 struct automaton_decl *automaton_decl;
750 /* The following field value is maximal cycle number (1, ...) on
751 which given unit occurs in insns. Zero value means that given
752 unit is not used in insns. */
753 int max_occ_cycle_num;
754 /* The following field value is minimal cycle number (0, ...) on
755 which given unit occurs in insns. -1 value means that given
756 unit is not used in insns. */
757 int min_occ_cycle_num;
758 /* The following list contains units which conflict with given
759 unit. */
760 unit_set_el_t excl_list;
761 /* The following list contains patterns which are required to
762 reservation of given unit. */
763 pattern_set_el_t presence_list;
764 pattern_set_el_t final_presence_list;
765 /* The following list contains patterns which should be not present
766 in reservation for given unit. */
767 pattern_set_el_t absence_list;
768 pattern_set_el_t final_absence_list;
769 /* The following is used only when `query_p' has nonzero value.
770 This is query number for the unit. */
771 int query_num;
772 /* The following is the last cycle on which the unit was checked for
773 correct distributions of units to automata in a regexp. */
774 int last_distribution_check_cycle;
776 /* The following fields are defined by automaton generator. */
778 /* The following field value is number of the automaton to which
779 given unit belongs. */
780 int corresponding_automaton_num;
781 /* If the following value is not zero, the cpu unit is present in a
782 `exclusion_set' or in right part of a `presence_set',
783 `final_presence_set', `absence_set', and
784 `final_absence_set'define_query_cpu_unit. */
785 char in_set_p;
788 /* This describes define_bypass (see file rtl.def). */
789 struct bypass_decl
791 int latency;
792 char *out_insn_name;
793 char *in_insn_name;
794 char *bypass_guard_name;
796 /* The following fields are defined by checker. */
798 /* output and input insns of given bypass. */
799 struct insn_reserv_decl *out_insn_reserv;
800 struct insn_reserv_decl *in_insn_reserv;
801 /* The next bypass for given output insn. */
802 struct bypass_decl *next;
805 /* This describes define_automaton (see file rtl.def). */
806 struct automaton_decl
808 char *name;
810 /* The following fields are defined by automaton generator. */
812 /* The following field value is nonzero if the automaton is used in
813 an regexp definition. */
814 char automaton_is_used;
816 /* The following fields are defined by checker. */
818 /* The following field value is the corresponding automaton. This
819 field is not NULL only if the automaton is present in unit
820 declarations and the automatic partition on automata is not
821 used. */
822 automaton_t corresponding_automaton;
825 /* This describes exclusion relations: exclusion_set (see file
826 rtl.def). */
827 struct excl_rel_decl
829 int all_names_num;
830 int first_list_length;
831 char *names [1];
834 /* This describes unit relations: [final_]presence_set or
835 [final_]absence_set (see file rtl.def). */
836 struct unit_pattern_rel_decl
838 int final_p;
839 int names_num;
840 int patterns_num;
841 char **names;
842 char ***patterns;
845 /* This describes define_reservation (see file rtl.def). */
846 struct reserv_decl
848 char *name;
849 regexp_t regexp;
851 /* The following fields are defined by checker. */
853 /* The following field value is nonzero if the unit is used in an
854 regexp. */
855 char reserv_is_used;
856 /* The following field is used to check up cycle in expression
857 definition. */
858 int loop_pass_num;
861 /* This describes define_insn_reservation (see file rtl.def). */
862 struct insn_reserv_decl
864 rtx condexp;
865 int default_latency;
866 regexp_t regexp;
867 char *name;
869 /* The following fields are defined by checker. */
871 /* The following field value is order number (0, 1, ...) of given
872 insn. */
873 int insn_num;
874 /* The following field value is list of bypasses in which given insn
875 is output insn. */
876 struct bypass_decl *bypass_list;
878 /* The following fields are defined by automaton generator. */
880 /* The following field is the insn regexp transformed that
881 the regexp has not optional regexp, repetition regexp, and an
882 reservation name (i.e. reservation identifiers are changed by the
883 corresponding regexp) and all alternations are the topest level
884 of the regexp. The value can be NULL only if it is special
885 insn `cycle advancing'. */
886 regexp_t transformed_regexp;
887 /* The following field value is list of arcs marked given
888 insn. The field is used in transformation NDFA -> DFA. */
889 arc_t arcs_marked_by_insn;
890 /* The two following fields are used during minimization of a finite state
891 automaton. */
892 /* The field value is number of equivalence class of state into
893 which arc marked by given insn enters from a state (fixed during
894 an automaton minimization). */
895 int equiv_class_num;
896 /* The field value is state_alts of arc leaving a state (fixed
897 during an automaton minimization) and marked by given insn
898 enters. */
899 int state_alts;
900 /* The following member value is the list to automata which can be
901 changed by the insn issue. */
902 automata_list_el_t important_automata_list;
903 /* The following member is used to process insn once for output. */
904 int processed_p;
907 /* This contains a declaration mentioned above. */
908 struct decl
910 /* What node in the union? */
911 enum decl_mode mode;
912 pos_t pos;
913 union
915 struct unit_decl unit;
916 struct bypass_decl bypass;
917 struct automaton_decl automaton;
918 struct excl_rel_decl excl;
919 struct unit_pattern_rel_decl presence;
920 struct unit_pattern_rel_decl absence;
921 struct reserv_decl reserv;
922 struct insn_reserv_decl insn_reserv;
923 } decl;
926 /* The following structures represent parsed reservation strings. */
927 enum regexp_mode
929 rm_unit,
930 rm_reserv,
931 rm_nothing,
932 rm_sequence,
933 rm_repeat,
934 rm_allof,
935 rm_oneof
938 /* Cpu unit in reservation. */
939 struct unit_regexp
941 char *name;
942 unit_decl_t unit_decl;
945 /* Define_reservation in a reservation. */
946 struct reserv_regexp
948 char *name;
949 struct reserv_decl *reserv_decl;
952 /* Absence of reservation (represented by string `nothing'). */
953 struct nothing_regexp
955 /* This used to be empty but ISO C doesn't allow that. */
956 char unused;
959 /* Representation of reservations separated by ',' (see file
960 rtl.def). */
961 struct sequence_regexp
963 int regexps_num;
964 regexp_t regexps [1];
967 /* Representation of construction `repeat' (see file rtl.def). */
968 struct repeat_regexp
970 int repeat_num;
971 regexp_t regexp;
974 /* Representation of reservations separated by '+' (see file
975 rtl.def). */
976 struct allof_regexp
978 int regexps_num;
979 regexp_t regexps [1];
982 /* Representation of reservations separated by '|' (see file
983 rtl.def). */
984 struct oneof_regexp
986 int regexps_num;
987 regexp_t regexps [1];
990 /* Representation of a reservation string. */
991 struct regexp
993 /* What node in the union? */
994 enum regexp_mode mode;
995 pos_t pos;
996 union
998 struct unit_regexp unit;
999 struct reserv_regexp reserv;
1000 struct nothing_regexp nothing;
1001 struct sequence_regexp sequence;
1002 struct repeat_regexp repeat;
1003 struct allof_regexp allof;
1004 struct oneof_regexp oneof;
1005 } regexp;
1008 /* Represents description of pipeline hazard description based on
1009 NDFA. */
1010 struct description
1012 int decls_num;
1014 /* The following fields are defined by checker. */
1016 /* The following fields values are correspondingly number of all
1017 units, query units, and insns in the description. */
1018 int units_num;
1019 int query_units_num;
1020 int insns_num;
1021 /* The following field value is max length (in cycles) of
1022 reservations of insns. The field value is defined only for
1023 correct programs. */
1024 int max_insn_reserv_cycles;
1026 /* The following fields are defined by automaton generator. */
1028 /* The following field value is the first automaton. */
1029 automaton_t first_automaton;
1031 /* The following field is created by pipeline hazard parser and
1032 contains all declarations. We allocate additional entry for
1033 special insn "cycle advancing" which is added by the automaton
1034 generator. */
1035 decl_t decls [1];
1039 /* The following nodes are created in automaton checker. */
1041 /* The following nodes represent exclusion set for cpu units. Each
1042 element is accessed through only one excl_list. */
1043 struct unit_set_el
1045 unit_decl_t unit_decl;
1046 unit_set_el_t next_unit_set_el;
1049 /* The following nodes represent presence or absence pattern for cpu
1050 units. Each element is accessed through only one presence_list or
1051 absence_list. */
1052 struct pattern_set_el
1054 /* The number of units in unit_decls. */
1055 int units_num;
1056 /* The units forming the pattern. */
1057 struct unit_decl **unit_decls;
1058 pattern_set_el_t next_pattern_set_el;
1062 /* The following nodes are created in automaton generator. */
1065 /* The following nodes represent presence or absence pattern for cpu
1066 units. Each element is accessed through only one element of
1067 unit_presence_set_table or unit_absence_set_table. */
1068 struct pattern_reserv
1070 reserv_sets_t reserv;
1071 pattern_reserv_t next_pattern_reserv;
1074 /* The following node type describes state automaton. The state may
1075 be deterministic or non-deterministic. Non-deterministic state has
1076 several component states which represent alternative cpu units
1077 reservations. The state also is used for describing a
1078 deterministic reservation of automaton insn. */
1079 struct state
1081 /* The following member value is nonzero if there is a transition by
1082 cycle advancing. */
1083 int new_cycle_p;
1084 /* The following field is list of processor unit reservations on
1085 each cycle. */
1086 reserv_sets_t reservs;
1087 /* The following field is unique number of given state between other
1088 states. */
1089 int unique_num;
1090 /* The following field value is automaton to which given state
1091 belongs. */
1092 automaton_t automaton;
1093 /* The following field value is the first arc output from given
1094 state. */
1095 arc_t first_out_arc;
1096 /* The following field is used to form NDFA. */
1097 char it_was_placed_in_stack_for_NDFA_forming;
1098 /* The following field is used to form DFA. */
1099 char it_was_placed_in_stack_for_DFA_forming;
1100 /* The following field is used to transform NDFA to DFA and DFA
1101 minimization. The field value is not NULL if the state is a
1102 compound state. In this case the value of field `unit_sets_list'
1103 is NULL. All states in the list are in the hash table. The list
1104 is formed through field `next_sorted_alt_state'. We should
1105 support only one level of nesting state. */
1106 alt_state_t component_states;
1107 /* The following field is used for passing graph of states. */
1108 int pass_num;
1109 /* The list of states belonging to one equivalence class is formed
1110 with the aid of the following field. */
1111 state_t next_equiv_class_state;
1112 /* The two following fields are used during minimization of a finite
1113 state automaton. */
1114 int equiv_class_num_1, equiv_class_num_2;
1115 /* The following field is used during minimization of a finite state
1116 automaton. The field value is state corresponding to equivalence
1117 class to which given state belongs. */
1118 state_t equiv_class_state;
1119 /* The following field value is the order number of given state.
1120 The states in final DFA is enumerated with the aid of the
1121 following field. */
1122 int order_state_num;
1123 /* This member is used for passing states for searching minimal
1124 delay time. */
1125 int state_pass_num;
1126 /* The following member is used to evaluate min issue delay of insn
1127 for a state. */
1128 int min_insn_issue_delay;
1129 /* The following member is used to evaluate max issue rate of the
1130 processor. The value of the member is maximal length of the path
1131 from given state no containing arcs marked by special insn `cycle
1132 advancing'. */
1133 int longest_path_length;
1136 /* The following macro is an initial value of member
1137 `longest_path_length' of a state. */
1138 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1140 /* Automaton arc. */
1141 struct arc
1143 /* The following field refers for the state into which given arc
1144 enters. */
1145 state_t to_state;
1146 /* The following field describes that the insn issue (with cycle
1147 advancing for special insn `cycle advancing' and without cycle
1148 advancing for others) makes transition from given state to
1149 another given state. */
1150 ainsn_t insn;
1151 /* The following field value is the next arc output from the same
1152 state. */
1153 arc_t next_out_arc;
1154 /* List of arcs marked given insn is formed with the following
1155 field. The field is used in transformation NDFA -> DFA. */
1156 arc_t next_arc_marked_by_insn;
1157 /* The following field is defined if NDFA_FLAG is zero. The member
1158 value is number of alternative reservations which can be used for
1159 transition for given state by given insn. */
1160 int state_alts;
1163 /* The following node type describes a deterministic alternative in
1164 non-deterministic state which characterizes cpu unit reservations
1165 of automaton insn or which is part of NDFA. */
1166 struct alt_state
1168 /* The following field is a deterministic state which characterizes
1169 unit reservations of the instruction. */
1170 state_t state;
1171 /* The following field refers to the next state which characterizes
1172 unit reservations of the instruction. */
1173 alt_state_t next_alt_state;
1174 /* The following field refers to the next state in sorted list. */
1175 alt_state_t next_sorted_alt_state;
1178 /* The following node type describes insn of automaton. They are
1179 labels of FA arcs. */
1180 struct ainsn
1182 /* The following field value is the corresponding insn declaration
1183 of description. */
1184 struct insn_reserv_decl *insn_reserv_decl;
1185 /* The following field value is the next insn declaration for an
1186 automaton. */
1187 ainsn_t next_ainsn;
1188 /* The following field is states which characterize automaton unit
1189 reservations of the instruction. The value can be NULL only if it
1190 is special insn `cycle advancing'. */
1191 alt_state_t alt_states;
1192 /* The following field is sorted list of states which characterize
1193 automaton unit reservations of the instruction. The value can be
1194 NULL only if it is special insn `cycle advancing'. */
1195 alt_state_t sorted_alt_states;
1196 /* The following field refers the next automaton insn with
1197 the same reservations. */
1198 ainsn_t next_same_reservs_insn;
1199 /* The following field is flag of the first automaton insn with the
1200 same reservations in the declaration list. Only arcs marked such
1201 insn is present in the automaton. This significantly decreases
1202 memory requirements especially when several automata are
1203 formed. */
1204 char first_insn_with_same_reservs;
1205 /* The following member has nonzero value if there is arc from state of
1206 the automaton marked by the ainsn. */
1207 char arc_exists_p;
1208 /* Cyclic list of insns of an equivalence class is formed with the
1209 aid of the following field. */
1210 ainsn_t next_equiv_class_insn;
1211 /* The following field value is nonzero if the insn declaration is
1212 the first insn declaration with given equivalence number. */
1213 char first_ainsn_with_given_equivalence_num;
1214 /* The following field is number of class of equivalence of insns.
1215 It is necessary because many insns may be equivalent with the
1216 point of view of pipeline hazards. */
1217 int insn_equiv_class_num;
1218 /* The following member value is TRUE if there is an arc in the
1219 automaton marked by the insn into another state. In other
1220 words, the insn can change the state of the automaton. */
1221 int important_p;
1224 /* The following describes an automaton for PHR. */
1225 struct automaton
1227 /* The following field value is the list of insn declarations for
1228 given automaton. */
1229 ainsn_t ainsn_list;
1230 /* The following field value is the corresponding automaton
1231 declaration. This field is not NULL only if the automatic
1232 partition on automata is not used. */
1233 struct automaton_decl *corresponding_automaton_decl;
1234 /* The following field value is the next automaton. */
1235 automaton_t next_automaton;
1236 /* The following field is start state of FA. There are not unit
1237 reservations in the state. */
1238 state_t start_state;
1239 /* The following field value is number of equivalence classes of
1240 insns (see field `insn_equiv_class_num' in
1241 `insn_reserv_decl'). */
1242 int insn_equiv_classes_num;
1243 /* The following field value is number of states of final DFA. */
1244 int achieved_states_num;
1245 /* The following field value is the order number (0, 1, ...) of
1246 given automaton. */
1247 int automaton_order_num;
1248 /* The following fields contain statistics information about
1249 building automaton. */
1250 int NDFA_states_num, DFA_states_num;
1251 /* The following field value is defined only if minimization of DFA
1252 is used. */
1253 int minimal_DFA_states_num;
1254 int NDFA_arcs_num, DFA_arcs_num;
1255 /* The following field value is defined only if minimization of DFA
1256 is used. */
1257 int minimal_DFA_arcs_num;
1258 /* The following two members refer for two table state x ainsn ->
1259 int. */
1260 state_ainsn_table_t trans_table;
1261 state_ainsn_table_t state_alts_table;
1262 /* The following member value is maximal value of min issue delay
1263 for insns of the automaton. */
1264 int max_min_delay;
1265 /* Usually min issue delay is small and we can place several (2, 4,
1266 8) elements in one vector element. So the compression factor can
1267 be 1 (no compression), 2, 4, 8. */
1268 int min_issue_delay_table_compression_factor;
1271 /* The following is the element of the list of automata. */
1272 struct automata_list_el
1274 /* The automaton itself. */
1275 automaton_t automaton;
1276 /* The next automata set element. */
1277 automata_list_el_t next_automata_list_el;
1280 /* The following structure describes a table state X ainsn -> int(>= 0). */
1281 struct state_ainsn_table
1283 /* Automaton to which given table belongs. */
1284 automaton_t automaton;
1285 /* The following tree vectors for comb vector implementation of the
1286 table. */
1287 vla_hwint_t comb_vect;
1288 vla_hwint_t check_vect;
1289 vla_hwint_t base_vect;
1290 /* This is simple implementation of the table. */
1291 vla_hwint_t full_vect;
1292 /* Minimal and maximal values of the previous vectors. */
1293 int min_comb_vect_el_value, max_comb_vect_el_value;
1294 int min_base_vect_el_value, max_base_vect_el_value;
1297 /* Macros to access members of unions. Use only them for access to
1298 union members of declarations and regexps. */
1300 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1302 #define DECL_UNIT(d) __extension__ \
1303 (({ struct decl *const _decl = (d); \
1304 if (_decl->mode != dm_unit) \
1305 decl_mode_check_failed (_decl->mode, "dm_unit", \
1306 __FILE__, __LINE__, __FUNCTION__); \
1307 &(_decl)->decl.unit; }))
1309 #define DECL_BYPASS(d) __extension__ \
1310 (({ struct decl *const _decl = (d); \
1311 if (_decl->mode != dm_bypass) \
1312 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1313 __FILE__, __LINE__, __FUNCTION__); \
1314 &(_decl)->decl.bypass; }))
1316 #define DECL_AUTOMATON(d) __extension__ \
1317 (({ struct decl *const _decl = (d); \
1318 if (_decl->mode != dm_automaton) \
1319 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1320 __FILE__, __LINE__, __FUNCTION__); \
1321 &(_decl)->decl.automaton; }))
1323 #define DECL_EXCL(d) __extension__ \
1324 (({ struct decl *const _decl = (d); \
1325 if (_decl->mode != dm_excl) \
1326 decl_mode_check_failed (_decl->mode, "dm_excl", \
1327 __FILE__, __LINE__, __FUNCTION__); \
1328 &(_decl)->decl.excl; }))
1330 #define DECL_PRESENCE(d) __extension__ \
1331 (({ struct decl *const _decl = (d); \
1332 if (_decl->mode != dm_presence) \
1333 decl_mode_check_failed (_decl->mode, "dm_presence", \
1334 __FILE__, __LINE__, __FUNCTION__); \
1335 &(_decl)->decl.presence; }))
1337 #define DECL_ABSENCE(d) __extension__ \
1338 (({ struct decl *const _decl = (d); \
1339 if (_decl->mode != dm_absence) \
1340 decl_mode_check_failed (_decl->mode, "dm_absence", \
1341 __FILE__, __LINE__, __FUNCTION__); \
1342 &(_decl)->decl.absence; }))
1344 #define DECL_RESERV(d) __extension__ \
1345 (({ struct decl *const _decl = (d); \
1346 if (_decl->mode != dm_reserv) \
1347 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1348 __FILE__, __LINE__, __FUNCTION__); \
1349 &(_decl)->decl.reserv; }))
1351 #define DECL_INSN_RESERV(d) __extension__ \
1352 (({ struct decl *const _decl = (d); \
1353 if (_decl->mode != dm_insn_reserv) \
1354 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1355 __FILE__, __LINE__, __FUNCTION__); \
1356 &(_decl)->decl.insn_reserv; }))
1358 static const char *decl_name (enum decl_mode);
1359 static void decl_mode_check_failed (enum decl_mode, const char *,
1360 const char *, int, const char *);
1362 /* Return string representation of declaration mode MODE. */
1363 static const char *
1364 decl_name (enum decl_mode mode)
1366 static char str [100];
1368 if (mode == dm_unit)
1369 return "dm_unit";
1370 else if (mode == dm_bypass)
1371 return "dm_bypass";
1372 else if (mode == dm_automaton)
1373 return "dm_automaton";
1374 else if (mode == dm_excl)
1375 return "dm_excl";
1376 else if (mode == dm_presence)
1377 return "dm_presence";
1378 else if (mode == dm_absence)
1379 return "dm_absence";
1380 else if (mode == dm_reserv)
1381 return "dm_reserv";
1382 else if (mode == dm_insn_reserv)
1383 return "dm_insn_reserv";
1384 else
1385 sprintf (str, "unknown (%d)", (int) mode);
1386 return str;
1389 /* The function prints message about unexpected declaration and finish
1390 the program. */
1391 static void
1392 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1393 const char *file, int line, const char *func)
1395 fprintf
1396 (stderr,
1397 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1398 file, line, func, expected_mode_str, decl_name (mode));
1399 exit (1);
1403 #define REGEXP_UNIT(r) __extension__ \
1404 (({ struct regexp *const _regexp = (r); \
1405 if (_regexp->mode != rm_unit) \
1406 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1407 __FILE__, __LINE__, __FUNCTION__); \
1408 &(_regexp)->regexp.unit; }))
1410 #define REGEXP_RESERV(r) __extension__ \
1411 (({ struct regexp *const _regexp = (r); \
1412 if (_regexp->mode != rm_reserv) \
1413 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1414 __FILE__, __LINE__, __FUNCTION__); \
1415 &(_regexp)->regexp.reserv; }))
1417 #define REGEXP_SEQUENCE(r) __extension__ \
1418 (({ struct regexp *const _regexp = (r); \
1419 if (_regexp->mode != rm_sequence) \
1420 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1421 __FILE__, __LINE__, __FUNCTION__); \
1422 &(_regexp)->regexp.sequence; }))
1424 #define REGEXP_REPEAT(r) __extension__ \
1425 (({ struct regexp *const _regexp = (r); \
1426 if (_regexp->mode != rm_repeat) \
1427 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1428 __FILE__, __LINE__, __FUNCTION__); \
1429 &(_regexp)->regexp.repeat; }))
1431 #define REGEXP_ALLOF(r) __extension__ \
1432 (({ struct regexp *const _regexp = (r); \
1433 if (_regexp->mode != rm_allof) \
1434 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1435 __FILE__, __LINE__, __FUNCTION__); \
1436 &(_regexp)->regexp.allof; }))
1438 #define REGEXP_ONEOF(r) __extension__ \
1439 (({ struct regexp *const _regexp = (r); \
1440 if (_regexp->mode != rm_oneof) \
1441 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1442 __FILE__, __LINE__, __FUNCTION__); \
1443 &(_regexp)->regexp.oneof; }))
1445 static const char *regexp_name (enum regexp_mode);
1446 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1447 const char *, int,
1448 const char *);
1451 /* Return string representation of regexp mode MODE. */
1452 static const char *
1453 regexp_name (enum regexp_mode mode)
1455 switch (mode)
1457 case rm_unit:
1458 return "rm_unit";
1459 case rm_reserv:
1460 return "rm_reserv";
1461 case rm_nothing:
1462 return "rm_nothing";
1463 case rm_sequence:
1464 return "rm_sequence";
1465 case rm_repeat:
1466 return "rm_repeat";
1467 case rm_allof:
1468 return "rm_allof";
1469 case rm_oneof:
1470 return "rm_oneof";
1471 default:
1472 gcc_unreachable ();
1476 /* The function prints message about unexpected regexp and finish the
1477 program. */
1478 static void
1479 regexp_mode_check_failed (enum regexp_mode mode,
1480 const char *expected_mode_str,
1481 const char *file, int line, const char *func)
1483 fprintf
1484 (stderr,
1485 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1486 file, line, func, expected_mode_str, regexp_name (mode));
1487 exit (1);
1490 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1492 #define DECL_UNIT(d) (&(d)->decl.unit)
1493 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1494 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1495 #define DECL_EXCL(d) (&(d)->decl.excl)
1496 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1497 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1498 #define DECL_RESERV(d) (&(d)->decl.reserv)
1499 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1501 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1502 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1503 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1504 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1505 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1506 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1508 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1510 /* Create IR structure (node). */
1511 static void *
1512 create_node (size_t size)
1514 void *result;
1516 obstack_blank (&irp, size);
1517 result = obstack_base (&irp);
1518 obstack_finish (&irp);
1519 /* Default values of members are NULL and zero. */
1520 memset (result, 0, size);
1521 return result;
1524 /* Copy IR structure (node). */
1525 static void *
1526 copy_node (const void *from, size_t size)
1528 void *const result = create_node (size);
1529 memcpy (result, from, size);
1530 return result;
1533 /* The function checks that NAME does not contain quotes (`"'). */
1534 static char *
1535 check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
1537 const char *str;
1539 for (str = name; *str != '\0'; str++)
1540 if (*str == '\"')
1541 error ("Name `%s' contains quotes", name);
1542 return name;
1545 /* Pointers to all declarations during IR generation are stored in the
1546 following. */
1547 static vla_ptr_t decls;
1549 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1550 string containing the next separated element, taking parentheses
1551 into account if PAR_FLAG has nonzero value. Advance the pointer to
1552 after the string scanned, or the end-of-string. Return NULL if at
1553 end of string. */
1554 static char *
1555 next_sep_el (char **pstr, int sep, int par_flag)
1557 char *out_str;
1558 char *p;
1559 int pars_num;
1560 int n_spaces;
1562 /* Remove leading whitespaces. */
1563 while (ISSPACE ((int) **pstr))
1564 (*pstr)++;
1566 if (**pstr == '\0')
1567 return NULL;
1569 n_spaces = 0;
1570 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1572 if (par_flag && *p == '(')
1573 pars_num++;
1574 else if (par_flag && *p == ')')
1575 pars_num--;
1576 else if (pars_num == 0 && *p == sep)
1577 break;
1578 if (pars_num == 0 && ISSPACE ((int) *p))
1579 n_spaces++;
1580 else
1582 for (; n_spaces != 0; n_spaces--)
1583 obstack_1grow (&irp, p [-n_spaces]);
1584 obstack_1grow (&irp, *p);
1587 obstack_1grow (&irp, '\0');
1588 out_str = obstack_base (&irp);
1589 obstack_finish (&irp);
1591 *pstr = p;
1592 if (**pstr == sep)
1593 (*pstr)++;
1595 return out_str;
1598 /* Given a string and a separator, return the number of separated
1599 elements in it, taking parentheses into account if PAR_FLAG has
1600 nonzero value. Return 0 for the null string, -1 if parentheses is
1601 not balanced. */
1602 static int
1603 n_sep_els (char *s, int sep, int par_flag)
1605 int n;
1606 int pars_num;
1608 if (*s == '\0')
1609 return 0;
1611 for (pars_num = 0, n = 1; *s; s++)
1612 if (par_flag && *s == '(')
1613 pars_num++;
1614 else if (par_flag && *s == ')')
1615 pars_num--;
1616 else if (pars_num == 0 && *s == sep)
1617 n++;
1619 return (pars_num != 0 ? -1 : n);
1622 /* Given a string and a separator, return vector of strings which are
1623 elements in the string and number of elements through els_num.
1624 Take parentheses into account if PAREN_P has nonzero value. The
1625 function also inserts the end marker NULL at the end of vector.
1626 Return 0 for the null string, -1 if parentheses are not balanced. */
1627 static char **
1628 get_str_vect (char *str, int *els_num, int sep, int paren_p)
1630 int i;
1631 char **vect;
1632 char **pstr;
1633 char *trail;
1635 *els_num = n_sep_els (str, sep, paren_p);
1636 if (*els_num <= 0)
1637 return NULL;
1638 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1639 vect = (char **) obstack_base (&irp);
1640 obstack_finish (&irp);
1641 pstr = &str;
1642 for (i = 0; i < *els_num; i++)
1643 vect [i] = next_sep_el (pstr, sep, paren_p);
1644 trail = next_sep_el (pstr, sep, paren_p);
1645 gcc_assert (!trail);
1646 vect [i] = NULL;
1647 return vect;
1650 /* Process a DEFINE_CPU_UNIT.
1652 This gives information about a unit contained in CPU. We fill a
1653 struct unit_decl with information used later by `expand_automata'. */
1654 void
1655 gen_cpu_unit (rtx def)
1657 decl_t decl;
1658 char **str_cpu_units;
1659 int vect_length;
1660 int i;
1662 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1663 FALSE);
1664 if (str_cpu_units == NULL)
1665 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1666 for (i = 0; i < vect_length; i++)
1668 decl = create_node (sizeof (struct decl));
1669 decl->mode = dm_unit;
1670 decl->pos = 0;
1671 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1672 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1673 DECL_UNIT (decl)->query_p = 0;
1674 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1675 DECL_UNIT (decl)->in_set_p = 0;
1676 VLA_PTR_ADD (decls, decl);
1677 num_dfa_decls++;
1681 /* Process a DEFINE_QUERY_CPU_UNIT.
1683 This gives information about a unit contained in CPU. We fill a
1684 struct unit_decl with information used later by `expand_automata'. */
1685 void
1686 gen_query_cpu_unit (rtx def)
1688 decl_t decl;
1689 char **str_cpu_units;
1690 int vect_length;
1691 int i;
1693 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1694 FALSE);
1695 if (str_cpu_units == NULL)
1696 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1697 for (i = 0; i < vect_length; i++)
1699 decl = create_node (sizeof (struct decl));
1700 decl->mode = dm_unit;
1701 decl->pos = 0;
1702 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1703 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1704 DECL_UNIT (decl)->query_p = 1;
1705 VLA_PTR_ADD (decls, decl);
1706 num_dfa_decls++;
1710 /* Process a DEFINE_BYPASS.
1712 This gives information about a unit contained in the CPU. We fill
1713 in a struct bypass_decl with information used later by
1714 `expand_automata'. */
1715 void
1716 gen_bypass (rtx def)
1718 decl_t decl;
1719 char **out_insns;
1720 int out_length;
1721 char **in_insns;
1722 int in_length;
1723 int i, j;
1725 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1726 if (out_insns == NULL)
1727 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1728 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1729 if (in_insns == NULL)
1730 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1731 for (i = 0; i < out_length; i++)
1732 for (j = 0; j < in_length; j++)
1734 decl = create_node (sizeof (struct decl));
1735 decl->mode = dm_bypass;
1736 decl->pos = 0;
1737 DECL_BYPASS (decl)->latency = XINT (def, 0);
1738 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1739 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1740 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1741 VLA_PTR_ADD (decls, decl);
1742 num_dfa_decls++;
1746 /* Process an EXCLUSION_SET.
1748 This gives information about a cpu unit conflicts. We fill a
1749 struct excl_rel_decl (excl) with information used later by
1750 `expand_automata'. */
1751 void
1752 gen_excl_set (rtx def)
1754 decl_t decl;
1755 char **first_str_cpu_units;
1756 char **second_str_cpu_units;
1757 int first_vect_length;
1758 int length;
1759 int i;
1761 first_str_cpu_units
1762 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1763 if (first_str_cpu_units == NULL)
1764 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1765 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1766 FALSE);
1767 if (second_str_cpu_units == NULL)
1768 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1769 length += first_vect_length;
1770 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1771 decl->mode = dm_excl;
1772 decl->pos = 0;
1773 DECL_EXCL (decl)->all_names_num = length;
1774 DECL_EXCL (decl)->first_list_length = first_vect_length;
1775 for (i = 0; i < length; i++)
1776 if (i < first_vect_length)
1777 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1778 else
1779 DECL_EXCL (decl)->names [i]
1780 = second_str_cpu_units [i - first_vect_length];
1781 VLA_PTR_ADD (decls, decl);
1782 num_dfa_decls++;
1785 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1786 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1788 This gives information about a cpu unit reservation requirements.
1789 We fill a struct unit_pattern_rel_decl with information used later
1790 by `expand_automata'. */
1791 static void
1792 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1794 decl_t decl;
1795 char **str_cpu_units;
1796 char ***str_patterns;
1797 int cpu_units_length;
1798 int length;
1799 int patterns_length;
1800 int i;
1802 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1803 FALSE);
1804 if (str_cpu_units == NULL)
1805 fatal ((presence_p
1806 ? (final_p
1807 ? "invalid first string `%s' in final_presence_set"
1808 : "invalid first string `%s' in presence_set")
1809 : (final_p
1810 ? "invalid first string `%s' in final_absence_set"
1811 : "invalid first string `%s' in absence_set")),
1812 XSTR (def, 0));
1813 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1814 &patterns_length, ',', FALSE);
1815 if (str_patterns == NULL)
1816 fatal ((presence_p
1817 ? (final_p
1818 ? "invalid second string `%s' in final_presence_set"
1819 : "invalid second string `%s' in presence_set")
1820 : (final_p
1821 ? "invalid second string `%s' in final_absence_set"
1822 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1823 for (i = 0; i < patterns_length; i++)
1825 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1826 FALSE);
1827 gcc_assert (str_patterns [i]);
1829 decl = create_node (sizeof (struct decl));
1830 decl->pos = 0;
1831 if (presence_p)
1833 decl->mode = dm_presence;
1834 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1835 DECL_PRESENCE (decl)->names = str_cpu_units;
1836 DECL_PRESENCE (decl)->patterns = str_patterns;
1837 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1838 DECL_PRESENCE (decl)->final_p = final_p;
1840 else
1842 decl->mode = dm_absence;
1843 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1844 DECL_ABSENCE (decl)->names = str_cpu_units;
1845 DECL_ABSENCE (decl)->patterns = str_patterns;
1846 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1847 DECL_ABSENCE (decl)->final_p = final_p;
1849 VLA_PTR_ADD (decls, decl);
1850 num_dfa_decls++;
1853 /* Process a PRESENCE_SET.
1855 This gives information about a cpu unit reservation requirements.
1856 We fill a struct unit_pattern_rel_decl (presence) with information
1857 used later by `expand_automata'. */
1858 void
1859 gen_presence_set (rtx def)
1861 gen_presence_absence_set (def, TRUE, FALSE);
1864 /* Process a FINAL_PRESENCE_SET.
1866 This gives information about a cpu unit reservation requirements.
1867 We fill a struct unit_pattern_rel_decl (presence) with information
1868 used later by `expand_automata'. */
1869 void
1870 gen_final_presence_set (rtx def)
1872 gen_presence_absence_set (def, TRUE, TRUE);
1875 /* Process an ABSENCE_SET.
1877 This gives information about a cpu unit reservation requirements.
1878 We fill a struct unit_pattern_rel_decl (absence) with information
1879 used later by `expand_automata'. */
1880 void
1881 gen_absence_set (rtx def)
1883 gen_presence_absence_set (def, FALSE, FALSE);
1886 /* Process a FINAL_ABSENCE_SET.
1888 This gives information about a cpu unit reservation requirements.
1889 We fill a struct unit_pattern_rel_decl (absence) with information
1890 used later by `expand_automata'. */
1891 void
1892 gen_final_absence_set (rtx def)
1894 gen_presence_absence_set (def, FALSE, TRUE);
1897 /* Process a DEFINE_AUTOMATON.
1899 This gives information about a finite state automaton used for
1900 recognizing pipeline hazards. We fill a struct automaton_decl
1901 with information used later by `expand_automata'. */
1902 void
1903 gen_automaton (rtx def)
1905 decl_t decl;
1906 char **str_automata;
1907 int vect_length;
1908 int i;
1910 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1911 FALSE);
1912 if (str_automata == NULL)
1913 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1914 for (i = 0; i < vect_length; i++)
1916 decl = create_node (sizeof (struct decl));
1917 decl->mode = dm_automaton;
1918 decl->pos = 0;
1919 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1920 VLA_PTR_ADD (decls, decl);
1921 num_dfa_decls++;
1925 /* Process an AUTOMATA_OPTION.
1927 This gives information how to generate finite state automaton used
1928 for recognizing pipeline hazards. */
1929 void
1930 gen_automata_option (rtx def)
1932 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1933 no_minimization_flag = 1;
1934 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1935 time_flag = 1;
1936 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1937 v_flag = 1;
1938 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1939 w_flag = 1;
1940 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1941 ndfa_flag = 1;
1942 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1943 progress_flag = 1;
1944 else
1945 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1948 /* Name in reservation to denote absence reservation. */
1949 #define NOTHING_NAME "nothing"
1951 /* The following string contains original reservation string being
1952 parsed. */
1953 static char *reserv_str;
1955 /* Parse an element in STR. */
1956 static regexp_t
1957 gen_regexp_el (char *str)
1959 regexp_t regexp;
1960 int len;
1962 if (*str == '(')
1964 len = strlen (str);
1965 if (str [len - 1] != ')')
1966 fatal ("garbage after ) in reservation `%s'", reserv_str);
1967 str [len - 1] = '\0';
1968 regexp = gen_regexp_sequence (str + 1);
1970 else if (strcmp (str, NOTHING_NAME) == 0)
1972 regexp = create_node (sizeof (struct decl));
1973 regexp->mode = rm_nothing;
1975 else
1977 regexp = create_node (sizeof (struct decl));
1978 regexp->mode = rm_unit;
1979 REGEXP_UNIT (regexp)->name = str;
1981 return regexp;
1984 /* Parse construction `repeat' in STR. */
1985 static regexp_t
1986 gen_regexp_repeat (char *str)
1988 regexp_t regexp;
1989 regexp_t repeat;
1990 char **repeat_vect;
1991 int els_num;
1992 int i;
1994 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1995 if (repeat_vect == NULL)
1996 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1997 if (els_num > 1)
1999 regexp = gen_regexp_el (repeat_vect [0]);
2000 for (i = 1; i < els_num; i++)
2002 repeat = create_node (sizeof (struct regexp));
2003 repeat->mode = rm_repeat;
2004 REGEXP_REPEAT (repeat)->regexp = regexp;
2005 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
2006 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
2007 fatal ("repetition `%s' <= 1 in reservation `%s'",
2008 str, reserv_str);
2009 regexp = repeat;
2011 return regexp;
2013 else
2014 return gen_regexp_el (str);
2017 /* Parse reservation STR which possibly contains separator '+'. */
2018 static regexp_t
2019 gen_regexp_allof (char *str)
2021 regexp_t allof;
2022 char **allof_vect;
2023 int els_num;
2024 int i;
2026 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
2027 if (allof_vect == NULL)
2028 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2029 if (els_num > 1)
2031 allof = create_node (sizeof (struct regexp)
2032 + sizeof (regexp_t) * (els_num - 1));
2033 allof->mode = rm_allof;
2034 REGEXP_ALLOF (allof)->regexps_num = els_num;
2035 for (i = 0; i < els_num; i++)
2036 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2037 return allof;
2039 else
2040 return gen_regexp_repeat (str);
2043 /* Parse reservation STR which possibly contains separator '|'. */
2044 static regexp_t
2045 gen_regexp_oneof (char *str)
2047 regexp_t oneof;
2048 char **oneof_vect;
2049 int els_num;
2050 int i;
2052 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
2053 if (oneof_vect == NULL)
2054 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2055 if (els_num > 1)
2057 oneof = create_node (sizeof (struct regexp)
2058 + sizeof (regexp_t) * (els_num - 1));
2059 oneof->mode = rm_oneof;
2060 REGEXP_ONEOF (oneof)->regexps_num = els_num;
2061 for (i = 0; i < els_num; i++)
2062 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2063 return oneof;
2065 else
2066 return gen_regexp_allof (str);
2069 /* Parse reservation STR which possibly contains separator ','. */
2070 static regexp_t
2071 gen_regexp_sequence (char *str)
2073 regexp_t sequence;
2074 char **sequence_vect;
2075 int els_num;
2076 int i;
2078 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
2079 if (els_num > 1)
2081 sequence = create_node (sizeof (struct regexp)
2082 + sizeof (regexp_t) * (els_num - 1));
2083 sequence->mode = rm_sequence;
2084 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
2085 for (i = 0; i < els_num; i++)
2086 REGEXP_SEQUENCE (sequence)->regexps [i]
2087 = gen_regexp_oneof (sequence_vect [i]);
2088 return sequence;
2090 else
2091 return gen_regexp_oneof (str);
2094 /* Parse construction reservation STR. */
2095 static regexp_t
2096 gen_regexp (char *str)
2098 reserv_str = str;
2099 return gen_regexp_sequence (str);;
2102 /* Process a DEFINE_RESERVATION.
2104 This gives information about a reservation of cpu units. We fill
2105 in a struct reserv_decl with information used later by
2106 `expand_automata'. */
2107 void
2108 gen_reserv (rtx def)
2110 decl_t decl;
2112 decl = create_node (sizeof (struct decl));
2113 decl->mode = dm_reserv;
2114 decl->pos = 0;
2115 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
2116 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2117 VLA_PTR_ADD (decls, decl);
2118 num_dfa_decls++;
2121 /* Process a DEFINE_INSN_RESERVATION.
2123 This gives information about the reservation of cpu units by an
2124 insn. We fill a struct insn_reserv_decl with information used
2125 later by `expand_automata'. */
2126 void
2127 gen_insn_reserv (rtx def)
2129 decl_t decl;
2131 decl = create_node (sizeof (struct decl));
2132 decl->mode = dm_insn_reserv;
2133 decl->pos = 0;
2134 DECL_INSN_RESERV (decl)->name
2135 = check_name ((char *) XSTR (def, 0), decl->pos);
2136 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2137 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2138 DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
2139 VLA_PTR_ADD (decls, decl);
2140 num_dfa_decls++;
2145 /* The function evaluates hash value (0..UINT_MAX) of string. */
2146 static unsigned
2147 string_hash (const char *string)
2149 unsigned result, i;
2151 for (result = i = 0;*string++ != '\0'; i++)
2152 result += ((unsigned char) *string << (i % CHAR_BIT));
2153 return result;
2158 /* This page contains abstract data `table of automaton declarations'.
2159 Elements of the table is nodes representing automaton declarations.
2160 Key of the table elements is name of given automaton. Remember
2161 that automaton names have own space. */
2163 /* The function evaluates hash value of an automaton declaration. The
2164 function is used by abstract data `hashtab'. The function returns
2165 hash value (0..UINT_MAX) of given automaton declaration. */
2166 static hashval_t
2167 automaton_decl_hash (const void *automaton_decl)
2169 const decl_t decl = (decl_t) automaton_decl;
2171 gcc_assert (decl->mode != dm_automaton
2172 || DECL_AUTOMATON (decl)->name);
2173 return string_hash (DECL_AUTOMATON (decl)->name);
2176 /* The function tests automaton declarations on equality of their
2177 keys. The function is used by abstract data `hashtab'. The
2178 function returns 1 if the declarations have the same key, 0
2179 otherwise. */
2180 static int
2181 automaton_decl_eq_p (const void* automaton_decl_1,
2182 const void* automaton_decl_2)
2184 const decl_t decl1 = (decl_t) automaton_decl_1;
2185 const decl_t decl2 = (decl_t) automaton_decl_2;
2187 gcc_assert (decl1->mode == dm_automaton
2188 && DECL_AUTOMATON (decl1)->name
2189 && decl2->mode == dm_automaton
2190 && DECL_AUTOMATON (decl2)->name);
2191 return strcmp (DECL_AUTOMATON (decl1)->name,
2192 DECL_AUTOMATON (decl2)->name) == 0;
2195 /* The automaton declaration table itself is represented by the
2196 following variable. */
2197 static htab_t automaton_decl_table;
2199 /* The function inserts automaton declaration into the table. The
2200 function does nothing if an automaton declaration with the same key
2201 exists already in the table. The function returns automaton
2202 declaration node in the table with the same key as given automaton
2203 declaration node. */
2204 static decl_t
2205 insert_automaton_decl (decl_t automaton_decl)
2207 void **entry_ptr;
2209 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2210 if (*entry_ptr == NULL)
2211 *entry_ptr = (void *) automaton_decl;
2212 return (decl_t) *entry_ptr;
2215 /* The following variable value is node representing automaton
2216 declaration. The node used for searching automaton declaration
2217 with given name. */
2218 static struct decl work_automaton_decl;
2220 /* The function searches for automaton declaration in the table with
2221 the same key as node representing name of the automaton
2222 declaration. The function returns node found in the table, NULL if
2223 such node does not exist in the table. */
2224 static decl_t
2225 find_automaton_decl (char *name)
2227 void *entry;
2229 work_automaton_decl.mode = dm_automaton;
2230 DECL_AUTOMATON (&work_automaton_decl)->name = name;
2231 entry = htab_find (automaton_decl_table, &work_automaton_decl);
2232 return (decl_t) entry;
2235 /* The function creates empty automaton declaration table and node
2236 representing automaton declaration and used for searching automaton
2237 declaration with given name. The function must be called only once
2238 before any work with the automaton declaration table. */
2239 static void
2240 initiate_automaton_decl_table (void)
2242 work_automaton_decl.mode = dm_automaton;
2243 automaton_decl_table = htab_create (10, automaton_decl_hash,
2244 automaton_decl_eq_p, (htab_del) 0);
2247 /* The function deletes the automaton declaration table. Only call of
2248 function `initiate_automaton_decl_table' is possible immediately
2249 after this function call. */
2250 static void
2251 finish_automaton_decl_table (void)
2253 htab_delete (automaton_decl_table);
2258 /* This page contains abstract data `table of insn declarations'.
2259 Elements of the table is nodes representing insn declarations. Key
2260 of the table elements is name of given insn (in corresponding
2261 define_insn_reservation). Remember that insn names have own
2262 space. */
2264 /* The function evaluates hash value of an insn declaration. The
2265 function is used by abstract data `hashtab'. The function returns
2266 hash value (0..UINT_MAX) of given insn declaration. */
2267 static hashval_t
2268 insn_decl_hash (const void *insn_decl)
2270 const decl_t decl = (decl_t) insn_decl;
2272 gcc_assert (decl->mode == dm_insn_reserv
2273 && DECL_INSN_RESERV (decl)->name);
2274 return string_hash (DECL_INSN_RESERV (decl)->name);
2277 /* The function tests insn declarations on equality of their keys.
2278 The function is used by abstract data `hashtab'. The function
2279 returns 1 if declarations have the same key, 0 otherwise. */
2280 static int
2281 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2283 const decl_t decl1 = (decl_t) insn_decl_1;
2284 const decl_t decl2 = (decl_t) insn_decl_2;
2286 gcc_assert (decl1->mode == dm_insn_reserv
2287 && DECL_INSN_RESERV (decl1)->name
2288 && decl2->mode == dm_insn_reserv
2289 && DECL_INSN_RESERV (decl2)->name);
2290 return strcmp (DECL_INSN_RESERV (decl1)->name,
2291 DECL_INSN_RESERV (decl2)->name) == 0;
2294 /* The insn declaration table itself is represented by the following
2295 variable. The table does not contain insn reservation
2296 declarations. */
2297 static htab_t insn_decl_table;
2299 /* The function inserts insn declaration into the table. The function
2300 does nothing if an insn declaration with the same key exists
2301 already in the table. The function returns insn declaration node
2302 in the table with the same key as given insn declaration node. */
2303 static decl_t
2304 insert_insn_decl (decl_t insn_decl)
2306 void **entry_ptr;
2308 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2309 if (*entry_ptr == NULL)
2310 *entry_ptr = (void *) insn_decl;
2311 return (decl_t) *entry_ptr;
2314 /* The following variable value is node representing insn reservation
2315 declaration. The node used for searching insn reservation
2316 declaration with given name. */
2317 static struct decl work_insn_decl;
2319 /* The function searches for insn reservation declaration in the table
2320 with the same key as node representing name of the insn reservation
2321 declaration. The function returns node found in the table, NULL if
2322 such node does not exist in the table. */
2323 static decl_t
2324 find_insn_decl (char *name)
2326 void *entry;
2328 work_insn_decl.mode = dm_insn_reserv;
2329 DECL_INSN_RESERV (&work_insn_decl)->name = name;
2330 entry = htab_find (insn_decl_table, &work_insn_decl);
2331 return (decl_t) entry;
2334 /* The function creates empty insn declaration table and node
2335 representing insn declaration and used for searching insn
2336 declaration with given name. The function must be called only once
2337 before any work with the insn declaration table. */
2338 static void
2339 initiate_insn_decl_table (void)
2341 work_insn_decl.mode = dm_insn_reserv;
2342 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2343 (htab_del) 0);
2346 /* The function deletes the insn declaration table. Only call of
2347 function `initiate_insn_decl_table' is possible immediately after
2348 this function call. */
2349 static void
2350 finish_insn_decl_table (void)
2352 htab_delete (insn_decl_table);
2357 /* This page contains abstract data `table of declarations'. Elements
2358 of the table is nodes representing declarations (of units and
2359 reservations). Key of the table elements is names of given
2360 declarations. */
2362 /* The function evaluates hash value of a declaration. The function
2363 is used by abstract data `hashtab'. The function returns hash
2364 value (0..UINT_MAX) of given declaration. */
2365 static hashval_t
2366 decl_hash (const void *decl)
2368 const decl_t d = (const decl_t) decl;
2370 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
2371 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
2372 return string_hash (d->mode == dm_unit
2373 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2376 /* The function tests declarations on equality of their keys. The
2377 function is used by abstract data 'hashtab'. The function
2378 returns 1 if the declarations have the same key, 0 otherwise. */
2379 static int
2380 decl_eq_p (const void *decl_1, const void *decl_2)
2382 const decl_t d1 = (const decl_t) decl_1;
2383 const decl_t d2 = (const decl_t) decl_2;
2385 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
2386 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
2387 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
2388 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
2389 return strcmp ((d1->mode == dm_unit
2390 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2391 (d2->mode == dm_unit
2392 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2395 /* The declaration table itself is represented by the following
2396 variable. */
2397 static htab_t decl_table;
2399 /* The function inserts declaration into the table. The function does
2400 nothing if a declaration with the same key exists already in the
2401 table. The function returns declaration node in the table with the
2402 same key as given declaration node. */
2404 static decl_t
2405 insert_decl (decl_t decl)
2407 void **entry_ptr;
2409 entry_ptr = htab_find_slot (decl_table, decl, 1);
2410 if (*entry_ptr == NULL)
2411 *entry_ptr = (void *) decl;
2412 return (decl_t) *entry_ptr;
2415 /* The following variable value is node representing declaration. The
2416 node used for searching declaration with given name. */
2417 static struct decl work_decl;
2419 /* The function searches for declaration in the table with the same
2420 key as node representing name of the declaration. The function
2421 returns node found in the table, NULL if such node does not exist
2422 in the table. */
2423 static decl_t
2424 find_decl (char *name)
2426 void *entry;
2428 work_decl.mode = dm_unit;
2429 DECL_UNIT (&work_decl)->name = name;
2430 entry = htab_find (decl_table, &work_decl);
2431 return (decl_t) entry;
2434 /* The function creates empty declaration table and node representing
2435 declaration and used for searching declaration with given name.
2436 The function must be called only once before any work with the
2437 declaration table. */
2438 static void
2439 initiate_decl_table (void)
2441 work_decl.mode = dm_unit;
2442 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2445 /* The function deletes the declaration table. Only call of function
2446 `initiate_declaration_table' is possible immediately after this
2447 function call. */
2448 static void
2449 finish_decl_table (void)
2451 htab_delete (decl_table);
2456 /* This page contains checker of pipeline hazard description. */
2458 /* Checking NAMES in an exclusion clause vector and returning formed
2459 unit_set_el_list. */
2460 static unit_set_el_t
2461 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2463 unit_set_el_t el_list;
2464 unit_set_el_t last_el;
2465 unit_set_el_t new_el;
2466 decl_t decl_in_table;
2467 int i;
2469 el_list = NULL;
2470 last_el = NULL;
2471 for (i = 0; i < num; i++)
2473 decl_in_table = find_decl (names [i]);
2474 if (decl_in_table == NULL)
2475 error ("unit `%s' in exclusion is not declared", names [i]);
2476 else if (decl_in_table->mode != dm_unit)
2477 error ("`%s' in exclusion is not unit", names [i]);
2478 else
2480 new_el = create_node (sizeof (struct unit_set_el));
2481 new_el->unit_decl = DECL_UNIT (decl_in_table);
2482 new_el->next_unit_set_el = NULL;
2483 if (last_el == NULL)
2484 el_list = last_el = new_el;
2485 else
2487 last_el->next_unit_set_el = new_el;
2488 last_el = last_el->next_unit_set_el;
2492 return el_list;
2495 /* The function adds each element from SOURCE_LIST to the exclusion
2496 list of the each element from DEST_LIST. Checking situation "unit
2497 excludes itself". */
2498 static void
2499 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2500 pos_t excl_pos ATTRIBUTE_UNUSED)
2502 unit_set_el_t dst;
2503 unit_set_el_t src;
2504 unit_set_el_t curr_el;
2505 unit_set_el_t prev_el;
2506 unit_set_el_t copy;
2508 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2509 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2511 if (dst->unit_decl == src->unit_decl)
2513 error ("unit `%s' excludes itself", src->unit_decl->name);
2514 continue;
2516 if (dst->unit_decl->automaton_name != NULL
2517 && src->unit_decl->automaton_name != NULL
2518 && strcmp (dst->unit_decl->automaton_name,
2519 src->unit_decl->automaton_name) != 0)
2521 error ("units `%s' and `%s' in exclusion set belong to different automata",
2522 src->unit_decl->name, dst->unit_decl->name);
2523 continue;
2525 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2526 curr_el != NULL;
2527 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2528 if (curr_el->unit_decl == src->unit_decl)
2529 break;
2530 if (curr_el == NULL)
2532 /* Element not found - insert. */
2533 copy = copy_node (src, sizeof (*src));
2534 copy->next_unit_set_el = NULL;
2535 if (prev_el == NULL)
2536 dst->unit_decl->excl_list = copy;
2537 else
2538 prev_el->next_unit_set_el = copy;
2543 /* Checking NAMES in presence/absence clause and returning the
2544 formed unit_set_el_list. The function is called only after
2545 processing all exclusion sets. */
2546 static unit_set_el_t
2547 process_presence_absence_names (char **names, int num,
2548 pos_t req_pos ATTRIBUTE_UNUSED,
2549 int presence_p, int final_p)
2551 unit_set_el_t el_list;
2552 unit_set_el_t last_el;
2553 unit_set_el_t new_el;
2554 decl_t decl_in_table;
2555 int i;
2557 el_list = NULL;
2558 last_el = NULL;
2559 for (i = 0; i < num; i++)
2561 decl_in_table = find_decl (names [i]);
2562 if (decl_in_table == NULL)
2563 error ((presence_p
2564 ? (final_p
2565 ? "unit `%s' in final presence set is not declared"
2566 : "unit `%s' in presence set is not declared")
2567 : (final_p
2568 ? "unit `%s' in final absence set is not declared"
2569 : "unit `%s' in absence set is not declared")), names [i]);
2570 else if (decl_in_table->mode != dm_unit)
2571 error ((presence_p
2572 ? (final_p
2573 ? "`%s' in final presence set is not unit"
2574 : "`%s' in presence set is not unit")
2575 : (final_p
2576 ? "`%s' in final absence set is not unit"
2577 : "`%s' in absence set is not unit")), names [i]);
2578 else
2580 new_el = create_node (sizeof (struct unit_set_el));
2581 new_el->unit_decl = DECL_UNIT (decl_in_table);
2582 new_el->next_unit_set_el = NULL;
2583 if (last_el == NULL)
2584 el_list = last_el = new_el;
2585 else
2587 last_el->next_unit_set_el = new_el;
2588 last_el = last_el->next_unit_set_el;
2592 return el_list;
2595 /* Checking NAMES in patterns of a presence/absence clause and
2596 returning the formed pattern_set_el_list. The function is called
2597 only after processing all exclusion sets. */
2598 static pattern_set_el_t
2599 process_presence_absence_patterns (char ***patterns, int num,
2600 pos_t req_pos ATTRIBUTE_UNUSED,
2601 int presence_p, int final_p)
2603 pattern_set_el_t el_list;
2604 pattern_set_el_t last_el;
2605 pattern_set_el_t new_el;
2606 decl_t decl_in_table;
2607 int i, j;
2609 el_list = NULL;
2610 last_el = NULL;
2611 for (i = 0; i < num; i++)
2613 for (j = 0; patterns [i] [j] != NULL; j++)
2615 new_el = create_node (sizeof (struct pattern_set_el)
2616 + sizeof (struct unit_decl *) * j);
2617 new_el->unit_decls
2618 = (struct unit_decl **) ((char *) new_el
2619 + sizeof (struct pattern_set_el));
2620 new_el->next_pattern_set_el = NULL;
2621 if (last_el == NULL)
2622 el_list = last_el = new_el;
2623 else
2625 last_el->next_pattern_set_el = new_el;
2626 last_el = last_el->next_pattern_set_el;
2628 new_el->units_num = 0;
2629 for (j = 0; patterns [i] [j] != NULL; j++)
2631 decl_in_table = find_decl (patterns [i] [j]);
2632 if (decl_in_table == NULL)
2633 error ((presence_p
2634 ? (final_p
2635 ? "unit `%s' in final presence set is not declared"
2636 : "unit `%s' in presence set is not declared")
2637 : (final_p
2638 ? "unit `%s' in final absence set is not declared"
2639 : "unit `%s' in absence set is not declared")),
2640 patterns [i] [j]);
2641 else if (decl_in_table->mode != dm_unit)
2642 error ((presence_p
2643 ? (final_p
2644 ? "`%s' in final presence set is not unit"
2645 : "`%s' in presence set is not unit")
2646 : (final_p
2647 ? "`%s' in final absence set is not unit"
2648 : "`%s' in absence set is not unit")),
2649 patterns [i] [j]);
2650 else
2652 new_el->unit_decls [new_el->units_num]
2653 = DECL_UNIT (decl_in_table);
2654 new_el->units_num++;
2658 return el_list;
2661 /* The function adds each element from PATTERN_LIST to presence (if
2662 PRESENCE_P) or absence list of the each element from DEST_LIST.
2663 Checking situations "unit requires own absence", and "unit excludes
2664 and requires presence of ...", "unit requires absence and presence
2665 of ...", "units in (final) presence set belong to different
2666 automata", and "units in (final) absence set belong to different
2667 automata". Remember that we process absence sets only after all
2668 presence sets. */
2669 static void
2670 add_presence_absence (unit_set_el_t dest_list,
2671 pattern_set_el_t pattern_list,
2672 pos_t req_pos ATTRIBUTE_UNUSED,
2673 int presence_p, int final_p)
2675 unit_set_el_t dst;
2676 pattern_set_el_t pat;
2677 struct unit_decl *unit;
2678 unit_set_el_t curr_excl_el;
2679 pattern_set_el_t curr_pat_el;
2680 pattern_set_el_t prev_el;
2681 pattern_set_el_t copy;
2682 int i;
2683 int no_error_flag;
2685 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2686 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2688 for (i = 0; i < pat->units_num; i++)
2690 unit = pat->unit_decls [i];
2691 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2693 error ("unit `%s' requires own absence", unit->name);
2694 continue;
2696 if (dst->unit_decl->automaton_name != NULL
2697 && unit->automaton_name != NULL
2698 && strcmp (dst->unit_decl->automaton_name,
2699 unit->automaton_name) != 0)
2701 error ((presence_p
2702 ? (final_p
2703 ? "units `%s' and `%s' in final presence set belong to different automata"
2704 : "units `%s' and `%s' in presence set belong to different automata")
2705 : (final_p
2706 ? "units `%s' and `%s' in final absence set belong to different automata"
2707 : "units `%s' and `%s' in absence set belong to different automata")),
2708 unit->name, dst->unit_decl->name);
2709 continue;
2711 no_error_flag = 1;
2712 if (presence_p)
2713 for (curr_excl_el = dst->unit_decl->excl_list;
2714 curr_excl_el != NULL;
2715 curr_excl_el = curr_excl_el->next_unit_set_el)
2717 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2719 if (!w_flag)
2721 error ("unit `%s' excludes and requires presence of `%s'",
2722 dst->unit_decl->name, unit->name);
2723 no_error_flag = 0;
2725 else
2726 warning
2727 (0, "unit `%s' excludes and requires presence of `%s'",
2728 dst->unit_decl->name, unit->name);
2731 else if (pat->units_num == 1)
2732 for (curr_pat_el = dst->unit_decl->presence_list;
2733 curr_pat_el != NULL;
2734 curr_pat_el = curr_pat_el->next_pattern_set_el)
2735 if (curr_pat_el->units_num == 1
2736 && unit == curr_pat_el->unit_decls [0])
2738 if (!w_flag)
2740 error
2741 ("unit `%s' requires absence and presence of `%s'",
2742 dst->unit_decl->name, unit->name);
2743 no_error_flag = 0;
2745 else
2746 warning
2747 (0, "unit `%s' requires absence and presence of `%s'",
2748 dst->unit_decl->name, unit->name);
2750 if (no_error_flag)
2752 for (prev_el = (presence_p
2753 ? (final_p
2754 ? dst->unit_decl->final_presence_list
2755 : dst->unit_decl->final_presence_list)
2756 : (final_p
2757 ? dst->unit_decl->final_absence_list
2758 : dst->unit_decl->absence_list));
2759 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2760 prev_el = prev_el->next_pattern_set_el)
2762 copy = copy_node (pat, sizeof (*pat));
2763 copy->next_pattern_set_el = NULL;
2764 if (prev_el == NULL)
2766 if (presence_p)
2768 if (final_p)
2769 dst->unit_decl->final_presence_list = copy;
2770 else
2771 dst->unit_decl->presence_list = copy;
2773 else if (final_p)
2774 dst->unit_decl->final_absence_list = copy;
2775 else
2776 dst->unit_decl->absence_list = copy;
2778 else
2779 prev_el->next_pattern_set_el = copy;
2786 /* The function searches for bypass with given IN_INSN_RESERV in given
2787 BYPASS_LIST. */
2788 static struct bypass_decl *
2789 find_bypass (struct bypass_decl *bypass_list,
2790 struct insn_reserv_decl *in_insn_reserv)
2792 struct bypass_decl *bypass;
2794 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2795 if (bypass->in_insn_reserv == in_insn_reserv)
2796 break;
2797 return bypass;
2800 /* The function processes pipeline description declarations, checks
2801 their correctness, and forms exclusion/presence/absence sets. */
2802 static void
2803 process_decls (void)
2805 decl_t decl;
2806 decl_t automaton_decl;
2807 decl_t decl_in_table;
2808 decl_t out_insn_reserv;
2809 decl_t in_insn_reserv;
2810 struct bypass_decl *bypass;
2811 int automaton_presence;
2812 int i;
2814 /* Checking repeated automata declarations. */
2815 automaton_presence = 0;
2816 for (i = 0; i < description->decls_num; i++)
2818 decl = description->decls [i];
2819 if (decl->mode == dm_automaton)
2821 automaton_presence = 1;
2822 decl_in_table = insert_automaton_decl (decl);
2823 if (decl_in_table != decl)
2825 if (!w_flag)
2826 error ("repeated declaration of automaton `%s'",
2827 DECL_AUTOMATON (decl)->name);
2828 else
2829 warning (0, "repeated declaration of automaton `%s'",
2830 DECL_AUTOMATON (decl)->name);
2834 /* Checking undeclared automata, repeated declarations (except for
2835 automata) and correctness of their attributes (insn latency times
2836 etc.). */
2837 for (i = 0; i < description->decls_num; i++)
2839 decl = description->decls [i];
2840 if (decl->mode == dm_insn_reserv)
2842 DECL_INSN_RESERV (decl)->condexp
2843 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2844 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2845 error ("define_insn_reservation `%s' has negative latency time",
2846 DECL_INSN_RESERV (decl)->name);
2847 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2848 description->insns_num++;
2849 decl_in_table = insert_insn_decl (decl);
2850 if (decl_in_table != decl)
2851 error ("`%s' is already used as insn reservation name",
2852 DECL_INSN_RESERV (decl)->name);
2854 else if (decl->mode == dm_bypass)
2856 if (DECL_BYPASS (decl)->latency < 0)
2857 error ("define_bypass `%s - %s' has negative latency time",
2858 DECL_BYPASS (decl)->out_insn_name,
2859 DECL_BYPASS (decl)->in_insn_name);
2861 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2863 if (decl->mode == dm_unit)
2865 DECL_UNIT (decl)->automaton_decl = NULL;
2866 if (DECL_UNIT (decl)->automaton_name != NULL)
2868 automaton_decl
2869 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2870 if (automaton_decl == NULL)
2871 error ("automaton `%s' is not declared",
2872 DECL_UNIT (decl)->automaton_name);
2873 else
2875 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2876 DECL_UNIT (decl)->automaton_decl
2877 = DECL_AUTOMATON (automaton_decl);
2880 else if (automaton_presence)
2881 error ("define_unit `%s' without automaton when one defined",
2882 DECL_UNIT (decl)->name);
2883 DECL_UNIT (decl)->unit_num = description->units_num;
2884 description->units_num++;
2885 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2887 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2888 continue;
2890 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2892 else
2894 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2896 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2897 continue;
2899 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2901 if (decl_in_table == NULL)
2902 decl_in_table = insert_decl (decl);
2903 else
2905 if (decl->mode == dm_unit)
2906 error ("repeated declaration of unit `%s'",
2907 DECL_UNIT (decl)->name);
2908 else
2909 error ("repeated declaration of reservation `%s'",
2910 DECL_RESERV (decl)->name);
2914 /* Check bypasses and form list of bypasses for each (output)
2915 insn. */
2916 for (i = 0; i < description->decls_num; i++)
2918 decl = description->decls [i];
2919 if (decl->mode == dm_bypass)
2921 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2922 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2923 if (out_insn_reserv == NULL)
2924 error ("there is no insn reservation `%s'",
2925 DECL_BYPASS (decl)->out_insn_name);
2926 else if (in_insn_reserv == NULL)
2927 error ("there is no insn reservation `%s'",
2928 DECL_BYPASS (decl)->in_insn_name);
2929 else
2931 DECL_BYPASS (decl)->out_insn_reserv
2932 = DECL_INSN_RESERV (out_insn_reserv);
2933 DECL_BYPASS (decl)->in_insn_reserv
2934 = DECL_INSN_RESERV (in_insn_reserv);
2935 bypass
2936 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2937 DECL_BYPASS (decl)->in_insn_reserv);
2938 if (bypass != NULL)
2940 if (DECL_BYPASS (decl)->latency == bypass->latency)
2942 if (!w_flag)
2943 error
2944 ("the same bypass `%s - %s' is already defined",
2945 DECL_BYPASS (decl)->out_insn_name,
2946 DECL_BYPASS (decl)->in_insn_name);
2947 else
2948 warning
2949 (0, "the same bypass `%s - %s' is already defined",
2950 DECL_BYPASS (decl)->out_insn_name,
2951 DECL_BYPASS (decl)->in_insn_name);
2953 else
2954 error ("bypass `%s - %s' is already defined",
2955 DECL_BYPASS (decl)->out_insn_name,
2956 DECL_BYPASS (decl)->in_insn_name);
2958 else
2960 DECL_BYPASS (decl)->next
2961 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2962 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2963 = DECL_BYPASS (decl);
2969 /* Check exclusion set declarations and form exclusion sets. */
2970 for (i = 0; i < description->decls_num; i++)
2972 decl = description->decls [i];
2973 if (decl->mode == dm_excl)
2975 unit_set_el_t unit_set_el_list;
2976 unit_set_el_t unit_set_el_list_2;
2978 unit_set_el_list
2979 = process_excls (DECL_EXCL (decl)->names,
2980 DECL_EXCL (decl)->first_list_length, decl->pos);
2981 unit_set_el_list_2
2982 = process_excls (&DECL_EXCL (decl)->names
2983 [DECL_EXCL (decl)->first_list_length],
2984 DECL_EXCL (decl)->all_names_num
2985 - DECL_EXCL (decl)->first_list_length,
2986 decl->pos);
2987 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2988 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2992 /* Check presence set declarations and form presence sets. */
2993 for (i = 0; i < description->decls_num; i++)
2995 decl = description->decls [i];
2996 if (decl->mode == dm_presence)
2998 unit_set_el_t unit_set_el_list;
2999 pattern_set_el_t pattern_set_el_list;
3001 unit_set_el_list
3002 = process_presence_absence_names
3003 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
3004 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3005 pattern_set_el_list
3006 = process_presence_absence_patterns
3007 (DECL_PRESENCE (decl)->patterns,
3008 DECL_PRESENCE (decl)->patterns_num,
3009 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3010 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3011 decl->pos, TRUE,
3012 DECL_PRESENCE (decl)->final_p);
3016 /* Check absence set declarations and form absence sets. */
3017 for (i = 0; i < description->decls_num; i++)
3019 decl = description->decls [i];
3020 if (decl->mode == dm_absence)
3022 unit_set_el_t unit_set_el_list;
3023 pattern_set_el_t pattern_set_el_list;
3025 unit_set_el_list
3026 = process_presence_absence_names
3027 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3028 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3029 pattern_set_el_list
3030 = process_presence_absence_patterns
3031 (DECL_ABSENCE (decl)->patterns,
3032 DECL_ABSENCE (decl)->patterns_num,
3033 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3034 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3035 decl->pos, FALSE,
3036 DECL_ABSENCE (decl)->final_p);
3041 /* The following function checks that declared automaton is used. If
3042 the automaton is not used, the function fixes error/warning. The
3043 following function must be called only after `process_decls'. */
3044 static void
3045 check_automaton_usage (void)
3047 decl_t decl;
3048 int i;
3050 for (i = 0; i < description->decls_num; i++)
3052 decl = description->decls [i];
3053 if (decl->mode == dm_automaton
3054 && !DECL_AUTOMATON (decl)->automaton_is_used)
3056 if (!w_flag)
3057 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3058 else
3059 warning (0, "automaton `%s' is not used",
3060 DECL_AUTOMATON (decl)->name);
3065 /* The following recursive function processes all regexp in order to
3066 fix usage of units or reservations and to fix errors of undeclared
3067 name. The function may change unit_regexp onto reserv_regexp.
3068 Remember that reserv_regexp does not exist before the function
3069 call. */
3070 static regexp_t
3071 process_regexp (regexp_t regexp)
3073 decl_t decl_in_table;
3074 regexp_t new_regexp;
3075 int i;
3077 switch (regexp->mode)
3079 case rm_unit:
3080 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3081 if (decl_in_table == NULL)
3082 error ("undeclared unit or reservation `%s'",
3083 REGEXP_UNIT (regexp)->name);
3084 else
3085 switch (decl_in_table->mode)
3087 case dm_unit:
3088 DECL_UNIT (decl_in_table)->unit_is_used = 1;
3089 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3090 break;
3092 case dm_reserv:
3093 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3094 new_regexp = create_node (sizeof (struct regexp));
3095 new_regexp->mode = rm_reserv;
3096 new_regexp->pos = regexp->pos;
3097 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3098 REGEXP_RESERV (new_regexp)->reserv_decl
3099 = DECL_RESERV (decl_in_table);
3100 regexp = new_regexp;
3101 break;
3103 default:
3104 gcc_unreachable ();
3106 break;
3107 case rm_sequence:
3108 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3109 REGEXP_SEQUENCE (regexp)->regexps [i]
3110 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3111 break;
3112 case rm_allof:
3113 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3114 REGEXP_ALLOF (regexp)->regexps [i]
3115 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3116 break;
3117 case rm_oneof:
3118 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3119 REGEXP_ONEOF (regexp)->regexps [i]
3120 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3121 break;
3122 case rm_repeat:
3123 REGEXP_REPEAT (regexp)->regexp
3124 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3125 break;
3126 case rm_nothing:
3127 break;
3128 default:
3129 gcc_unreachable ();
3131 return regexp;
3134 /* The following function processes regexp of define_reservation and
3135 define_insn_reservation with the aid of function
3136 `process_regexp'. */
3137 static void
3138 process_regexp_decls (void)
3140 decl_t decl;
3141 int i;
3143 for (i = 0; i < description->decls_num; i++)
3145 decl = description->decls [i];
3146 if (decl->mode == dm_reserv)
3147 DECL_RESERV (decl)->regexp
3148 = process_regexp (DECL_RESERV (decl)->regexp);
3149 else if (decl->mode == dm_insn_reserv)
3150 DECL_INSN_RESERV (decl)->regexp
3151 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3155 /* The following function checks that declared unit is used. If the
3156 unit is not used, the function fixes errors/warnings. The
3157 following function must be called only after `process_decls',
3158 `process_regexp_decls'. */
3159 static void
3160 check_usage (void)
3162 decl_t decl;
3163 int i;
3165 for (i = 0; i < description->decls_num; i++)
3167 decl = description->decls [i];
3168 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3170 if (!w_flag)
3171 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3172 else
3173 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
3175 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3177 if (!w_flag)
3178 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3179 else
3180 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
3185 /* The following variable value is number of reservation being
3186 processed on loop recognition. */
3187 static int curr_loop_pass_num;
3189 /* The following recursive function returns nonzero value if REGEXP
3190 contains given decl or reservations in given regexp refers for
3191 given decl. */
3192 static int
3193 loop_in_regexp (regexp_t regexp, decl_t start_decl)
3195 int i;
3197 if (regexp == NULL)
3198 return 0;
3199 switch (regexp->mode)
3201 case rm_unit:
3202 return 0;
3204 case rm_reserv:
3205 if (start_decl->mode == dm_reserv
3206 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3207 return 1;
3208 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3209 == curr_loop_pass_num)
3210 /* declaration has been processed. */
3211 return 0;
3212 else
3214 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3215 = curr_loop_pass_num;
3216 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3217 start_decl);
3220 case rm_sequence:
3221 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3222 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3223 return 1;
3224 return 0;
3226 case rm_allof:
3227 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3228 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3229 return 1;
3230 return 0;
3232 case rm_oneof:
3233 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3234 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3235 return 1;
3236 return 0;
3238 case rm_repeat:
3239 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3241 case rm_nothing:
3242 return 0;
3244 default:
3245 gcc_unreachable ();
3249 /* The following function fixes errors "cycle in definition ...". The
3250 function uses function `loop_in_regexp' for that. */
3251 static void
3252 check_loops_in_regexps (void)
3254 decl_t decl;
3255 int i;
3257 for (i = 0; i < description->decls_num; i++)
3259 decl = description->decls [i];
3260 if (decl->mode == dm_reserv)
3261 DECL_RESERV (decl)->loop_pass_num = 0;
3263 for (i = 0; i < description->decls_num; i++)
3265 decl = description->decls [i];
3266 curr_loop_pass_num = i;
3268 if (decl->mode == dm_reserv)
3270 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3271 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3273 gcc_assert (DECL_RESERV (decl)->regexp);
3274 error ("cycle in definition of reservation `%s'",
3275 DECL_RESERV (decl)->name);
3281 /* The function recursively processes IR of reservation and defines
3282 max and min cycle for reservation of unit. */
3283 static void
3284 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3285 int min_start_cycle, int *max_finish_cycle,
3286 int *min_finish_cycle)
3288 int i;
3290 switch (regexp->mode)
3292 case rm_unit:
3293 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3294 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3295 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3296 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3297 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3298 *max_finish_cycle = max_start_cycle;
3299 *min_finish_cycle = min_start_cycle;
3300 break;
3302 case rm_reserv:
3303 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3304 max_start_cycle, min_start_cycle,
3305 max_finish_cycle, min_finish_cycle);
3306 break;
3308 case rm_repeat:
3309 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3311 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3312 max_start_cycle, min_start_cycle,
3313 max_finish_cycle, min_finish_cycle);
3314 max_start_cycle = *max_finish_cycle + 1;
3315 min_start_cycle = *min_finish_cycle + 1;
3317 break;
3319 case rm_sequence:
3320 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3322 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3323 max_start_cycle, min_start_cycle,
3324 max_finish_cycle, min_finish_cycle);
3325 max_start_cycle = *max_finish_cycle + 1;
3326 min_start_cycle = *min_finish_cycle + 1;
3328 break;
3330 case rm_allof:
3332 int max_cycle = 0;
3333 int min_cycle = 0;
3335 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3337 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3338 max_start_cycle, min_start_cycle,
3339 max_finish_cycle, min_finish_cycle);
3340 if (max_cycle < *max_finish_cycle)
3341 max_cycle = *max_finish_cycle;
3342 if (i == 0 || min_cycle > *min_finish_cycle)
3343 min_cycle = *min_finish_cycle;
3345 *max_finish_cycle = max_cycle;
3346 *min_finish_cycle = min_cycle;
3348 break;
3350 case rm_oneof:
3352 int max_cycle = 0;
3353 int min_cycle = 0;
3355 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3357 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3358 max_start_cycle, min_start_cycle,
3359 max_finish_cycle, min_finish_cycle);
3360 if (max_cycle < *max_finish_cycle)
3361 max_cycle = *max_finish_cycle;
3362 if (i == 0 || min_cycle > *min_finish_cycle)
3363 min_cycle = *min_finish_cycle;
3365 *max_finish_cycle = max_cycle;
3366 *min_finish_cycle = min_cycle;
3368 break;
3370 case rm_nothing:
3371 *max_finish_cycle = max_start_cycle;
3372 *min_finish_cycle = min_start_cycle;
3373 break;
3375 default:
3376 gcc_unreachable ();
3380 /* The following function is called only for correct program. The
3381 function defines max reservation of insns in cycles. */
3382 static void
3383 evaluate_max_reserv_cycles (void)
3385 int max_insn_cycles_num;
3386 int min_insn_cycles_num;
3387 decl_t decl;
3388 int i;
3390 description->max_insn_reserv_cycles = 0;
3391 for (i = 0; i < description->decls_num; i++)
3393 decl = description->decls [i];
3394 if (decl->mode == dm_insn_reserv)
3396 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3397 &max_insn_cycles_num, &min_insn_cycles_num);
3398 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3399 description->max_insn_reserv_cycles = max_insn_cycles_num;
3402 description->max_insn_reserv_cycles++;
3405 /* The following function calls functions for checking all
3406 description. */
3407 static void
3408 check_all_description (void)
3410 process_decls ();
3411 check_automaton_usage ();
3412 process_regexp_decls ();
3413 check_usage ();
3414 check_loops_in_regexps ();
3415 if (!have_error)
3416 evaluate_max_reserv_cycles ();
3421 /* The page contains abstract data `ticker'. This data is used to
3422 report time of different phases of building automata. It is
3423 possibly to write a description for which automata will be built
3424 during several minutes even on fast machine. */
3426 /* The following function creates ticker and makes it active. */
3427 static ticker_t
3428 create_ticker (void)
3430 ticker_t ticker;
3432 ticker.modified_creation_time = get_run_time ();
3433 ticker.incremented_off_time = 0;
3434 return ticker;
3437 /* The following function switches off given ticker. */
3438 static void
3439 ticker_off (ticker_t *ticker)
3441 if (ticker->incremented_off_time == 0)
3442 ticker->incremented_off_time = get_run_time () + 1;
3445 /* The following function switches on given ticker. */
3446 static void
3447 ticker_on (ticker_t *ticker)
3449 if (ticker->incremented_off_time != 0)
3451 ticker->modified_creation_time
3452 += get_run_time () - ticker->incremented_off_time + 1;
3453 ticker->incremented_off_time = 0;
3457 /* The following function returns current time in milliseconds since
3458 the moment when given ticker was created. */
3459 static int
3460 active_time (ticker_t ticker)
3462 if (ticker.incremented_off_time != 0)
3463 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3464 else
3465 return get_run_time () - ticker.modified_creation_time;
3468 /* The following function returns string representation of active time
3469 of given ticker. The result is string representation of seconds
3470 with accuracy of 1/100 second. Only result of the last call of the
3471 function exists. Therefore the following code is not correct
3473 printf ("parser time: %s\ngeneration time: %s\n",
3474 active_time_string (parser_ticker),
3475 active_time_string (generation_ticker));
3477 Correct code has to be the following
3479 printf ("parser time: %s\n", active_time_string (parser_ticker));
3480 printf ("generation time: %s\n",
3481 active_time_string (generation_ticker));
3484 static void
3485 print_active_time (FILE *f, ticker_t ticker)
3487 int msecs;
3489 msecs = active_time (ticker);
3490 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3495 /* The following variable value is number of automaton which are
3496 really being created. This value is defined on the base of
3497 argument of option `-split'. If the variable has zero value the
3498 number of automata is defined by the constructions `%automaton'.
3499 This case occurs when option `-split' is absent or has zero
3500 argument. If constructions `define_automaton' is absent only one
3501 automaton is created. */
3502 static int automata_num;
3504 /* The following variable values are times of
3505 o transformation of regular expressions
3506 o building NDFA (DFA if !ndfa_flag)
3507 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3508 o DFA minimization
3509 o building insn equivalence classes
3510 o all previous ones
3511 o code output */
3512 static ticker_t transform_time;
3513 static ticker_t NDFA_time;
3514 static ticker_t NDFA_to_DFA_time;
3515 static ticker_t minimize_time;
3516 static ticker_t equiv_time;
3517 static ticker_t automaton_generation_time;
3518 static ticker_t output_time;
3520 /* The following variable values are times of
3521 all checking
3522 all generation
3523 all pipeline hazard translator work */
3524 static ticker_t check_time;
3525 static ticker_t generation_time;
3526 static ticker_t all_time;
3530 /* Pseudo insn decl which denotes advancing cycle. */
3531 static decl_t advance_cycle_insn_decl;
3532 static void
3533 add_advance_cycle_insn_decl (void)
3535 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3536 advance_cycle_insn_decl->mode = dm_insn_reserv;
3537 advance_cycle_insn_decl->pos = no_pos;
3538 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3539 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
3540 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3541 = description->insns_num;
3542 description->decls [description->decls_num] = advance_cycle_insn_decl;
3543 description->decls_num++;
3544 description->insns_num++;
3545 num_dfa_decls++;
3549 /* Abstract data `alternative states' which represents
3550 nondeterministic nature of the description (see comments for
3551 structures alt_state and state). */
3553 /* List of free states. */
3554 static alt_state_t first_free_alt_state;
3556 #ifndef NDEBUG
3557 /* The following variables is maximal number of allocated nodes
3558 alt_state. */
3559 static int allocated_alt_states_num = 0;
3560 #endif
3562 /* The following function returns free node alt_state. It may be new
3563 allocated node or node freed earlier. */
3564 static alt_state_t
3565 get_free_alt_state (void)
3567 alt_state_t result;
3569 if (first_free_alt_state != NULL)
3571 result = first_free_alt_state;
3572 first_free_alt_state = first_free_alt_state->next_alt_state;
3574 else
3576 #ifndef NDEBUG
3577 allocated_alt_states_num++;
3578 #endif
3579 result = create_node (sizeof (struct alt_state));
3581 result->state = NULL;
3582 result->next_alt_state = NULL;
3583 result->next_sorted_alt_state = NULL;
3584 return result;
3587 /* The function frees node ALT_STATE. */
3588 static void
3589 free_alt_state (alt_state_t alt_state)
3591 if (alt_state == NULL)
3592 return;
3593 alt_state->next_alt_state = first_free_alt_state;
3594 first_free_alt_state = alt_state;
3597 /* The function frees list started with node ALT_STATE_LIST. */
3598 static void
3599 free_alt_states (alt_state_t alt_states_list)
3601 alt_state_t curr_alt_state;
3602 alt_state_t next_alt_state;
3604 for (curr_alt_state = alt_states_list;
3605 curr_alt_state != NULL;
3606 curr_alt_state = next_alt_state)
3608 next_alt_state = curr_alt_state->next_alt_state;
3609 free_alt_state (curr_alt_state);
3613 /* The function compares unique numbers of alt states. */
3614 static int
3615 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3617 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3618 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3619 return 0;
3620 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3621 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3622 return -1;
3623 else
3624 return 1;
3627 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3628 states from the list. The comparison key is alt state unique
3629 number. */
3630 static alt_state_t
3631 uniq_sort_alt_states (alt_state_t alt_states_list)
3633 alt_state_t curr_alt_state;
3634 vla_ptr_t alt_states;
3635 size_t i;
3636 size_t prev_unique_state_ind;
3637 alt_state_t result;
3638 alt_state_t *result_ptr;
3640 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3641 for (curr_alt_state = alt_states_list;
3642 curr_alt_state != NULL;
3643 curr_alt_state = curr_alt_state->next_alt_state)
3644 VLA_PTR_ADD (alt_states, curr_alt_state);
3645 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3646 sizeof (alt_state_t), alt_state_cmp);
3647 if (VLA_PTR_LENGTH (alt_states) == 0)
3648 result = NULL;
3649 else
3651 result_ptr = VLA_PTR_BEGIN (alt_states);
3652 prev_unique_state_ind = 0;
3653 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3654 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3656 prev_unique_state_ind++;
3657 result_ptr [prev_unique_state_ind] = result_ptr [i];
3659 #if 0
3660 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3661 free_alt_state (result_ptr [i]);
3662 #endif
3663 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3664 result_ptr = VLA_PTR_BEGIN (alt_states);
3665 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3666 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3667 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3668 result = *result_ptr;
3670 VLA_PTR_DELETE (alt_states);
3671 return result;
3674 /* The function checks equality of alt state lists. Remember that the
3675 lists must be already sorted by the previous function. */
3676 static int
3677 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3679 while (alt_states_1 != NULL && alt_states_2 != NULL
3680 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3682 alt_states_1 = alt_states_1->next_sorted_alt_state;
3683 alt_states_2 = alt_states_2->next_sorted_alt_state;
3685 return alt_states_1 == alt_states_2;
3688 /* Initialization of the abstract data. */
3689 static void
3690 initiate_alt_states (void)
3692 first_free_alt_state = NULL;
3695 /* Finishing work with the abstract data. */
3696 static void
3697 finish_alt_states (void)
3703 /* The page contains macros for work with bits strings. We could use
3704 standard gcc bitmap or sbitmap but it would result in difficulties
3705 of building canadian cross. */
3707 /* Set bit number bitno in the bit string. The macro is not side
3708 effect proof. */
3709 #define SET_BIT(bitstring, bitno) \
3710 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3712 #define CLEAR_BIT(bitstring, bitno) \
3713 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3715 /* Test if bit number bitno in the bitstring is set. The macro is not
3716 side effect proof. */
3717 #define TEST_BIT(bitstring, bitno) \
3718 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3722 /* This page contains abstract data `state'. */
3724 /* Maximal length of reservations in cycles (>= 1). */
3725 static int max_cycles_num;
3727 /* Number of set elements (see type set_el_t) needed for
3728 representation of one cycle reservation. It is depended on units
3729 number. */
3730 static int els_in_cycle_reserv;
3732 /* Number of set elements (see type set_el_t) needed for
3733 representation of maximal length reservation. Deterministic
3734 reservation is stored as set (bit string) of length equal to the
3735 variable value * number of bits in set_el_t. */
3736 static int els_in_reservs;
3738 /* VLA for representation of array of pointers to unit
3739 declarations. */
3740 static vla_ptr_t units_container;
3742 /* The start address of the array. */
3743 static unit_decl_t *units_array;
3745 /* Temporary reservation of maximal length. */
3746 static reserv_sets_t temp_reserv;
3748 /* The state table itself is represented by the following variable. */
3749 static htab_t state_table;
3751 /* VLA for representation of array of pointers to free nodes
3752 `state'. */
3753 static vla_ptr_t free_states;
3755 static int curr_unique_state_num;
3757 #ifndef NDEBUG
3758 /* The following variables is maximal number of allocated nodes
3759 `state'. */
3760 static int allocated_states_num = 0;
3761 #endif
3763 /* Allocate new reservation set. */
3764 static reserv_sets_t
3765 alloc_empty_reserv_sets (void)
3767 reserv_sets_t result;
3769 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3770 result = (reserv_sets_t) obstack_base (&irp);
3771 obstack_finish (&irp);
3772 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3773 return result;
3776 /* Hash value of reservation set. */
3777 static unsigned
3778 reserv_sets_hash_value (reserv_sets_t reservs)
3780 set_el_t hash_value;
3781 unsigned result;
3782 int reservs_num, i;
3783 set_el_t *reserv_ptr;
3785 hash_value = 0;
3786 reservs_num = els_in_reservs;
3787 reserv_ptr = reservs;
3788 i = 0;
3789 while (reservs_num != 0)
3791 reservs_num--;
3792 hash_value += ((*reserv_ptr >> i)
3793 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3794 i++;
3795 if (i == sizeof (set_el_t) * CHAR_BIT)
3796 i = 0;
3797 reserv_ptr++;
3799 if (sizeof (set_el_t) <= sizeof (unsigned))
3800 return hash_value;
3801 result = 0;
3802 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3804 result += (unsigned) hash_value;
3805 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3807 return result;
3810 /* Comparison of given reservation sets. */
3811 static int
3812 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3814 int reservs_num;
3815 set_el_t *reserv_ptr_1;
3816 set_el_t *reserv_ptr_2;
3818 gcc_assert (reservs_1 && reservs_2);
3819 reservs_num = els_in_reservs;
3820 reserv_ptr_1 = reservs_1;
3821 reserv_ptr_2 = reservs_2;
3822 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3824 reservs_num--;
3825 reserv_ptr_1++;
3826 reserv_ptr_2++;
3828 if (reservs_num == 0)
3829 return 0;
3830 else if (*reserv_ptr_1 < *reserv_ptr_2)
3831 return -1;
3832 else
3833 return 1;
3836 /* The function checks equality of the reservation sets. */
3837 static int
3838 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3840 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3843 /* Set up in the reservation set that unit with UNIT_NUM is used on
3844 CYCLE_NUM. */
3845 static void
3846 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3848 gcc_assert (cycle_num < max_cycles_num);
3849 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3850 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3853 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3854 used on CYCLE_NUM. */
3855 static int
3856 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3858 gcc_assert (cycle_num < max_cycles_num);
3859 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3860 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3863 /* The function checks that the reservation set represents no one unit
3864 reservation. */
3865 static int
3866 it_is_empty_reserv_sets (reserv_sets_t operand)
3868 set_el_t *reserv_ptr;
3869 int reservs_num;
3871 gcc_assert (operand);
3872 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3873 reservs_num != 0;
3874 reserv_ptr++, reservs_num--)
3875 if (*reserv_ptr != 0)
3876 return 0;
3877 return 1;
3880 /* The function checks that the reservation sets are intersected,
3881 i.e. there is a unit reservation on a cycle in both reservation
3882 sets. */
3883 static int
3884 reserv_sets_are_intersected (reserv_sets_t operand_1,
3885 reserv_sets_t operand_2)
3887 set_el_t *el_ptr_1;
3888 set_el_t *el_ptr_2;
3889 set_el_t *cycle_ptr_1;
3890 set_el_t *cycle_ptr_2;
3892 gcc_assert (operand_1 && operand_2);
3893 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3894 el_ptr_1 < operand_1 + els_in_reservs;
3895 el_ptr_1++, el_ptr_2++)
3896 if (*el_ptr_1 & *el_ptr_2)
3897 return 1;
3898 reserv_sets_or (temp_reserv, operand_1, operand_2);
3899 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3900 cycle_ptr_1 < operand_1 + els_in_reservs;
3901 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3903 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3904 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3905 el_ptr_1++, el_ptr_2++)
3906 if (*el_ptr_1 & *el_ptr_2)
3907 return 1;
3908 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3909 return 1;
3910 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3911 - operand_2),
3912 cycle_ptr_2, TRUE))
3913 return 1;
3914 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3915 return 1;
3916 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3917 cycle_ptr_2, TRUE))
3918 return 1;
3920 return 0;
3923 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3924 cpu cycle. The remaining bits of OPERAND (representing the last
3925 cycle unit reservations) are not changed. */
3926 static void
3927 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3929 int i;
3931 gcc_assert (result && operand && result != operand);
3932 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3933 result [i - els_in_cycle_reserv] = operand [i];
3936 /* OR of the reservation sets. */
3937 static void
3938 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3939 reserv_sets_t operand_2)
3941 set_el_t *el_ptr_1;
3942 set_el_t *el_ptr_2;
3943 set_el_t *result_set_el_ptr;
3945 gcc_assert (result && operand_1 && operand_2);
3946 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3947 el_ptr_1 < operand_1 + els_in_reservs;
3948 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3949 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3952 /* AND of the reservation sets. */
3953 static void
3954 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3955 reserv_sets_t operand_2)
3957 set_el_t *el_ptr_1;
3958 set_el_t *el_ptr_2;
3959 set_el_t *result_set_el_ptr;
3961 gcc_assert (result && operand_1 && operand_2);
3962 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3963 el_ptr_1 < operand_1 + els_in_reservs;
3964 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3965 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3968 /* The function outputs string representation of units reservation on
3969 cycle START_CYCLE in the reservation set. The function uses repeat
3970 construction if REPETITION_NUM > 1. */
3971 static void
3972 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3973 int repetition_num)
3975 int unit_num;
3976 int reserved_units_num;
3978 reserved_units_num = 0;
3979 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3980 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3981 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3982 reserved_units_num++;
3983 gcc_assert (repetition_num > 0);
3984 if (repetition_num != 1 && reserved_units_num > 1)
3985 fprintf (f, "(");
3986 reserved_units_num = 0;
3987 for (unit_num = 0;
3988 unit_num < description->units_num;
3989 unit_num++)
3990 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3991 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3993 if (reserved_units_num != 0)
3994 fprintf (f, "+");
3995 reserved_units_num++;
3996 fprintf (f, "%s", units_array [unit_num]->name);
3998 if (reserved_units_num == 0)
3999 fprintf (f, NOTHING_NAME);
4000 gcc_assert (repetition_num > 0);
4001 if (repetition_num != 1 && reserved_units_num > 1)
4002 fprintf (f, ")");
4003 if (repetition_num != 1)
4004 fprintf (f, "*%d", repetition_num);
4007 /* The function outputs string representation of units reservation in
4008 the reservation set. */
4009 static void
4010 output_reserv_sets (FILE *f, reserv_sets_t reservs)
4012 int start_cycle = 0;
4013 int cycle;
4014 int repetition_num;
4016 repetition_num = 0;
4017 for (cycle = 0; cycle < max_cycles_num; cycle++)
4018 if (repetition_num == 0)
4020 repetition_num++;
4021 start_cycle = cycle;
4023 else if (memcmp
4024 ((char *) reservs + start_cycle * els_in_cycle_reserv
4025 * sizeof (set_el_t),
4026 (char *) reservs + cycle * els_in_cycle_reserv
4027 * sizeof (set_el_t),
4028 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
4029 repetition_num++;
4030 else
4032 if (start_cycle != 0)
4033 fprintf (f, ", ");
4034 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4035 repetition_num = 1;
4036 start_cycle = cycle;
4038 if (start_cycle < max_cycles_num)
4040 if (start_cycle != 0)
4041 fprintf (f, ", ");
4042 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4046 /* The following function returns free node state for AUTOMATON. It
4047 may be new allocated node or node freed earlier. The function also
4048 allocates reservation set if WITH_RESERVS has nonzero value. */
4049 static state_t
4050 get_free_state (int with_reservs, automaton_t automaton)
4052 state_t result;
4054 gcc_assert (max_cycles_num > 0 && automaton);
4055 if (VLA_PTR_LENGTH (free_states) != 0)
4057 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
4058 VLA_PTR_SHORTEN (free_states, 1);
4059 result->automaton = automaton;
4060 result->first_out_arc = NULL;
4061 result->it_was_placed_in_stack_for_NDFA_forming = 0;
4062 result->it_was_placed_in_stack_for_DFA_forming = 0;
4063 result->component_states = NULL;
4064 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4066 else
4068 #ifndef NDEBUG
4069 allocated_states_num++;
4070 #endif
4071 result = create_node (sizeof (struct state));
4072 result->automaton = automaton;
4073 result->first_out_arc = NULL;
4074 result->unique_num = curr_unique_state_num;
4075 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4076 curr_unique_state_num++;
4078 if (with_reservs)
4080 if (result->reservs == NULL)
4081 result->reservs = alloc_empty_reserv_sets ();
4082 else
4083 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
4085 return result;
4088 /* The function frees node STATE. */
4089 static void
4090 free_state (state_t state)
4092 free_alt_states (state->component_states);
4093 VLA_PTR_ADD (free_states, state);
4096 /* Hash value of STATE. If STATE represents deterministic state it is
4097 simply hash value of the corresponding reservation set. Otherwise
4098 it is formed from hash values of the component deterministic
4099 states. One more key is order number of state automaton. */
4100 static hashval_t
4101 state_hash (const void *state)
4103 unsigned int hash_value;
4104 alt_state_t alt_state;
4106 if (((state_t) state)->component_states == NULL)
4107 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4108 else
4110 hash_value = 0;
4111 for (alt_state = ((state_t) state)->component_states;
4112 alt_state != NULL;
4113 alt_state = alt_state->next_sorted_alt_state)
4114 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4115 | (hash_value << CHAR_BIT))
4116 + alt_state->state->unique_num);
4118 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4119 | (hash_value << CHAR_BIT))
4120 + ((state_t) state)->automaton->automaton_order_num);
4121 return hash_value;
4124 /* Return nonzero value if the states are the same. */
4125 static int
4126 state_eq_p (const void *state_1, const void *state_2)
4128 alt_state_t alt_state_1;
4129 alt_state_t alt_state_2;
4131 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4132 return 0;
4133 else if (((state_t) state_1)->component_states == NULL
4134 && ((state_t) state_2)->component_states == NULL)
4135 return reserv_sets_eq (((state_t) state_1)->reservs,
4136 ((state_t) state_2)->reservs);
4137 else if (((state_t) state_1)->component_states != NULL
4138 && ((state_t) state_2)->component_states != NULL)
4140 for (alt_state_1 = ((state_t) state_1)->component_states,
4141 alt_state_2 = ((state_t) state_2)->component_states;
4142 alt_state_1 != NULL && alt_state_2 != NULL;
4143 alt_state_1 = alt_state_1->next_sorted_alt_state,
4144 alt_state_2 = alt_state_2->next_sorted_alt_state)
4145 /* All state in the list must be already in the hash table.
4146 Also the lists must be sorted. */
4147 if (alt_state_1->state != alt_state_2->state)
4148 return 0;
4149 return alt_state_1 == alt_state_2;
4151 else
4152 return 0;
4155 /* Insert STATE into the state table. */
4156 static state_t
4157 insert_state (state_t state)
4159 void **entry_ptr;
4161 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4162 if (*entry_ptr == NULL)
4163 *entry_ptr = (void *) state;
4164 return (state_t) *entry_ptr;
4167 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4168 deterministic STATE. */
4169 static void
4170 set_state_reserv (state_t state, int cycle_num, int unit_num)
4172 set_unit_reserv (state->reservs, cycle_num, unit_num);
4175 /* Return nonzero value if the deterministic states contains a
4176 reservation of the same cpu unit on the same cpu cycle. */
4177 static int
4178 intersected_state_reservs_p (state_t state1, state_t state2)
4180 gcc_assert (state1->automaton == state2->automaton);
4181 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4184 /* Return deterministic state (inserted into the table) which
4185 representing the automaton state which is union of reservations of
4186 the deterministic states masked by RESERVS. */
4187 static state_t
4188 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4190 state_t result;
4191 state_t state_in_table;
4193 gcc_assert (state1->automaton == state2->automaton);
4194 result = get_free_state (1, state1->automaton);
4195 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4196 reserv_sets_and (result->reservs, result->reservs, reservs);
4197 state_in_table = insert_state (result);
4198 if (result != state_in_table)
4200 free_state (result);
4201 result = state_in_table;
4203 return result;
4206 /* Return deterministic state (inserted into the table) which
4207 represent the automaton state is obtained from deterministic STATE
4208 by advancing cpu cycle and masking by RESERVS. */
4209 static state_t
4210 state_shift (state_t state, reserv_sets_t reservs)
4212 state_t result;
4213 state_t state_in_table;
4215 result = get_free_state (1, state->automaton);
4216 reserv_sets_shift (result->reservs, state->reservs);
4217 reserv_sets_and (result->reservs, result->reservs, reservs);
4218 state_in_table = insert_state (result);
4219 if (result != state_in_table)
4221 free_state (result);
4222 result = state_in_table;
4224 return result;
4227 /* Initialization of the abstract data. */
4228 static void
4229 initiate_states (void)
4231 decl_t decl;
4232 int i;
4234 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
4235 units_array
4236 = (description->decls_num && description->units_num
4237 ? VLA_PTR_BEGIN (units_container) : NULL);
4238 for (i = 0; i < description->decls_num; i++)
4240 decl = description->decls [i];
4241 if (decl->mode == dm_unit)
4242 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4244 max_cycles_num = description->max_insn_reserv_cycles;
4245 els_in_cycle_reserv
4246 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4247 / (sizeof (set_el_t) * CHAR_BIT));
4248 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4249 curr_unique_state_num = 0;
4250 initiate_alt_states ();
4251 VLA_PTR_CREATE (free_states, 1500, "free states");
4252 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4253 temp_reserv = alloc_empty_reserv_sets ();
4256 /* Finishing work with the abstract data. */
4257 static void
4258 finish_states (void)
4260 VLA_PTR_DELETE (units_container);
4261 htab_delete (state_table);
4262 VLA_PTR_DELETE (free_states);
4263 finish_alt_states ();
4268 /* Abstract data `arcs'. */
4270 /* List of free arcs. */
4271 static arc_t first_free_arc;
4273 #ifndef NDEBUG
4274 /* The following variables is maximal number of allocated nodes
4275 `arc'. */
4276 static int allocated_arcs_num = 0;
4277 #endif
4279 /* The function frees node ARC. */
4280 static void
4281 free_arc (arc_t arc)
4283 arc->next_out_arc = first_free_arc;
4284 first_free_arc = arc;
4287 /* The function removes and frees ARC staring from FROM_STATE. */
4288 static void
4289 remove_arc (state_t from_state, arc_t arc)
4291 arc_t prev_arc;
4292 arc_t curr_arc;
4294 gcc_assert (arc);
4295 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4296 curr_arc != NULL;
4297 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4298 if (curr_arc == arc)
4299 break;
4300 gcc_assert (curr_arc);
4301 if (prev_arc == NULL)
4302 from_state->first_out_arc = arc->next_out_arc;
4303 else
4304 prev_arc->next_out_arc = arc->next_out_arc;
4305 free_arc (arc);
4308 /* The functions returns arc with given characteristics (or NULL if
4309 the arc does not exist). */
4310 static arc_t
4311 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4313 arc_t arc;
4315 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4316 if (arc->to_state == to_state && arc->insn == insn)
4317 return arc;
4318 return NULL;
4321 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4322 and with given STATE_ALTS. The function returns added arc (or
4323 already existing arc). */
4324 static arc_t
4325 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4326 int state_alts)
4328 arc_t new_arc;
4330 new_arc = find_arc (from_state, to_state, ainsn);
4331 if (new_arc != NULL)
4332 return new_arc;
4333 if (first_free_arc == NULL)
4335 #ifndef NDEBUG
4336 allocated_arcs_num++;
4337 #endif
4338 new_arc = create_node (sizeof (struct arc));
4339 new_arc->to_state = NULL;
4340 new_arc->insn = NULL;
4341 new_arc->next_out_arc = NULL;
4343 else
4345 new_arc = first_free_arc;
4346 first_free_arc = first_free_arc->next_out_arc;
4348 new_arc->to_state = to_state;
4349 new_arc->insn = ainsn;
4350 ainsn->arc_exists_p = 1;
4351 new_arc->next_out_arc = from_state->first_out_arc;
4352 from_state->first_out_arc = new_arc;
4353 new_arc->next_arc_marked_by_insn = NULL;
4354 new_arc->state_alts = state_alts;
4355 return new_arc;
4358 /* The function returns the first arc starting from STATE. */
4359 static arc_t
4360 first_out_arc (state_t state)
4362 return state->first_out_arc;
4365 /* The function returns next out arc after ARC. */
4366 static arc_t
4367 next_out_arc (arc_t arc)
4369 return arc->next_out_arc;
4372 /* Initialization of the abstract data. */
4373 static void
4374 initiate_arcs (void)
4376 first_free_arc = NULL;
4379 /* Finishing work with the abstract data. */
4380 static void
4381 finish_arcs (void)
4387 /* Abstract data `automata lists'. */
4389 /* List of free states. */
4390 static automata_list_el_t first_free_automata_list_el;
4392 /* The list being formed. */
4393 static automata_list_el_t current_automata_list;
4395 /* Hash table of automata lists. */
4396 static htab_t automata_list_table;
4398 /* The following function returns free automata list el. It may be
4399 new allocated node or node freed earlier. */
4400 static automata_list_el_t
4401 get_free_automata_list_el (void)
4403 automata_list_el_t result;
4405 if (first_free_automata_list_el != NULL)
4407 result = first_free_automata_list_el;
4408 first_free_automata_list_el
4409 = first_free_automata_list_el->next_automata_list_el;
4411 else
4412 result = create_node (sizeof (struct automata_list_el));
4413 result->automaton = NULL;
4414 result->next_automata_list_el = NULL;
4415 return result;
4418 /* The function frees node AUTOMATA_LIST_EL. */
4419 static void
4420 free_automata_list_el (automata_list_el_t automata_list_el)
4422 if (automata_list_el == NULL)
4423 return;
4424 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4425 first_free_automata_list_el = automata_list_el;
4428 /* The function frees list AUTOMATA_LIST. */
4429 static void
4430 free_automata_list (automata_list_el_t automata_list)
4432 automata_list_el_t curr_automata_list_el;
4433 automata_list_el_t next_automata_list_el;
4435 for (curr_automata_list_el = automata_list;
4436 curr_automata_list_el != NULL;
4437 curr_automata_list_el = next_automata_list_el)
4439 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4440 free_automata_list_el (curr_automata_list_el);
4444 /* Hash value of AUTOMATA_LIST. */
4445 static hashval_t
4446 automata_list_hash (const void *automata_list)
4448 unsigned int hash_value;
4449 automata_list_el_t curr_automata_list_el;
4451 hash_value = 0;
4452 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4453 curr_automata_list_el != NULL;
4454 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4455 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4456 | (hash_value << CHAR_BIT))
4457 + curr_automata_list_el->automaton->automaton_order_num);
4458 return hash_value;
4461 /* Return nonzero value if the automata_lists are the same. */
4462 static int
4463 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4465 automata_list_el_t automata_list_el_1;
4466 automata_list_el_t automata_list_el_2;
4468 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4469 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4470 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4471 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4472 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4473 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4474 return 0;
4475 return automata_list_el_1 == automata_list_el_2;
4478 /* Initialization of the abstract data. */
4479 static void
4480 initiate_automata_lists (void)
4482 first_free_automata_list_el = NULL;
4483 automata_list_table = htab_create (1500, automata_list_hash,
4484 automata_list_eq_p, (htab_del) 0);
4487 /* The following function starts new automata list and makes it the
4488 current one. */
4489 static void
4490 automata_list_start (void)
4492 current_automata_list = NULL;
4495 /* The following function adds AUTOMATON to the current list. */
4496 static void
4497 automata_list_add (automaton_t automaton)
4499 automata_list_el_t el;
4501 el = get_free_automata_list_el ();
4502 el->automaton = automaton;
4503 el->next_automata_list_el = current_automata_list;
4504 current_automata_list = el;
4507 /* The following function finishes forming the current list, inserts
4508 it into the table and returns it. */
4509 static automata_list_el_t
4510 automata_list_finish (void)
4512 void **entry_ptr;
4514 if (current_automata_list == NULL)
4515 return NULL;
4516 entry_ptr = htab_find_slot (automata_list_table,
4517 (void *) current_automata_list, 1);
4518 if (*entry_ptr == NULL)
4519 *entry_ptr = (void *) current_automata_list;
4520 else
4521 free_automata_list (current_automata_list);
4522 current_automata_list = NULL;
4523 return (automata_list_el_t) *entry_ptr;
4526 /* Finishing work with the abstract data. */
4527 static void
4528 finish_automata_lists (void)
4530 htab_delete (automata_list_table);
4535 /* The page contains abstract data for work with exclusion sets (see
4536 exclusion_set in file rtl.def). */
4538 /* The following variable refers to an exclusion set returned by
4539 get_excl_set. This is bit string of length equal to cpu units
4540 number. If exclusion set for given unit contains 1 for a unit,
4541 then simultaneous reservation of the units is prohibited. */
4542 static reserv_sets_t excl_set;
4544 /* The array contains exclusion sets for each unit. */
4545 static reserv_sets_t *unit_excl_set_table;
4547 /* The following function forms the array containing exclusion sets
4548 for each unit. */
4549 static void
4550 initiate_excl_sets (void)
4552 decl_t decl;
4553 reserv_sets_t unit_excl_set;
4554 unit_set_el_t el;
4555 int i;
4557 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4558 excl_set = (reserv_sets_t) obstack_base (&irp);
4559 obstack_finish (&irp);
4560 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4561 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4562 obstack_finish (&irp);
4563 /* Evaluate unit exclusion sets. */
4564 for (i = 0; i < description->decls_num; i++)
4566 decl = description->decls [i];
4567 if (decl->mode == dm_unit)
4569 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4570 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4571 obstack_finish (&irp);
4572 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4573 for (el = DECL_UNIT (decl)->excl_list;
4574 el != NULL;
4575 el = el->next_unit_set_el)
4577 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4578 el->unit_decl->in_set_p = TRUE;
4580 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4585 /* The function sets up and return EXCL_SET which is union of
4586 exclusion sets for each unit in IN_SET. */
4587 static reserv_sets_t
4588 get_excl_set (reserv_sets_t in_set)
4590 int excl_char_num;
4591 int chars_num;
4592 int i;
4593 int start_unit_num;
4594 int unit_num;
4596 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4597 memset (excl_set, 0, chars_num);
4598 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4599 if (((unsigned char *) in_set) [excl_char_num])
4600 for (i = CHAR_BIT - 1; i >= 0; i--)
4601 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4603 start_unit_num = excl_char_num * CHAR_BIT + i;
4604 if (start_unit_num >= description->units_num)
4605 return excl_set;
4606 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4608 excl_set [unit_num]
4609 |= unit_excl_set_table [start_unit_num] [unit_num];
4612 return excl_set;
4617 /* The page contains abstract data for work with presence/absence
4618 pattern sets (see presence_set/absence_set in file rtl.def). */
4620 /* The following arrays contain correspondingly presence, final
4621 presence, absence, and final absence patterns for each unit. */
4622 static pattern_reserv_t *unit_presence_set_table;
4623 static pattern_reserv_t *unit_final_presence_set_table;
4624 static pattern_reserv_t *unit_absence_set_table;
4625 static pattern_reserv_t *unit_final_absence_set_table;
4627 /* The following function forms list of reservation sets for given
4628 PATTERN_LIST. */
4629 static pattern_reserv_t
4630 form_reserv_sets_list (pattern_set_el_t pattern_list)
4632 pattern_set_el_t el;
4633 pattern_reserv_t first, curr, prev;
4634 int i;
4636 prev = first = NULL;
4637 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4639 curr = create_node (sizeof (struct pattern_reserv));
4640 curr->reserv = alloc_empty_reserv_sets ();
4641 curr->next_pattern_reserv = NULL;
4642 for (i = 0; i < el->units_num; i++)
4644 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4645 el->unit_decls [i]->in_set_p = TRUE;
4647 if (prev != NULL)
4648 prev->next_pattern_reserv = curr;
4649 else
4650 first = curr;
4651 prev = curr;
4653 return first;
4656 /* The following function forms the array containing presence and
4657 absence pattern sets for each unit. */
4658 static void
4659 initiate_presence_absence_pattern_sets (void)
4661 decl_t decl;
4662 int i;
4664 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4665 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4666 obstack_finish (&irp);
4667 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4668 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4669 obstack_finish (&irp);
4670 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4671 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4672 obstack_finish (&irp);
4673 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4674 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4675 obstack_finish (&irp);
4676 /* Evaluate unit presence/absence sets. */
4677 for (i = 0; i < description->decls_num; i++)
4679 decl = description->decls [i];
4680 if (decl->mode == dm_unit)
4682 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4683 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4684 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4685 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4686 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4687 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4688 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4689 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4694 /* The function checks that CHECKED_SET satisfies all presence pattern
4695 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4696 is ok. */
4697 static int
4698 check_presence_pattern_sets (reserv_sets_t checked_set,
4699 reserv_sets_t origional_set,
4700 int final_p)
4702 int char_num;
4703 int chars_num;
4704 int i;
4705 int start_unit_num;
4706 int unit_num;
4707 int presence_p;
4708 pattern_reserv_t pat_reserv;
4710 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4711 for (char_num = 0; char_num < chars_num; char_num++)
4712 if (((unsigned char *) origional_set) [char_num])
4713 for (i = CHAR_BIT - 1; i >= 0; i--)
4714 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4716 start_unit_num = char_num * CHAR_BIT + i;
4717 if (start_unit_num >= description->units_num)
4718 break;
4719 if ((final_p
4720 && unit_final_presence_set_table [start_unit_num] == NULL)
4721 || (!final_p
4722 && unit_presence_set_table [start_unit_num] == NULL))
4723 continue;
4724 presence_p = FALSE;
4725 for (pat_reserv = (final_p
4726 ? unit_final_presence_set_table [start_unit_num]
4727 : unit_presence_set_table [start_unit_num]);
4728 pat_reserv != NULL;
4729 pat_reserv = pat_reserv->next_pattern_reserv)
4731 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4732 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4733 != pat_reserv->reserv [unit_num])
4734 break;
4735 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4737 if (!presence_p)
4738 return FALSE;
4740 return TRUE;
4743 /* The function checks that CHECKED_SET satisfies all absence pattern
4744 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4745 is ok. */
4746 static int
4747 check_absence_pattern_sets (reserv_sets_t checked_set,
4748 reserv_sets_t origional_set,
4749 int final_p)
4751 int char_num;
4752 int chars_num;
4753 int i;
4754 int start_unit_num;
4755 int unit_num;
4756 pattern_reserv_t pat_reserv;
4758 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4759 for (char_num = 0; char_num < chars_num; char_num++)
4760 if (((unsigned char *) origional_set) [char_num])
4761 for (i = CHAR_BIT - 1; i >= 0; i--)
4762 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4764 start_unit_num = char_num * CHAR_BIT + i;
4765 if (start_unit_num >= description->units_num)
4766 break;
4767 for (pat_reserv = (final_p
4768 ? unit_final_absence_set_table [start_unit_num]
4769 : unit_absence_set_table [start_unit_num]);
4770 pat_reserv != NULL;
4771 pat_reserv = pat_reserv->next_pattern_reserv)
4773 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4774 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4775 != pat_reserv->reserv [unit_num]
4776 && pat_reserv->reserv [unit_num])
4777 break;
4778 if (unit_num >= els_in_cycle_reserv)
4779 return FALSE;
4782 return TRUE;
4787 /* This page contains code for transformation of original reservations
4788 described in .md file. The main goal of transformations is
4789 simplifying reservation and lifting up all `|' on the top of IR
4790 reservation representation. */
4793 /* The following function makes copy of IR representation of
4794 reservation. The function also substitutes all reservations
4795 defined by define_reservation by corresponding value during making
4796 the copy. */
4797 static regexp_t
4798 copy_insn_regexp (regexp_t regexp)
4800 regexp_t result;
4801 int i;
4803 switch (regexp->mode)
4805 case rm_reserv:
4806 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4807 break;
4809 case rm_unit:
4810 result = copy_node (regexp, sizeof (struct regexp));
4811 break;
4813 case rm_repeat:
4814 result = copy_node (regexp, sizeof (struct regexp));
4815 REGEXP_REPEAT (result)->regexp
4816 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4817 break;
4819 case rm_sequence:
4820 result = copy_node (regexp,
4821 sizeof (struct regexp) + sizeof (regexp_t)
4822 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4823 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4824 REGEXP_SEQUENCE (result)->regexps [i]
4825 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4826 break;
4828 case rm_allof:
4829 result = copy_node (regexp,
4830 sizeof (struct regexp) + sizeof (regexp_t)
4831 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4832 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4833 REGEXP_ALLOF (result)->regexps [i]
4834 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4835 break;
4837 case rm_oneof:
4838 result = copy_node (regexp,
4839 sizeof (struct regexp) + sizeof (regexp_t)
4840 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4841 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4842 REGEXP_ONEOF (result)->regexps [i]
4843 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4844 break;
4846 case rm_nothing:
4847 result = copy_node (regexp, sizeof (struct regexp));
4848 break;
4850 default:
4851 gcc_unreachable ();
4853 return result;
4856 /* The following variable is set up 1 if a transformation has been
4857 applied. */
4858 static int regexp_transformed_p;
4860 /* The function makes transformation
4861 A*N -> A, A, ... */
4862 static regexp_t
4863 transform_1 (regexp_t regexp)
4865 int i;
4866 int repeat_num;
4867 regexp_t operand;
4868 pos_t pos;
4870 if (regexp->mode == rm_repeat)
4872 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4873 gcc_assert (repeat_num > 1);
4874 operand = REGEXP_REPEAT (regexp)->regexp;
4875 pos = regexp->mode;
4876 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4877 * (repeat_num - 1));
4878 regexp->mode = rm_sequence;
4879 regexp->pos = pos;
4880 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4881 for (i = 0; i < repeat_num; i++)
4882 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4883 regexp_transformed_p = 1;
4885 return regexp;
4888 /* The function makes transformations
4889 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4890 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4891 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4892 static regexp_t
4893 transform_2 (regexp_t regexp)
4895 if (regexp->mode == rm_sequence)
4897 regexp_t sequence = NULL;
4898 regexp_t result;
4899 int sequence_index = 0;
4900 int i, j;
4902 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4903 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4905 sequence_index = i;
4906 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4907 break;
4909 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4911 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4912 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4913 result = create_node (sizeof (struct regexp)
4914 + sizeof (regexp_t)
4915 * (REGEXP_SEQUENCE (regexp)->regexps_num
4916 + REGEXP_SEQUENCE (sequence)->regexps_num
4917 - 2));
4918 result->mode = rm_sequence;
4919 result->pos = regexp->pos;
4920 REGEXP_SEQUENCE (result)->regexps_num
4921 = (REGEXP_SEQUENCE (regexp)->regexps_num
4922 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4923 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4924 if (i < sequence_index)
4925 REGEXP_SEQUENCE (result)->regexps [i]
4926 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4927 else if (i > sequence_index)
4928 REGEXP_SEQUENCE (result)->regexps
4929 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4930 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4931 else
4932 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4933 REGEXP_SEQUENCE (result)->regexps [i + j]
4934 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4935 regexp_transformed_p = 1;
4936 regexp = result;
4939 else if (regexp->mode == rm_allof)
4941 regexp_t allof = NULL;
4942 regexp_t result;
4943 int allof_index = 0;
4944 int i, j;
4946 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4947 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4949 allof_index = i;
4950 allof = REGEXP_ALLOF (regexp)->regexps [i];
4951 break;
4953 if (i < REGEXP_ALLOF (regexp)->regexps_num)
4955 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4956 && REGEXP_ALLOF (regexp)->regexps_num > 1);
4957 result = create_node (sizeof (struct regexp)
4958 + sizeof (regexp_t)
4959 * (REGEXP_ALLOF (regexp)->regexps_num
4960 + REGEXP_ALLOF (allof)->regexps_num - 2));
4961 result->mode = rm_allof;
4962 result->pos = regexp->pos;
4963 REGEXP_ALLOF (result)->regexps_num
4964 = (REGEXP_ALLOF (regexp)->regexps_num
4965 + REGEXP_ALLOF (allof)->regexps_num - 1);
4966 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4967 if (i < allof_index)
4968 REGEXP_ALLOF (result)->regexps [i]
4969 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4970 else if (i > allof_index)
4971 REGEXP_ALLOF (result)->regexps
4972 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4973 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4974 else
4975 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4976 REGEXP_ALLOF (result)->regexps [i + j]
4977 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4978 regexp_transformed_p = 1;
4979 regexp = result;
4982 else if (regexp->mode == rm_oneof)
4984 regexp_t oneof = NULL;
4985 regexp_t result;
4986 int oneof_index = 0;
4987 int i, j;
4989 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4990 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4992 oneof_index = i;
4993 oneof = REGEXP_ONEOF (regexp)->regexps [i];
4994 break;
4996 if (i < REGEXP_ONEOF (regexp)->regexps_num)
4998 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4999 && REGEXP_ONEOF (regexp)->regexps_num > 1);
5000 result = create_node (sizeof (struct regexp)
5001 + sizeof (regexp_t)
5002 * (REGEXP_ONEOF (regexp)->regexps_num
5003 + REGEXP_ONEOF (oneof)->regexps_num - 2));
5004 result->mode = rm_oneof;
5005 result->pos = regexp->pos;
5006 REGEXP_ONEOF (result)->regexps_num
5007 = (REGEXP_ONEOF (regexp)->regexps_num
5008 + REGEXP_ONEOF (oneof)->regexps_num - 1);
5009 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5010 if (i < oneof_index)
5011 REGEXP_ONEOF (result)->regexps [i]
5012 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5013 else if (i > oneof_index)
5014 REGEXP_ONEOF (result)->regexps
5015 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
5016 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5017 else
5018 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
5019 REGEXP_ONEOF (result)->regexps [i + j]
5020 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
5021 regexp_transformed_p = 1;
5022 regexp = result;
5025 return regexp;
5028 /* The function makes transformations
5029 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
5030 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
5031 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
5032 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
5033 static regexp_t
5034 transform_3 (regexp_t regexp)
5036 if (regexp->mode == rm_sequence)
5038 regexp_t oneof = NULL;
5039 int oneof_index = 0;
5040 regexp_t result;
5041 regexp_t sequence;
5042 int i, j;
5044 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5045 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
5047 oneof_index = i;
5048 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
5049 break;
5051 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
5053 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5054 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
5055 result = create_node (sizeof (struct regexp)
5056 + sizeof (regexp_t)
5057 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5058 result->mode = rm_oneof;
5059 result->pos = regexp->pos;
5060 REGEXP_ONEOF (result)->regexps_num
5061 = REGEXP_ONEOF (oneof)->regexps_num;
5062 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5064 sequence
5065 = create_node (sizeof (struct regexp)
5066 + sizeof (regexp_t)
5067 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
5068 sequence->mode = rm_sequence;
5069 sequence->pos = regexp->pos;
5070 REGEXP_SEQUENCE (sequence)->regexps_num
5071 = REGEXP_SEQUENCE (regexp)->regexps_num;
5072 REGEXP_ONEOF (result)->regexps [i] = sequence;
5073 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
5074 if (j != oneof_index)
5075 REGEXP_SEQUENCE (sequence)->regexps [j]
5076 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
5077 else
5078 REGEXP_SEQUENCE (sequence)->regexps [j]
5079 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5081 regexp_transformed_p = 1;
5082 regexp = result;
5085 else if (regexp->mode == rm_allof)
5087 regexp_t oneof = NULL;
5088 regexp_t seq;
5089 int oneof_index = 0;
5090 int max_seq_length, allof_length;
5091 regexp_t result;
5092 regexp_t allof = NULL;
5093 regexp_t allof_op = NULL;
5094 int i, j;
5096 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5097 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
5099 oneof_index = i;
5100 oneof = REGEXP_ALLOF (regexp)->regexps [i];
5101 break;
5103 if (i < REGEXP_ALLOF (regexp)->regexps_num)
5105 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5106 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5107 result = create_node (sizeof (struct regexp)
5108 + sizeof (regexp_t)
5109 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5110 result->mode = rm_oneof;
5111 result->pos = regexp->pos;
5112 REGEXP_ONEOF (result)->regexps_num
5113 = REGEXP_ONEOF (oneof)->regexps_num;
5114 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5116 allof
5117 = create_node (sizeof (struct regexp)
5118 + sizeof (regexp_t)
5119 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5120 allof->mode = rm_allof;
5121 allof->pos = regexp->pos;
5122 REGEXP_ALLOF (allof)->regexps_num
5123 = REGEXP_ALLOF (regexp)->regexps_num;
5124 REGEXP_ONEOF (result)->regexps [i] = allof;
5125 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5126 if (j != oneof_index)
5127 REGEXP_ALLOF (allof)->regexps [j]
5128 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5129 else
5130 REGEXP_ALLOF (allof)->regexps [j]
5131 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5133 regexp_transformed_p = 1;
5134 regexp = result;
5136 max_seq_length = 0;
5137 if (regexp->mode == rm_allof)
5138 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5140 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
5142 case rm_sequence:
5143 seq = REGEXP_ALLOF (regexp)->regexps [i];
5144 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5145 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5146 break;
5148 case rm_unit:
5149 case rm_nothing:
5150 break;
5152 default:
5153 max_seq_length = 0;
5154 goto break_for;
5157 break_for:
5158 if (max_seq_length != 0)
5160 gcc_assert (max_seq_length != 1
5161 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5162 result = create_node (sizeof (struct regexp)
5163 + sizeof (regexp_t) * (max_seq_length - 1));
5164 result->mode = rm_sequence;
5165 result->pos = regexp->pos;
5166 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5167 for (i = 0; i < max_seq_length; i++)
5169 allof_length = 0;
5170 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5171 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
5173 case rm_sequence:
5174 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5175 ->regexps [j])->regexps_num))
5177 allof_op
5178 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5179 ->regexps [j])
5180 ->regexps [i]);
5181 allof_length++;
5183 break;
5184 case rm_unit:
5185 case rm_nothing:
5186 if (i == 0)
5188 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5189 allof_length++;
5191 break;
5192 default:
5193 break;
5196 if (allof_length == 1)
5197 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5198 else
5200 allof = create_node (sizeof (struct regexp)
5201 + sizeof (regexp_t)
5202 * (allof_length - 1));
5203 allof->mode = rm_allof;
5204 allof->pos = regexp->pos;
5205 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5206 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5207 allof_length = 0;
5208 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5209 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5210 && (i <
5211 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5212 ->regexps [j])->regexps_num)))
5214 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5215 ->regexps [j])
5216 ->regexps [i]);
5217 REGEXP_ALLOF (allof)->regexps [allof_length]
5218 = allof_op;
5219 allof_length++;
5221 else if (i == 0
5222 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5223 == rm_unit
5224 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5225 == rm_nothing)))
5227 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5228 REGEXP_ALLOF (allof)->regexps [allof_length]
5229 = allof_op;
5230 allof_length++;
5234 regexp_transformed_p = 1;
5235 regexp = result;
5238 return regexp;
5241 /* The function traverses IR of reservation and applies transformations
5242 implemented by FUNC. */
5243 static regexp_t
5244 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5246 int i;
5248 switch (regexp->mode)
5250 case rm_sequence:
5251 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5252 REGEXP_SEQUENCE (regexp)->regexps [i]
5253 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
5254 func);
5255 break;
5257 case rm_allof:
5258 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5259 REGEXP_ALLOF (regexp)->regexps [i]
5260 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5261 break;
5263 case rm_oneof:
5264 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5265 REGEXP_ONEOF (regexp)->regexps [i]
5266 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5267 break;
5269 case rm_repeat:
5270 REGEXP_REPEAT (regexp)->regexp
5271 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5272 break;
5274 case rm_nothing:
5275 case rm_unit:
5276 break;
5278 default:
5279 gcc_unreachable ();
5281 return (*func) (regexp);
5284 /* The function applies all transformations for IR representation of
5285 reservation REGEXP. */
5286 static regexp_t
5287 transform_regexp (regexp_t regexp)
5289 regexp = regexp_transform_func (regexp, transform_1);
5292 regexp_transformed_p = 0;
5293 regexp = regexp_transform_func (regexp, transform_2);
5294 regexp = regexp_transform_func (regexp, transform_3);
5296 while (regexp_transformed_p);
5297 return regexp;
5300 /* The function applies all transformations for reservations of all
5301 insn declarations. */
5302 static void
5303 transform_insn_regexps (void)
5305 decl_t decl;
5306 int i;
5308 transform_time = create_ticker ();
5309 add_advance_cycle_insn_decl ();
5310 if (progress_flag)
5311 fprintf (stderr, "Reservation transformation...");
5312 for (i = 0; i < description->decls_num; i++)
5314 decl = description->decls [i];
5315 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5316 DECL_INSN_RESERV (decl)->transformed_regexp
5317 = transform_regexp (copy_insn_regexp
5318 (DECL_INSN_RESERV (decl)->regexp));
5320 if (progress_flag)
5321 fprintf (stderr, "done\n");
5322 ticker_off (&transform_time);
5327 /* The following variable value is TRUE if the first annotated message
5328 about units to automata distribution has been output. */
5329 static int annotation_message_reported_p;
5331 /* The following structure describes usage of a unit in a reservation. */
5332 struct unit_usage
5334 unit_decl_t unit_decl;
5335 /* The following forms a list of units used on the same cycle in the
5336 same alternative. */
5337 struct unit_usage *next;
5340 /* Obstack for unit_usage structures. */
5341 static struct obstack unit_usages;
5343 /* VLA for representation of array of pointers to unit usage
5344 structures. There is an element for each combination of
5345 (alternative number, cycle). Unit usages on given cycle in
5346 alternative with given number are referred through element with
5347 index equals to the cycle * number of all alternatives in the regexp
5348 + the alternative number. */
5349 static vla_ptr_t cycle_alt_unit_usages;
5351 /* The following function creates the structure unit_usage for UNIT on
5352 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5353 accessed through cycle_alt_unit_usages. */
5354 static void
5355 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5356 int alt_num)
5358 size_t i, length, old_length;
5359 unit_decl_t unit_decl;
5360 struct unit_usage *unit_usage_ptr;
5361 int index;
5363 gcc_assert (regexp && regexp->mode == rm_oneof
5364 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
5365 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5366 old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
5367 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5368 if (old_length < length)
5370 VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
5371 for (i = old_length; i < length; i++)
5372 VLA_PTR (cycle_alt_unit_usages, i) = NULL;
5374 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5375 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5376 obstack_finish (&unit_usages);
5377 unit_usage_ptr->unit_decl = unit_decl;
5378 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5379 unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
5380 VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
5381 unit_decl->last_distribution_check_cycle = -1; /* undefined */
5384 /* The function processes given REGEXP to find units with the wrong
5385 distribution. */
5386 static void
5387 check_regexp_units_distribution (const char *insn_reserv_name,
5388 regexp_t regexp)
5390 int i, j, k, cycle;
5391 regexp_t seq, allof, unit;
5392 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5394 if (regexp == NULL || regexp->mode != rm_oneof)
5395 return;
5396 /* Store all unit usages in the regexp: */
5397 obstack_init (&unit_usages);
5398 VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
5399 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5401 seq = REGEXP_ONEOF (regexp)->regexps [i];
5402 switch (seq->mode)
5404 case rm_sequence:
5405 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5407 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5408 switch (allof->mode)
5410 case rm_allof:
5411 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5413 unit = REGEXP_ALLOF (allof)->regexps [k];
5414 if (unit->mode == rm_unit)
5415 store_alt_unit_usage (regexp, unit, j, i);
5416 else
5417 gcc_assert (unit->mode == rm_nothing);
5419 break;
5421 case rm_unit:
5422 store_alt_unit_usage (regexp, allof, j, i);
5423 break;
5425 case rm_nothing:
5426 break;
5428 default:
5429 gcc_unreachable ();
5432 break;
5434 case rm_allof:
5435 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5437 unit = REGEXP_ALLOF (seq)->regexps [k];
5438 switch (unit->mode)
5440 case rm_unit:
5441 store_alt_unit_usage (regexp, unit, 0, i);
5442 break;
5444 case rm_nothing:
5445 break;
5447 default:
5448 gcc_unreachable ();
5451 break;
5453 case rm_unit:
5454 store_alt_unit_usage (regexp, seq, 0, i);
5455 break;
5457 case rm_nothing:
5458 break;
5460 default:
5461 gcc_unreachable ();
5464 /* Check distribution: */
5465 for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
5467 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5468 for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
5469 unit_usage_ptr != NULL;
5470 unit_usage_ptr = unit_usage_ptr->next)
5471 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5473 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5474 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5475 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5476 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5477 k++)
5479 for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
5480 other_unit_usage_ptr != NULL;
5481 other_unit_usage_ptr = other_unit_usage_ptr->next)
5482 if (unit_usage_ptr->unit_decl->automaton_decl
5483 == other_unit_usage_ptr->unit_decl->automaton_decl)
5484 break;
5485 if (other_unit_usage_ptr == NULL
5486 && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
5487 break;
5489 if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5490 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5492 if (!annotation_message_reported_p)
5494 fprintf (stderr, "\n");
5495 error ("The following units do not satisfy units-automata distribution rule");
5496 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5497 annotation_message_reported_p = TRUE;
5499 error ("Unit %s, reserv. %s, cycle %d",
5500 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5501 cycle);
5505 VLA_PTR_DELETE (cycle_alt_unit_usages);
5506 obstack_free (&unit_usages, NULL);
5509 /* The function finds units which violates units to automata
5510 distribution rule. If the units exist, report about them. */
5511 static void
5512 check_unit_distributions_to_automata (void)
5514 decl_t decl;
5515 int i;
5517 if (progress_flag)
5518 fprintf (stderr, "Check unit distributions to automata...");
5519 annotation_message_reported_p = FALSE;
5520 for (i = 0; i < description->decls_num; i++)
5522 decl = description->decls [i];
5523 if (decl->mode == dm_insn_reserv)
5524 check_regexp_units_distribution
5525 (DECL_INSN_RESERV (decl)->name,
5526 DECL_INSN_RESERV (decl)->transformed_regexp);
5528 if (progress_flag)
5529 fprintf (stderr, "done\n");
5534 /* The page contains code for building alt_states (see comments for
5535 IR) describing all possible insns reservations of an automaton. */
5537 /* Current state being formed for which the current alt_state
5538 refers. */
5539 static state_t state_being_formed;
5541 /* Current alt_state being formed. */
5542 static alt_state_t alt_state_being_formed;
5544 /* This recursive function processes `,' and units in reservation
5545 REGEXP for forming alt_states of AUTOMATON. It is believed that
5546 CURR_CYCLE is start cycle of all reservation REGEXP. */
5547 static int
5548 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5549 int curr_cycle)
5551 int i;
5553 if (regexp == NULL)
5554 return curr_cycle;
5556 switch (regexp->mode)
5558 case rm_unit:
5559 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5560 == automaton->automaton_order_num)
5561 set_state_reserv (state_being_formed, curr_cycle,
5562 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5563 return curr_cycle;
5565 case rm_sequence:
5566 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5567 curr_cycle
5568 = process_seq_for_forming_states
5569 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5570 return curr_cycle;
5572 case rm_allof:
5574 int finish_cycle = 0;
5575 int cycle;
5577 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5579 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5580 ->regexps [i],
5581 automaton, curr_cycle);
5582 if (finish_cycle < cycle)
5583 finish_cycle = cycle;
5585 return finish_cycle;
5588 case rm_nothing:
5589 return curr_cycle;
5591 default:
5592 gcc_unreachable ();
5596 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5597 inserts alt_state into the table. */
5598 static void
5599 finish_forming_alt_state (alt_state_t alt_state,
5600 automaton_t automaton ATTRIBUTE_UNUSED)
5602 state_t state_in_table;
5603 state_t corresponding_state;
5605 corresponding_state = alt_state->state;
5606 state_in_table = insert_state (corresponding_state);
5607 if (state_in_table != corresponding_state)
5609 free_state (corresponding_state);
5610 alt_state->state = state_in_table;
5614 /* The following variable value is current automaton insn for whose
5615 reservation the alt states are created. */
5616 static ainsn_t curr_ainsn;
5618 /* This recursive function processes `|' in reservation REGEXP for
5619 forming alt_states of AUTOMATON. List of the alt states should
5620 have the same order as in the description. */
5621 static void
5622 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5623 int inside_oneof_p)
5625 int i;
5627 if (regexp->mode != rm_oneof)
5629 alt_state_being_formed = get_free_alt_state ();
5630 state_being_formed = get_free_state (1, automaton);
5631 alt_state_being_formed->state = state_being_formed;
5632 /* We inserts in reverse order but we process alternatives also
5633 in reverse order. So we have the same order of alternative
5634 as in the description. */
5635 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5636 curr_ainsn->alt_states = alt_state_being_formed;
5637 (void) process_seq_for_forming_states (regexp, automaton, 0);
5638 finish_forming_alt_state (alt_state_being_formed, automaton);
5640 else
5642 gcc_assert (!inside_oneof_p);
5643 /* We processes it in reverse order to get list with the same
5644 order as in the description. See also the previous
5645 commentary. */
5646 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5647 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5648 automaton, 1);
5652 /* Create nodes alt_state for all AUTOMATON insns. */
5653 static void
5654 create_alt_states (automaton_t automaton)
5656 struct insn_reserv_decl *reserv_decl;
5658 for (curr_ainsn = automaton->ainsn_list;
5659 curr_ainsn != NULL;
5660 curr_ainsn = curr_ainsn->next_ainsn)
5662 reserv_decl = curr_ainsn->insn_reserv_decl;
5663 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5665 curr_ainsn->alt_states = NULL;
5666 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5667 automaton, 0);
5668 curr_ainsn->sorted_alt_states
5669 = uniq_sort_alt_states (curr_ainsn->alt_states);
5676 /* The page contains major code for building DFA(s) for fast pipeline
5677 hazards recognition. */
5679 /* The function forms list of ainsns of AUTOMATON with the same
5680 reservation. */
5681 static void
5682 form_ainsn_with_same_reservs (automaton_t automaton)
5684 ainsn_t curr_ainsn;
5685 size_t i;
5686 vla_ptr_t first_insns;
5687 vla_ptr_t last_insns;
5689 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5690 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5691 for (curr_ainsn = automaton->ainsn_list;
5692 curr_ainsn != NULL;
5693 curr_ainsn = curr_ainsn->next_ainsn)
5694 if (curr_ainsn->insn_reserv_decl
5695 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5697 curr_ainsn->next_same_reservs_insn = NULL;
5698 curr_ainsn->first_insn_with_same_reservs = 1;
5700 else
5702 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5703 if (alt_states_eq
5704 (curr_ainsn->sorted_alt_states,
5705 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5706 break;
5707 curr_ainsn->next_same_reservs_insn = NULL;
5708 if (i < VLA_PTR_LENGTH (first_insns))
5710 curr_ainsn->first_insn_with_same_reservs = 0;
5711 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5712 = curr_ainsn;
5713 VLA_PTR (last_insns, i) = curr_ainsn;
5715 else
5717 VLA_PTR_ADD (first_insns, curr_ainsn);
5718 VLA_PTR_ADD (last_insns, curr_ainsn);
5719 curr_ainsn->first_insn_with_same_reservs = 1;
5722 VLA_PTR_DELETE (first_insns);
5723 VLA_PTR_DELETE (last_insns);
5726 /* Forming unit reservations which can affect creating the automaton
5727 states achieved from a given state. It permits to build smaller
5728 automata in many cases. We would have the same automata after
5729 the minimization without such optimization, but the automaton
5730 right after the building could be huge. So in other words, usage
5731 of reservs_matter means some minimization during building the
5732 automaton. */
5733 static reserv_sets_t
5734 form_reservs_matter (automaton_t automaton)
5736 int cycle, unit;
5737 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5739 for (cycle = 0; cycle < max_cycles_num; cycle++)
5740 for (unit = 0; unit < description->units_num; unit++)
5741 if (units_array [unit]->automaton_decl
5742 == automaton->corresponding_automaton_decl
5743 && (cycle >= units_array [unit]->min_occ_cycle_num
5744 /* We can not remove queried unit from reservations. */
5745 || units_array [unit]->query_p
5746 /* We can not remove units which are used
5747 `exclusion_set', `presence_set',
5748 `final_presence_set', `absence_set', and
5749 `final_absence_set'. */
5750 || units_array [unit]->in_set_p))
5751 set_unit_reserv (reservs_matter, cycle, unit);
5752 return reservs_matter;
5755 /* The following function creates all states of nondeterministic (if
5756 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5757 static void
5758 make_automaton (automaton_t automaton)
5760 ainsn_t ainsn;
5761 struct insn_reserv_decl *insn_reserv_decl;
5762 alt_state_t alt_state;
5763 state_t state;
5764 state_t start_state;
5765 state_t state2;
5766 ainsn_t advance_cycle_ainsn;
5767 arc_t added_arc;
5768 vla_ptr_t state_stack;
5769 int states_n;
5770 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5772 VLA_PTR_CREATE (state_stack, 150, "state stack");
5773 /* Create the start state (empty state). */
5774 start_state = insert_state (get_free_state (1, automaton));
5775 automaton->start_state = start_state;
5776 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5777 VLA_PTR_ADD (state_stack, start_state);
5778 states_n = 1;
5779 while (VLA_PTR_LENGTH (state_stack) != 0)
5781 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5782 VLA_PTR_SHORTEN (state_stack, 1);
5783 advance_cycle_ainsn = NULL;
5784 for (ainsn = automaton->ainsn_list;
5785 ainsn != NULL;
5786 ainsn = ainsn->next_ainsn)
5787 if (ainsn->first_insn_with_same_reservs)
5789 insn_reserv_decl = ainsn->insn_reserv_decl;
5790 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5792 /* We process alt_states in the same order as they are
5793 present in the description. */
5794 added_arc = NULL;
5795 for (alt_state = ainsn->alt_states;
5796 alt_state != NULL;
5797 alt_state = alt_state->next_alt_state)
5799 state2 = alt_state->state;
5800 if (!intersected_state_reservs_p (state, state2))
5802 state2 = states_union (state, state2, reservs_matter);
5803 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5805 state2->it_was_placed_in_stack_for_NDFA_forming
5806 = 1;
5807 VLA_PTR_ADD (state_stack, state2);
5808 states_n++;
5809 if (progress_flag && states_n % 100 == 0)
5810 fprintf (stderr, ".");
5812 added_arc = add_arc (state, state2, ainsn, 1);
5813 if (!ndfa_flag)
5814 break;
5817 if (!ndfa_flag && added_arc != NULL)
5819 added_arc->state_alts = 0;
5820 for (alt_state = ainsn->alt_states;
5821 alt_state != NULL;
5822 alt_state = alt_state->next_alt_state)
5824 state2 = alt_state->state;
5825 if (!intersected_state_reservs_p (state, state2))
5826 added_arc->state_alts++;
5830 else
5831 advance_cycle_ainsn = ainsn;
5833 /* Add transition to advance cycle. */
5834 state2 = state_shift (state, reservs_matter);
5835 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5837 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5838 VLA_PTR_ADD (state_stack, state2);
5839 states_n++;
5840 if (progress_flag && states_n % 100 == 0)
5841 fprintf (stderr, ".");
5843 gcc_assert (advance_cycle_ainsn);
5844 add_arc (state, state2, advance_cycle_ainsn, 1);
5846 VLA_PTR_DELETE (state_stack);
5849 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5850 static void
5851 form_arcs_marked_by_insn (state_t state)
5853 decl_t decl;
5854 arc_t arc;
5855 int i;
5857 for (i = 0; i < description->decls_num; i++)
5859 decl = description->decls [i];
5860 if (decl->mode == dm_insn_reserv)
5861 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5863 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5865 gcc_assert (arc->insn);
5866 arc->next_arc_marked_by_insn
5867 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5868 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5872 /* The function creates composed state (see comments for IR) from
5873 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5874 same insn. If the composed state is not in STATE_STACK yet, it is
5875 pushed into STATE_STACK. */
5876 static int
5877 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5878 vla_ptr_t *state_stack)
5880 state_t state;
5881 alt_state_t alt_state, curr_alt_state;
5882 alt_state_t new_alt_state;
5883 arc_t curr_arc;
5884 arc_t next_arc;
5885 state_t state_in_table;
5886 state_t temp_state;
5887 alt_state_t canonical_alt_states_list;
5888 int alts_number;
5889 int new_state_p = 0;
5891 if (arcs_marked_by_insn == NULL)
5892 return new_state_p;
5893 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5894 state = arcs_marked_by_insn->to_state;
5895 else
5897 gcc_assert (ndfa_flag);
5898 /* Create composed state. */
5899 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5900 curr_alt_state = NULL;
5901 for (curr_arc = arcs_marked_by_insn;
5902 curr_arc != NULL;
5903 curr_arc = curr_arc->next_arc_marked_by_insn)
5904 if (curr_arc->to_state->component_states == NULL)
5906 new_alt_state = get_free_alt_state ();
5907 new_alt_state->next_alt_state = curr_alt_state;
5908 new_alt_state->state = curr_arc->to_state;
5909 curr_alt_state = new_alt_state;
5911 else
5912 for (alt_state = curr_arc->to_state->component_states;
5913 alt_state != NULL;
5914 alt_state = alt_state->next_sorted_alt_state)
5916 new_alt_state = get_free_alt_state ();
5917 new_alt_state->next_alt_state = curr_alt_state;
5918 new_alt_state->state = alt_state->state;
5919 gcc_assert (!alt_state->state->component_states);
5920 curr_alt_state = new_alt_state;
5922 /* There are not identical sets in the alt state list. */
5923 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5924 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5926 temp_state = state;
5927 state = canonical_alt_states_list->state;
5928 free_state (temp_state);
5930 else
5932 state->component_states = canonical_alt_states_list;
5933 state_in_table = insert_state (state);
5934 if (state_in_table != state)
5936 gcc_assert
5937 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5938 free_state (state);
5939 state = state_in_table;
5941 else
5943 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5944 new_state_p = 1;
5945 for (curr_alt_state = state->component_states;
5946 curr_alt_state != NULL;
5947 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5948 for (curr_arc = first_out_arc (curr_alt_state->state);
5949 curr_arc != NULL;
5950 curr_arc = next_out_arc (curr_arc))
5951 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5953 arcs_marked_by_insn->to_state = state;
5954 for (alts_number = 0,
5955 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5956 curr_arc != NULL;
5957 curr_arc = next_arc)
5959 next_arc = curr_arc->next_arc_marked_by_insn;
5960 remove_arc (original_state, curr_arc);
5961 alts_number++;
5963 arcs_marked_by_insn->state_alts = alts_number;
5966 if (!state->it_was_placed_in_stack_for_DFA_forming)
5968 state->it_was_placed_in_stack_for_DFA_forming = 1;
5969 VLA_PTR_ADD (*state_stack, state);
5971 return new_state_p;
5974 /* The function transforms nondeterministic AUTOMATON into
5975 deterministic. */
5976 static void
5977 NDFA_to_DFA (automaton_t automaton)
5979 state_t start_state;
5980 state_t state;
5981 decl_t decl;
5982 vla_ptr_t state_stack;
5983 int i;
5984 int states_n;
5986 VLA_PTR_CREATE (state_stack, 150, "state stack");
5987 /* Create the start state (empty state). */
5988 start_state = automaton->start_state;
5989 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5990 VLA_PTR_ADD (state_stack, start_state);
5991 states_n = 1;
5992 while (VLA_PTR_LENGTH (state_stack) != 0)
5994 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5995 VLA_PTR_SHORTEN (state_stack, 1);
5996 form_arcs_marked_by_insn (state);
5997 for (i = 0; i < description->decls_num; i++)
5999 decl = description->decls [i];
6000 if (decl->mode == dm_insn_reserv
6001 && create_composed_state
6002 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
6003 &state_stack))
6005 states_n++;
6006 if (progress_flag && states_n % 100 == 0)
6007 fprintf (stderr, ".");
6011 VLA_PTR_DELETE (state_stack);
6014 /* The following variable value is current number (1, 2, ...) of passing
6015 graph of states. */
6016 static int curr_state_graph_pass_num;
6018 /* This recursive function passes all states achieved from START_STATE
6019 and applies APPLIED_FUNC to them. */
6020 static void
6021 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
6023 arc_t arc;
6025 if (start_state->pass_num == curr_state_graph_pass_num)
6026 return;
6027 start_state->pass_num = curr_state_graph_pass_num;
6028 (*applied_func) (start_state);
6029 for (arc = first_out_arc (start_state);
6030 arc != NULL;
6031 arc = next_out_arc (arc))
6032 pass_state_graph (arc->to_state, applied_func);
6035 /* This recursive function passes all states of AUTOMATON and applies
6036 APPLIED_FUNC to them. */
6037 static void
6038 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
6040 curr_state_graph_pass_num++;
6041 pass_state_graph (automaton->start_state, applied_func);
6044 /* The function initializes code for passing of all states. */
6045 static void
6046 initiate_pass_states (void)
6048 curr_state_graph_pass_num = 0;
6051 /* The following vla is used for storing pointers to all achieved
6052 states. */
6053 static vla_ptr_t all_achieved_states;
6055 /* This function is called by function pass_states to add an achieved
6056 STATE. */
6057 static void
6058 add_achieved_state (state_t state)
6060 VLA_PTR_ADD (all_achieved_states, state);
6063 /* The function sets up equivalence numbers of insns which mark all
6064 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6065 nonzero value) or by equiv_class_num_2 of the destination state.
6066 The function returns number of out arcs of STATE. */
6067 static int
6068 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
6070 int state_out_arcs_num;
6071 arc_t arc;
6073 state_out_arcs_num = 0;
6074 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6076 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
6077 && !arc->insn->insn_reserv_decl->state_alts);
6078 state_out_arcs_num++;
6079 arc->insn->insn_reserv_decl->equiv_class_num
6080 = (odd_iteration_flag
6081 ? arc->to_state->equiv_class_num_1
6082 : arc->to_state->equiv_class_num_2);
6083 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6084 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
6085 && arc->insn->insn_reserv_decl->state_alts > 0);
6087 return state_out_arcs_num;
6090 /* The function clears equivalence numbers and alt_states in all insns
6091 which mark all out arcs of STATE. */
6092 static void
6093 clear_arc_insns_equiv_num (state_t state)
6095 arc_t arc;
6097 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6099 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6100 arc->insn->insn_reserv_decl->state_alts = 0;
6104 /* The function copies pointers to equivalent states from vla FROM
6105 into vla TO. */
6106 static void
6107 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
6109 state_t *class_ptr;
6111 VLA_PTR_NULLIFY (*to);
6112 for (class_ptr = VLA_PTR_BEGIN (*from);
6113 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6114 class_ptr++)
6115 VLA_PTR_ADD (*to, *class_ptr);
6118 /* The following function returns TRUE if STATE reserves the unit with
6119 UNIT_NUM on the first cycle. */
6120 static int
6121 first_cycle_unit_presence (state_t state, int unit_num)
6123 alt_state_t alt_state;
6125 if (state->component_states == NULL)
6126 return test_unit_reserv (state->reservs, 0, unit_num);
6127 else
6129 for (alt_state = state->component_states;
6130 alt_state != NULL;
6131 alt_state = alt_state->next_sorted_alt_state)
6132 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
6133 return true;
6135 return false;
6138 /* The function returns nonzero value if STATE is not equivalent to
6139 ANOTHER_STATE from the same current partition on equivalence
6140 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6141 output arcs. Iteration of making equivalence partition is defined
6142 by ODD_ITERATION_FLAG. */
6143 static int
6144 state_is_differed (state_t state, state_t another_state,
6145 int another_state_out_arcs_num, int odd_iteration_flag)
6147 arc_t arc;
6148 int state_out_arcs_num;
6149 int i, presence1_p, presence2_p;
6151 state_out_arcs_num = 0;
6152 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6154 state_out_arcs_num++;
6155 if ((odd_iteration_flag
6156 ? arc->to_state->equiv_class_num_1
6157 : arc->to_state->equiv_class_num_2)
6158 != arc->insn->insn_reserv_decl->equiv_class_num
6159 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6160 return 1;
6162 if (state_out_arcs_num != another_state_out_arcs_num)
6163 return 1;
6164 /* Now we are looking at the states with the point of view of query
6165 units. */
6166 for (i = 0; i < description->units_num; i++)
6167 if (units_array [i]->query_p)
6169 presence1_p = first_cycle_unit_presence (state, i);
6170 presence2_p = first_cycle_unit_presence (another_state, i);
6171 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6172 return 1;
6174 return 0;
6177 /* The function makes initial partition of STATES on equivalent
6178 classes. */
6179 static state_t
6180 init_equiv_class (state_t *states, int states_num)
6182 state_t *state_ptr;
6183 state_t result_equiv_class;
6185 result_equiv_class = NULL;
6186 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6188 (*state_ptr)->equiv_class_num_1 = 1;
6189 (*state_ptr)->next_equiv_class_state = result_equiv_class;
6190 result_equiv_class = *state_ptr;
6192 return result_equiv_class;
6195 /* The function processes equivalence class given by its pointer
6196 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6197 are not equivalent states, the function partitions the class
6198 removing nonequivalent states and placing them in
6199 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6200 assigns it to the state equivalence number. If the class has been
6201 partitioned, the function returns nonzero value. */
6202 static int
6203 partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
6204 vla_ptr_t *next_iteration_classes,
6205 int *new_equiv_class_num_ptr)
6207 state_t new_equiv_class;
6208 int partition_p;
6209 state_t first_state;
6210 state_t curr_state;
6211 state_t prev_state;
6212 state_t next_state;
6213 int out_arcs_num;
6215 partition_p = 0;
6216 gcc_assert (*equiv_class_ptr);
6217 for (first_state = *equiv_class_ptr;
6218 first_state != NULL;
6219 first_state = new_equiv_class)
6221 new_equiv_class = NULL;
6222 if (first_state->next_equiv_class_state != NULL)
6224 /* There are more one states in the class equivalence. */
6225 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6226 odd_iteration_flag);
6227 for (prev_state = first_state,
6228 curr_state = first_state->next_equiv_class_state;
6229 curr_state != NULL;
6230 curr_state = next_state)
6232 next_state = curr_state->next_equiv_class_state;
6233 if (state_is_differed (curr_state, first_state, out_arcs_num,
6234 odd_iteration_flag))
6236 /* Remove curr state from the class equivalence. */
6237 prev_state->next_equiv_class_state = next_state;
6238 /* Add curr state to the new class equivalence. */
6239 curr_state->next_equiv_class_state = new_equiv_class;
6240 if (new_equiv_class == NULL)
6241 (*new_equiv_class_num_ptr)++;
6242 if (odd_iteration_flag)
6243 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6244 else
6245 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6246 new_equiv_class = curr_state;
6247 partition_p = 1;
6249 else
6250 prev_state = curr_state;
6252 clear_arc_insns_equiv_num (first_state);
6254 if (new_equiv_class != NULL)
6255 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
6257 return partition_p;
6260 /* The function finds equivalent states of AUTOMATON. */
6261 static void
6262 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
6264 state_t new_equiv_class;
6265 int new_equiv_class_num;
6266 int odd_iteration_flag;
6267 int finish_flag;
6268 vla_ptr_t next_iteration_classes;
6269 state_t *equiv_class_ptr;
6270 state_t *state_ptr;
6272 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6273 pass_states (automaton, add_achieved_state);
6274 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6275 VLA_PTR_LENGTH (all_achieved_states));
6276 odd_iteration_flag = 0;
6277 new_equiv_class_num = 1;
6278 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6279 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6282 odd_iteration_flag = !odd_iteration_flag;
6283 finish_flag = 1;
6284 copy_equiv_class (equiv_classes, &next_iteration_classes);
6285 /* Transfer equiv numbers for the next iteration. */
6286 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6287 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6288 state_ptr++)
6289 if (odd_iteration_flag)
6290 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6291 else
6292 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6293 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6294 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6295 equiv_class_ptr++)
6296 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6297 &next_iteration_classes,
6298 &new_equiv_class_num))
6299 finish_flag = 0;
6301 while (!finish_flag);
6302 VLA_PTR_DELETE (next_iteration_classes);
6303 VLA_PTR_DELETE (all_achieved_states);
6306 /* The function merges equivalent states of AUTOMATON. */
6307 static void
6308 merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
6310 state_t *equiv_class_ptr;
6311 state_t curr_state;
6312 state_t new_state;
6313 state_t first_class_state;
6314 alt_state_t alt_states;
6315 alt_state_t alt_state, new_alt_state;
6316 arc_t curr_arc;
6317 arc_t next_arc;
6319 /* Create states corresponding to equivalence classes containing two
6320 or more states. */
6321 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6322 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6323 equiv_class_ptr++)
6324 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6326 /* There are more one states in the class equivalence. */
6327 /* Create new compound state. */
6328 new_state = get_free_state (0, automaton);
6329 alt_states = NULL;
6330 first_class_state = *equiv_class_ptr;
6331 for (curr_state = first_class_state;
6332 curr_state != NULL;
6333 curr_state = curr_state->next_equiv_class_state)
6335 curr_state->equiv_class_state = new_state;
6336 if (curr_state->component_states == NULL)
6338 new_alt_state = get_free_alt_state ();
6339 new_alt_state->state = curr_state;
6340 new_alt_state->next_alt_state = alt_states;
6341 alt_states = new_alt_state;
6343 else
6344 for (alt_state = curr_state->component_states;
6345 alt_state != NULL;
6346 alt_state = alt_state->next_sorted_alt_state)
6348 new_alt_state = get_free_alt_state ();
6349 new_alt_state->state = alt_state->state;
6350 new_alt_state->next_alt_state = alt_states;
6351 alt_states = new_alt_state;
6354 /* Its is important that alt states were sorted before and
6355 after merging to have the same querying results. */
6356 new_state->component_states = uniq_sort_alt_states (alt_states);
6358 else
6359 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6360 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6361 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6362 equiv_class_ptr++)
6363 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6365 first_class_state = *equiv_class_ptr;
6366 /* Create new arcs output from the state corresponding to
6367 equiv class. */
6368 for (curr_arc = first_out_arc (first_class_state);
6369 curr_arc != NULL;
6370 curr_arc = next_out_arc (curr_arc))
6371 add_arc (first_class_state->equiv_class_state,
6372 curr_arc->to_state->equiv_class_state,
6373 curr_arc->insn, curr_arc->state_alts);
6374 /* Delete output arcs from states of given class equivalence. */
6375 for (curr_state = first_class_state;
6376 curr_state != NULL;
6377 curr_state = curr_state->next_equiv_class_state)
6379 if (automaton->start_state == curr_state)
6380 automaton->start_state = curr_state->equiv_class_state;
6381 /* Delete the state and its output arcs. */
6382 for (curr_arc = first_out_arc (curr_state);
6383 curr_arc != NULL;
6384 curr_arc = next_arc)
6386 next_arc = next_out_arc (curr_arc);
6387 free_arc (curr_arc);
6391 else
6393 /* Change `to_state' of arcs output from the state of given
6394 equivalence class. */
6395 for (curr_arc = first_out_arc (*equiv_class_ptr);
6396 curr_arc != NULL;
6397 curr_arc = next_out_arc (curr_arc))
6398 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6402 /* The function sets up new_cycle_p for states if there is arc to the
6403 state marked by advance_cycle_insn_decl. */
6404 static void
6405 set_new_cycle_flags (state_t state)
6407 arc_t arc;
6409 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6410 if (arc->insn->insn_reserv_decl
6411 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6412 arc->to_state->new_cycle_p = 1;
6415 /* The top level function for minimization of deterministic
6416 AUTOMATON. */
6417 static void
6418 minimize_DFA (automaton_t automaton)
6420 vla_ptr_t equiv_classes;
6422 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6423 evaluate_equiv_classes (automaton, &equiv_classes);
6424 merge_states (automaton, &equiv_classes);
6425 pass_states (automaton, set_new_cycle_flags);
6426 VLA_PTR_DELETE (equiv_classes);
6429 /* Values of two variables are counted number of states and arcs in an
6430 automaton. */
6431 static int curr_counted_states_num;
6432 static int curr_counted_arcs_num;
6434 /* The function is called by function `pass_states' to count states
6435 and arcs of an automaton. */
6436 static void
6437 incr_states_and_arcs_nums (state_t state)
6439 arc_t arc;
6441 curr_counted_states_num++;
6442 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6443 curr_counted_arcs_num++;
6446 /* The function counts states and arcs of AUTOMATON. */
6447 static void
6448 count_states_and_arcs (automaton_t automaton, int *states_num,
6449 int *arcs_num)
6451 curr_counted_states_num = 0;
6452 curr_counted_arcs_num = 0;
6453 pass_states (automaton, incr_states_and_arcs_nums);
6454 *states_num = curr_counted_states_num;
6455 *arcs_num = curr_counted_arcs_num;
6458 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6459 recognition after checking and simplifying IR of the
6460 description. */
6461 static void
6462 build_automaton (automaton_t automaton)
6464 int states_num;
6465 int arcs_num;
6467 ticker_on (&NDFA_time);
6468 if (progress_flag)
6470 if (automaton->corresponding_automaton_decl == NULL)
6471 fprintf (stderr, "Create anonymous automaton");
6472 else
6473 fprintf (stderr, "Create automaton `%s'",
6474 automaton->corresponding_automaton_decl->name);
6475 fprintf (stderr, " (1 dot is 100 new states):");
6477 make_automaton (automaton);
6478 if (progress_flag)
6479 fprintf (stderr, " done\n");
6480 ticker_off (&NDFA_time);
6481 count_states_and_arcs (automaton, &states_num, &arcs_num);
6482 automaton->NDFA_states_num = states_num;
6483 automaton->NDFA_arcs_num = arcs_num;
6484 ticker_on (&NDFA_to_DFA_time);
6485 if (progress_flag)
6487 if (automaton->corresponding_automaton_decl == NULL)
6488 fprintf (stderr, "Make anonymous DFA");
6489 else
6490 fprintf (stderr, "Make DFA `%s'",
6491 automaton->corresponding_automaton_decl->name);
6492 fprintf (stderr, " (1 dot is 100 new states):");
6494 NDFA_to_DFA (automaton);
6495 if (progress_flag)
6496 fprintf (stderr, " done\n");
6497 ticker_off (&NDFA_to_DFA_time);
6498 count_states_and_arcs (automaton, &states_num, &arcs_num);
6499 automaton->DFA_states_num = states_num;
6500 automaton->DFA_arcs_num = arcs_num;
6501 if (!no_minimization_flag)
6503 ticker_on (&minimize_time);
6504 if (progress_flag)
6506 if (automaton->corresponding_automaton_decl == NULL)
6507 fprintf (stderr, "Minimize anonymous DFA...");
6508 else
6509 fprintf (stderr, "Minimize DFA `%s'...",
6510 automaton->corresponding_automaton_decl->name);
6512 minimize_DFA (automaton);
6513 if (progress_flag)
6514 fprintf (stderr, "done\n");
6515 ticker_off (&minimize_time);
6516 count_states_and_arcs (automaton, &states_num, &arcs_num);
6517 automaton->minimal_DFA_states_num = states_num;
6518 automaton->minimal_DFA_arcs_num = arcs_num;
6524 /* The page contains code for enumeration of all states of an automaton. */
6526 /* Variable used for enumeration of all states of an automaton. Its
6527 value is current number of automaton states. */
6528 static int curr_state_order_num;
6530 /* The function is called by function `pass_states' for enumerating
6531 states. */
6532 static void
6533 set_order_state_num (state_t state)
6535 state->order_state_num = curr_state_order_num;
6536 curr_state_order_num++;
6539 /* The function enumerates all states of AUTOMATON. */
6540 static void
6541 enumerate_states (automaton_t automaton)
6543 curr_state_order_num = 0;
6544 pass_states (automaton, set_order_state_num);
6545 automaton->achieved_states_num = curr_state_order_num;
6550 /* The page contains code for finding equivalent automaton insns
6551 (ainsns). */
6553 /* The function inserts AINSN into cyclic list
6554 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6555 static ainsn_t
6556 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6557 ainsn_t cyclic_equiv_class_insn_list)
6559 if (cyclic_equiv_class_insn_list == NULL)
6560 ainsn->next_equiv_class_insn = ainsn;
6561 else
6563 ainsn->next_equiv_class_insn
6564 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6565 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6567 return ainsn;
6570 /* The function deletes equiv_class_insn into cyclic list of
6571 equivalent ainsns. */
6572 static void
6573 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6575 ainsn_t curr_equiv_class_insn;
6576 ainsn_t prev_equiv_class_insn;
6578 prev_equiv_class_insn = equiv_class_insn;
6579 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6580 curr_equiv_class_insn != equiv_class_insn;
6581 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6582 prev_equiv_class_insn = curr_equiv_class_insn;
6583 if (prev_equiv_class_insn != equiv_class_insn)
6584 prev_equiv_class_insn->next_equiv_class_insn
6585 = equiv_class_insn->next_equiv_class_insn;
6588 /* The function processes AINSN of a state in order to find equivalent
6589 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6590 state. */
6591 static void
6592 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6594 ainsn_t next_insn;
6595 ainsn_t curr_insn;
6596 ainsn_t cyclic_insn_list;
6597 arc_t arc;
6599 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6600 curr_insn = ainsn;
6601 /* New class of ainsns which are not equivalent to given ainsn. */
6602 cyclic_insn_list = NULL;
6605 next_insn = curr_insn->next_equiv_class_insn;
6606 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6607 if (arc == NULL
6608 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6609 != arc->to_state))
6611 delete_ainsn_from_equiv_class (curr_insn);
6612 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6613 cyclic_insn_list);
6615 curr_insn = next_insn;
6617 while (curr_insn != ainsn);
6620 /* The function processes STATE in order to find equivalent ainsns. */
6621 static void
6622 process_state_for_insn_equiv_partition (state_t state)
6624 arc_t arc;
6625 arc_t *insn_arcs_array;
6626 int i;
6627 vla_ptr_t insn_arcs_vect;
6629 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6630 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6631 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6632 /* Process insns of the arcs. */
6633 for (i = 0; i < description->insns_num; i++)
6634 insn_arcs_array [i] = NULL;
6635 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6636 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6637 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6638 process_insn_equiv_class (arc->insn, insn_arcs_array);
6639 VLA_PTR_DELETE (insn_arcs_vect);
6642 /* The function searches for equivalent ainsns of AUTOMATON. */
6643 static void
6644 set_insn_equiv_classes (automaton_t automaton)
6646 ainsn_t ainsn;
6647 ainsn_t first_insn;
6648 ainsn_t curr_insn;
6649 ainsn_t cyclic_insn_list;
6650 ainsn_t insn_with_same_reservs;
6651 int equiv_classes_num;
6653 /* All insns are included in one equivalence class. */
6654 cyclic_insn_list = NULL;
6655 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6656 if (ainsn->first_insn_with_same_reservs)
6657 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6658 cyclic_insn_list);
6659 /* Process insns in order to make equivalence partition. */
6660 pass_states (automaton, process_state_for_insn_equiv_partition);
6661 /* Enumerate equiv classes. */
6662 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6663 /* Set undefined value. */
6664 ainsn->insn_equiv_class_num = -1;
6665 equiv_classes_num = 0;
6666 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6667 if (ainsn->insn_equiv_class_num < 0)
6669 first_insn = ainsn;
6670 gcc_assert (first_insn->first_insn_with_same_reservs);
6671 first_insn->first_ainsn_with_given_equivalence_num = 1;
6672 curr_insn = first_insn;
6675 for (insn_with_same_reservs = curr_insn;
6676 insn_with_same_reservs != NULL;
6677 insn_with_same_reservs
6678 = insn_with_same_reservs->next_same_reservs_insn)
6679 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6680 curr_insn = curr_insn->next_equiv_class_insn;
6682 while (curr_insn != first_insn);
6683 equiv_classes_num++;
6685 automaton->insn_equiv_classes_num = equiv_classes_num;
6690 /* This page contains code for creating DFA(s) and calls functions
6691 building them. */
6694 /* The following value is used to prevent floating point overflow for
6695 estimating an automaton bound. The value should be less DBL_MAX on
6696 the host machine. We use here approximate minimum of maximal
6697 double floating point value required by ANSI C standard. It
6698 will work for non ANSI sun compiler too. */
6700 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6702 /* The function estimate size of the single DFA used by PHR (pipeline
6703 hazards recognizer). */
6704 static double
6705 estimate_one_automaton_bound (void)
6707 decl_t decl;
6708 double one_automaton_estimation_bound;
6709 double root_value;
6710 int i;
6712 one_automaton_estimation_bound = 1.0;
6713 for (i = 0; i < description->decls_num; i++)
6715 decl = description->decls [i];
6716 if (decl->mode == dm_unit)
6718 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6719 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6720 / automata_num);
6721 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6722 > one_automaton_estimation_bound)
6723 one_automaton_estimation_bound *= root_value;
6726 return one_automaton_estimation_bound;
6729 /* The function compares unit declarations according to their maximal
6730 cycle in reservations. */
6731 static int
6732 compare_max_occ_cycle_nums (const void *unit_decl_1,
6733 const void *unit_decl_2)
6735 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6736 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6737 return 1;
6738 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6739 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6740 return 0;
6741 else
6742 return -1;
6745 /* The function makes heuristic assigning automata to units. Actually
6746 efficacy of the algorithm has been checked yet??? */
6747 static void
6748 units_to_automata_heuristic_distr (void)
6750 double estimation_bound;
6751 decl_t decl;
6752 decl_t *unit_decl_ptr;
6753 int automaton_num;
6754 int rest_units_num;
6755 double bound_value;
6756 vla_ptr_t unit_decls;
6757 int i;
6759 if (description->units_num == 0)
6760 return;
6761 estimation_bound = estimate_one_automaton_bound ();
6762 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6763 for (i = 0; i < description->decls_num; i++)
6765 decl = description->decls [i];
6766 if (decl->mode == dm_unit)
6767 VLA_PTR_ADD (unit_decls, decl);
6769 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6770 sizeof (decl_t), compare_max_occ_cycle_nums);
6771 automaton_num = 0;
6772 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6773 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6774 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6775 for (unit_decl_ptr++;
6776 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6777 unit_decl_ptr++)
6779 rest_units_num
6780 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6781 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6782 if (automaton_num < automata_num - 1
6783 && ((automata_num - automaton_num - 1 == rest_units_num)
6784 || (bound_value
6785 > (estimation_bound
6786 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6788 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6789 automaton_num++;
6791 else
6792 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6793 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6795 gcc_assert (automaton_num == automata_num - 1);
6796 VLA_PTR_DELETE (unit_decls);
6799 /* The functions creates automaton insns for each automata. Automaton
6800 insn is simply insn for given automaton which makes reservation
6801 only of units of the automaton. */
6802 static ainsn_t
6803 create_ainsns (void)
6805 decl_t decl;
6806 ainsn_t first_ainsn;
6807 ainsn_t curr_ainsn;
6808 ainsn_t prev_ainsn;
6809 int i;
6811 first_ainsn = NULL;
6812 prev_ainsn = NULL;
6813 for (i = 0; i < description->decls_num; i++)
6815 decl = description->decls [i];
6816 if (decl->mode == dm_insn_reserv)
6818 curr_ainsn = create_node (sizeof (struct ainsn));
6819 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6820 curr_ainsn->important_p = FALSE;
6821 curr_ainsn->next_ainsn = NULL;
6822 if (prev_ainsn == NULL)
6823 first_ainsn = curr_ainsn;
6824 else
6825 prev_ainsn->next_ainsn = curr_ainsn;
6826 prev_ainsn = curr_ainsn;
6829 return first_ainsn;
6832 /* The function assigns automata to units according to constructions
6833 `define_automaton' in the description. */
6834 static void
6835 units_to_automata_distr (void)
6837 decl_t decl;
6838 int i;
6840 for (i = 0; i < description->decls_num; i++)
6842 decl = description->decls [i];
6843 if (decl->mode == dm_unit)
6845 if (DECL_UNIT (decl)->automaton_decl == NULL
6846 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6847 == NULL))
6848 /* Distribute to the first automaton. */
6849 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6850 else
6851 DECL_UNIT (decl)->corresponding_automaton_num
6852 = (DECL_UNIT (decl)->automaton_decl
6853 ->corresponding_automaton->automaton_order_num);
6858 /* The function creates DFA(s) for fast pipeline hazards recognition
6859 after checking and simplifying IR of the description. */
6860 static void
6861 create_automata (void)
6863 automaton_t curr_automaton;
6864 automaton_t prev_automaton;
6865 decl_t decl;
6866 int curr_automaton_num;
6867 int i;
6869 if (automata_num != 0)
6871 units_to_automata_heuristic_distr ();
6872 for (prev_automaton = NULL, curr_automaton_num = 0;
6873 curr_automaton_num < automata_num;
6874 curr_automaton_num++, prev_automaton = curr_automaton)
6876 curr_automaton = create_node (sizeof (struct automaton));
6877 curr_automaton->ainsn_list = create_ainsns ();
6878 curr_automaton->corresponding_automaton_decl = NULL;
6879 curr_automaton->next_automaton = NULL;
6880 curr_automaton->automaton_order_num = curr_automaton_num;
6881 if (prev_automaton == NULL)
6882 description->first_automaton = curr_automaton;
6883 else
6884 prev_automaton->next_automaton = curr_automaton;
6887 else
6889 curr_automaton_num = 0;
6890 prev_automaton = NULL;
6891 for (i = 0; i < description->decls_num; i++)
6893 decl = description->decls [i];
6894 if (decl->mode == dm_automaton
6895 && DECL_AUTOMATON (decl)->automaton_is_used)
6897 curr_automaton = create_node (sizeof (struct automaton));
6898 curr_automaton->ainsn_list = create_ainsns ();
6899 curr_automaton->corresponding_automaton_decl
6900 = DECL_AUTOMATON (decl);
6901 curr_automaton->next_automaton = NULL;
6902 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6903 curr_automaton->automaton_order_num = curr_automaton_num;
6904 if (prev_automaton == NULL)
6905 description->first_automaton = curr_automaton;
6906 else
6907 prev_automaton->next_automaton = curr_automaton;
6908 curr_automaton_num++;
6909 prev_automaton = curr_automaton;
6912 if (curr_automaton_num == 0)
6914 curr_automaton = create_node (sizeof (struct automaton));
6915 curr_automaton->ainsn_list = create_ainsns ();
6916 curr_automaton->corresponding_automaton_decl = NULL;
6917 curr_automaton->next_automaton = NULL;
6918 description->first_automaton = curr_automaton;
6920 units_to_automata_distr ();
6922 NDFA_time = create_ticker ();
6923 ticker_off (&NDFA_time);
6924 NDFA_to_DFA_time = create_ticker ();
6925 ticker_off (&NDFA_to_DFA_time);
6926 minimize_time = create_ticker ();
6927 ticker_off (&minimize_time);
6928 equiv_time = create_ticker ();
6929 ticker_off (&equiv_time);
6930 for (curr_automaton = description->first_automaton;
6931 curr_automaton != NULL;
6932 curr_automaton = curr_automaton->next_automaton)
6934 if (progress_flag)
6936 if (curr_automaton->corresponding_automaton_decl == NULL)
6937 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6938 else
6939 fprintf (stderr, "Prepare automaton `%s' creation...",
6940 curr_automaton->corresponding_automaton_decl->name);
6942 create_alt_states (curr_automaton);
6943 form_ainsn_with_same_reservs (curr_automaton);
6944 if (progress_flag)
6945 fprintf (stderr, "done\n");
6946 build_automaton (curr_automaton);
6947 enumerate_states (curr_automaton);
6948 ticker_on (&equiv_time);
6949 set_insn_equiv_classes (curr_automaton);
6950 ticker_off (&equiv_time);
6956 /* This page contains code for forming string representation of
6957 regexp. The representation is formed on IR obstack. So you should
6958 not work with IR obstack between regexp_representation and
6959 finish_regexp_representation calls. */
6961 /* This recursive function forms string representation of regexp
6962 (without tailing '\0'). */
6963 static void
6964 form_regexp (regexp_t regexp)
6966 int i;
6968 switch (regexp->mode)
6970 case rm_unit: case rm_reserv:
6972 const char *name = (regexp->mode == rm_unit
6973 ? REGEXP_UNIT (regexp)->name
6974 : REGEXP_RESERV (regexp)->name);
6976 obstack_grow (&irp, name, strlen (name));
6977 break;
6980 case rm_sequence:
6981 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6983 if (i != 0)
6984 obstack_1grow (&irp, ',');
6985 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6987 break;
6989 case rm_allof:
6990 obstack_1grow (&irp, '(');
6991 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6993 if (i != 0)
6994 obstack_1grow (&irp, '+');
6995 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6996 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6997 obstack_1grow (&irp, '(');
6998 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6999 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
7000 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
7001 obstack_1grow (&irp, ')');
7003 obstack_1grow (&irp, ')');
7004 break;
7006 case rm_oneof:
7007 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
7009 if (i != 0)
7010 obstack_1grow (&irp, '|');
7011 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7012 obstack_1grow (&irp, '(');
7013 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
7014 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7015 obstack_1grow (&irp, ')');
7017 break;
7019 case rm_repeat:
7021 char digits [30];
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 form_regexp (REGEXP_REPEAT (regexp)->regexp);
7028 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7029 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7030 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7031 obstack_1grow (&irp, ')');
7032 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
7033 obstack_grow (&irp, digits, strlen (digits));
7034 break;
7037 case rm_nothing:
7038 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
7039 break;
7041 default:
7042 gcc_unreachable ();
7046 /* The function returns string representation of REGEXP on IR
7047 obstack. */
7048 static const char *
7049 regexp_representation (regexp_t regexp)
7051 form_regexp (regexp);
7052 obstack_1grow (&irp, '\0');
7053 return obstack_base (&irp);
7056 /* The function frees memory allocated for last formed string
7057 representation of regexp. */
7058 static void
7059 finish_regexp_representation (void)
7061 int length = obstack_object_size (&irp);
7063 obstack_blank_fast (&irp, -length);
7068 /* This page contains code for output PHR (pipeline hazards recognizer). */
7070 /* The function outputs minimal C type which is sufficient for
7071 representation numbers in range min_range_value and
7072 max_range_value. Because host machine and build machine may be
7073 different, we use here minimal values required by ANSI C standard
7074 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7075 approximation. */
7077 static void
7078 output_range_type (FILE *f, long int min_range_value,
7079 long int max_range_value)
7081 if (min_range_value >= 0 && max_range_value <= 255)
7082 fprintf (f, "unsigned char");
7083 else if (min_range_value >= -127 && max_range_value <= 127)
7084 fprintf (f, "signed char");
7085 else if (min_range_value >= 0 && max_range_value <= 65535)
7086 fprintf (f, "unsigned short");
7087 else if (min_range_value >= -32767 && max_range_value <= 32767)
7088 fprintf (f, "short");
7089 else
7090 fprintf (f, "int");
7093 /* The following macro value is used as value of member
7094 `longest_path_length' of state when we are processing path and the
7095 state on the path. */
7097 #define ON_THE_PATH -2
7099 /* The following recursive function searches for the length of the
7100 longest path starting from STATE which does not contain cycles and
7101 `cycle advance' arcs. */
7103 static int
7104 longest_path_length (state_t state)
7106 arc_t arc;
7107 int length, result;
7109 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7111 /* We don't expect the path cycle here. Our graph may contain
7112 only cycles with one state on the path not containing `cycle
7113 advance' arcs -- see comment below. */
7114 gcc_assert (state->longest_path_length != ON_THE_PATH);
7116 /* We already visited the state. */
7117 return state->longest_path_length;
7120 result = 0;
7121 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7122 /* Ignore cycles containing one state and `cycle advance' arcs. */
7123 if (arc->to_state != state
7124 && (arc->insn->insn_reserv_decl
7125 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7127 length = longest_path_length (arc->to_state);
7128 if (length > result)
7129 result = length;
7131 state->longest_path_length = result + 1;
7132 return result;
7135 /* The following variable value is value of the corresponding global
7136 variable in the automaton based pipeline interface. */
7138 static int max_dfa_issue_rate;
7140 /* The following function processes the longest path length staring
7141 from STATE to find MAX_DFA_ISSUE_RATE. */
7143 static void
7144 process_state_longest_path_length (state_t state)
7146 int value;
7148 value = longest_path_length (state);
7149 if (value > max_dfa_issue_rate)
7150 max_dfa_issue_rate = value;
7153 /* The following macro value is name of the corresponding global
7154 variable in the automaton based pipeline interface. */
7156 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7158 /* The following function calculates value of the corresponding
7159 global variable and outputs its declaration. */
7161 static void
7162 output_dfa_max_issue_rate (void)
7164 automaton_t automaton;
7166 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
7167 max_dfa_issue_rate = 0;
7168 for (automaton = description->first_automaton;
7169 automaton != NULL;
7170 automaton = automaton->next_automaton)
7171 pass_states (automaton, process_state_longest_path_length);
7172 fprintf (output_file, "\nint %s = %d;\n",
7173 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7176 /* The function outputs all initialization values of VECT with length
7177 vect_length. */
7178 static void
7179 output_vect (vect_el_t *vect, int vect_length)
7181 int els_on_line;
7183 els_on_line = 1;
7184 if (vect_length == 0)
7185 fprintf (output_file,
7186 "0 /* This is dummy el because the vect is empty */");
7187 else
7191 fprintf (output_file, "%5ld", (long) *vect);
7192 vect_length--;
7193 if (els_on_line == 10)
7195 els_on_line = 0;
7196 fprintf (output_file, ",\n");
7198 else if (vect_length != 0)
7199 fprintf (output_file, ", ");
7200 els_on_line++;
7201 vect++;
7203 while (vect_length != 0);
7207 /* The following is name of the structure which represents DFA(s) for
7208 PHR. */
7209 #define CHIP_NAME "DFA_chip"
7211 /* The following is name of member which represents state of a DFA for
7212 PHR. */
7213 static void
7214 output_chip_member_name (FILE *f, automaton_t automaton)
7216 if (automaton->corresponding_automaton_decl == NULL)
7217 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7218 else
7219 fprintf (f, "%s_automaton_state",
7220 automaton->corresponding_automaton_decl->name);
7223 /* The following is name of temporary variable which stores state of a
7224 DFA for PHR. */
7225 static void
7226 output_temp_chip_member_name (FILE *f, automaton_t automaton)
7228 fprintf (f, "_");
7229 output_chip_member_name (f, automaton);
7232 /* This is name of macro value which is code of pseudo_insn
7233 representing advancing cpu cycle. Its value is used as internal
7234 code unknown insn. */
7235 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7237 /* Output name of translate vector for given automaton. */
7238 static void
7239 output_translate_vect_name (FILE *f, automaton_t automaton)
7241 if (automaton->corresponding_automaton_decl == NULL)
7242 fprintf (f, "translate_%d", automaton->automaton_order_num);
7243 else
7244 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7247 /* Output name for simple transition table representation. */
7248 static void
7249 output_trans_full_vect_name (FILE *f, automaton_t automaton)
7251 if (automaton->corresponding_automaton_decl == NULL)
7252 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7253 else
7254 fprintf (f, "%s_transitions",
7255 automaton->corresponding_automaton_decl->name);
7258 /* Output name of comb vector of the transition table for given
7259 automaton. */
7260 static void
7261 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7263 if (automaton->corresponding_automaton_decl == NULL)
7264 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7265 else
7266 fprintf (f, "%s_transitions",
7267 automaton->corresponding_automaton_decl->name);
7270 /* Output name of check vector of the transition table for given
7271 automaton. */
7272 static void
7273 output_trans_check_vect_name (FILE *f, automaton_t automaton)
7275 if (automaton->corresponding_automaton_decl == NULL)
7276 fprintf (f, "check_%d", automaton->automaton_order_num);
7277 else
7278 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7281 /* Output name of base vector of the transition table for given
7282 automaton. */
7283 static void
7284 output_trans_base_vect_name (FILE *f, automaton_t automaton)
7286 if (automaton->corresponding_automaton_decl == NULL)
7287 fprintf (f, "base_%d", automaton->automaton_order_num);
7288 else
7289 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7292 /* Output name for simple alternatives number representation. */
7293 static void
7294 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7296 if (automaton->corresponding_automaton_decl == NULL)
7297 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7298 else
7299 fprintf (f, "%s_state_alts",
7300 automaton->corresponding_automaton_decl->name);
7303 /* Output name of comb vector of the alternatives number table for given
7304 automaton. */
7305 static void
7306 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7308 if (automaton->corresponding_automaton_decl == NULL)
7309 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7310 else
7311 fprintf (f, "%s_state_alts",
7312 automaton->corresponding_automaton_decl->name);
7315 /* Output name of check vector of the alternatives number table for given
7316 automaton. */
7317 static void
7318 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7320 if (automaton->corresponding_automaton_decl == NULL)
7321 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7322 else
7323 fprintf (f, "%s_check_state_alts",
7324 automaton->corresponding_automaton_decl->name);
7327 /* Output name of base vector of the alternatives number table for given
7328 automaton. */
7329 static void
7330 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7332 if (automaton->corresponding_automaton_decl == NULL)
7333 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7334 else
7335 fprintf (f, "%s_base_state_alts",
7336 automaton->corresponding_automaton_decl->name);
7339 /* Output name of simple min issue delay table representation. */
7340 static void
7341 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7343 if (automaton->corresponding_automaton_decl == NULL)
7344 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7345 else
7346 fprintf (f, "%s_min_issue_delay",
7347 automaton->corresponding_automaton_decl->name);
7350 /* Output name of deadlock vector for given automaton. */
7351 static void
7352 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7354 if (automaton->corresponding_automaton_decl == NULL)
7355 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7356 else
7357 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7360 /* Output name of reserved units table for AUTOMATON into file F. */
7361 static void
7362 output_reserved_units_table_name (FILE *f, automaton_t automaton)
7364 if (automaton->corresponding_automaton_decl == NULL)
7365 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7366 else
7367 fprintf (f, "%s_reserved_units",
7368 automaton->corresponding_automaton_decl->name);
7371 /* Name of the PHR interface macro. */
7372 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7374 /* Name of the PHR interface macro. */
7375 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7377 /* Names of an internal functions: */
7378 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7380 /* This is external type of DFA(s) state. */
7381 #define STATE_TYPE_NAME "state_t"
7383 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7385 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7387 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7389 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7391 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7393 /* Name of cache of insn dfa codes. */
7394 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7396 /* Name of length of cache of insn dfa codes. */
7397 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7399 /* Names of the PHR interface functions: */
7400 #define SIZE_FUNC_NAME "state_size"
7402 #define TRANSITION_FUNC_NAME "state_transition"
7404 #define STATE_ALTS_FUNC_NAME "state_alts"
7406 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7408 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7410 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7412 #define RESET_FUNC_NAME "state_reset"
7414 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7416 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7418 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7420 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7422 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7424 #define DFA_START_FUNC_NAME "dfa_start"
7426 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7428 /* Names of parameters of the PHR interface functions. */
7429 #define STATE_NAME "state"
7431 #define INSN_PARAMETER_NAME "insn"
7433 #define INSN2_PARAMETER_NAME "insn2"
7435 #define CHIP_PARAMETER_NAME "chip"
7437 #define FILE_PARAMETER_NAME "f"
7439 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7441 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7443 /* Names of the variables whose values are internal insn code of rtx
7444 insn. */
7445 #define INTERNAL_INSN_CODE_NAME "insn_code"
7447 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7449 /* Names of temporary variables in some functions. */
7450 #define TEMPORARY_VARIABLE_NAME "temp"
7452 #define I_VARIABLE_NAME "i"
7454 /* Name of result variable in some functions. */
7455 #define RESULT_VARIABLE_NAME "res"
7457 /* Name of function (attribute) to translate insn into internal insn
7458 code. */
7459 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7461 /* Name of function (attribute) to translate insn into internal insn
7462 code with caching. */
7463 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7465 /* Name of function (attribute) to translate insn into internal insn
7466 code. */
7467 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7469 /* Name of function (attribute) to translate insn into internal insn
7470 code. */
7471 #define BYPASS_P_FUNC_NAME "bypass_p"
7473 /* Output C type which is used for representation of codes of states
7474 of AUTOMATON. */
7475 static void
7476 output_state_member_type (FILE *f, automaton_t automaton)
7478 output_range_type (f, 0, automaton->achieved_states_num);
7481 /* Output definition of the structure representing current DFA(s)
7482 state(s). */
7483 static void
7484 output_chip_definitions (void)
7486 automaton_t automaton;
7488 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7489 for (automaton = description->first_automaton;
7490 automaton != NULL;
7491 automaton = automaton->next_automaton)
7493 fprintf (output_file, " ");
7494 output_state_member_type (output_file, automaton);
7495 fprintf (output_file, " ");
7496 output_chip_member_name (output_file, automaton);
7497 fprintf (output_file, ";\n");
7499 fprintf (output_file, "};\n\n");
7500 #if 0
7501 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7502 #endif
7506 /* The function outputs translate vector of internal insn code into
7507 insn equivalence class number. The equivalence class number is
7508 used to access to table and vectors representing DFA(s). */
7509 static void
7510 output_translate_vect (automaton_t automaton)
7512 ainsn_t ainsn;
7513 int insn_value;
7514 vla_hwint_t translate_vect;
7516 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7517 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7518 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7519 /* Undefined value */
7520 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7521 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7522 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7523 = ainsn->insn_equiv_class_num;
7524 fprintf (output_file,
7525 "/* Vector translating external insn codes to internal ones.*/\n");
7526 fprintf (output_file, "static const ");
7527 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7528 fprintf (output_file, " ");
7529 output_translate_vect_name (output_file, automaton);
7530 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7531 output_vect (VLA_HWINT_BEGIN (translate_vect),
7532 VLA_HWINT_LENGTH (translate_vect));
7533 fprintf (output_file, "};\n\n");
7534 VLA_HWINT_DELETE (translate_vect);
7537 /* The value in a table state x ainsn -> something which represents
7538 undefined value. */
7539 static int undefined_vect_el_value;
7541 /* The following function returns nonzero value if the best
7542 representation of the table is comb vector. */
7543 static int
7544 comb_vect_p (state_ainsn_table_t tab)
7546 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7547 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7550 /* The following function creates new table for AUTOMATON. */
7551 static state_ainsn_table_t
7552 create_state_ainsn_table (automaton_t automaton)
7554 state_ainsn_table_t tab;
7555 int full_vect_length;
7556 int i;
7558 tab = create_node (sizeof (struct state_ainsn_table));
7559 tab->automaton = automaton;
7560 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7561 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7562 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7563 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7564 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7565 full_vect_length = (automaton->insn_equiv_classes_num
7566 * automaton->achieved_states_num);
7567 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7568 for (i = 0; i < full_vect_length; i++)
7569 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7570 tab->min_base_vect_el_value = 0;
7571 tab->max_base_vect_el_value = 0;
7572 tab->min_comb_vect_el_value = 0;
7573 tab->max_comb_vect_el_value = 0;
7574 return tab;
7577 /* The following function outputs the best C representation of the
7578 table TAB of given TABLE_NAME. */
7579 static void
7580 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
7581 void (*output_full_vect_name_func) (FILE *, automaton_t),
7582 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7583 void (*output_check_vect_name_func) (FILE *, automaton_t),
7584 void (*output_base_vect_name_func) (FILE *, automaton_t))
7586 if (!comb_vect_p (tab))
7588 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7589 fprintf (output_file, "static const ");
7590 output_range_type (output_file, tab->min_comb_vect_el_value,
7591 tab->max_comb_vect_el_value);
7592 fprintf (output_file, " ");
7593 (*output_full_vect_name_func) (output_file, tab->automaton);
7594 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7595 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7596 VLA_HWINT_LENGTH (tab->full_vect));
7597 fprintf (output_file, "};\n\n");
7599 else
7601 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7602 fprintf (output_file, "static const ");
7603 output_range_type (output_file, tab->min_comb_vect_el_value,
7604 tab->max_comb_vect_el_value);
7605 fprintf (output_file, " ");
7606 (*output_comb_vect_name_func) (output_file, tab->automaton);
7607 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7608 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7609 VLA_HWINT_LENGTH (tab->comb_vect));
7610 fprintf (output_file, "};\n\n");
7611 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7612 fprintf (output_file, "static const ");
7613 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7614 fprintf (output_file, " ");
7615 (*output_check_vect_name_func) (output_file, tab->automaton);
7616 fprintf (output_file, "[] = {\n");
7617 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7618 VLA_HWINT_LENGTH (tab->check_vect));
7619 fprintf (output_file, "};\n\n");
7620 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7621 fprintf (output_file, "static const ");
7622 output_range_type (output_file, tab->min_base_vect_el_value,
7623 tab->max_base_vect_el_value);
7624 fprintf (output_file, " ");
7625 (*output_base_vect_name_func) (output_file, tab->automaton);
7626 fprintf (output_file, "[] = {\n");
7627 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7628 VLA_HWINT_LENGTH (tab->base_vect));
7629 fprintf (output_file, "};\n\n");
7633 /* The following function adds vector with length VECT_LENGTH and
7634 elements pointed by VECT to table TAB as its line with number
7635 VECT_NUM. */
7636 static void
7637 add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
7638 int vect_length)
7640 int real_vect_length;
7641 vect_el_t *comb_vect_start;
7642 vect_el_t *check_vect_start;
7643 int comb_vect_index;
7644 int comb_vect_els_num;
7645 int vect_index;
7646 int first_unempty_vect_index;
7647 int additional_els_num;
7648 int no_state_value;
7649 vect_el_t vect_el;
7650 int i;
7651 unsigned long vect_mask, comb_vect_mask;
7653 gcc_assert (vect_length);
7654 real_vect_length = tab->automaton->insn_equiv_classes_num;
7655 gcc_assert (vect [vect_length - 1] != undefined_vect_el_value);
7656 /* Form full vector in the table: */
7657 for (i = 0; i < vect_length; i++)
7658 VLA_HWINT (tab->full_vect,
7659 i + tab->automaton->insn_equiv_classes_num * vect_num)
7660 = vect [i];
7661 /* Form comb vector in the table: */
7662 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7663 == VLA_HWINT_LENGTH (tab->check_vect));
7664 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7665 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7666 for (first_unempty_vect_index = 0;
7667 first_unempty_vect_index < vect_length;
7668 first_unempty_vect_index++)
7669 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7670 break;
7672 /* Search for the place in comb vect for the inserted vect. */
7674 /* Slow case. */
7675 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7677 for (comb_vect_index = 0;
7678 comb_vect_index < comb_vect_els_num;
7679 comb_vect_index++)
7681 for (vect_index = first_unempty_vect_index;
7682 vect_index < vect_length
7683 && vect_index + comb_vect_index < comb_vect_els_num;
7684 vect_index++)
7685 if (vect [vect_index] != undefined_vect_el_value
7686 && (comb_vect_start [vect_index + comb_vect_index]
7687 != undefined_vect_el_value))
7688 break;
7689 if (vect_index >= vect_length
7690 || vect_index + comb_vect_index >= comb_vect_els_num)
7691 break;
7693 goto found;
7696 /* Fast case. */
7697 vect_mask = 0;
7698 for (vect_index = first_unempty_vect_index;
7699 vect_index < vect_length;
7700 vect_index++)
7702 vect_mask = vect_mask << 1;
7703 if (vect [vect_index] != undefined_vect_el_value)
7704 vect_mask |= 1;
7707 /* Search for the place in comb vect for the inserted vect. */
7708 comb_vect_index = 0;
7709 if (comb_vect_els_num == 0)
7710 goto found;
7712 comb_vect_mask = 0;
7713 for (vect_index = first_unempty_vect_index;
7714 vect_index < vect_length && vect_index < comb_vect_els_num;
7715 vect_index++)
7717 comb_vect_mask <<= 1;
7718 if (vect_index + comb_vect_index < comb_vect_els_num
7719 && comb_vect_start [vect_index + comb_vect_index]
7720 != undefined_vect_el_value)
7721 comb_vect_mask |= 1;
7723 if ((vect_mask & comb_vect_mask) == 0)
7724 goto found;
7726 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7727 comb_vect_index++, i++)
7729 comb_vect_mask = (comb_vect_mask << 1) | 1;
7730 comb_vect_mask ^= comb_vect_start [i] == undefined_vect_el_value;
7731 if ((vect_mask & comb_vect_mask) == 0)
7732 goto found;
7734 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7736 comb_vect_mask <<= 1;
7737 if ((vect_mask & comb_vect_mask) == 0)
7738 goto found;
7741 found:
7742 /* Slot was found. */
7743 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7744 if (additional_els_num < 0)
7745 additional_els_num = 0;
7746 /* Expand comb and check vectors. */
7747 vect_el = undefined_vect_el_value;
7748 no_state_value = tab->automaton->achieved_states_num;
7749 while (additional_els_num > 0)
7751 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7752 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7753 additional_els_num--;
7755 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7756 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7757 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7758 >= (size_t) (comb_vect_index + real_vect_length));
7759 /* Fill comb and check vectors. */
7760 for (vect_index = 0; vect_index < vect_length; vect_index++)
7761 if (vect [vect_index] != undefined_vect_el_value)
7763 gcc_assert (comb_vect_start [comb_vect_index + vect_index]
7764 == undefined_vect_el_value);
7765 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7766 gcc_assert (vect [vect_index] >= 0);
7767 if (tab->max_comb_vect_el_value < vect [vect_index])
7768 tab->max_comb_vect_el_value = vect [vect_index];
7769 if (tab->min_comb_vect_el_value > vect [vect_index])
7770 tab->min_comb_vect_el_value = vect [vect_index];
7771 check_vect_start [comb_vect_index + vect_index] = vect_num;
7773 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7774 tab->max_comb_vect_el_value = undefined_vect_el_value;
7775 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7776 tab->min_comb_vect_el_value = undefined_vect_el_value;
7777 if (tab->max_base_vect_el_value < comb_vect_index)
7778 tab->max_base_vect_el_value = comb_vect_index;
7779 if (tab->min_base_vect_el_value > comb_vect_index)
7780 tab->min_base_vect_el_value = comb_vect_index;
7781 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7784 /* Return number of out arcs of STATE. */
7785 static int
7786 out_state_arcs_num (state_t state)
7788 int result;
7789 arc_t arc;
7791 result = 0;
7792 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7794 gcc_assert (arc->insn);
7795 if (arc->insn->first_ainsn_with_given_equivalence_num)
7796 result++;
7798 return result;
7801 /* Compare number of possible transitions from the states. */
7802 static int
7803 compare_transition_els_num (const void *state_ptr_1,
7804 const void *state_ptr_2)
7806 int transition_els_num_1;
7807 int transition_els_num_2;
7809 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7810 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7811 if (transition_els_num_1 < transition_els_num_2)
7812 return 1;
7813 else if (transition_els_num_1 == transition_els_num_2)
7814 return 0;
7815 else
7816 return -1;
7819 /* The function adds element EL_VALUE to vector VECT for a table state
7820 x AINSN. */
7821 static void
7822 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7824 int equiv_class_num;
7825 int vect_index;
7827 gcc_assert (ainsn);
7828 equiv_class_num = ainsn->insn_equiv_class_num;
7829 for (vect_index = VLA_HWINT_LENGTH (*vect);
7830 vect_index <= equiv_class_num;
7831 vect_index++)
7832 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7833 VLA_HWINT (*vect, equiv_class_num) = el_value;
7836 /* This is for forming vector of states of an automaton. */
7837 static vla_ptr_t output_states_vect;
7839 /* The function is called by function pass_states. The function adds
7840 STATE to `output_states_vect'. */
7841 static void
7842 add_states_vect_el (state_t state)
7844 VLA_PTR_ADD (output_states_vect, state);
7847 /* Form and output vectors (comb, check, base or full vector)
7848 representing transition table of AUTOMATON. */
7849 static void
7850 output_trans_table (automaton_t automaton)
7852 state_t *state_ptr;
7853 arc_t arc;
7854 vla_hwint_t transition_vect;
7856 undefined_vect_el_value = automaton->achieved_states_num;
7857 automaton->trans_table = create_state_ainsn_table (automaton);
7858 /* Create vect of pointers to states ordered by num of transitions
7859 from the state (state with the maximum num is the first). */
7860 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7861 pass_states (automaton, add_states_vect_el);
7862 qsort (VLA_PTR_BEGIN (output_states_vect),
7863 VLA_PTR_LENGTH (output_states_vect),
7864 sizeof (state_t), compare_transition_els_num);
7865 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7866 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7867 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7868 state_ptr++)
7870 VLA_HWINT_NULLIFY (transition_vect);
7871 for (arc = first_out_arc (*state_ptr);
7872 arc != NULL;
7873 arc = next_out_arc (arc))
7875 gcc_assert (arc->insn);
7876 if (arc->insn->first_ainsn_with_given_equivalence_num)
7877 add_vect_el (&transition_vect, arc->insn,
7878 arc->to_state->order_state_num);
7880 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7881 VLA_HWINT_BEGIN (transition_vect),
7882 VLA_HWINT_LENGTH (transition_vect));
7884 output_state_ainsn_table
7885 (automaton->trans_table, (char *) "state transitions",
7886 output_trans_full_vect_name, output_trans_comb_vect_name,
7887 output_trans_check_vect_name, output_trans_base_vect_name);
7888 VLA_PTR_DELETE (output_states_vect);
7889 VLA_HWINT_DELETE (transition_vect);
7892 /* Form and output vectors (comb, check, base or simple vect)
7893 representing alts number table of AUTOMATON. The table is state x
7894 ainsn -> number of possible alternative reservations by the
7895 ainsn. */
7896 static void
7897 output_state_alts_table (automaton_t automaton)
7899 state_t *state_ptr;
7900 arc_t arc;
7901 vla_hwint_t state_alts_vect;
7903 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7904 automaton->state_alts_table = create_state_ainsn_table (automaton);
7905 /* Create vect of pointers to states ordered by num of transitions
7906 from the state (state with the maximum num is the first). */
7907 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7908 pass_states (automaton, add_states_vect_el);
7909 qsort (VLA_PTR_BEGIN (output_states_vect),
7910 VLA_PTR_LENGTH (output_states_vect),
7911 sizeof (state_t), compare_transition_els_num);
7912 /* Create base, comb, and check vectors. */
7913 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7914 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7915 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7916 state_ptr++)
7918 VLA_HWINT_NULLIFY (state_alts_vect);
7919 for (arc = first_out_arc (*state_ptr);
7920 arc != NULL;
7921 arc = next_out_arc (arc))
7923 gcc_assert (arc->insn);
7924 if (arc->insn->first_ainsn_with_given_equivalence_num)
7925 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7927 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7928 VLA_HWINT_BEGIN (state_alts_vect),
7929 VLA_HWINT_LENGTH (state_alts_vect));
7931 output_state_ainsn_table
7932 (automaton->state_alts_table, (char *) "state insn alternatives",
7933 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7934 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7935 VLA_PTR_DELETE (output_states_vect);
7936 VLA_HWINT_DELETE (state_alts_vect);
7939 /* The current number of passing states to find minimal issue delay
7940 value for an ainsn and state. */
7941 static int curr_state_pass_num;
7943 /* This recursive function passes states to find minimal issue delay
7944 value for AINSN. The state being visited is STATE. The function
7945 returns minimal issue delay value for AINSN in STATE or -1 if we
7946 enter into a loop. */
7947 static int
7948 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7950 arc_t arc;
7951 int min_insn_issue_delay, insn_issue_delay;
7953 if (state->state_pass_num == curr_state_pass_num
7954 || state->min_insn_issue_delay != -1)
7955 /* We've entered into a loop or already have the correct value for
7956 given state and ainsn. */
7957 return state->min_insn_issue_delay;
7958 state->state_pass_num = curr_state_pass_num;
7959 min_insn_issue_delay = -1;
7960 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7961 if (arc->insn == ainsn)
7963 min_insn_issue_delay = 0;
7964 break;
7966 else
7968 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7969 if (insn_issue_delay != -1)
7971 if (arc->insn->insn_reserv_decl
7972 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7973 insn_issue_delay++;
7974 if (min_insn_issue_delay == -1
7975 || min_insn_issue_delay > insn_issue_delay)
7977 min_insn_issue_delay = insn_issue_delay;
7978 if (insn_issue_delay == 0)
7979 break;
7983 return min_insn_issue_delay;
7986 /* The function searches minimal issue delay value for AINSN in STATE.
7987 The function can return negative value if we can not issue AINSN. We
7988 will report about it later. */
7989 static int
7990 min_issue_delay (state_t state, ainsn_t ainsn)
7992 curr_state_pass_num++;
7993 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7994 return state->min_insn_issue_delay;
7997 /* The function initiates code for finding minimal issue delay values.
7998 It should be called only once. */
7999 static void
8000 initiate_min_issue_delay_pass_states (void)
8002 curr_state_pass_num = 0;
8005 /* Form and output vectors representing minimal issue delay table of
8006 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8007 the ainsn. */
8008 static void
8009 output_min_issue_delay_table (automaton_t automaton)
8011 vla_hwint_t min_issue_delay_vect;
8012 vla_hwint_t compressed_min_issue_delay_vect;
8013 vect_el_t min_delay;
8014 ainsn_t ainsn;
8015 state_t *state_ptr;
8016 int i;
8018 /* Create vect of pointers to states ordered by num of transitions
8019 from the state (state with the maximum num is the first). */
8020 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8021 pass_states (automaton, add_states_vect_el);
8022 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
8023 VLA_HWINT_EXPAND (min_issue_delay_vect,
8024 VLA_HWINT_LENGTH (output_states_vect)
8025 * automaton->insn_equiv_classes_num);
8026 for (i = 0;
8027 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
8028 * automaton->insn_equiv_classes_num);
8029 i++)
8030 VLA_HWINT (min_issue_delay_vect, i) = 0;
8031 automaton->max_min_delay = 0;
8032 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
8033 if (ainsn->first_ainsn_with_given_equivalence_num)
8035 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8036 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8037 state_ptr++)
8038 (*state_ptr)->min_insn_issue_delay = -1;
8039 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8040 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8041 state_ptr++)
8043 min_delay = min_issue_delay (*state_ptr, ainsn);
8044 if (automaton->max_min_delay < min_delay)
8045 automaton->max_min_delay = min_delay;
8046 VLA_HWINT (min_issue_delay_vect,
8047 (*state_ptr)->order_state_num
8048 * automaton->insn_equiv_classes_num
8049 + ainsn->insn_equiv_class_num) = min_delay;
8052 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
8053 fprintf (output_file, "static const ");
8054 output_range_type (output_file, 0, automaton->max_min_delay);
8055 fprintf (output_file, " ");
8056 output_min_issue_delay_vect_name (output_file, automaton);
8057 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
8058 /* Compress the vector. */
8059 if (automaton->max_min_delay < 2)
8060 automaton->min_issue_delay_table_compression_factor = 8;
8061 else if (automaton->max_min_delay < 4)
8062 automaton->min_issue_delay_table_compression_factor = 4;
8063 else if (automaton->max_min_delay < 16)
8064 automaton->min_issue_delay_table_compression_factor = 2;
8065 else
8066 automaton->min_issue_delay_table_compression_factor = 1;
8067 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
8068 "compressed min issue delay vector");
8069 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
8070 (VLA_HWINT_LENGTH (min_issue_delay_vect)
8071 + automaton->min_issue_delay_table_compression_factor
8072 - 1)
8073 / automaton->min_issue_delay_table_compression_factor);
8074 for (i = 0;
8075 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
8076 i++)
8077 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
8078 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
8079 VLA_HWINT (compressed_min_issue_delay_vect,
8080 i / automaton->min_issue_delay_table_compression_factor)
8081 |= (VLA_HWINT (min_issue_delay_vect, i)
8082 << (8 - (i % automaton->min_issue_delay_table_compression_factor
8083 + 1)
8084 * (8 / automaton->min_issue_delay_table_compression_factor)));
8085 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
8086 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
8087 fprintf (output_file, "};\n\n");
8088 VLA_PTR_DELETE (output_states_vect);
8089 VLA_HWINT_DELETE (min_issue_delay_vect);
8090 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
8093 #ifndef NDEBUG
8094 /* Number of states which contains transition only by advancing cpu
8095 cycle. */
8096 static int locked_states_num;
8097 #endif
8099 /* Form and output vector representing the locked states of
8100 AUTOMATON. */
8101 static void
8102 output_dead_lock_vect (automaton_t automaton)
8104 state_t *state_ptr;
8105 arc_t arc;
8106 vla_hwint_t dead_lock_vect;
8108 /* Create vect of pointers to states ordered by num of
8109 transitions from the state (state with the maximum num is the
8110 first). */
8111 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8112 pass_states (automaton, add_states_vect_el);
8113 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
8114 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
8115 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8116 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8117 state_ptr++)
8119 arc = first_out_arc (*state_ptr);
8120 gcc_assert (arc);
8121 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8122 = (next_out_arc (arc) == NULL
8123 && (arc->insn->insn_reserv_decl
8124 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8125 #ifndef NDEBUG
8126 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8127 locked_states_num++;
8128 #endif
8130 fprintf (output_file, "/* Vector for locked state flags. */\n");
8131 fprintf (output_file, "static const ");
8132 output_range_type (output_file, 0, 1);
8133 fprintf (output_file, " ");
8134 output_dead_lock_vect_name (output_file, automaton);
8135 fprintf (output_file, "[] = {\n");
8136 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8137 VLA_HWINT_LENGTH (dead_lock_vect));
8138 fprintf (output_file, "};\n\n");
8139 VLA_HWINT_DELETE (dead_lock_vect);
8140 VLA_PTR_DELETE (output_states_vect);
8143 /* Form and output vector representing reserved units of the states of
8144 AUTOMATON. */
8145 static void
8146 output_reserved_units_table (automaton_t automaton)
8148 state_t *curr_state_ptr;
8149 vla_hwint_t reserved_units_table;
8150 size_t state_byte_size;
8151 int i;
8153 /* Create vect of pointers to states. */
8154 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8155 pass_states (automaton, add_states_vect_el);
8156 /* Create vector. */
8157 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8158 state_byte_size = (description->query_units_num + 7) / 8;
8159 VLA_HWINT_EXPAND (reserved_units_table,
8160 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8161 for (i = 0;
8162 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8163 i++)
8164 VLA_HWINT (reserved_units_table, i) = 0;
8165 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8166 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8167 curr_state_ptr++)
8169 for (i = 0; i < description->units_num; i++)
8170 if (units_array [i]->query_p
8171 && first_cycle_unit_presence (*curr_state_ptr, i))
8172 VLA_HWINT (reserved_units_table,
8173 (*curr_state_ptr)->order_state_num * state_byte_size
8174 + units_array [i]->query_num / 8)
8175 += (1 << (units_array [i]->query_num % 8));
8177 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8178 fprintf (output_file, "static const ");
8179 output_range_type (output_file, 0, 255);
8180 fprintf (output_file, " ");
8181 output_reserved_units_table_name (output_file, automaton);
8182 fprintf (output_file, "[] = {\n");
8183 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8184 VLA_HWINT_LENGTH (reserved_units_table));
8185 fprintf (output_file, "};\n\n");
8186 VLA_HWINT_DELETE (reserved_units_table);
8187 VLA_PTR_DELETE (output_states_vect);
8190 /* The function outputs all tables representing DFA(s) used for fast
8191 pipeline hazards recognition. */
8192 static void
8193 output_tables (void)
8195 automaton_t automaton;
8197 #ifndef NDEBUG
8198 locked_states_num = 0;
8199 #endif
8200 initiate_min_issue_delay_pass_states ();
8201 for (automaton = description->first_automaton;
8202 automaton != NULL;
8203 automaton = automaton->next_automaton)
8205 output_translate_vect (automaton);
8206 output_trans_table (automaton);
8207 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8208 output_state_alts_table (automaton);
8209 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8210 AUTOMATON_STATE_ALTS_MACRO_NAME);
8211 output_min_issue_delay_table (automaton);
8212 output_dead_lock_vect (automaton);
8213 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8214 output_reserved_units_table (automaton);
8215 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8216 CPU_UNITS_QUERY_MACRO_NAME);
8218 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8219 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8222 /* The function outputs definition and value of PHR interface variable
8223 `max_insn_queue_index'. Its value is not less than maximal queue
8224 length needed for the insn scheduler. */
8225 static void
8226 output_max_insn_queue_index_def (void)
8228 int i, max, latency;
8229 decl_t decl;
8231 max = description->max_insn_reserv_cycles;
8232 for (i = 0; i < description->decls_num; i++)
8234 decl = description->decls [i];
8235 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8237 latency = DECL_INSN_RESERV (decl)->default_latency;
8238 if (latency > max)
8239 max = latency;
8241 else if (decl->mode == dm_bypass)
8243 latency = DECL_BYPASS (decl)->latency;
8244 if (latency > max)
8245 max = latency;
8248 for (i = 0; (1 << i) <= max; i++)
8250 gcc_assert (i >= 0);
8251 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8255 /* The function outputs switch cases for insn reservations using
8256 function *output_automata_list_code. */
8257 static void
8258 output_insn_code_cases (void (*output_automata_list_code)
8259 (automata_list_el_t))
8261 decl_t decl, decl2;
8262 int i, j;
8264 for (i = 0; i < description->decls_num; i++)
8266 decl = description->decls [i];
8267 if (decl->mode == dm_insn_reserv)
8268 DECL_INSN_RESERV (decl)->processed_p = FALSE;
8270 for (i = 0; i < description->decls_num; i++)
8272 decl = description->decls [i];
8273 if (decl->mode == dm_insn_reserv
8274 && !DECL_INSN_RESERV (decl)->processed_p)
8276 for (j = i; j < description->decls_num; j++)
8278 decl2 = description->decls [j];
8279 if (decl2->mode == dm_insn_reserv
8280 && (DECL_INSN_RESERV (decl2)->important_automata_list
8281 == DECL_INSN_RESERV (decl)->important_automata_list))
8283 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8284 fprintf (output_file, " case %d: /* %s */\n",
8285 DECL_INSN_RESERV (decl2)->insn_num,
8286 DECL_INSN_RESERV (decl2)->name);
8289 (*output_automata_list_code)
8290 (DECL_INSN_RESERV (decl)->important_automata_list);
8296 /* The function outputs a code for evaluation of a minimal delay of
8297 issue of insns which have reservations in given AUTOMATA_LIST. */
8298 static void
8299 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8301 automata_list_el_t el;
8302 automaton_t automaton;
8304 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8306 automaton = el->automaton;
8307 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8308 output_min_issue_delay_vect_name (output_file, automaton);
8309 fprintf (output_file,
8310 (automaton->min_issue_delay_table_compression_factor != 1
8311 ? " [(" : " ["));
8312 output_translate_vect_name (output_file, automaton);
8313 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8314 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8315 output_chip_member_name (output_file, automaton);
8316 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8317 if (automaton->min_issue_delay_table_compression_factor == 1)
8318 fprintf (output_file, "];\n");
8319 else
8321 fprintf (output_file, ") / %d];\n",
8322 automaton->min_issue_delay_table_compression_factor);
8323 fprintf (output_file, " %s = (%s >> (8 - (",
8324 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8325 output_translate_vect_name (output_file, automaton);
8326 fprintf
8327 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8328 INTERNAL_INSN_CODE_NAME,
8329 automaton->min_issue_delay_table_compression_factor,
8330 8 / automaton->min_issue_delay_table_compression_factor,
8331 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8332 - 1);
8334 if (el == automata_list)
8335 fprintf (output_file, " %s = %s;\n",
8336 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8337 else
8339 fprintf (output_file, " if (%s > %s)\n",
8340 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8341 fprintf (output_file, " %s = %s;\n",
8342 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8345 fprintf (output_file, " break;\n\n");
8348 /* Output function `internal_min_issue_delay'. */
8349 static void
8350 output_internal_min_issue_delay_func (void)
8352 fprintf (output_file,
8353 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8354 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8355 CHIP_NAME, CHIP_PARAMETER_NAME);
8356 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8357 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8358 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8359 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8360 fprintf (output_file,
8361 "\n default:\n %s = -1;\n break;\n }\n",
8362 RESULT_VARIABLE_NAME);
8363 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8364 fprintf (output_file, "}\n\n");
8367 /* The function outputs a code changing state after issue of insns
8368 which have reservations in given AUTOMATA_LIST. */
8369 static void
8370 output_automata_list_transition_code (automata_list_el_t automata_list)
8372 automata_list_el_t el, next_el;
8374 fprintf (output_file, " {\n");
8375 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8376 for (el = automata_list;; el = next_el)
8378 next_el = el->next_automata_list_el;
8379 if (next_el == NULL)
8380 break;
8381 fprintf (output_file, " ");
8382 output_state_member_type (output_file, el->automaton);
8383 fprintf (output_file, " ");
8384 output_temp_chip_member_name (output_file, el->automaton);
8385 fprintf (output_file, ";\n");
8387 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8388 if (comb_vect_p (el->automaton->trans_table))
8390 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8391 output_trans_base_vect_name (output_file, el->automaton);
8392 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8393 output_chip_member_name (output_file, el->automaton);
8394 fprintf (output_file, "] + ");
8395 output_translate_vect_name (output_file, el->automaton);
8396 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8397 fprintf (output_file, " if (");
8398 output_trans_check_vect_name (output_file, el->automaton);
8399 fprintf (output_file, " [%s] != %s->",
8400 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8401 output_chip_member_name (output_file, el->automaton);
8402 fprintf (output_file, ")\n");
8403 fprintf (output_file, " return %s (%s, %s);\n",
8404 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8405 CHIP_PARAMETER_NAME);
8406 fprintf (output_file, " else\n");
8407 fprintf (output_file, " ");
8408 if (el->next_automata_list_el != NULL)
8409 output_temp_chip_member_name (output_file, el->automaton);
8410 else
8412 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8413 output_chip_member_name (output_file, el->automaton);
8415 fprintf (output_file, " = ");
8416 output_trans_comb_vect_name (output_file, el->automaton);
8417 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8419 else
8421 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8422 output_trans_full_vect_name (output_file, el->automaton);
8423 fprintf (output_file, " [");
8424 output_translate_vect_name (output_file, el->automaton);
8425 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8426 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8427 output_chip_member_name (output_file, el->automaton);
8428 fprintf (output_file, " * %d];\n",
8429 el->automaton->insn_equiv_classes_num);
8430 fprintf (output_file, " if (%s >= %d)\n",
8431 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8432 fprintf (output_file, " return %s (%s, %s);\n",
8433 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8434 CHIP_PARAMETER_NAME);
8435 fprintf (output_file, " else\n ");
8436 if (el->next_automata_list_el != NULL)
8437 output_temp_chip_member_name (output_file, el->automaton);
8438 else
8440 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8441 output_chip_member_name (output_file, el->automaton);
8443 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8445 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8446 for (el = automata_list;; el = next_el)
8448 next_el = el->next_automata_list_el;
8449 if (next_el == NULL)
8450 break;
8451 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8452 output_chip_member_name (output_file, el->automaton);
8453 fprintf (output_file, " = ");
8454 output_temp_chip_member_name (output_file, el->automaton);
8455 fprintf (output_file, ";\n");
8457 fprintf (output_file, " return -1;\n");
8458 fprintf (output_file, " }\n");
8461 /* Output function `internal_state_transition'. */
8462 static void
8463 output_internal_trans_func (void)
8465 fprintf (output_file,
8466 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8467 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8468 CHIP_NAME, CHIP_PARAMETER_NAME);
8469 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8470 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8471 output_insn_code_cases (output_automata_list_transition_code);
8472 fprintf (output_file, "\n default:\n return -1;\n }\n");
8473 fprintf (output_file, "}\n\n");
8476 /* Output code
8478 if (insn != 0)
8480 insn_code = dfa_insn_code (insn);
8481 if (insn_code > DFA__ADVANCE_CYCLE)
8482 return code;
8484 else
8485 insn_code = DFA__ADVANCE_CYCLE;
8487 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8488 code denotes CODE. */
8489 static void
8490 output_internal_insn_code_evaluation (const char *insn_name,
8491 const char *insn_code_name,
8492 int code)
8494 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8495 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8496 DFA_INSN_CODE_FUNC_NAME, insn_name);
8497 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8498 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8499 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8500 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8504 /* This function outputs `dfa_insn_code' and its helper function
8505 `dfa_insn_code_enlarge'. */
8506 static void
8507 output_dfa_insn_code_func (void)
8509 /* Emacs c-mode gets really confused if there's a { or } in column 0
8510 inside a string, so don't do that. */
8511 fprintf (output_file, "\
8512 static void\n\
8513 dfa_insn_code_enlarge (int uid)\n\
8514 {\n\
8515 int i = %s;\n\
8516 %s = 2 * uid;\n\
8517 %s = xrealloc (%s,\n\
8518 %s * sizeof(int));\n\
8519 for (; i < %s; i++)\n\
8520 %s[i] = -1;\n}\n\n",
8521 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8522 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8523 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8524 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8525 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8526 DFA_INSN_CODES_VARIABLE_NAME);
8527 fprintf (output_file, "\
8528 static inline int\n%s (rtx %s)\n\
8529 {\n\
8530 int uid = INSN_UID (%s);\n\
8531 int %s;\n\n",
8532 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8533 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8535 fprintf (output_file,
8536 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8537 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8538 fprintf (output_file, " %s = %s[uid];\n",
8539 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8540 fprintf (output_file, "\
8541 if (%s < 0)\n\
8542 {\n\
8543 %s = %s (%s);\n\
8544 %s[uid] = %s;\n\
8545 }\n",
8546 INTERNAL_INSN_CODE_NAME,
8547 INTERNAL_INSN_CODE_NAME,
8548 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8549 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8550 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8553 /* The function outputs PHR interface function `state_transition'. */
8554 static void
8555 output_trans_func (void)
8557 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8558 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8559 INSN_PARAMETER_NAME);
8560 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8561 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8562 INTERNAL_INSN_CODE_NAME, -1);
8563 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8564 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8567 /* The function outputs a code for evaluation of alternative states
8568 number for insns which have reservations in given AUTOMATA_LIST. */
8569 static void
8570 output_automata_list_state_alts_code (automata_list_el_t automata_list)
8572 automata_list_el_t el;
8573 automaton_t automaton;
8575 fprintf (output_file, " {\n");
8576 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8577 if (comb_vect_p (el->automaton->state_alts_table))
8579 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8580 break;
8582 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8584 automaton = el->automaton;
8585 if (comb_vect_p (automaton->state_alts_table))
8587 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8588 output_state_alts_base_vect_name (output_file, automaton);
8589 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8590 output_chip_member_name (output_file, automaton);
8591 fprintf (output_file, "] + ");
8592 output_translate_vect_name (output_file, automaton);
8593 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8594 fprintf (output_file, " if (");
8595 output_state_alts_check_vect_name (output_file, automaton);
8596 fprintf (output_file, " [%s] != %s->",
8597 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8598 output_chip_member_name (output_file, automaton);
8599 fprintf (output_file, ")\n");
8600 fprintf (output_file, " return 0;\n");
8601 fprintf (output_file, " else\n");
8602 fprintf (output_file,
8603 (el == automata_list
8604 ? " %s = " : " %s += "),
8605 RESULT_VARIABLE_NAME);
8606 output_state_alts_comb_vect_name (output_file, automaton);
8607 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8609 else
8611 fprintf (output_file,
8612 (el == automata_list
8613 ? "\n %s = " : " %s += "),
8614 RESULT_VARIABLE_NAME);
8615 output_state_alts_full_vect_name (output_file, automaton);
8616 fprintf (output_file, " [");
8617 output_translate_vect_name (output_file, automaton);
8618 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8619 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8620 output_chip_member_name (output_file, automaton);
8621 fprintf (output_file, " * %d];\n",
8622 automaton->insn_equiv_classes_num);
8625 fprintf (output_file, " break;\n }\n\n");
8628 /* Output function `internal_state_alts'. */
8629 static void
8630 output_internal_state_alts_func (void)
8632 fprintf (output_file,
8633 "static int\n%s (int %s, struct %s *%s)\n",
8634 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8635 CHIP_NAME, CHIP_PARAMETER_NAME);
8636 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8637 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8638 output_insn_code_cases (output_automata_list_state_alts_code);
8639 fprintf (output_file,
8640 "\n default:\n %s = 0;\n break;\n }\n",
8641 RESULT_VARIABLE_NAME);
8642 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8643 fprintf (output_file, "}\n\n");
8646 /* The function outputs PHR interface function `state_alts'. */
8647 static void
8648 output_state_alts_func (void)
8650 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8651 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8652 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8653 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8654 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8655 INTERNAL_INSN_CODE_NAME, 0);
8656 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8657 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8660 /* Output function `min_issue_delay'. */
8661 static void
8662 output_min_issue_delay_func (void)
8664 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8665 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8666 INSN_PARAMETER_NAME);
8667 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8668 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8669 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8670 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8671 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8672 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8673 fprintf (output_file, " }\n else\n %s = %s;\n",
8674 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8675 fprintf (output_file, "\n return %s (%s, %s);\n",
8676 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8677 STATE_NAME);
8678 fprintf (output_file, "}\n\n");
8681 /* Output function `internal_dead_lock'. */
8682 static void
8683 output_internal_dead_lock_func (void)
8685 automaton_t automaton;
8687 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8688 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8689 fprintf (output_file, "{\n");
8690 for (automaton = description->first_automaton;
8691 automaton != NULL;
8692 automaton = automaton->next_automaton)
8694 fprintf (output_file, " if (");
8695 output_dead_lock_vect_name (output_file, automaton);
8696 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8697 output_chip_member_name (output_file, automaton);
8698 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8700 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8703 /* The function outputs PHR interface function `state_dead_lock_p'. */
8704 static void
8705 output_dead_lock_func (void)
8707 fprintf (output_file, "int\n%s (%s %s)\n",
8708 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8709 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8710 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8713 /* Output function `internal_reset'. */
8714 static void
8715 output_internal_reset_func (void)
8717 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8718 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8719 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8720 CHIP_PARAMETER_NAME, CHIP_NAME);
8723 /* The function outputs PHR interface function `state_size'. */
8724 static void
8725 output_size_func (void)
8727 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8728 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8731 /* The function outputs PHR interface function `state_reset'. */
8732 static void
8733 output_reset_func (void)
8735 fprintf (output_file, "void\n%s (%s %s)\n",
8736 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8737 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8738 STATE_NAME);
8741 /* Output function `min_insn_conflict_delay'. */
8742 static void
8743 output_min_insn_conflict_delay_func (void)
8745 fprintf (output_file,
8746 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8747 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8748 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8749 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
8750 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8751 INTERNAL_INSN2_CODE_NAME);
8752 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8753 INTERNAL_INSN_CODE_NAME, 0);
8754 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8755 INTERNAL_INSN2_CODE_NAME, 0);
8756 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8757 CHIP_NAME, STATE_NAME, CHIP_NAME);
8758 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8759 fprintf (output_file, " transition = %s (%s, &%s);\n",
8760 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8761 fprintf (output_file, " gcc_assert (transition <= 0);\n");
8762 fprintf (output_file, " return %s (%s, &%s);\n",
8763 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8764 CHIP_NAME);
8765 fprintf (output_file, "}\n\n");
8768 /* Output function `internal_insn_latency'. */
8769 static void
8770 output_internal_insn_latency_func (void)
8772 decl_t decl;
8773 struct bypass_decl *bypass;
8774 int i, j, col;
8775 const char *tabletype = "unsigned char";
8777 /* Find the smallest integer type that can hold all the default
8778 latency values. */
8779 for (i = 0; i < description->decls_num; i++)
8780 if (description->decls[i]->mode == dm_insn_reserv)
8782 decl = description->decls[i];
8783 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8784 && tabletype[0] != 'i') /* Don't shrink it. */
8785 tabletype = "unsigned short";
8786 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8787 tabletype = "int";
8790 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",
8791 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8792 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8793 INSN2_PARAMETER_NAME);
8794 fprintf (output_file, "{\n");
8796 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8798 fputs (" return 0;\n}\n\n", output_file);
8799 return;
8802 fprintf (output_file, " static const %s default_latencies[] =\n {",
8803 tabletype);
8805 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8806 if (description->decls[i]->mode == dm_insn_reserv
8807 && description->decls[i] != advance_cycle_insn_decl)
8809 if ((col = (col+1) % 8) == 0)
8810 fputs ("\n ", output_file);
8811 decl = description->decls[i];
8812 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8813 fprintf (output_file, "% 4d,",
8814 DECL_INSN_RESERV (decl)->default_latency);
8816 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8817 fputs ("\n };\n", output_file);
8819 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8820 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8821 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8823 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8824 for (i = 0; i < description->decls_num; i++)
8825 if (description->decls[i]->mode == dm_insn_reserv
8826 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8828 decl = description->decls [i];
8829 fprintf (output_file,
8830 " case %d:\n switch (%s)\n {\n",
8831 DECL_INSN_RESERV (decl)->insn_num,
8832 INTERNAL_INSN2_CODE_NAME);
8833 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8834 bypass != NULL;
8835 bypass = bypass->next)
8837 gcc_assert (bypass->in_insn_reserv->insn_num
8838 != (DECL_INSN_RESERV
8839 (advance_cycle_insn_decl)->insn_num));
8840 fprintf (output_file, " case %d:\n",
8841 bypass->in_insn_reserv->insn_num);
8842 if (bypass->bypass_guard_name == NULL)
8843 fprintf (output_file, " return %d;\n",
8844 bypass->latency);
8845 else
8847 fprintf (output_file,
8848 " if (%s (%s, %s))\n",
8849 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8850 INSN2_PARAMETER_NAME);
8851 fprintf (output_file,
8852 " return %d;\n break;\n",
8853 bypass->latency);
8856 fputs (" }\n break;\n", output_file);
8859 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8860 INTERNAL_INSN_CODE_NAME);
8863 /* The function outputs PHR interface function `insn_latency'. */
8864 static void
8865 output_insn_latency_func (void)
8867 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8868 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8869 fprintf (output_file, "{\n int %s, %s;\n",
8870 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8871 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8872 INTERNAL_INSN_CODE_NAME, 0);
8873 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8874 INTERNAL_INSN2_CODE_NAME, 0);
8875 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8876 INTERNAL_INSN_LATENCY_FUNC_NAME,
8877 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8878 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8881 /* The function outputs PHR interface function `print_reservation'. */
8882 static void
8883 output_print_reservation_func (void)
8885 decl_t decl;
8886 int i, j;
8888 fprintf (output_file,
8889 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8890 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8891 INSN_PARAMETER_NAME);
8893 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8895 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8896 NOTHING_NAME, FILE_PARAMETER_NAME);
8897 return;
8901 fputs (" static const char *const reservation_names[] =\n {",
8902 output_file);
8904 for (i = 0, j = 0; i < description->decls_num; i++)
8906 decl = description->decls [i];
8907 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8909 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8910 j++;
8912 fprintf (output_file, "\n \"%s\",",
8913 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8914 finish_regexp_representation ();
8917 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8919 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8920 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8922 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8923 INSN_PARAMETER_NAME,
8924 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8925 fprintf (output_file, " else\n\
8926 {\n\
8927 %s = %s (%s);\n\
8928 if (%s > %s)\n\
8929 %s = %s;\n\
8930 }\n",
8931 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8932 INSN_PARAMETER_NAME,
8933 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8934 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8936 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8937 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8940 /* The following function is used to sort unit declaration by their
8941 names. */
8942 static int
8943 units_cmp (const void *unit1, const void *unit2)
8945 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8946 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8948 return strcmp (u1->name, u2->name);
8951 /* The following macro value is name of struct containing unit name
8952 and unit code. */
8953 #define NAME_CODE_STRUCT_NAME "name_code"
8955 /* The following macro value is name of table of struct name_code. */
8956 #define NAME_CODE_TABLE_NAME "name_code_table"
8958 /* The following macro values are member names for struct name_code. */
8959 #define NAME_MEMBER_NAME "name"
8960 #define CODE_MEMBER_NAME "code"
8962 /* The following macro values are local variable names for function
8963 `get_cpu_unit_code'. */
8964 #define CMP_VARIABLE_NAME "cmp"
8965 #define LOW_VARIABLE_NAME "l"
8966 #define MIDDLE_VARIABLE_NAME "m"
8967 #define HIGH_VARIABLE_NAME "h"
8969 /* The following function outputs function to obtain internal cpu unit
8970 code by the cpu unit name. */
8971 static void
8972 output_get_cpu_unit_code_func (void)
8974 int i;
8975 unit_decl_t *units;
8977 fprintf (output_file, "int\n%s (const char *%s)\n",
8978 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
8979 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8980 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8981 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8982 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8983 fprintf (output_file, " static struct %s %s [] =\n {\n",
8984 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8985 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8986 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8987 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8988 for (i = 0; i < description->units_num; i++)
8989 if (units [i]->query_p)
8990 fprintf (output_file, " {\"%s\", %d},\n",
8991 units[i]->name, units[i]->query_num);
8992 fprintf (output_file, " };\n\n");
8993 fprintf (output_file, " /* The following is binary search: */\n");
8994 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8995 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8996 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8997 fprintf (output_file, " while (%s <= %s)\n {\n",
8998 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8999 fprintf (output_file, " %s = (%s + %s) / 2;\n",
9000 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9001 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
9002 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
9003 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
9004 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
9005 fprintf (output_file, " %s = %s - 1;\n",
9006 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9007 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
9008 fprintf (output_file, " %s = %s + 1;\n",
9009 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9010 fprintf (output_file, " else\n");
9011 fprintf (output_file, " return %s [%s].%s;\n }\n",
9012 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
9013 fprintf (output_file, " return -1;\n}\n\n");
9014 free (units);
9017 /* The following function outputs function to check reservation of cpu
9018 unit (its internal code will be passed as the function argument) in
9019 given cpu state. */
9020 static void
9021 output_cpu_unit_reservation_p (void)
9023 automaton_t automaton;
9025 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
9026 CPU_UNIT_RESERVATION_P_FUNC_NAME,
9027 STATE_TYPE_NAME, STATE_NAME,
9028 CPU_CODE_PARAMETER_NAME);
9029 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
9030 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
9031 description->query_units_num);
9032 for (automaton = description->first_automaton;
9033 automaton != NULL;
9034 automaton = automaton->next_automaton)
9036 fprintf (output_file, " if ((");
9037 output_reserved_units_table_name (output_file, automaton);
9038 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
9039 output_chip_member_name (output_file, automaton);
9040 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9041 (description->query_units_num + 7) / 8,
9042 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
9043 fprintf (output_file, " return 1;\n");
9045 fprintf (output_file, " return 0;\n}\n\n");
9048 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9049 static void
9050 output_dfa_clean_insn_cache_func (void)
9052 fprintf (output_file,
9053 "void\n%s (void)\n{\n int %s;\n\n",
9054 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
9055 fprintf (output_file,
9056 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9057 I_VARIABLE_NAME, I_VARIABLE_NAME,
9058 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
9059 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
9062 /* The function outputs PHR interface function `dfa_start'. */
9063 static void
9064 output_dfa_start_func (void)
9066 fprintf (output_file,
9067 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
9068 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9069 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
9070 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9071 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
9074 /* The function outputs PHR interface function `dfa_finish'. */
9075 static void
9076 output_dfa_finish_func (void)
9078 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
9079 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
9084 /* The page contains code for output description file (readable
9085 representation of original description and generated DFA(s). */
9087 /* The function outputs string representation of IR reservation. */
9088 static void
9089 output_regexp (regexp_t regexp)
9091 fprintf (output_description_file, "%s", regexp_representation (regexp));
9092 finish_regexp_representation ();
9095 /* Output names of units in LIST separated by comma. */
9096 static void
9097 output_unit_set_el_list (unit_set_el_t list)
9099 unit_set_el_t el;
9101 for (el = list; el != NULL; el = el->next_unit_set_el)
9103 if (el != list)
9104 fprintf (output_description_file, ", ");
9105 fprintf (output_description_file, "%s", el->unit_decl->name);
9109 /* Output patterns in LIST separated by comma. */
9110 static void
9111 output_pattern_set_el_list (pattern_set_el_t list)
9113 pattern_set_el_t el;
9114 int i;
9116 for (el = list; el != NULL; el = el->next_pattern_set_el)
9118 if (el != list)
9119 fprintf (output_description_file, ", ");
9120 for (i = 0; i < el->units_num; i++)
9121 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9122 el->unit_decls [i]->name);
9126 /* The function outputs string representation of IR define_reservation
9127 and define_insn_reservation. */
9128 static void
9129 output_description (void)
9131 decl_t decl;
9132 int i;
9134 for (i = 0; i < description->decls_num; i++)
9136 decl = description->decls [i];
9137 if (decl->mode == dm_unit)
9139 if (DECL_UNIT (decl)->excl_list != NULL)
9141 fprintf (output_description_file, "unit %s exlusion_set: ",
9142 DECL_UNIT (decl)->name);
9143 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9144 fprintf (output_description_file, "\n");
9146 if (DECL_UNIT (decl)->presence_list != NULL)
9148 fprintf (output_description_file, "unit %s presence_set: ",
9149 DECL_UNIT (decl)->name);
9150 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9151 fprintf (output_description_file, "\n");
9153 if (DECL_UNIT (decl)->final_presence_list != NULL)
9155 fprintf (output_description_file, "unit %s final_presence_set: ",
9156 DECL_UNIT (decl)->name);
9157 output_pattern_set_el_list
9158 (DECL_UNIT (decl)->final_presence_list);
9159 fprintf (output_description_file, "\n");
9161 if (DECL_UNIT (decl)->absence_list != NULL)
9163 fprintf (output_description_file, "unit %s absence_set: ",
9164 DECL_UNIT (decl)->name);
9165 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9166 fprintf (output_description_file, "\n");
9168 if (DECL_UNIT (decl)->final_absence_list != NULL)
9170 fprintf (output_description_file, "unit %s final_absence_set: ",
9171 DECL_UNIT (decl)->name);
9172 output_pattern_set_el_list
9173 (DECL_UNIT (decl)->final_absence_list);
9174 fprintf (output_description_file, "\n");
9178 fprintf (output_description_file, "\n");
9179 for (i = 0; i < description->decls_num; i++)
9181 decl = description->decls [i];
9182 if (decl->mode == dm_reserv)
9184 fprintf (output_description_file, "reservation %s: ",
9185 DECL_RESERV (decl)->name);
9186 output_regexp (DECL_RESERV (decl)->regexp);
9187 fprintf (output_description_file, "\n");
9189 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9191 fprintf (output_description_file, "insn reservation %s ",
9192 DECL_INSN_RESERV (decl)->name);
9193 print_rtl (output_description_file,
9194 DECL_INSN_RESERV (decl)->condexp);
9195 fprintf (output_description_file, ": ");
9196 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9197 fprintf (output_description_file, "\n");
9199 else if (decl->mode == dm_bypass)
9200 fprintf (output_description_file, "bypass %d %s %s\n",
9201 DECL_BYPASS (decl)->latency,
9202 DECL_BYPASS (decl)->out_insn_name,
9203 DECL_BYPASS (decl)->in_insn_name);
9205 fprintf (output_description_file, "\n\f\n");
9208 /* The function outputs name of AUTOMATON. */
9209 static void
9210 output_automaton_name (FILE *f, automaton_t automaton)
9212 if (automaton->corresponding_automaton_decl == NULL)
9213 fprintf (f, "#%d", automaton->automaton_order_num);
9214 else
9215 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9218 /* Maximal length of line for pretty printing into description
9219 file. */
9220 #define MAX_LINE_LENGTH 70
9222 /* The function outputs units name belonging to AUTOMATON. */
9223 static void
9224 output_automaton_units (automaton_t automaton)
9226 decl_t decl;
9227 char *name;
9228 int curr_line_length;
9229 int there_is_an_automaton_unit;
9230 int i;
9232 fprintf (output_description_file, "\n Corresponding units:\n");
9233 fprintf (output_description_file, " ");
9234 curr_line_length = 4;
9235 there_is_an_automaton_unit = 0;
9236 for (i = 0; i < description->decls_num; i++)
9238 decl = description->decls [i];
9239 if (decl->mode == dm_unit
9240 && (DECL_UNIT (decl)->corresponding_automaton_num
9241 == automaton->automaton_order_num))
9243 there_is_an_automaton_unit = 1;
9244 name = DECL_UNIT (decl)->name;
9245 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9247 curr_line_length = strlen (name) + 4;
9248 fprintf (output_description_file, "\n ");
9250 else
9252 curr_line_length += strlen (name) + 1;
9253 fprintf (output_description_file, " ");
9255 fprintf (output_description_file, "%s", name);
9258 if (!there_is_an_automaton_unit)
9259 fprintf (output_description_file, "<None>");
9260 fprintf (output_description_file, "\n\n");
9263 /* The following variable is used for forming array of all possible cpu unit
9264 reservations described by the current DFA state. */
9265 static vla_ptr_t state_reservs;
9267 /* The function forms `state_reservs' for STATE. */
9268 static void
9269 add_state_reservs (state_t state)
9271 alt_state_t curr_alt_state;
9272 reserv_sets_t reservs;
9274 if (state->component_states != NULL)
9275 for (curr_alt_state = state->component_states;
9276 curr_alt_state != NULL;
9277 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9278 add_state_reservs (curr_alt_state->state);
9279 else
9281 reservs = state->reservs;
9282 VLA_PTR_ADD (state_reservs, reservs);
9286 /* The function outputs readable representation of all out arcs of
9287 STATE. */
9288 static void
9289 output_state_arcs (state_t state)
9291 arc_t arc;
9292 ainsn_t ainsn;
9293 char *insn_name;
9294 int curr_line_length;
9296 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9298 ainsn = arc->insn;
9299 gcc_assert (ainsn->first_insn_with_same_reservs);
9300 fprintf (output_description_file, " ");
9301 curr_line_length = 7;
9302 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9305 insn_name = ainsn->insn_reserv_decl->name;
9306 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9308 if (ainsn != arc->insn)
9310 fprintf (output_description_file, ",\n ");
9311 curr_line_length = strlen (insn_name) + 6;
9313 else
9314 curr_line_length += strlen (insn_name);
9316 else
9318 curr_line_length += strlen (insn_name);
9319 if (ainsn != arc->insn)
9321 curr_line_length += 2;
9322 fprintf (output_description_file, ", ");
9325 fprintf (output_description_file, "%s", insn_name);
9326 ainsn = ainsn->next_same_reservs_insn;
9328 while (ainsn != NULL);
9329 fprintf (output_description_file, " %d (%d)\n",
9330 arc->to_state->order_state_num, arc->state_alts);
9332 fprintf (output_description_file, "\n");
9335 /* The following function is used for sorting possible cpu unit
9336 reservation of a DFA state. */
9337 static int
9338 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9340 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9341 *(reserv_sets_t *) reservs_ptr_2);
9344 /* The following function is used for sorting possible cpu unit
9345 reservation of a DFA state. */
9346 static void
9347 remove_state_duplicate_reservs (void)
9349 reserv_sets_t *reservs_ptr;
9350 reserv_sets_t *last_formed_reservs_ptr;
9352 last_formed_reservs_ptr = NULL;
9353 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9354 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9355 reservs_ptr++)
9356 if (last_formed_reservs_ptr == NULL)
9357 last_formed_reservs_ptr = reservs_ptr;
9358 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9360 ++last_formed_reservs_ptr;
9361 *last_formed_reservs_ptr = *reservs_ptr;
9363 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9366 /* The following function output readable representation of DFA(s)
9367 state used for fast recognition of pipeline hazards. State is
9368 described by possible (current and scheduled) cpu unit
9369 reservations. */
9370 static void
9371 output_state (state_t state)
9373 reserv_sets_t *reservs_ptr;
9375 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9376 fprintf (output_description_file, " State #%d", state->order_state_num);
9377 fprintf (output_description_file,
9378 state->new_cycle_p ? " (new cycle)\n" : "\n");
9379 add_state_reservs (state);
9380 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9381 sizeof (reserv_sets_t), state_reservs_cmp);
9382 remove_state_duplicate_reservs ();
9383 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9384 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9385 reservs_ptr++)
9387 fprintf (output_description_file, " ");
9388 output_reserv_sets (output_description_file, *reservs_ptr);
9389 fprintf (output_description_file, "\n");
9391 fprintf (output_description_file, "\n");
9392 output_state_arcs (state);
9393 VLA_PTR_DELETE (state_reservs);
9396 /* The following function output readable representation of
9397 DFAs used for fast recognition of pipeline hazards. */
9398 static void
9399 output_automaton_descriptions (void)
9401 automaton_t automaton;
9403 for (automaton = description->first_automaton;
9404 automaton != NULL;
9405 automaton = automaton->next_automaton)
9407 fprintf (output_description_file, "\nAutomaton ");
9408 output_automaton_name (output_description_file, automaton);
9409 fprintf (output_description_file, "\n");
9410 output_automaton_units (automaton);
9411 pass_states (automaton, output_state);
9417 /* The page contains top level function for generation DFA(s) used for
9418 PHR. */
9420 /* The function outputs statistics about work of different phases of
9421 DFA generator. */
9422 static void
9423 output_statistics (FILE *f)
9425 automaton_t automaton;
9426 int states_num;
9427 #ifndef NDEBUG
9428 int transition_comb_vect_els = 0;
9429 int transition_full_vect_els = 0;
9430 int state_alts_comb_vect_els = 0;
9431 int state_alts_full_vect_els = 0;
9432 int min_issue_delay_vect_els = 0;
9433 #endif
9435 for (automaton = description->first_automaton;
9436 automaton != NULL;
9437 automaton = automaton->next_automaton)
9439 fprintf (f, "\nAutomaton ");
9440 output_automaton_name (f, automaton);
9441 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9442 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9443 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9444 automaton->DFA_states_num, automaton->DFA_arcs_num);
9445 states_num = automaton->DFA_states_num;
9446 if (!no_minimization_flag)
9448 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9449 automaton->minimal_DFA_states_num,
9450 automaton->minimal_DFA_arcs_num);
9451 states_num = automaton->minimal_DFA_states_num;
9453 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9454 description->insns_num, automaton->insn_equiv_classes_num);
9455 #ifndef NDEBUG
9456 fprintf
9457 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9458 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9459 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9460 (comb_vect_p (automaton->trans_table)
9461 ? "use comb vect" : "use simple vect"));
9462 fprintf
9463 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9464 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9465 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9466 (comb_vect_p (automaton->state_alts_table)
9467 ? "use comb vect" : "use simple vect"));
9468 fprintf
9469 (f, "%5ld min delay table els, compression factor %d\n",
9470 (long) states_num * automaton->insn_equiv_classes_num,
9471 automaton->min_issue_delay_table_compression_factor);
9472 transition_comb_vect_els
9473 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9474 transition_full_vect_els
9475 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9476 state_alts_comb_vect_els
9477 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9478 state_alts_full_vect_els
9479 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9480 min_issue_delay_vect_els
9481 += states_num * automaton->insn_equiv_classes_num;
9482 #endif
9484 #ifndef NDEBUG
9485 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9486 allocated_states_num, allocated_arcs_num);
9487 fprintf (f, "%5d all allocated alternative states\n",
9488 allocated_alt_states_num);
9489 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9490 transition_comb_vect_els, transition_full_vect_els);
9491 fprintf
9492 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9493 state_alts_comb_vect_els, state_alts_full_vect_els);
9494 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9495 fprintf (f, "%5d locked states num\n", locked_states_num);
9496 #endif
9499 /* The function output times of work of different phases of DFA
9500 generator. */
9501 static void
9502 output_time_statistics (FILE *f)
9504 fprintf (f, "\n transformation: ");
9505 print_active_time (f, transform_time);
9506 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9507 print_active_time (f, NDFA_time);
9508 if (ndfa_flag)
9510 fprintf (f, ", NDFA -> DFA: ");
9511 print_active_time (f, NDFA_to_DFA_time);
9513 fprintf (f, "\n DFA minimization: ");
9514 print_active_time (f, minimize_time);
9515 fprintf (f, ", making insn equivalence: ");
9516 print_active_time (f, equiv_time);
9517 fprintf (f, "\n all automaton generation: ");
9518 print_active_time (f, automaton_generation_time);
9519 fprintf (f, ", output: ");
9520 print_active_time (f, output_time);
9521 fprintf (f, "\n");
9524 /* The function generates DFA (deterministic finite state automaton)
9525 for fast recognition of pipeline hazards. No errors during
9526 checking must be fixed before this function call. */
9527 static void
9528 generate (void)
9530 automata_num = split_argument;
9531 if (description->units_num < automata_num)
9532 automata_num = description->units_num;
9533 initiate_states ();
9534 initiate_arcs ();
9535 initiate_automata_lists ();
9536 initiate_pass_states ();
9537 initiate_excl_sets ();
9538 initiate_presence_absence_pattern_sets ();
9539 automaton_generation_time = create_ticker ();
9540 create_automata ();
9541 ticker_off (&automaton_generation_time);
9546 /* The following function creates insn attribute whose values are
9547 number alternatives in insn reservations. */
9548 static void
9549 make_insn_alts_attr (void)
9551 int i, insn_num;
9552 decl_t decl;
9553 rtx condexp;
9555 condexp = rtx_alloc (COND);
9556 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9557 XEXP (condexp, 1) = make_numeric_value (0);
9558 for (i = insn_num = 0; i < description->decls_num; i++)
9560 decl = description->decls [i];
9561 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9563 XVECEXP (condexp, 0, 2 * insn_num)
9564 = DECL_INSN_RESERV (decl)->condexp;
9565 XVECEXP (condexp, 0, 2 * insn_num + 1)
9566 = make_numeric_value
9567 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9568 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9569 ->transformed_regexp)->regexps_num);
9570 insn_num++;
9573 gcc_assert (description->insns_num == insn_num + 1);
9574 make_internal_attr (attr_printf (sizeof ("*")
9575 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9576 "*%s", INSN_ALTS_FUNC_NAME),
9577 condexp, ATTR_NONE);
9582 /* The following function creates attribute which is order number of
9583 insn in pipeline hazard description translator. */
9584 static void
9585 make_internal_dfa_insn_code_attr (void)
9587 int i, insn_num;
9588 decl_t decl;
9589 rtx condexp;
9591 condexp = rtx_alloc (COND);
9592 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9593 XEXP (condexp, 1)
9594 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9595 ->insn_num + 1);
9596 for (i = insn_num = 0; i < description->decls_num; i++)
9598 decl = description->decls [i];
9599 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9601 XVECEXP (condexp, 0, 2 * insn_num)
9602 = DECL_INSN_RESERV (decl)->condexp;
9603 XVECEXP (condexp, 0, 2 * insn_num + 1)
9604 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9605 insn_num++;
9608 gcc_assert (description->insns_num == insn_num + 1);
9609 make_internal_attr
9610 (attr_printf (sizeof ("*")
9611 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9612 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9613 condexp, ATTR_STATIC);
9618 /* The following function creates attribute which order number of insn
9619 in pipeline hazard description translator. */
9620 static void
9621 make_default_insn_latency_attr (void)
9623 int i, insn_num;
9624 decl_t decl;
9625 rtx condexp;
9627 condexp = rtx_alloc (COND);
9628 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9629 XEXP (condexp, 1) = make_numeric_value (0);
9630 for (i = insn_num = 0; i < description->decls_num; i++)
9632 decl = description->decls [i];
9633 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9635 XVECEXP (condexp, 0, 2 * insn_num)
9636 = DECL_INSN_RESERV (decl)->condexp;
9637 XVECEXP (condexp, 0, 2 * insn_num + 1)
9638 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9639 insn_num++;
9642 gcc_assert (description->insns_num == insn_num + 1);
9643 make_internal_attr (attr_printf (sizeof ("*")
9644 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9645 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9646 condexp, ATTR_NONE);
9651 /* The following function creates attribute which returns 1 if given
9652 output insn has bypassing and 0 otherwise. */
9653 static void
9654 make_bypass_attr (void)
9656 int i, bypass_insn;
9657 int bypass_insns_num = 0;
9658 decl_t decl;
9659 rtx result_rtx;
9661 for (i = 0; i < description->decls_num; i++)
9663 decl = description->decls [i];
9664 if (decl->mode == dm_insn_reserv
9665 && DECL_INSN_RESERV (decl)->condexp != NULL
9666 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9667 bypass_insns_num++;
9669 if (bypass_insns_num == 0)
9670 result_rtx = make_numeric_value (0);
9671 else
9673 result_rtx = rtx_alloc (COND);
9674 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9675 XEXP (result_rtx, 1) = make_numeric_value (0);
9677 for (i = bypass_insn = 0; i < description->decls_num; i++)
9679 decl = description->decls [i];
9680 if (decl->mode == dm_insn_reserv
9681 && DECL_INSN_RESERV (decl)->condexp != NULL
9682 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9684 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9685 = DECL_INSN_RESERV (decl)->condexp;
9686 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9687 = make_numeric_value (1);
9688 bypass_insn++;
9692 make_internal_attr (attr_printf (sizeof ("*")
9693 + strlen (BYPASS_P_FUNC_NAME) + 1,
9694 "*%s", BYPASS_P_FUNC_NAME),
9695 result_rtx, ATTR_NONE);
9700 /* This page mainly contains top level functions of pipeline hazards
9701 description translator. */
9703 /* The following macro value is suffix of name of description file of
9704 pipeline hazards description translator. */
9705 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9707 /* The function returns suffix of given file name. The returned
9708 string can not be changed. */
9709 static const char *
9710 file_name_suffix (const char *file_name)
9712 const char *last_period;
9714 for (last_period = NULL; *file_name != '\0'; file_name++)
9715 if (*file_name == '.')
9716 last_period = file_name;
9717 return (last_period == NULL ? file_name : last_period);
9720 /* The function returns base name of given file name, i.e. pointer to
9721 first char after last `/' (or `\' for WIN32) in given file name,
9722 given file name itself if the directory name is absent. The
9723 returned string can not be changed. */
9724 static const char *
9725 base_file_name (const char *file_name)
9727 int directory_name_length;
9729 directory_name_length = strlen (file_name);
9730 #ifdef WIN32
9731 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9732 && file_name[directory_name_length] != '\\')
9733 #else
9734 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9735 #endif
9736 directory_name_length--;
9737 return file_name + directory_name_length + 1;
9740 /* The following is top level function to initialize the work of
9741 pipeline hazards description translator. */
9742 void
9743 initiate_automaton_gen (int argc, char **argv)
9745 const char *base_name;
9746 int i;
9748 ndfa_flag = 0;
9749 split_argument = 0; /* default value */
9750 no_minimization_flag = 0;
9751 time_flag = 0;
9752 v_flag = 0;
9753 w_flag = 0;
9754 progress_flag = 0;
9755 for (i = 2; i < argc; i++)
9756 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9757 no_minimization_flag = 1;
9758 else if (strcmp (argv [i], TIME_OPTION) == 0)
9759 time_flag = 1;
9760 else if (strcmp (argv [i], V_OPTION) == 0)
9761 v_flag = 1;
9762 else if (strcmp (argv [i], W_OPTION) == 0)
9763 w_flag = 1;
9764 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9765 ndfa_flag = 1;
9766 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9767 progress_flag = 1;
9768 else if (strcmp (argv [i], "-split") == 0)
9770 if (i + 1 >= argc)
9771 fatal ("-split has no argument.");
9772 fatal ("option `-split' has not been implemented yet\n");
9773 /* split_argument = atoi (argument_vect [i + 1]); */
9775 VLA_PTR_CREATE (decls, 150, "decls");
9776 /* Initialize IR storage. */
9777 obstack_init (&irp);
9778 initiate_automaton_decl_table ();
9779 initiate_insn_decl_table ();
9780 initiate_decl_table ();
9781 output_file = stdout;
9782 output_description_file = NULL;
9783 base_name = base_file_name (argv[1]);
9784 obstack_grow (&irp, base_name,
9785 strlen (base_name) - strlen (file_name_suffix (base_name)));
9786 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9787 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9788 obstack_1grow (&irp, '\0');
9789 output_description_file_name = obstack_base (&irp);
9790 obstack_finish (&irp);
9793 /* The following function checks existence at least one arc marked by
9794 each insn. */
9795 static void
9796 check_automata_insn_issues (void)
9798 automaton_t automaton;
9799 ainsn_t ainsn, reserv_ainsn;
9801 for (automaton = description->first_automaton;
9802 automaton != NULL;
9803 automaton = automaton->next_automaton)
9805 for (ainsn = automaton->ainsn_list;
9806 ainsn != NULL;
9807 ainsn = ainsn->next_ainsn)
9808 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9810 for (reserv_ainsn = ainsn;
9811 reserv_ainsn != NULL;
9812 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9813 if (automaton->corresponding_automaton_decl != NULL)
9815 if (!w_flag)
9816 error ("Automaton `%s': Insn `%s' will never be issued",
9817 automaton->corresponding_automaton_decl->name,
9818 reserv_ainsn->insn_reserv_decl->name);
9819 else
9820 warning
9821 (0, "Automaton `%s': Insn `%s' will never be issued",
9822 automaton->corresponding_automaton_decl->name,
9823 reserv_ainsn->insn_reserv_decl->name);
9825 else
9827 if (!w_flag)
9828 error ("Insn `%s' will never be issued",
9829 reserv_ainsn->insn_reserv_decl->name);
9830 else
9831 warning (0, "Insn `%s' will never be issued",
9832 reserv_ainsn->insn_reserv_decl->name);
9838 /* The following vla is used for storing pointers to all achieved
9839 states. */
9840 static vla_ptr_t automaton_states;
9842 /* This function is called by function pass_states to add an achieved
9843 STATE. */
9844 static void
9845 add_automaton_state (state_t state)
9847 VLA_PTR_ADD (automaton_states, state);
9850 /* The following function forms list of important automata (whose
9851 states may be changed after the insn issue) for each insn. */
9852 static void
9853 form_important_insn_automata_lists (void)
9855 automaton_t automaton;
9856 state_t *state_ptr;
9857 decl_t decl;
9858 ainsn_t ainsn;
9859 arc_t arc;
9860 int i;
9862 VLA_PTR_CREATE (automaton_states, 1500,
9863 "automaton states for forming important insn automata sets");
9864 /* Mark important ainsns. */
9865 for (automaton = description->first_automaton;
9866 automaton != NULL;
9867 automaton = automaton->next_automaton)
9869 VLA_PTR_NULLIFY (automaton_states);
9870 pass_states (automaton, add_automaton_state);
9871 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9872 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9873 state_ptr++)
9875 for (arc = first_out_arc (*state_ptr);
9876 arc != NULL;
9877 arc = next_out_arc (arc))
9878 if (arc->to_state != *state_ptr)
9880 gcc_assert (arc->insn->first_insn_with_same_reservs);
9881 for (ainsn = arc->insn;
9882 ainsn != NULL;
9883 ainsn = ainsn->next_same_reservs_insn)
9884 ainsn->important_p = TRUE;
9888 VLA_PTR_DELETE (automaton_states);
9889 /* Create automata sets for the insns. */
9890 for (i = 0; i < description->decls_num; i++)
9892 decl = description->decls [i];
9893 if (decl->mode == dm_insn_reserv)
9895 automata_list_start ();
9896 for (automaton = description->first_automaton;
9897 automaton != NULL;
9898 automaton = automaton->next_automaton)
9899 for (ainsn = automaton->ainsn_list;
9900 ainsn != NULL;
9901 ainsn = ainsn->next_ainsn)
9902 if (ainsn->important_p
9903 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9905 automata_list_add (automaton);
9906 break;
9908 DECL_INSN_RESERV (decl)->important_automata_list
9909 = automata_list_finish ();
9915 /* The following is top level function to generate automat(a,on) for
9916 fast recognition of pipeline hazards. */
9917 void
9918 expand_automata (void)
9920 int i;
9922 description = create_node (sizeof (struct description)
9923 /* One entry for cycle advancing insn. */
9924 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9925 description->decls_num = VLA_PTR_LENGTH (decls);
9926 description->query_units_num = 0;
9927 for (i = 0; i < description->decls_num; i++)
9929 description->decls [i] = VLA_PTR (decls, i);
9930 if (description->decls [i]->mode == dm_unit
9931 && DECL_UNIT (description->decls [i])->query_p)
9932 DECL_UNIT (description->decls [i])->query_num
9933 = description->query_units_num++;
9935 all_time = create_ticker ();
9936 check_time = create_ticker ();
9937 if (progress_flag)
9938 fprintf (stderr, "Check description...");
9939 check_all_description ();
9940 if (progress_flag)
9941 fprintf (stderr, "done\n");
9942 ticker_off (&check_time);
9943 generation_time = create_ticker ();
9944 if (!have_error)
9946 transform_insn_regexps ();
9947 check_unit_distributions_to_automata ();
9949 if (!have_error)
9951 generate ();
9952 check_automata_insn_issues ();
9954 if (!have_error)
9956 form_important_insn_automata_lists ();
9957 if (progress_flag)
9958 fprintf (stderr, "Generation of attributes...");
9959 make_internal_dfa_insn_code_attr ();
9960 make_insn_alts_attr ();
9961 make_default_insn_latency_attr ();
9962 make_bypass_attr ();
9963 if (progress_flag)
9964 fprintf (stderr, "done\n");
9966 ticker_off (&generation_time);
9967 ticker_off (&all_time);
9968 if (progress_flag)
9969 fprintf (stderr, "All other genattrtab stuff...");
9972 /* The following is top level function to output PHR and to finish
9973 work with pipeline description translator. */
9974 void
9975 write_automata (void)
9977 if (progress_flag)
9978 fprintf (stderr, "done\n");
9979 if (have_error)
9980 fatal ("Errors in DFA description");
9981 ticker_on (&all_time);
9982 output_time = create_ticker ();
9983 if (progress_flag)
9984 fprintf (stderr, "Forming and outputting automata tables...");
9985 output_dfa_max_issue_rate ();
9986 output_tables ();
9987 if (progress_flag)
9989 fprintf (stderr, "done\n");
9990 fprintf (stderr, "Output functions to work with automata...");
9992 output_chip_definitions ();
9993 output_max_insn_queue_index_def ();
9994 output_internal_min_issue_delay_func ();
9995 output_internal_trans_func ();
9996 /* Cache of insn dfa codes: */
9997 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9998 fprintf (output_file, "\nstatic int %s;\n\n",
9999 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
10000 output_dfa_insn_code_func ();
10001 output_trans_func ();
10002 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
10003 output_internal_state_alts_func ();
10004 output_state_alts_func ();
10005 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10006 AUTOMATON_STATE_ALTS_MACRO_NAME);
10007 output_min_issue_delay_func ();
10008 output_internal_dead_lock_func ();
10009 output_dead_lock_func ();
10010 output_size_func ();
10011 output_internal_reset_func ();
10012 output_reset_func ();
10013 output_min_insn_conflict_delay_func ();
10014 output_internal_insn_latency_func ();
10015 output_insn_latency_func ();
10016 output_print_reservation_func ();
10017 /* Output function get_cpu_unit_code. */
10018 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10019 output_get_cpu_unit_code_func ();
10020 output_cpu_unit_reservation_p ();
10021 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10022 CPU_UNITS_QUERY_MACRO_NAME);
10023 output_dfa_clean_insn_cache_func ();
10024 output_dfa_start_func ();
10025 output_dfa_finish_func ();
10026 if (progress_flag)
10027 fprintf (stderr, "done\n");
10028 if (v_flag)
10030 output_description_file = fopen (output_description_file_name, "w");
10031 if (output_description_file == NULL)
10033 perror (output_description_file_name);
10034 exit (FATAL_EXIT_CODE);
10036 if (progress_flag)
10037 fprintf (stderr, "Output automata description...");
10038 output_description ();
10039 output_automaton_descriptions ();
10040 if (progress_flag)
10041 fprintf (stderr, "done\n");
10042 output_statistics (output_description_file);
10044 output_statistics (stderr);
10045 ticker_off (&output_time);
10046 output_time_statistics (stderr);
10047 finish_states ();
10048 finish_arcs ();
10049 finish_automata_lists ();
10050 if (time_flag)
10052 fprintf (stderr, "Summary:\n");
10053 fprintf (stderr, " check time ");
10054 print_active_time (stderr, check_time);
10055 fprintf (stderr, ", generation time ");
10056 print_active_time (stderr, generation_time);
10057 fprintf (stderr, ", all time ");
10058 print_active_time (stderr, all_time);
10059 fprintf (stderr, "\n");
10061 /* Finish all work. */
10062 if (output_description_file != NULL)
10064 fflush (output_description_file);
10065 if (ferror (stdout) != 0)
10066 fatal ("Error in writing DFA description file %s",
10067 output_description_file_name);
10068 fclose (output_description_file);
10070 finish_automaton_decl_table ();
10071 finish_insn_decl_table ();
10072 finish_decl_table ();
10073 obstack_free (&irp, NULL);
10074 if (have_error && output_description_file != NULL)
10075 remove (output_description_file_name);