re PR c++/24780 (ICE set_mem_attributes_minus_bitpos)
[gcc.git] / gcc / genautomata.c
1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4
5 Written by Vladimir Makarov <vmakarov@redhat.com>
6
7 This file is part of GCC.
8
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.
13
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.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA. */
23
24 /* References:
25
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.
29
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.
33
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.
38
39 The current implementation is different from the 2nd article in the
40 following:
41
42 1. New operator `|' (alternative) is permitted in functional unit
43 reservation which can be treated deterministically and
44 non-deterministically.
45
46 2. Possibility of usage of nondeterministic automata too.
47
48 3. Possibility to query functional unit reservations for given
49 automaton state.
50
51 4. Several constructions to describe impossible reservations
52 (`exclusion_set', `presence_set', `final_presence_set',
53 `absence_set', and `final_absence_set').
54
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.
58
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. */
63
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.
68
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.
77
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
80 It can be divided on:
81
82 o checking correctness of the automaton pipeline description
83 (major function is `check_all_description').
84
85 o generating automaton (automata) from the description (major
86 function is `make_automaton').
87
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).
92
93 o optional minimization of the finite state automata by merging
94 equivalent automaton states (major function is `minimize_DFA').
95
96 o forming tables (some as comb vectors) and attributes
97 representing the automata (functions output_..._table).
98
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. */
104
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"
112
113 #include <math.h>
114 #include "hashtab.h"
115 #include "varray.h"
116
117 #ifndef CHAR_BIT
118 #define CHAR_BIT 8
119 #endif
120
121 #include "genattrtab.h"
122
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;
126
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;
130
131 /* Reservations of function units are represented by value of the following
132 type. */
133 typedef set_el_t *reserv_sets_t;
134
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;
143
144 typedef vla_ptr_t vla_hwint_t;
145
146 /* The following structure describes a ticker. */
147 struct ticker
148 {
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;
156 };
157
158 /* The ticker is represented by the following type. */
159 typedef struct ticker ticker_t;
160
161 /* The following type describes elements of output vectors. */
162 typedef HOST_WIDE_INT vect_el_t;
163
164 /* Forward declaration of structures of internal representation of
165 pipeline description based on NDFA. */
166
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;
194
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;
209
210
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'. */
218
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 *);
232
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);
241
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);
249
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);
257
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);
283
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);
289
290 static void add_advance_cycle_insn_decl (void);
291
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);
301
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);
331
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);
340
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);
351
352 static void initiate_excl_sets (void);
353 static reserv_sets_t get_excl_set (reserv_sets_t);
354
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);
361
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);
370
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);
374
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);
382
383 static void form_ainsn_with_same_reservs (automaton_t);
384
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);
411
412 static void set_order_state_num (state_t);
413 static void enumerate_states (automaton_t);
414
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);
420
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);
428
429 static void form_regexp (regexp_t);
430 static const char *regexp_representation (regexp_t);
431 static void finish_regexp_representation (void);
432
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);
507
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);
524
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);
534
535 /* Undefined position. */
536 static pos_t no_pos = 0;
537
538 /* All IR is stored in the following obstack. */
539 static struct obstack irp;
540
541 \f
542
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. */
547
548 /* Start work with vla. */
549 #define VLA_PTR_CREATE(vla, allocated_length, name) \
550 do \
551 { \
552 vla_ptr_t *const _vla_ptr = &(vla); \
553 \
554 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
555 _vla_ptr->length = 0; \
556 } \
557 while (0)
558
559 /* Finish work with the vla. */
560 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
561
562 /* Return start address of the vla. */
563 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
564
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)
571
572 /* Shorten the vla on given number bytes. */
573 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
574
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; \
581 \
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)
588
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); \
593 \
594 VLA_PTR_EXPAND (*_vla_ptr, 1); \
595 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
596 } while (0)
597
598 /* Length of the vla in elements. */
599 #define VLA_PTR_LENGTH(vla) ((vla).length)
600
601 /* N-th element of the vla. */
602 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
603
604
605 /* The following macros are analogous to the previous ones but for
606 VLAs of HOST WIDE INTs. */
607
608 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
609 do { \
610 vla_hwint_t *const _vla_ptr = &(vla); \
611 \
612 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
613 _vla_ptr->length = 0; \
614 } while (0)
615
616 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
617
618 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
619
620 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
621
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; \
626 \
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)
633
634 #define VLA_HWINT_ADD(vla, ptr) \
635 do { \
636 vla_hwint_t *const _vla_ptr = &(vla); \
637 \
638 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
639 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
640 } while (0)
641
642 #define VLA_HWINT_LENGTH(vla) ((vla).length)
643
644 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
645
646 \f
647
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. */
651
652 #define NO_MINIMIZATION_OPTION "-no-minimization"
653
654 #define TIME_OPTION "-time"
655
656 #define V_OPTION "-v"
657
658 #define W_OPTION "-w"
659
660 #define NDFA_OPTION "-ndfa"
661
662 #define PROGRESS_OPTION "-progress"
663
664 /* The following flags are set up by function `initiate_automaton_gen'. */
665
666 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
667 static int ndfa_flag;
668
669 /* Do not make minimization of DFA (`-no-minimization'). */
670 static int no_minimization_flag;
671
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;
678
679 /* Flag of output time statistics (`-time'). */
680 static int time_flag;
681
682 /* Flag of creation of description file which contains description of
683 result automaton and statistics information (`-v'). */
684 static int v_flag;
685
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;
689
690 /* Flag of generating warning instead of error for non-critical errors
691 (`-w'). */
692 static int w_flag;
693
694
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;
698
699 /* Description file of PHR. The value is NULL if the file is not
700 created. */
701 static FILE *output_description_file;
702
703 /* PHR description file name. */
704 static char *output_description_file_name;
705
706 /* Value of the following variable is node representing description
707 being processed. This is start point of IR. */
708 static struct description *description;
709
710 \f
711
712 /* This page contains description of IR structure (nodes). */
713
714 enum decl_mode
715 {
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
724 };
725
726 /* This describes define_cpu_unit and define_query_cpu_unit (see file
727 rtl.def). */
728 struct unit_decl
729 {
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;
736
737 /* The following fields are defined by checker. */
738
739 /* The following field value is nonzero if the unit is used in an
740 regexp. */
741 char unit_is_used;
742
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;
775
776 /* The following fields are defined by automaton generator. */
777
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;
786 };
787
788 /* This describes define_bypass (see file rtl.def). */
789 struct bypass_decl
790 {
791 int latency;
792 char *out_insn_name;
793 char *in_insn_name;
794 char *bypass_guard_name;
795
796 /* The following fields are defined by checker. */
797
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;
803 };
804
805 /* This describes define_automaton (see file rtl.def). */
806 struct automaton_decl
807 {
808 char *name;
809
810 /* The following fields are defined by automaton generator. */
811
812 /* The following field value is nonzero if the automaton is used in
813 an regexp definition. */
814 char automaton_is_used;
815
816 /* The following fields are defined by checker. */
817
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;
823 };
824
825 /* This describes exclusion relations: exclusion_set (see file
826 rtl.def). */
827 struct excl_rel_decl
828 {
829 int all_names_num;
830 int first_list_length;
831 char *names [1];
832 };
833
834 /* This describes unit relations: [final_]presence_set or
835 [final_]absence_set (see file rtl.def). */
836 struct unit_pattern_rel_decl
837 {
838 int final_p;
839 int names_num;
840 int patterns_num;
841 char **names;
842 char ***patterns;
843 };
844
845 /* This describes define_reservation (see file rtl.def). */
846 struct reserv_decl
847 {
848 char *name;
849 regexp_t regexp;
850
851 /* The following fields are defined by checker. */
852
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;
859 };
860
861 /* This describes define_insn_reservation (see file rtl.def). */
862 struct insn_reserv_decl
863 {
864 rtx condexp;
865 int default_latency;
866 regexp_t regexp;
867 char *name;
868
869 /* The following fields are defined by checker. */
870
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;
877
878 /* The following fields are defined by automaton generator. */
879
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;
905 };
906
907 /* This contains a declaration mentioned above. */
908 struct decl
909 {
910 /* What node in the union? */
911 enum decl_mode mode;
912 pos_t pos;
913 union
914 {
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;
924 };
925
926 /* The following structures represent parsed reservation strings. */
927 enum regexp_mode
928 {
929 rm_unit,
930 rm_reserv,
931 rm_nothing,
932 rm_sequence,
933 rm_repeat,
934 rm_allof,
935 rm_oneof
936 };
937
938 /* Cpu unit in reservation. */
939 struct unit_regexp
940 {
941 char *name;
942 unit_decl_t unit_decl;
943 };
944
945 /* Define_reservation in a reservation. */
946 struct reserv_regexp
947 {
948 char *name;
949 struct reserv_decl *reserv_decl;
950 };
951
952 /* Absence of reservation (represented by string `nothing'). */
953 struct nothing_regexp
954 {
955 /* This used to be empty but ISO C doesn't allow that. */
956 char unused;
957 };
958
959 /* Representation of reservations separated by ',' (see file
960 rtl.def). */
961 struct sequence_regexp
962 {
963 int regexps_num;
964 regexp_t regexps [1];
965 };
966
967 /* Representation of construction `repeat' (see file rtl.def). */
968 struct repeat_regexp
969 {
970 int repeat_num;
971 regexp_t regexp;
972 };
973
974 /* Representation of reservations separated by '+' (see file
975 rtl.def). */
976 struct allof_regexp
977 {
978 int regexps_num;
979 regexp_t regexps [1];
980 };
981
982 /* Representation of reservations separated by '|' (see file
983 rtl.def). */
984 struct oneof_regexp
985 {
986 int regexps_num;
987 regexp_t regexps [1];
988 };
989
990 /* Representation of a reservation string. */
991 struct regexp
992 {
993 /* What node in the union? */
994 enum regexp_mode mode;
995 pos_t pos;
996 union
997 {
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;
1006 };
1007
1008 /* Represents description of pipeline hazard description based on
1009 NDFA. */
1010 struct description
1011 {
1012 int decls_num;
1013
1014 /* The following fields are defined by checker. */
1015
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;
1025
1026 /* The following fields are defined by automaton generator. */
1027
1028 /* The following field value is the first automaton. */
1029 automaton_t first_automaton;
1030
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];
1036 };
1037
1038
1039 /* The following nodes are created in automaton checker. */
1040
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
1044 {
1045 unit_decl_t unit_decl;
1046 unit_set_el_t next_unit_set_el;
1047 };
1048
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
1053 {
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;
1059 };
1060
1061
1062 /* The following nodes are created in automaton generator. */
1063
1064
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
1069 {
1070 reserv_sets_t reserv;
1071 pattern_reserv_t next_pattern_reserv;
1072 };
1073
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
1080 {
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;
1134 };
1135
1136 /* The following macro is an initial value of member
1137 `longest_path_length' of a state. */
1138 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1139
1140 /* Automaton arc. */
1141 struct arc
1142 {
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;
1161 };
1162
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
1167 {
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;
1176 };
1177
1178 /* The following node type describes insn of automaton. They are
1179 labels of FA arcs. */
1180 struct ainsn
1181 {
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;
1222 };
1223
1224 /* The following describes an automaton for PHR. */
1225 struct automaton
1226 {
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;
1269 };
1270
1271 /* The following is the element of the list of automata. */
1272 struct automata_list_el
1273 {
1274 /* The automaton itself. */
1275 automaton_t automaton;
1276 /* The next automata set element. */
1277 automata_list_el_t next_automata_list_el;
1278 };
1279
1280 /* The following structure describes a table state X ainsn -> int(>= 0). */
1281 struct state_ainsn_table
1282 {
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;
1295 };
1296
1297 /* Macros to access members of unions. Use only them for access to
1298 union members of declarations and regexps. */
1299
1300 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1301
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; }))
1308
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; }))
1315
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; }))
1322
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; }))
1329
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; }))
1336
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; }))
1343
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; }))
1350
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; }))
1357
1358 static const char *decl_name (enum decl_mode);
1359 static void decl_mode_check_failed (enum decl_mode, const char *,
1360 const char *, int, const char *)
1361 ATTRIBUTE_NORETURN;
1362
1363 /* Return string representation of declaration mode MODE. */
1364 static const char *
1365 decl_name (enum decl_mode mode)
1366 {
1367 static char str [100];
1368
1369 if (mode == dm_unit)
1370 return "dm_unit";
1371 else if (mode == dm_bypass)
1372 return "dm_bypass";
1373 else if (mode == dm_automaton)
1374 return "dm_automaton";
1375 else if (mode == dm_excl)
1376 return "dm_excl";
1377 else if (mode == dm_presence)
1378 return "dm_presence";
1379 else if (mode == dm_absence)
1380 return "dm_absence";
1381 else if (mode == dm_reserv)
1382 return "dm_reserv";
1383 else if (mode == dm_insn_reserv)
1384 return "dm_insn_reserv";
1385 else
1386 sprintf (str, "unknown (%d)", (int) mode);
1387 return str;
1388 }
1389
1390 /* The function prints message about unexpected declaration and finish
1391 the program. */
1392 static void
1393 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1394 const char *file, int line, const char *func)
1395 {
1396 fprintf
1397 (stderr,
1398 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1399 file, line, func, expected_mode_str, decl_name (mode));
1400 exit (1);
1401 }
1402
1403
1404 #define REGEXP_UNIT(r) __extension__ \
1405 (({ struct regexp *const _regexp = (r); \
1406 if (_regexp->mode != rm_unit) \
1407 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1408 __FILE__, __LINE__, __FUNCTION__); \
1409 &(_regexp)->regexp.unit; }))
1410
1411 #define REGEXP_RESERV(r) __extension__ \
1412 (({ struct regexp *const _regexp = (r); \
1413 if (_regexp->mode != rm_reserv) \
1414 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1415 __FILE__, __LINE__, __FUNCTION__); \
1416 &(_regexp)->regexp.reserv; }))
1417
1418 #define REGEXP_SEQUENCE(r) __extension__ \
1419 (({ struct regexp *const _regexp = (r); \
1420 if (_regexp->mode != rm_sequence) \
1421 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1422 __FILE__, __LINE__, __FUNCTION__); \
1423 &(_regexp)->regexp.sequence; }))
1424
1425 #define REGEXP_REPEAT(r) __extension__ \
1426 (({ struct regexp *const _regexp = (r); \
1427 if (_regexp->mode != rm_repeat) \
1428 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1429 __FILE__, __LINE__, __FUNCTION__); \
1430 &(_regexp)->regexp.repeat; }))
1431
1432 #define REGEXP_ALLOF(r) __extension__ \
1433 (({ struct regexp *const _regexp = (r); \
1434 if (_regexp->mode != rm_allof) \
1435 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1436 __FILE__, __LINE__, __FUNCTION__); \
1437 &(_regexp)->regexp.allof; }))
1438
1439 #define REGEXP_ONEOF(r) __extension__ \
1440 (({ struct regexp *const _regexp = (r); \
1441 if (_regexp->mode != rm_oneof) \
1442 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1443 __FILE__, __LINE__, __FUNCTION__); \
1444 &(_regexp)->regexp.oneof; }))
1445
1446 static const char *regexp_name (enum regexp_mode);
1447 static void regexp_mode_check_failed (enum regexp_mode, const char *,
1448 const char *, int,
1449 const char *) ATTRIBUTE_NORETURN;
1450
1451
1452 /* Return string representation of regexp mode MODE. */
1453 static const char *
1454 regexp_name (enum regexp_mode mode)
1455 {
1456 switch (mode)
1457 {
1458 case rm_unit:
1459 return "rm_unit";
1460 case rm_reserv:
1461 return "rm_reserv";
1462 case rm_nothing:
1463 return "rm_nothing";
1464 case rm_sequence:
1465 return "rm_sequence";
1466 case rm_repeat:
1467 return "rm_repeat";
1468 case rm_allof:
1469 return "rm_allof";
1470 case rm_oneof:
1471 return "rm_oneof";
1472 default:
1473 gcc_unreachable ();
1474 }
1475 }
1476
1477 /* The function prints message about unexpected regexp and finish the
1478 program. */
1479 static void
1480 regexp_mode_check_failed (enum regexp_mode mode,
1481 const char *expected_mode_str,
1482 const char *file, int line, const char *func)
1483 {
1484 fprintf
1485 (stderr,
1486 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1487 file, line, func, expected_mode_str, regexp_name (mode));
1488 exit (1);
1489 }
1490
1491 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1492
1493 #define DECL_UNIT(d) (&(d)->decl.unit)
1494 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1495 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1496 #define DECL_EXCL(d) (&(d)->decl.excl)
1497 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1498 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1499 #define DECL_RESERV(d) (&(d)->decl.reserv)
1500 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1501
1502 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1503 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1504 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1505 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1506 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1507 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1508
1509 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1510
1511 /* Create IR structure (node). */
1512 static void *
1513 create_node (size_t size)
1514 {
1515 void *result;
1516
1517 obstack_blank (&irp, size);
1518 result = obstack_base (&irp);
1519 obstack_finish (&irp);
1520 /* Default values of members are NULL and zero. */
1521 memset (result, 0, size);
1522 return result;
1523 }
1524
1525 /* Copy IR structure (node). */
1526 static void *
1527 copy_node (const void *from, size_t size)
1528 {
1529 void *const result = create_node (size);
1530 memcpy (result, from, size);
1531 return result;
1532 }
1533
1534 /* The function checks that NAME does not contain quotes (`"'). */
1535 static char *
1536 check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
1537 {
1538 const char *str;
1539
1540 for (str = name; *str != '\0'; str++)
1541 if (*str == '\"')
1542 error ("Name `%s' contains quotes", name);
1543 return name;
1544 }
1545
1546 /* Pointers to all declarations during IR generation are stored in the
1547 following. */
1548 static vla_ptr_t decls;
1549
1550 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1551 string containing the next separated element, taking parentheses
1552 into account if PAR_FLAG has nonzero value. Advance the pointer to
1553 after the string scanned, or the end-of-string. Return NULL if at
1554 end of string. */
1555 static char *
1556 next_sep_el (char **pstr, int sep, int par_flag)
1557 {
1558 char *out_str;
1559 char *p;
1560 int pars_num;
1561 int n_spaces;
1562
1563 /* Remove leading whitespaces. */
1564 while (ISSPACE ((int) **pstr))
1565 (*pstr)++;
1566
1567 if (**pstr == '\0')
1568 return NULL;
1569
1570 n_spaces = 0;
1571 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1572 {
1573 if (par_flag && *p == '(')
1574 pars_num++;
1575 else if (par_flag && *p == ')')
1576 pars_num--;
1577 else if (pars_num == 0 && *p == sep)
1578 break;
1579 if (pars_num == 0 && ISSPACE ((int) *p))
1580 n_spaces++;
1581 else
1582 {
1583 for (; n_spaces != 0; n_spaces--)
1584 obstack_1grow (&irp, p [-n_spaces]);
1585 obstack_1grow (&irp, *p);
1586 }
1587 }
1588 obstack_1grow (&irp, '\0');
1589 out_str = obstack_base (&irp);
1590 obstack_finish (&irp);
1591
1592 *pstr = p;
1593 if (**pstr == sep)
1594 (*pstr)++;
1595
1596 return out_str;
1597 }
1598
1599 /* Given a string and a separator, return the number of separated
1600 elements in it, taking parentheses into account if PAR_FLAG has
1601 nonzero value. Return 0 for the null string, -1 if parentheses is
1602 not balanced. */
1603 static int
1604 n_sep_els (char *s, int sep, int par_flag)
1605 {
1606 int n;
1607 int pars_num;
1608
1609 if (*s == '\0')
1610 return 0;
1611
1612 for (pars_num = 0, n = 1; *s; s++)
1613 if (par_flag && *s == '(')
1614 pars_num++;
1615 else if (par_flag && *s == ')')
1616 pars_num--;
1617 else if (pars_num == 0 && *s == sep)
1618 n++;
1619
1620 return (pars_num != 0 ? -1 : n);
1621 }
1622
1623 /* Given a string and a separator, return vector of strings which are
1624 elements in the string and number of elements through els_num.
1625 Take parentheses into account if PAREN_P has nonzero value. The
1626 function also inserts the end marker NULL at the end of vector.
1627 Return 0 for the null string, -1 if parentheses are not balanced. */
1628 static char **
1629 get_str_vect (char *str, int *els_num, int sep, int paren_p)
1630 {
1631 int i;
1632 char **vect;
1633 char **pstr;
1634 char *trail;
1635
1636 *els_num = n_sep_els (str, sep, paren_p);
1637 if (*els_num <= 0)
1638 return NULL;
1639 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1640 vect = (char **) obstack_base (&irp);
1641 obstack_finish (&irp);
1642 pstr = &str;
1643 for (i = 0; i < *els_num; i++)
1644 vect [i] = next_sep_el (pstr, sep, paren_p);
1645 trail = next_sep_el (pstr, sep, paren_p);
1646 gcc_assert (!trail);
1647 vect [i] = NULL;
1648 return vect;
1649 }
1650
1651 /* Process a DEFINE_CPU_UNIT.
1652
1653 This gives information about a unit contained in CPU. We fill a
1654 struct unit_decl with information used later by `expand_automata'. */
1655 void
1656 gen_cpu_unit (rtx def)
1657 {
1658 decl_t decl;
1659 char **str_cpu_units;
1660 int vect_length;
1661 int i;
1662
1663 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1664 FALSE);
1665 if (str_cpu_units == NULL)
1666 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1667 for (i = 0; i < vect_length; i++)
1668 {
1669 decl = create_node (sizeof (struct decl));
1670 decl->mode = dm_unit;
1671 decl->pos = 0;
1672 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1673 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1674 DECL_UNIT (decl)->query_p = 0;
1675 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1676 DECL_UNIT (decl)->in_set_p = 0;
1677 VLA_PTR_ADD (decls, decl);
1678 num_dfa_decls++;
1679 }
1680 }
1681
1682 /* Process a DEFINE_QUERY_CPU_UNIT.
1683
1684 This gives information about a unit contained in CPU. We fill a
1685 struct unit_decl with information used later by `expand_automata'. */
1686 void
1687 gen_query_cpu_unit (rtx def)
1688 {
1689 decl_t decl;
1690 char **str_cpu_units;
1691 int vect_length;
1692 int i;
1693
1694 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1695 FALSE);
1696 if (str_cpu_units == NULL)
1697 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1698 for (i = 0; i < vect_length; i++)
1699 {
1700 decl = create_node (sizeof (struct decl));
1701 decl->mode = dm_unit;
1702 decl->pos = 0;
1703 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1704 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1705 DECL_UNIT (decl)->query_p = 1;
1706 VLA_PTR_ADD (decls, decl);
1707 num_dfa_decls++;
1708 }
1709 }
1710
1711 /* Process a DEFINE_BYPASS.
1712
1713 This gives information about a unit contained in the CPU. We fill
1714 in a struct bypass_decl with information used later by
1715 `expand_automata'. */
1716 void
1717 gen_bypass (rtx def)
1718 {
1719 decl_t decl;
1720 char **out_insns;
1721 int out_length;
1722 char **in_insns;
1723 int in_length;
1724 int i, j;
1725
1726 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1727 if (out_insns == NULL)
1728 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1729 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1730 if (in_insns == NULL)
1731 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1732 for (i = 0; i < out_length; i++)
1733 for (j = 0; j < in_length; j++)
1734 {
1735 decl = create_node (sizeof (struct decl));
1736 decl->mode = dm_bypass;
1737 decl->pos = 0;
1738 DECL_BYPASS (decl)->latency = XINT (def, 0);
1739 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1740 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1741 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1742 VLA_PTR_ADD (decls, decl);
1743 num_dfa_decls++;
1744 }
1745 }
1746
1747 /* Process an EXCLUSION_SET.
1748
1749 This gives information about a cpu unit conflicts. We fill a
1750 struct excl_rel_decl (excl) with information used later by
1751 `expand_automata'. */
1752 void
1753 gen_excl_set (rtx def)
1754 {
1755 decl_t decl;
1756 char **first_str_cpu_units;
1757 char **second_str_cpu_units;
1758 int first_vect_length;
1759 int length;
1760 int i;
1761
1762 first_str_cpu_units
1763 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1764 if (first_str_cpu_units == NULL)
1765 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1766 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1767 FALSE);
1768 if (second_str_cpu_units == NULL)
1769 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1770 length += first_vect_length;
1771 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1772 decl->mode = dm_excl;
1773 decl->pos = 0;
1774 DECL_EXCL (decl)->all_names_num = length;
1775 DECL_EXCL (decl)->first_list_length = first_vect_length;
1776 for (i = 0; i < length; i++)
1777 if (i < first_vect_length)
1778 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1779 else
1780 DECL_EXCL (decl)->names [i]
1781 = second_str_cpu_units [i - first_vect_length];
1782 VLA_PTR_ADD (decls, decl);
1783 num_dfa_decls++;
1784 }
1785
1786 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1787 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1788
1789 This gives information about a cpu unit reservation requirements.
1790 We fill a struct unit_pattern_rel_decl with information used later
1791 by `expand_automata'. */
1792 static void
1793 gen_presence_absence_set (rtx def, int presence_p, int final_p)
1794 {
1795 decl_t decl;
1796 char **str_cpu_units;
1797 char ***str_patterns;
1798 int cpu_units_length;
1799 int length;
1800 int patterns_length;
1801 int i;
1802
1803 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1804 FALSE);
1805 if (str_cpu_units == NULL)
1806 fatal ((presence_p
1807 ? (final_p
1808 ? "invalid first string `%s' in final_presence_set"
1809 : "invalid first string `%s' in presence_set")
1810 : (final_p
1811 ? "invalid first string `%s' in final_absence_set"
1812 : "invalid first string `%s' in absence_set")),
1813 XSTR (def, 0));
1814 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1815 &patterns_length, ',', FALSE);
1816 if (str_patterns == NULL)
1817 fatal ((presence_p
1818 ? (final_p
1819 ? "invalid second string `%s' in final_presence_set"
1820 : "invalid second string `%s' in presence_set")
1821 : (final_p
1822 ? "invalid second string `%s' in final_absence_set"
1823 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1824 for (i = 0; i < patterns_length; i++)
1825 {
1826 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1827 FALSE);
1828 gcc_assert (str_patterns [i]);
1829 }
1830 decl = create_node (sizeof (struct decl));
1831 decl->pos = 0;
1832 if (presence_p)
1833 {
1834 decl->mode = dm_presence;
1835 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1836 DECL_PRESENCE (decl)->names = str_cpu_units;
1837 DECL_PRESENCE (decl)->patterns = str_patterns;
1838 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1839 DECL_PRESENCE (decl)->final_p = final_p;
1840 }
1841 else
1842 {
1843 decl->mode = dm_absence;
1844 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1845 DECL_ABSENCE (decl)->names = str_cpu_units;
1846 DECL_ABSENCE (decl)->patterns = str_patterns;
1847 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1848 DECL_ABSENCE (decl)->final_p = final_p;
1849 }
1850 VLA_PTR_ADD (decls, decl);
1851 num_dfa_decls++;
1852 }
1853
1854 /* Process a PRESENCE_SET.
1855
1856 This gives information about a cpu unit reservation requirements.
1857 We fill a struct unit_pattern_rel_decl (presence) with information
1858 used later by `expand_automata'. */
1859 void
1860 gen_presence_set (rtx def)
1861 {
1862 gen_presence_absence_set (def, TRUE, FALSE);
1863 }
1864
1865 /* Process a FINAL_PRESENCE_SET.
1866
1867 This gives information about a cpu unit reservation requirements.
1868 We fill a struct unit_pattern_rel_decl (presence) with information
1869 used later by `expand_automata'. */
1870 void
1871 gen_final_presence_set (rtx def)
1872 {
1873 gen_presence_absence_set (def, TRUE, TRUE);
1874 }
1875
1876 /* Process an ABSENCE_SET.
1877
1878 This gives information about a cpu unit reservation requirements.
1879 We fill a struct unit_pattern_rel_decl (absence) with information
1880 used later by `expand_automata'. */
1881 void
1882 gen_absence_set (rtx def)
1883 {
1884 gen_presence_absence_set (def, FALSE, FALSE);
1885 }
1886
1887 /* Process a FINAL_ABSENCE_SET.
1888
1889 This gives information about a cpu unit reservation requirements.
1890 We fill a struct unit_pattern_rel_decl (absence) with information
1891 used later by `expand_automata'. */
1892 void
1893 gen_final_absence_set (rtx def)
1894 {
1895 gen_presence_absence_set (def, FALSE, TRUE);
1896 }
1897
1898 /* Process a DEFINE_AUTOMATON.
1899
1900 This gives information about a finite state automaton used for
1901 recognizing pipeline hazards. We fill a struct automaton_decl
1902 with information used later by `expand_automata'. */
1903 void
1904 gen_automaton (rtx def)
1905 {
1906 decl_t decl;
1907 char **str_automata;
1908 int vect_length;
1909 int i;
1910
1911 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1912 FALSE);
1913 if (str_automata == NULL)
1914 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1915 for (i = 0; i < vect_length; i++)
1916 {
1917 decl = create_node (sizeof (struct decl));
1918 decl->mode = dm_automaton;
1919 decl->pos = 0;
1920 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1921 VLA_PTR_ADD (decls, decl);
1922 num_dfa_decls++;
1923 }
1924 }
1925
1926 /* Process an AUTOMATA_OPTION.
1927
1928 This gives information how to generate finite state automaton used
1929 for recognizing pipeline hazards. */
1930 void
1931 gen_automata_option (rtx def)
1932 {
1933 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1934 no_minimization_flag = 1;
1935 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1936 time_flag = 1;
1937 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1938 v_flag = 1;
1939 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1940 w_flag = 1;
1941 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1942 ndfa_flag = 1;
1943 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1944 progress_flag = 1;
1945 else
1946 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1947 }
1948
1949 /* Name in reservation to denote absence reservation. */
1950 #define NOTHING_NAME "nothing"
1951
1952 /* The following string contains original reservation string being
1953 parsed. */
1954 static char *reserv_str;
1955
1956 /* Parse an element in STR. */
1957 static regexp_t
1958 gen_regexp_el (char *str)
1959 {
1960 regexp_t regexp;
1961 int len;
1962
1963 if (*str == '(')
1964 {
1965 len = strlen (str);
1966 if (str [len - 1] != ')')
1967 fatal ("garbage after ) in reservation `%s'", reserv_str);
1968 str [len - 1] = '\0';
1969 regexp = gen_regexp_sequence (str + 1);
1970 }
1971 else if (strcmp (str, NOTHING_NAME) == 0)
1972 {
1973 regexp = create_node (sizeof (struct decl));
1974 regexp->mode = rm_nothing;
1975 }
1976 else
1977 {
1978 regexp = create_node (sizeof (struct decl));
1979 regexp->mode = rm_unit;
1980 REGEXP_UNIT (regexp)->name = str;
1981 }
1982 return regexp;
1983 }
1984
1985 /* Parse construction `repeat' in STR. */
1986 static regexp_t
1987 gen_regexp_repeat (char *str)
1988 {
1989 regexp_t regexp;
1990 regexp_t repeat;
1991 char **repeat_vect;
1992 int els_num;
1993 int i;
1994
1995 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1996 if (repeat_vect == NULL)
1997 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1998 if (els_num > 1)
1999 {
2000 regexp = gen_regexp_el (repeat_vect [0]);
2001 for (i = 1; i < els_num; i++)
2002 {
2003 repeat = create_node (sizeof (struct regexp));
2004 repeat->mode = rm_repeat;
2005 REGEXP_REPEAT (repeat)->regexp = regexp;
2006 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
2007 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
2008 fatal ("repetition `%s' <= 1 in reservation `%s'",
2009 str, reserv_str);
2010 regexp = repeat;
2011 }
2012 return regexp;
2013 }
2014 else
2015 return gen_regexp_el (str);
2016 }
2017
2018 /* Parse reservation STR which possibly contains separator '+'. */
2019 static regexp_t
2020 gen_regexp_allof (char *str)
2021 {
2022 regexp_t allof;
2023 char **allof_vect;
2024 int els_num;
2025 int i;
2026
2027 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
2028 if (allof_vect == NULL)
2029 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2030 if (els_num > 1)
2031 {
2032 allof = create_node (sizeof (struct regexp)
2033 + sizeof (regexp_t) * (els_num - 1));
2034 allof->mode = rm_allof;
2035 REGEXP_ALLOF (allof)->regexps_num = els_num;
2036 for (i = 0; i < els_num; i++)
2037 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2038 return allof;
2039 }
2040 else
2041 return gen_regexp_repeat (str);
2042 }
2043
2044 /* Parse reservation STR which possibly contains separator '|'. */
2045 static regexp_t
2046 gen_regexp_oneof (char *str)
2047 {
2048 regexp_t oneof;
2049 char **oneof_vect;
2050 int els_num;
2051 int i;
2052
2053 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
2054 if (oneof_vect == NULL)
2055 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2056 if (els_num > 1)
2057 {
2058 oneof = create_node (sizeof (struct regexp)
2059 + sizeof (regexp_t) * (els_num - 1));
2060 oneof->mode = rm_oneof;
2061 REGEXP_ONEOF (oneof)->regexps_num = els_num;
2062 for (i = 0; i < els_num; i++)
2063 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2064 return oneof;
2065 }
2066 else
2067 return gen_regexp_allof (str);
2068 }
2069
2070 /* Parse reservation STR which possibly contains separator ','. */
2071 static regexp_t
2072 gen_regexp_sequence (char *str)
2073 {
2074 regexp_t sequence;
2075 char **sequence_vect;
2076 int els_num;
2077 int i;
2078
2079 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
2080 if (els_num > 1)
2081 {
2082 sequence = create_node (sizeof (struct regexp)
2083 + sizeof (regexp_t) * (els_num - 1));
2084 sequence->mode = rm_sequence;
2085 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
2086 for (i = 0; i < els_num; i++)
2087 REGEXP_SEQUENCE (sequence)->regexps [i]
2088 = gen_regexp_oneof (sequence_vect [i]);
2089 return sequence;
2090 }
2091 else
2092 return gen_regexp_oneof (str);
2093 }
2094
2095 /* Parse construction reservation STR. */
2096 static regexp_t
2097 gen_regexp (char *str)
2098 {
2099 reserv_str = str;
2100 return gen_regexp_sequence (str);;
2101 }
2102
2103 /* Process a DEFINE_RESERVATION.
2104
2105 This gives information about a reservation of cpu units. We fill
2106 in a struct reserv_decl with information used later by
2107 `expand_automata'. */
2108 void
2109 gen_reserv (rtx def)
2110 {
2111 decl_t decl;
2112
2113 decl = create_node (sizeof (struct decl));
2114 decl->mode = dm_reserv;
2115 decl->pos = 0;
2116 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
2117 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2118 VLA_PTR_ADD (decls, decl);
2119 num_dfa_decls++;
2120 }
2121
2122 /* Process a DEFINE_INSN_RESERVATION.
2123
2124 This gives information about the reservation of cpu units by an
2125 insn. We fill a struct insn_reserv_decl with information used
2126 later by `expand_automata'. */
2127 void
2128 gen_insn_reserv (rtx def)
2129 {
2130 decl_t decl;
2131
2132 decl = create_node (sizeof (struct decl));
2133 decl->mode = dm_insn_reserv;
2134 decl->pos = 0;
2135 DECL_INSN_RESERV (decl)->name
2136 = check_name ((char *) XSTR (def, 0), decl->pos);
2137 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2138 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2139 DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
2140 VLA_PTR_ADD (decls, decl);
2141 num_dfa_decls++;
2142 }
2143
2144 \f
2145
2146 /* The function evaluates hash value (0..UINT_MAX) of string. */
2147 static unsigned
2148 string_hash (const char *string)
2149 {
2150 unsigned result, i;
2151
2152 for (result = i = 0;*string++ != '\0'; i++)
2153 result += ((unsigned char) *string << (i % CHAR_BIT));
2154 return result;
2155 }
2156
2157 \f
2158
2159 /* This page contains abstract data `table of automaton declarations'.
2160 Elements of the table is nodes representing automaton declarations.
2161 Key of the table elements is name of given automaton. Remember
2162 that automaton names have own space. */
2163
2164 /* The function evaluates hash value of an automaton declaration. The
2165 function is used by abstract data `hashtab'. The function returns
2166 hash value (0..UINT_MAX) of given automaton declaration. */
2167 static hashval_t
2168 automaton_decl_hash (const void *automaton_decl)
2169 {
2170 const decl_t decl = (decl_t) automaton_decl;
2171
2172 gcc_assert (decl->mode != dm_automaton
2173 || DECL_AUTOMATON (decl)->name);
2174 return string_hash (DECL_AUTOMATON (decl)->name);
2175 }
2176
2177 /* The function tests automaton declarations on equality of their
2178 keys. The function is used by abstract data `hashtab'. The
2179 function returns 1 if the declarations have the same key, 0
2180 otherwise. */
2181 static int
2182 automaton_decl_eq_p (const void* automaton_decl_1,
2183 const void* automaton_decl_2)
2184 {
2185 const decl_t decl1 = (decl_t) automaton_decl_1;
2186 const decl_t decl2 = (decl_t) automaton_decl_2;
2187
2188 gcc_assert (decl1->mode == dm_automaton
2189 && DECL_AUTOMATON (decl1)->name
2190 && decl2->mode == dm_automaton
2191 && DECL_AUTOMATON (decl2)->name);
2192 return strcmp (DECL_AUTOMATON (decl1)->name,
2193 DECL_AUTOMATON (decl2)->name) == 0;
2194 }
2195
2196 /* The automaton declaration table itself is represented by the
2197 following variable. */
2198 static htab_t automaton_decl_table;
2199
2200 /* The function inserts automaton declaration into the table. The
2201 function does nothing if an automaton declaration with the same key
2202 exists already in the table. The function returns automaton
2203 declaration node in the table with the same key as given automaton
2204 declaration node. */
2205 static decl_t
2206 insert_automaton_decl (decl_t automaton_decl)
2207 {
2208 void **entry_ptr;
2209
2210 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2211 if (*entry_ptr == NULL)
2212 *entry_ptr = (void *) automaton_decl;
2213 return (decl_t) *entry_ptr;
2214 }
2215
2216 /* The following variable value is node representing automaton
2217 declaration. The node used for searching automaton declaration
2218 with given name. */
2219 static struct decl work_automaton_decl;
2220
2221 /* The function searches for automaton declaration in the table with
2222 the same key as node representing name of the automaton
2223 declaration. The function returns node found in the table, NULL if
2224 such node does not exist in the table. */
2225 static decl_t
2226 find_automaton_decl (char *name)
2227 {
2228 void *entry;
2229
2230 work_automaton_decl.mode = dm_automaton;
2231 DECL_AUTOMATON (&work_automaton_decl)->name = name;
2232 entry = htab_find (automaton_decl_table, &work_automaton_decl);
2233 return (decl_t) entry;
2234 }
2235
2236 /* The function creates empty automaton declaration table and node
2237 representing automaton declaration and used for searching automaton
2238 declaration with given name. The function must be called only once
2239 before any work with the automaton declaration table. */
2240 static void
2241 initiate_automaton_decl_table (void)
2242 {
2243 work_automaton_decl.mode = dm_automaton;
2244 automaton_decl_table = htab_create (10, automaton_decl_hash,
2245 automaton_decl_eq_p, (htab_del) 0);
2246 }
2247
2248 /* The function deletes the automaton declaration table. Only call of
2249 function `initiate_automaton_decl_table' is possible immediately
2250 after this function call. */
2251 static void
2252 finish_automaton_decl_table (void)
2253 {
2254 htab_delete (automaton_decl_table);
2255 }
2256
2257 \f
2258
2259 /* This page contains abstract data `table of insn declarations'.
2260 Elements of the table is nodes representing insn declarations. Key
2261 of the table elements is name of given insn (in corresponding
2262 define_insn_reservation). Remember that insn names have own
2263 space. */
2264
2265 /* The function evaluates hash value of an insn declaration. The
2266 function is used by abstract data `hashtab'. The function returns
2267 hash value (0..UINT_MAX) of given insn declaration. */
2268 static hashval_t
2269 insn_decl_hash (const void *insn_decl)
2270 {
2271 const decl_t decl = (decl_t) insn_decl;
2272
2273 gcc_assert (decl->mode == dm_insn_reserv
2274 && DECL_INSN_RESERV (decl)->name);
2275 return string_hash (DECL_INSN_RESERV (decl)->name);
2276 }
2277
2278 /* The function tests insn declarations on equality of their keys.
2279 The function is used by abstract data `hashtab'. The function
2280 returns 1 if declarations have the same key, 0 otherwise. */
2281 static int
2282 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2283 {
2284 const decl_t decl1 = (decl_t) insn_decl_1;
2285 const decl_t decl2 = (decl_t) insn_decl_2;
2286
2287 gcc_assert (decl1->mode == dm_insn_reserv
2288 && DECL_INSN_RESERV (decl1)->name
2289 && decl2->mode == dm_insn_reserv
2290 && DECL_INSN_RESERV (decl2)->name);
2291 return strcmp (DECL_INSN_RESERV (decl1)->name,
2292 DECL_INSN_RESERV (decl2)->name) == 0;
2293 }
2294
2295 /* The insn declaration table itself is represented by the following
2296 variable. The table does not contain insn reservation
2297 declarations. */
2298 static htab_t insn_decl_table;
2299
2300 /* The function inserts insn declaration into the table. The function
2301 does nothing if an insn declaration with the same key exists
2302 already in the table. The function returns insn declaration node
2303 in the table with the same key as given insn declaration node. */
2304 static decl_t
2305 insert_insn_decl (decl_t insn_decl)
2306 {
2307 void **entry_ptr;
2308
2309 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2310 if (*entry_ptr == NULL)
2311 *entry_ptr = (void *) insn_decl;
2312 return (decl_t) *entry_ptr;
2313 }
2314
2315 /* The following variable value is node representing insn reservation
2316 declaration. The node used for searching insn reservation
2317 declaration with given name. */
2318 static struct decl work_insn_decl;
2319
2320 /* The function searches for insn reservation declaration in the table
2321 with the same key as node representing name of the insn reservation
2322 declaration. The function returns node found in the table, NULL if
2323 such node does not exist in the table. */
2324 static decl_t
2325 find_insn_decl (char *name)
2326 {
2327 void *entry;
2328
2329 work_insn_decl.mode = dm_insn_reserv;
2330 DECL_INSN_RESERV (&work_insn_decl)->name = name;
2331 entry = htab_find (insn_decl_table, &work_insn_decl);
2332 return (decl_t) entry;
2333 }
2334
2335 /* The function creates empty insn declaration table and node
2336 representing insn declaration and used for searching insn
2337 declaration with given name. The function must be called only once
2338 before any work with the insn declaration table. */
2339 static void
2340 initiate_insn_decl_table (void)
2341 {
2342 work_insn_decl.mode = dm_insn_reserv;
2343 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2344 (htab_del) 0);
2345 }
2346
2347 /* The function deletes the insn declaration table. Only call of
2348 function `initiate_insn_decl_table' is possible immediately after
2349 this function call. */
2350 static void
2351 finish_insn_decl_table (void)
2352 {
2353 htab_delete (insn_decl_table);
2354 }
2355
2356 \f
2357
2358 /* This page contains abstract data `table of declarations'. Elements
2359 of the table is nodes representing declarations (of units and
2360 reservations). Key of the table elements is names of given
2361 declarations. */
2362
2363 /* The function evaluates hash value of a declaration. The function
2364 is used by abstract data `hashtab'. The function returns hash
2365 value (0..UINT_MAX) of given declaration. */
2366 static hashval_t
2367 decl_hash (const void *decl)
2368 {
2369 const decl_t d = (const decl_t) decl;
2370
2371 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
2372 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
2373 return string_hash (d->mode == dm_unit
2374 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2375 }
2376
2377 /* The function tests declarations on equality of their keys. The
2378 function is used by abstract data 'hashtab'. The function
2379 returns 1 if the declarations have the same key, 0 otherwise. */
2380 static int
2381 decl_eq_p (const void *decl_1, const void *decl_2)
2382 {
2383 const decl_t d1 = (const decl_t) decl_1;
2384 const decl_t d2 = (const decl_t) decl_2;
2385
2386 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
2387 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
2388 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
2389 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
2390 return strcmp ((d1->mode == dm_unit
2391 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2392 (d2->mode == dm_unit
2393 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2394 }
2395
2396 /* The declaration table itself is represented by the following
2397 variable. */
2398 static htab_t decl_table;
2399
2400 /* The function inserts declaration into the table. The function does
2401 nothing if a declaration with the same key exists already in the
2402 table. The function returns declaration node in the table with the
2403 same key as given declaration node. */
2404
2405 static decl_t
2406 insert_decl (decl_t decl)
2407 {
2408 void **entry_ptr;
2409
2410 entry_ptr = htab_find_slot (decl_table, decl, 1);
2411 if (*entry_ptr == NULL)
2412 *entry_ptr = (void *) decl;
2413 return (decl_t) *entry_ptr;
2414 }
2415
2416 /* The following variable value is node representing declaration. The
2417 node used for searching declaration with given name. */
2418 static struct decl work_decl;
2419
2420 /* The function searches for declaration in the table with the same
2421 key as node representing name of the declaration. The function
2422 returns node found in the table, NULL if such node does not exist
2423 in the table. */
2424 static decl_t
2425 find_decl (char *name)
2426 {
2427 void *entry;
2428
2429 work_decl.mode = dm_unit;
2430 DECL_UNIT (&work_decl)->name = name;
2431 entry = htab_find (decl_table, &work_decl);
2432 return (decl_t) entry;
2433 }
2434
2435 /* The function creates empty declaration table and node representing
2436 declaration and used for searching declaration with given name.
2437 The function must be called only once before any work with the
2438 declaration table. */
2439 static void
2440 initiate_decl_table (void)
2441 {
2442 work_decl.mode = dm_unit;
2443 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2444 }
2445
2446 /* The function deletes the declaration table. Only call of function
2447 `initiate_declaration_table' is possible immediately after this
2448 function call. */
2449 static void
2450 finish_decl_table (void)
2451 {
2452 htab_delete (decl_table);
2453 }
2454
2455 \f
2456
2457 /* This page contains checker of pipeline hazard description. */
2458
2459 /* Checking NAMES in an exclusion clause vector and returning formed
2460 unit_set_el_list. */
2461 static unit_set_el_t
2462 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2463 {
2464 unit_set_el_t el_list;
2465 unit_set_el_t last_el;
2466 unit_set_el_t new_el;
2467 decl_t decl_in_table;
2468 int i;
2469
2470 el_list = NULL;
2471 last_el = NULL;
2472 for (i = 0; i < num; i++)
2473 {
2474 decl_in_table = find_decl (names [i]);
2475 if (decl_in_table == NULL)
2476 error ("unit `%s' in exclusion is not declared", names [i]);
2477 else if (decl_in_table->mode != dm_unit)
2478 error ("`%s' in exclusion is not unit", names [i]);
2479 else
2480 {
2481 new_el = create_node (sizeof (struct unit_set_el));
2482 new_el->unit_decl = DECL_UNIT (decl_in_table);
2483 new_el->next_unit_set_el = NULL;
2484 if (last_el == NULL)
2485 el_list = last_el = new_el;
2486 else
2487 {
2488 last_el->next_unit_set_el = new_el;
2489 last_el = last_el->next_unit_set_el;
2490 }
2491 }
2492 }
2493 return el_list;
2494 }
2495
2496 /* The function adds each element from SOURCE_LIST to the exclusion
2497 list of the each element from DEST_LIST. Checking situation "unit
2498 excludes itself". */
2499 static void
2500 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2501 pos_t excl_pos ATTRIBUTE_UNUSED)
2502 {
2503 unit_set_el_t dst;
2504 unit_set_el_t src;
2505 unit_set_el_t curr_el;
2506 unit_set_el_t prev_el;
2507 unit_set_el_t copy;
2508
2509 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2510 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2511 {
2512 if (dst->unit_decl == src->unit_decl)
2513 {
2514 error ("unit `%s' excludes itself", src->unit_decl->name);
2515 continue;
2516 }
2517 if (dst->unit_decl->automaton_name != NULL
2518 && src->unit_decl->automaton_name != NULL
2519 && strcmp (dst->unit_decl->automaton_name,
2520 src->unit_decl->automaton_name) != 0)
2521 {
2522 error ("units `%s' and `%s' in exclusion set belong to different automata",
2523 src->unit_decl->name, dst->unit_decl->name);
2524 continue;
2525 }
2526 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2527 curr_el != NULL;
2528 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2529 if (curr_el->unit_decl == src->unit_decl)
2530 break;
2531 if (curr_el == NULL)
2532 {
2533 /* Element not found - insert. */
2534 copy = copy_node (src, sizeof (*src));
2535 copy->next_unit_set_el = NULL;
2536 if (prev_el == NULL)
2537 dst->unit_decl->excl_list = copy;
2538 else
2539 prev_el->next_unit_set_el = copy;
2540 }
2541 }
2542 }
2543
2544 /* Checking NAMES in presence/absence clause and returning the
2545 formed unit_set_el_list. The function is called only after
2546 processing all exclusion sets. */
2547 static unit_set_el_t
2548 process_presence_absence_names (char **names, int num,
2549 pos_t req_pos ATTRIBUTE_UNUSED,
2550 int presence_p, int final_p)
2551 {
2552 unit_set_el_t el_list;
2553 unit_set_el_t last_el;
2554 unit_set_el_t new_el;
2555 decl_t decl_in_table;
2556 int i;
2557
2558 el_list = NULL;
2559 last_el = NULL;
2560 for (i = 0; i < num; i++)
2561 {
2562 decl_in_table = find_decl (names [i]);
2563 if (decl_in_table == NULL)
2564 error ((presence_p
2565 ? (final_p
2566 ? "unit `%s' in final presence set is not declared"
2567 : "unit `%s' in presence set is not declared")
2568 : (final_p
2569 ? "unit `%s' in final absence set is not declared"
2570 : "unit `%s' in absence set is not declared")), names [i]);
2571 else if (decl_in_table->mode != dm_unit)
2572 error ((presence_p
2573 ? (final_p
2574 ? "`%s' in final presence set is not unit"
2575 : "`%s' in presence set is not unit")
2576 : (final_p
2577 ? "`%s' in final absence set is not unit"
2578 : "`%s' in absence set is not unit")), names [i]);
2579 else
2580 {
2581 new_el = create_node (sizeof (struct unit_set_el));
2582 new_el->unit_decl = DECL_UNIT (decl_in_table);
2583 new_el->next_unit_set_el = NULL;
2584 if (last_el == NULL)
2585 el_list = last_el = new_el;
2586 else
2587 {
2588 last_el->next_unit_set_el = new_el;
2589 last_el = last_el->next_unit_set_el;
2590 }
2591 }
2592 }
2593 return el_list;
2594 }
2595
2596 /* Checking NAMES in patterns of a presence/absence clause and
2597 returning the formed pattern_set_el_list. The function is called
2598 only after processing all exclusion sets. */
2599 static pattern_set_el_t
2600 process_presence_absence_patterns (char ***patterns, int num,
2601 pos_t req_pos ATTRIBUTE_UNUSED,
2602 int presence_p, int final_p)
2603 {
2604 pattern_set_el_t el_list;
2605 pattern_set_el_t last_el;
2606 pattern_set_el_t new_el;
2607 decl_t decl_in_table;
2608 int i, j;
2609
2610 el_list = NULL;
2611 last_el = NULL;
2612 for (i = 0; i < num; i++)
2613 {
2614 for (j = 0; patterns [i] [j] != NULL; j++)
2615 ;
2616 new_el = create_node (sizeof (struct pattern_set_el)
2617 + sizeof (struct unit_decl *) * j);
2618 new_el->unit_decls
2619 = (struct unit_decl **) ((char *) new_el
2620 + sizeof (struct pattern_set_el));
2621 new_el->next_pattern_set_el = NULL;
2622 if (last_el == NULL)
2623 el_list = last_el = new_el;
2624 else
2625 {
2626 last_el->next_pattern_set_el = new_el;
2627 last_el = last_el->next_pattern_set_el;
2628 }
2629 new_el->units_num = 0;
2630 for (j = 0; patterns [i] [j] != NULL; j++)
2631 {
2632 decl_in_table = find_decl (patterns [i] [j]);
2633 if (decl_in_table == NULL)
2634 error ((presence_p
2635 ? (final_p
2636 ? "unit `%s' in final presence set is not declared"
2637 : "unit `%s' in presence set is not declared")
2638 : (final_p
2639 ? "unit `%s' in final absence set is not declared"
2640 : "unit `%s' in absence set is not declared")),
2641 patterns [i] [j]);
2642 else if (decl_in_table->mode != dm_unit)
2643 error ((presence_p
2644 ? (final_p
2645 ? "`%s' in final presence set is not unit"
2646 : "`%s' in presence set is not unit")
2647 : (final_p
2648 ? "`%s' in final absence set is not unit"
2649 : "`%s' in absence set is not unit")),
2650 patterns [i] [j]);
2651 else
2652 {
2653 new_el->unit_decls [new_el->units_num]
2654 = DECL_UNIT (decl_in_table);
2655 new_el->units_num++;
2656 }
2657 }
2658 }
2659 return el_list;
2660 }
2661
2662 /* The function adds each element from PATTERN_LIST to presence (if
2663 PRESENCE_P) or absence list of the each element from DEST_LIST.
2664 Checking situations "unit requires own absence", and "unit excludes
2665 and requires presence of ...", "unit requires absence and presence
2666 of ...", "units in (final) presence set belong to different
2667 automata", and "units in (final) absence set belong to different
2668 automata". Remember that we process absence sets only after all
2669 presence sets. */
2670 static void
2671 add_presence_absence (unit_set_el_t dest_list,
2672 pattern_set_el_t pattern_list,
2673 pos_t req_pos ATTRIBUTE_UNUSED,
2674 int presence_p, int final_p)
2675 {
2676 unit_set_el_t dst;
2677 pattern_set_el_t pat;
2678 struct unit_decl *unit;
2679 unit_set_el_t curr_excl_el;
2680 pattern_set_el_t curr_pat_el;
2681 pattern_set_el_t prev_el;
2682 pattern_set_el_t copy;
2683 int i;
2684 int no_error_flag;
2685
2686 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2687 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2688 {
2689 for (i = 0; i < pat->units_num; i++)
2690 {
2691 unit = pat->unit_decls [i];
2692 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2693 {
2694 error ("unit `%s' requires own absence", unit->name);
2695 continue;
2696 }
2697 if (dst->unit_decl->automaton_name != NULL
2698 && unit->automaton_name != NULL
2699 && strcmp (dst->unit_decl->automaton_name,
2700 unit->automaton_name) != 0)
2701 {
2702 error ((presence_p
2703 ? (final_p
2704 ? "units `%s' and `%s' in final presence set belong to different automata"
2705 : "units `%s' and `%s' in presence set belong to different automata")
2706 : (final_p
2707 ? "units `%s' and `%s' in final absence set belong to different automata"
2708 : "units `%s' and `%s' in absence set belong to different automata")),
2709 unit->name, dst->unit_decl->name);
2710 continue;
2711 }
2712 no_error_flag = 1;
2713 if (presence_p)
2714 for (curr_excl_el = dst->unit_decl->excl_list;
2715 curr_excl_el != NULL;
2716 curr_excl_el = curr_excl_el->next_unit_set_el)
2717 {
2718 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2719 {
2720 if (!w_flag)
2721 {
2722 error ("unit `%s' excludes and requires presence of `%s'",
2723 dst->unit_decl->name, unit->name);
2724 no_error_flag = 0;
2725 }
2726 else
2727 warning
2728 (0, "unit `%s' excludes and requires presence of `%s'",
2729 dst->unit_decl->name, unit->name);
2730 }
2731 }
2732 else if (pat->units_num == 1)
2733 for (curr_pat_el = dst->unit_decl->presence_list;
2734 curr_pat_el != NULL;
2735 curr_pat_el = curr_pat_el->next_pattern_set_el)
2736 if (curr_pat_el->units_num == 1
2737 && unit == curr_pat_el->unit_decls [0])
2738 {
2739 if (!w_flag)
2740 {
2741 error
2742 ("unit `%s' requires absence and presence of `%s'",
2743 dst->unit_decl->name, unit->name);
2744 no_error_flag = 0;
2745 }
2746 else
2747 warning
2748 (0, "unit `%s' requires absence and presence of `%s'",
2749 dst->unit_decl->name, unit->name);
2750 }
2751 if (no_error_flag)
2752 {
2753 for (prev_el = (presence_p
2754 ? (final_p
2755 ? dst->unit_decl->final_presence_list
2756 : dst->unit_decl->final_presence_list)
2757 : (final_p
2758 ? dst->unit_decl->final_absence_list
2759 : dst->unit_decl->absence_list));
2760 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2761 prev_el = prev_el->next_pattern_set_el)
2762 ;
2763 copy = copy_node (pat, sizeof (*pat));
2764 copy->next_pattern_set_el = NULL;
2765 if (prev_el == NULL)
2766 {
2767 if (presence_p)
2768 {
2769 if (final_p)
2770 dst->unit_decl->final_presence_list = copy;
2771 else
2772 dst->unit_decl->presence_list = copy;
2773 }
2774 else if (final_p)
2775 dst->unit_decl->final_absence_list = copy;
2776 else
2777 dst->unit_decl->absence_list = copy;
2778 }
2779 else
2780 prev_el->next_pattern_set_el = copy;
2781 }
2782 }
2783 }
2784 }
2785
2786
2787 /* The function searches for bypass with given IN_INSN_RESERV in given
2788 BYPASS_LIST. */
2789 static struct bypass_decl *
2790 find_bypass (struct bypass_decl *bypass_list,
2791 struct insn_reserv_decl *in_insn_reserv)
2792 {
2793 struct bypass_decl *bypass;
2794
2795 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2796 if (bypass->in_insn_reserv == in_insn_reserv)
2797 break;
2798 return bypass;
2799 }
2800
2801 /* The function processes pipeline description declarations, checks
2802 their correctness, and forms exclusion/presence/absence sets. */
2803 static void
2804 process_decls (void)
2805 {
2806 decl_t decl;
2807 decl_t automaton_decl;
2808 decl_t decl_in_table;
2809 decl_t out_insn_reserv;
2810 decl_t in_insn_reserv;
2811 struct bypass_decl *bypass;
2812 int automaton_presence;
2813 int i;
2814
2815 /* Checking repeated automata declarations. */
2816 automaton_presence = 0;
2817 for (i = 0; i < description->decls_num; i++)
2818 {
2819 decl = description->decls [i];
2820 if (decl->mode == dm_automaton)
2821 {
2822 automaton_presence = 1;
2823 decl_in_table = insert_automaton_decl (decl);
2824 if (decl_in_table != decl)
2825 {
2826 if (!w_flag)
2827 error ("repeated declaration of automaton `%s'",
2828 DECL_AUTOMATON (decl)->name);
2829 else
2830 warning (0, "repeated declaration of automaton `%s'",
2831 DECL_AUTOMATON (decl)->name);
2832 }
2833 }
2834 }
2835 /* Checking undeclared automata, repeated declarations (except for
2836 automata) and correctness of their attributes (insn latency times
2837 etc.). */
2838 for (i = 0; i < description->decls_num; i++)
2839 {
2840 decl = description->decls [i];
2841 if (decl->mode == dm_insn_reserv)
2842 {
2843 DECL_INSN_RESERV (decl)->condexp
2844 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2845 if (DECL_INSN_RESERV (decl)->default_latency < 0)
2846 error ("define_insn_reservation `%s' has negative latency time",
2847 DECL_INSN_RESERV (decl)->name);
2848 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2849 description->insns_num++;
2850 decl_in_table = insert_insn_decl (decl);
2851 if (decl_in_table != decl)
2852 error ("`%s' is already used as insn reservation name",
2853 DECL_INSN_RESERV (decl)->name);
2854 }
2855 else if (decl->mode == dm_bypass)
2856 {
2857 if (DECL_BYPASS (decl)->latency < 0)
2858 error ("define_bypass `%s - %s' has negative latency time",
2859 DECL_BYPASS (decl)->out_insn_name,
2860 DECL_BYPASS (decl)->in_insn_name);
2861 }
2862 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2863 {
2864 if (decl->mode == dm_unit)
2865 {
2866 DECL_UNIT (decl)->automaton_decl = NULL;
2867 if (DECL_UNIT (decl)->automaton_name != NULL)
2868 {
2869 automaton_decl
2870 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2871 if (automaton_decl == NULL)
2872 error ("automaton `%s' is not declared",
2873 DECL_UNIT (decl)->automaton_name);
2874 else
2875 {
2876 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2877 DECL_UNIT (decl)->automaton_decl
2878 = DECL_AUTOMATON (automaton_decl);
2879 }
2880 }
2881 else if (automaton_presence)
2882 error ("define_unit `%s' without automaton when one defined",
2883 DECL_UNIT (decl)->name);
2884 DECL_UNIT (decl)->unit_num = description->units_num;
2885 description->units_num++;
2886 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2887 {
2888 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2889 continue;
2890 }
2891 decl_in_table = find_decl (DECL_UNIT (decl)->name);
2892 }
2893 else
2894 {
2895 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2896 {
2897 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2898 continue;
2899 }
2900 decl_in_table = find_decl (DECL_RESERV (decl)->name);
2901 }
2902 if (decl_in_table == NULL)
2903 decl_in_table = insert_decl (decl);
2904 else
2905 {
2906 if (decl->mode == dm_unit)
2907 error ("repeated declaration of unit `%s'",
2908 DECL_UNIT (decl)->name);
2909 else
2910 error ("repeated declaration of reservation `%s'",
2911 DECL_RESERV (decl)->name);
2912 }
2913 }
2914 }
2915 /* Check bypasses and form list of bypasses for each (output)
2916 insn. */
2917 for (i = 0; i < description->decls_num; i++)
2918 {
2919 decl = description->decls [i];
2920 if (decl->mode == dm_bypass)
2921 {
2922 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2923 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2924 if (out_insn_reserv == NULL)
2925 error ("there is no insn reservation `%s'",
2926 DECL_BYPASS (decl)->out_insn_name);
2927 else if (in_insn_reserv == NULL)
2928 error ("there is no insn reservation `%s'",
2929 DECL_BYPASS (decl)->in_insn_name);
2930 else
2931 {
2932 DECL_BYPASS (decl)->out_insn_reserv
2933 = DECL_INSN_RESERV (out_insn_reserv);
2934 DECL_BYPASS (decl)->in_insn_reserv
2935 = DECL_INSN_RESERV (in_insn_reserv);
2936 bypass
2937 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2938 DECL_BYPASS (decl)->in_insn_reserv);
2939 if (bypass != NULL)
2940 {
2941 if (DECL_BYPASS (decl)->latency == bypass->latency)
2942 {
2943 if (!w_flag)
2944 error
2945 ("the same bypass `%s - %s' is already defined",
2946 DECL_BYPASS (decl)->out_insn_name,
2947 DECL_BYPASS (decl)->in_insn_name);
2948 else
2949 warning
2950 (0, "the same bypass `%s - %s' is already defined",
2951 DECL_BYPASS (decl)->out_insn_name,
2952 DECL_BYPASS (decl)->in_insn_name);
2953 }
2954 else
2955 error ("bypass `%s - %s' is already defined",
2956 DECL_BYPASS (decl)->out_insn_name,
2957 DECL_BYPASS (decl)->in_insn_name);
2958 }
2959 else
2960 {
2961 DECL_BYPASS (decl)->next
2962 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2963 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2964 = DECL_BYPASS (decl);
2965 }
2966 }
2967 }
2968 }
2969
2970 /* Check exclusion set declarations and form exclusion sets. */
2971 for (i = 0; i < description->decls_num; i++)
2972 {
2973 decl = description->decls [i];
2974 if (decl->mode == dm_excl)
2975 {
2976 unit_set_el_t unit_set_el_list;
2977 unit_set_el_t unit_set_el_list_2;
2978
2979 unit_set_el_list
2980 = process_excls (DECL_EXCL (decl)->names,
2981 DECL_EXCL (decl)->first_list_length, decl->pos);
2982 unit_set_el_list_2
2983 = process_excls (&DECL_EXCL (decl)->names
2984 [DECL_EXCL (decl)->first_list_length],
2985 DECL_EXCL (decl)->all_names_num
2986 - DECL_EXCL (decl)->first_list_length,
2987 decl->pos);
2988 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2989 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2990 }
2991 }
2992
2993 /* Check presence set declarations and form presence sets. */
2994 for (i = 0; i < description->decls_num; i++)
2995 {
2996 decl = description->decls [i];
2997 if (decl->mode == dm_presence)
2998 {
2999 unit_set_el_t unit_set_el_list;
3000 pattern_set_el_t pattern_set_el_list;
3001
3002 unit_set_el_list
3003 = process_presence_absence_names
3004 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
3005 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3006 pattern_set_el_list
3007 = process_presence_absence_patterns
3008 (DECL_PRESENCE (decl)->patterns,
3009 DECL_PRESENCE (decl)->patterns_num,
3010 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3011 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3012 decl->pos, TRUE,
3013 DECL_PRESENCE (decl)->final_p);
3014 }
3015 }
3016
3017 /* Check absence set declarations and form absence sets. */
3018 for (i = 0; i < description->decls_num; i++)
3019 {
3020 decl = description->decls [i];
3021 if (decl->mode == dm_absence)
3022 {
3023 unit_set_el_t unit_set_el_list;
3024 pattern_set_el_t pattern_set_el_list;
3025
3026 unit_set_el_list
3027 = process_presence_absence_names
3028 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3029 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3030 pattern_set_el_list
3031 = process_presence_absence_patterns
3032 (DECL_ABSENCE (decl)->patterns,
3033 DECL_ABSENCE (decl)->patterns_num,
3034 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3035 add_presence_absence (unit_set_el_list, pattern_set_el_list,
3036 decl->pos, FALSE,
3037 DECL_ABSENCE (decl)->final_p);
3038 }
3039 }
3040 }
3041
3042 /* The following function checks that declared automaton is used. If
3043 the automaton is not used, the function fixes error/warning. The
3044 following function must be called only after `process_decls'. */
3045 static void
3046 check_automaton_usage (void)
3047 {
3048 decl_t decl;
3049 int i;
3050
3051 for (i = 0; i < description->decls_num; i++)
3052 {
3053 decl = description->decls [i];
3054 if (decl->mode == dm_automaton
3055 && !DECL_AUTOMATON (decl)->automaton_is_used)
3056 {
3057 if (!w_flag)
3058 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3059 else
3060 warning (0, "automaton `%s' is not used",
3061 DECL_AUTOMATON (decl)->name);
3062 }
3063 }
3064 }
3065
3066 /* The following recursive function processes all regexp in order to
3067 fix usage of units or reservations and to fix errors of undeclared
3068 name. The function may change unit_regexp onto reserv_regexp.
3069 Remember that reserv_regexp does not exist before the function
3070 call. */
3071 static regexp_t
3072 process_regexp (regexp_t regexp)
3073 {
3074 decl_t decl_in_table;
3075 regexp_t new_regexp;
3076 int i;
3077
3078 switch (regexp->mode)
3079 {
3080 case rm_unit:
3081 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3082 if (decl_in_table == NULL)
3083 error ("undeclared unit or reservation `%s'",
3084 REGEXP_UNIT (regexp)->name);
3085 else
3086 switch (decl_in_table->mode)
3087 {
3088 case dm_unit:
3089 DECL_UNIT (decl_in_table)->unit_is_used = 1;
3090 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3091 break;
3092
3093 case dm_reserv:
3094 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3095 new_regexp = create_node (sizeof (struct regexp));
3096 new_regexp->mode = rm_reserv;
3097 new_regexp->pos = regexp->pos;
3098 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3099 REGEXP_RESERV (new_regexp)->reserv_decl
3100 = DECL_RESERV (decl_in_table);
3101 regexp = new_regexp;
3102 break;
3103
3104 default:
3105 gcc_unreachable ();
3106 }
3107 break;
3108 case rm_sequence:
3109 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3110 REGEXP_SEQUENCE (regexp)->regexps [i]
3111 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3112 break;
3113 case rm_allof:
3114 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3115 REGEXP_ALLOF (regexp)->regexps [i]
3116 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3117 break;
3118 case rm_oneof:
3119 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3120 REGEXP_ONEOF (regexp)->regexps [i]
3121 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3122 break;
3123 case rm_repeat:
3124 REGEXP_REPEAT (regexp)->regexp
3125 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3126 break;
3127 case rm_nothing:
3128 break;
3129 default:
3130 gcc_unreachable ();
3131 }
3132 return regexp;
3133 }
3134
3135 /* The following function processes regexp of define_reservation and
3136 define_insn_reservation with the aid of function
3137 `process_regexp'. */
3138 static void
3139 process_regexp_decls (void)
3140 {
3141 decl_t decl;
3142 int i;
3143
3144 for (i = 0; i < description->decls_num; i++)
3145 {
3146 decl = description->decls [i];
3147 if (decl->mode == dm_reserv)
3148 DECL_RESERV (decl)->regexp
3149 = process_regexp (DECL_RESERV (decl)->regexp);
3150 else if (decl->mode == dm_insn_reserv)
3151 DECL_INSN_RESERV (decl)->regexp
3152 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3153 }
3154 }
3155
3156 /* The following function checks that declared unit is used. If the
3157 unit is not used, the function fixes errors/warnings. The
3158 following function must be called only after `process_decls',
3159 `process_regexp_decls'. */
3160 static void
3161 check_usage (void)
3162 {
3163 decl_t decl;
3164 int i;
3165
3166 for (i = 0; i < description->decls_num; i++)
3167 {
3168 decl = description->decls [i];
3169 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3170 {
3171 if (!w_flag)
3172 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3173 else
3174 warning (0, "unit `%s' is not used", DECL_UNIT (decl)->name);
3175 }
3176 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3177 {
3178 if (!w_flag)
3179 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3180 else
3181 warning (0, "reservation `%s' is not used", DECL_RESERV (decl)->name);
3182 }
3183 }
3184 }
3185
3186 /* The following variable value is number of reservation being
3187 processed on loop recognition. */
3188 static int curr_loop_pass_num;
3189
3190 /* The following recursive function returns nonzero value if REGEXP
3191 contains given decl or reservations in given regexp refers for
3192 given decl. */
3193 static int
3194 loop_in_regexp (regexp_t regexp, decl_t start_decl)
3195 {
3196 int i;
3197
3198 if (regexp == NULL)
3199 return 0;
3200 switch (regexp->mode)
3201 {
3202 case rm_unit:
3203 return 0;
3204
3205 case rm_reserv:
3206 if (start_decl->mode == dm_reserv
3207 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3208 return 1;
3209 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3210 == curr_loop_pass_num)
3211 /* declaration has been processed. */
3212 return 0;
3213 else
3214 {
3215 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3216 = curr_loop_pass_num;
3217 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3218 start_decl);
3219 }
3220
3221 case rm_sequence:
3222 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3223 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3224 return 1;
3225 return 0;
3226
3227 case rm_allof:
3228 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3229 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3230 return 1;
3231 return 0;
3232
3233 case rm_oneof:
3234 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3235 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3236 return 1;
3237 return 0;
3238
3239 case rm_repeat:
3240 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3241
3242 case rm_nothing:
3243 return 0;
3244
3245 default:
3246 gcc_unreachable ();
3247 }
3248 }
3249
3250 /* The following function fixes errors "cycle in definition ...". The
3251 function uses function `loop_in_regexp' for that. */
3252 static void
3253 check_loops_in_regexps (void)
3254 {
3255 decl_t decl;
3256 int i;
3257
3258 for (i = 0; i < description->decls_num; i++)
3259 {
3260 decl = description->decls [i];
3261 if (decl->mode == dm_reserv)
3262 DECL_RESERV (decl)->loop_pass_num = 0;
3263 }
3264 for (i = 0; i < description->decls_num; i++)
3265 {
3266 decl = description->decls [i];
3267 curr_loop_pass_num = i;
3268
3269 if (decl->mode == dm_reserv)
3270 {
3271 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3272 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3273 {
3274 gcc_assert (DECL_RESERV (decl)->regexp);
3275 error ("cycle in definition of reservation `%s'",
3276 DECL_RESERV (decl)->name);
3277 }
3278 }
3279 }
3280 }
3281
3282 /* The function recursively processes IR of reservation and defines
3283 max and min cycle for reservation of unit. */
3284 static void
3285 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3286 int min_start_cycle, int *max_finish_cycle,
3287 int *min_finish_cycle)
3288 {
3289 int i;
3290
3291 switch (regexp->mode)
3292 {
3293 case rm_unit:
3294 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3295 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3296 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3297 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3298 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3299 *max_finish_cycle = max_start_cycle;
3300 *min_finish_cycle = min_start_cycle;
3301 break;
3302
3303 case rm_reserv:
3304 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3305 max_start_cycle, min_start_cycle,
3306 max_finish_cycle, min_finish_cycle);
3307 break;
3308
3309 case rm_repeat:
3310 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3311 {
3312 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3313 max_start_cycle, min_start_cycle,
3314 max_finish_cycle, min_finish_cycle);
3315 max_start_cycle = *max_finish_cycle + 1;
3316 min_start_cycle = *min_finish_cycle + 1;
3317 }
3318 break;
3319
3320 case rm_sequence:
3321 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3322 {
3323 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3324 max_start_cycle, min_start_cycle,
3325 max_finish_cycle, min_finish_cycle);
3326 max_start_cycle = *max_finish_cycle + 1;
3327 min_start_cycle = *min_finish_cycle + 1;
3328 }
3329 break;
3330
3331 case rm_allof:
3332 {
3333 int max_cycle = 0;
3334 int min_cycle = 0;
3335
3336 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3337 {
3338 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3339 max_start_cycle, min_start_cycle,
3340 max_finish_cycle, min_finish_cycle);
3341 if (max_cycle < *max_finish_cycle)
3342 max_cycle = *max_finish_cycle;
3343 if (i == 0 || min_cycle > *min_finish_cycle)
3344 min_cycle = *min_finish_cycle;
3345 }
3346 *max_finish_cycle = max_cycle;
3347 *min_finish_cycle = min_cycle;
3348 }
3349 break;
3350
3351 case rm_oneof:
3352 {
3353 int max_cycle = 0;
3354 int min_cycle = 0;
3355
3356 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3357 {
3358 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3359 max_start_cycle, min_start_cycle,
3360 max_finish_cycle, min_finish_cycle);
3361 if (max_cycle < *max_finish_cycle)
3362 max_cycle = *max_finish_cycle;
3363 if (i == 0 || min_cycle > *min_finish_cycle)
3364 min_cycle = *min_finish_cycle;
3365 }
3366 *max_finish_cycle = max_cycle;
3367 *min_finish_cycle = min_cycle;
3368 }
3369 break;
3370
3371 case rm_nothing:
3372 *max_finish_cycle = max_start_cycle;
3373 *min_finish_cycle = min_start_cycle;
3374 break;
3375
3376 default:
3377 gcc_unreachable ();
3378 }
3379 }
3380
3381 /* The following function is called only for correct program. The
3382 function defines max reservation of insns in cycles. */
3383 static void
3384 evaluate_max_reserv_cycles (void)
3385 {
3386 int max_insn_cycles_num;
3387 int min_insn_cycles_num;
3388 decl_t decl;
3389 int i;
3390
3391 description->max_insn_reserv_cycles = 0;
3392 for (i = 0; i < description->decls_num; i++)
3393 {
3394 decl = description->decls [i];
3395 if (decl->mode == dm_insn_reserv)
3396 {
3397 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3398 &max_insn_cycles_num, &min_insn_cycles_num);
3399 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3400 description->max_insn_reserv_cycles = max_insn_cycles_num;
3401 }
3402 }
3403 description->max_insn_reserv_cycles++;
3404 }
3405
3406 /* The following function calls functions for checking all
3407 description. */
3408 static void
3409 check_all_description (void)
3410 {
3411 process_decls ();
3412 check_automaton_usage ();
3413 process_regexp_decls ();
3414 check_usage ();
3415 check_loops_in_regexps ();
3416 if (!have_error)
3417 evaluate_max_reserv_cycles ();
3418 }
3419
3420 \f
3421
3422 /* The page contains abstract data `ticker'. This data is used to
3423 report time of different phases of building automata. It is
3424 possibly to write a description for which automata will be built
3425 during several minutes even on fast machine. */
3426
3427 /* The following function creates ticker and makes it active. */
3428 static ticker_t
3429 create_ticker (void)
3430 {
3431 ticker_t ticker;
3432
3433 ticker.modified_creation_time = get_run_time ();
3434 ticker.incremented_off_time = 0;
3435 return ticker;
3436 }
3437
3438 /* The following function switches off given ticker. */
3439 static void
3440 ticker_off (ticker_t *ticker)
3441 {
3442 if (ticker->incremented_off_time == 0)
3443 ticker->incremented_off_time = get_run_time () + 1;
3444 }
3445
3446 /* The following function switches on given ticker. */
3447 static void
3448 ticker_on (ticker_t *ticker)
3449 {
3450 if (ticker->incremented_off_time != 0)
3451 {
3452 ticker->modified_creation_time
3453 += get_run_time () - ticker->incremented_off_time + 1;
3454 ticker->incremented_off_time = 0;
3455 }
3456 }
3457
3458 /* The following function returns current time in milliseconds since
3459 the moment when given ticker was created. */
3460 static int
3461 active_time (ticker_t ticker)
3462 {
3463 if (ticker.incremented_off_time != 0)
3464 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3465 else
3466 return get_run_time () - ticker.modified_creation_time;
3467 }
3468
3469 /* The following function returns string representation of active time
3470 of given ticker. The result is string representation of seconds
3471 with accuracy of 1/100 second. Only result of the last call of the
3472 function exists. Therefore the following code is not correct
3473
3474 printf ("parser time: %s\ngeneration time: %s\n",
3475 active_time_string (parser_ticker),
3476 active_time_string (generation_ticker));
3477
3478 Correct code has to be the following
3479
3480 printf ("parser time: %s\n", active_time_string (parser_ticker));
3481 printf ("generation time: %s\n",
3482 active_time_string (generation_ticker));
3483
3484 */
3485 static void
3486 print_active_time (FILE *f, ticker_t ticker)
3487 {
3488 int msecs;
3489
3490 msecs = active_time (ticker);
3491 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3492 }
3493
3494 \f
3495
3496 /* The following variable value is number of automaton which are
3497 really being created. This value is defined on the base of
3498 argument of option `-split'. If the variable has zero value the
3499 number of automata is defined by the constructions `%automaton'.
3500 This case occurs when option `-split' is absent or has zero
3501 argument. If constructions `define_automaton' is absent only one
3502 automaton is created. */
3503 static int automata_num;
3504
3505 /* The following variable values are times of
3506 o transformation of regular expressions
3507 o building NDFA (DFA if !ndfa_flag)
3508 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3509 o DFA minimization
3510 o building insn equivalence classes
3511 o all previous ones
3512 o code output */
3513 static ticker_t transform_time;
3514 static ticker_t NDFA_time;
3515 static ticker_t NDFA_to_DFA_time;
3516 static ticker_t minimize_time;
3517 static ticker_t equiv_time;
3518 static ticker_t automaton_generation_time;
3519 static ticker_t output_time;
3520
3521 /* The following variable values are times of
3522 all checking
3523 all generation
3524 all pipeline hazard translator work */
3525 static ticker_t check_time;
3526 static ticker_t generation_time;
3527 static ticker_t all_time;
3528
3529 \f
3530
3531 /* Pseudo insn decl which denotes advancing cycle. */
3532 static decl_t advance_cycle_insn_decl;
3533 static void
3534 add_advance_cycle_insn_decl (void)
3535 {
3536 advance_cycle_insn_decl = create_node (sizeof (struct decl));
3537 advance_cycle_insn_decl->mode = dm_insn_reserv;
3538 advance_cycle_insn_decl->pos = no_pos;
3539 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3540 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
3541 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3542 = description->insns_num;
3543 description->decls [description->decls_num] = advance_cycle_insn_decl;
3544 description->decls_num++;
3545 description->insns_num++;
3546 num_dfa_decls++;
3547 }
3548
3549 \f
3550 /* Abstract data `alternative states' which represents
3551 nondeterministic nature of the description (see comments for
3552 structures alt_state and state). */
3553
3554 /* List of free states. */
3555 static alt_state_t first_free_alt_state;
3556
3557 #ifndef NDEBUG
3558 /* The following variables is maximal number of allocated nodes
3559 alt_state. */
3560 static int allocated_alt_states_num = 0;
3561 #endif
3562
3563 /* The following function returns free node alt_state. It may be new
3564 allocated node or node freed earlier. */
3565 static alt_state_t
3566 get_free_alt_state (void)
3567 {
3568 alt_state_t result;
3569
3570 if (first_free_alt_state != NULL)
3571 {
3572 result = first_free_alt_state;
3573 first_free_alt_state = first_free_alt_state->next_alt_state;
3574 }
3575 else
3576 {
3577 #ifndef NDEBUG
3578 allocated_alt_states_num++;
3579 #endif
3580 result = create_node (sizeof (struct alt_state));
3581 }
3582 result->state = NULL;
3583 result->next_alt_state = NULL;
3584 result->next_sorted_alt_state = NULL;
3585 return result;
3586 }
3587
3588 /* The function frees node ALT_STATE. */
3589 static void
3590 free_alt_state (alt_state_t alt_state)
3591 {
3592 if (alt_state == NULL)
3593 return;
3594 alt_state->next_alt_state = first_free_alt_state;
3595 first_free_alt_state = alt_state;
3596 }
3597
3598 /* The function frees list started with node ALT_STATE_LIST. */
3599 static void
3600 free_alt_states (alt_state_t alt_states_list)
3601 {
3602 alt_state_t curr_alt_state;
3603 alt_state_t next_alt_state;
3604
3605 for (curr_alt_state = alt_states_list;
3606 curr_alt_state != NULL;
3607 curr_alt_state = next_alt_state)
3608 {
3609 next_alt_state = curr_alt_state->next_alt_state;
3610 free_alt_state (curr_alt_state);
3611 }
3612 }
3613
3614 /* The function compares unique numbers of alt states. */
3615 static int
3616 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3617 {
3618 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3619 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3620 return 0;
3621 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3622 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3623 return -1;
3624 else
3625 return 1;
3626 }
3627
3628 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3629 states from the list. The comparison key is alt state unique
3630 number. */
3631 static alt_state_t
3632 uniq_sort_alt_states (alt_state_t alt_states_list)
3633 {
3634 alt_state_t curr_alt_state;
3635 vla_ptr_t alt_states;
3636 size_t i;
3637 size_t prev_unique_state_ind;
3638 alt_state_t result;
3639 alt_state_t *result_ptr;
3640
3641 VLA_PTR_CREATE (alt_states, 150, "alt_states");
3642 for (curr_alt_state = alt_states_list;
3643 curr_alt_state != NULL;
3644 curr_alt_state = curr_alt_state->next_alt_state)
3645 VLA_PTR_ADD (alt_states, curr_alt_state);
3646 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3647 sizeof (alt_state_t), alt_state_cmp);
3648 if (VLA_PTR_LENGTH (alt_states) == 0)
3649 result = NULL;
3650 else
3651 {
3652 result_ptr = VLA_PTR_BEGIN (alt_states);
3653 prev_unique_state_ind = 0;
3654 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3655 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3656 {
3657 prev_unique_state_ind++;
3658 result_ptr [prev_unique_state_ind] = result_ptr [i];
3659 }
3660 #if 0
3661 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3662 free_alt_state (result_ptr [i]);
3663 #endif
3664 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3665 result_ptr = VLA_PTR_BEGIN (alt_states);
3666 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3667 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3668 result_ptr [i - 1]->next_sorted_alt_state = NULL;
3669 result = *result_ptr;
3670 }
3671 VLA_PTR_DELETE (alt_states);
3672 return result;
3673 }
3674
3675 /* The function checks equality of alt state lists. Remember that the
3676 lists must be already sorted by the previous function. */
3677 static int
3678 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3679 {
3680 while (alt_states_1 != NULL && alt_states_2 != NULL
3681 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3682 {
3683 alt_states_1 = alt_states_1->next_sorted_alt_state;
3684 alt_states_2 = alt_states_2->next_sorted_alt_state;
3685 }
3686 return alt_states_1 == alt_states_2;
3687 }
3688
3689 /* Initialization of the abstract data. */
3690 static void
3691 initiate_alt_states (void)
3692 {
3693 first_free_alt_state = NULL;
3694 }
3695
3696 /* Finishing work with the abstract data. */
3697 static void
3698 finish_alt_states (void)
3699 {
3700 }
3701
3702 \f
3703
3704 /* The page contains macros for work with bits strings. We could use
3705 standard gcc bitmap or sbitmap but it would result in difficulties
3706 of building canadian cross. */
3707
3708 /* Set bit number bitno in the bit string. The macro is not side
3709 effect proof. */
3710 #define SET_BIT(bitstring, bitno) \
3711 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3712
3713 #define CLEAR_BIT(bitstring, bitno) \
3714 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3715
3716 /* Test if bit number bitno in the bitstring is set. The macro is not
3717 side effect proof. */
3718 #define TEST_BIT(bitstring, bitno) \
3719 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3720
3721 \f
3722
3723 /* This page contains abstract data `state'. */
3724
3725 /* Maximal length of reservations in cycles (>= 1). */
3726 static int max_cycles_num;
3727
3728 /* Number of set elements (see type set_el_t) needed for
3729 representation of one cycle reservation. It is depended on units
3730 number. */
3731 static int els_in_cycle_reserv;
3732
3733 /* Number of set elements (see type set_el_t) needed for
3734 representation of maximal length reservation. Deterministic
3735 reservation is stored as set (bit string) of length equal to the
3736 variable value * number of bits in set_el_t. */
3737 static int els_in_reservs;
3738
3739 /* VLA for representation of array of pointers to unit
3740 declarations. */
3741 static vla_ptr_t units_container;
3742
3743 /* The start address of the array. */
3744 static unit_decl_t *units_array;
3745
3746 /* Temporary reservation of maximal length. */
3747 static reserv_sets_t temp_reserv;
3748
3749 /* The state table itself is represented by the following variable. */
3750 static htab_t state_table;
3751
3752 /* VLA for representation of array of pointers to free nodes
3753 `state'. */
3754 static vla_ptr_t free_states;
3755
3756 static int curr_unique_state_num;
3757
3758 #ifndef NDEBUG
3759 /* The following variables is maximal number of allocated nodes
3760 `state'. */
3761 static int allocated_states_num = 0;
3762 #endif
3763
3764 /* Allocate new reservation set. */
3765 static reserv_sets_t
3766 alloc_empty_reserv_sets (void)
3767 {
3768 reserv_sets_t result;
3769
3770 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3771 result = (reserv_sets_t) obstack_base (&irp);
3772 obstack_finish (&irp);
3773 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3774 return result;
3775 }
3776
3777 /* Hash value of reservation set. */
3778 static unsigned
3779 reserv_sets_hash_value (reserv_sets_t reservs)
3780 {
3781 set_el_t hash_value;
3782 unsigned result;
3783 int reservs_num, i;
3784 set_el_t *reserv_ptr;
3785
3786 hash_value = 0;
3787 reservs_num = els_in_reservs;
3788 reserv_ptr = reservs;
3789 i = 0;
3790 while (reservs_num != 0)
3791 {
3792 reservs_num--;
3793 hash_value += ((*reserv_ptr >> i)
3794 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3795 i++;
3796 if (i == sizeof (set_el_t) * CHAR_BIT)
3797 i = 0;
3798 reserv_ptr++;
3799 }
3800 if (sizeof (set_el_t) <= sizeof (unsigned))
3801 return hash_value;
3802 result = 0;
3803 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3804 {
3805 result += (unsigned) hash_value;
3806 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3807 }
3808 return result;
3809 }
3810
3811 /* Comparison of given reservation sets. */
3812 static int
3813 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3814 {
3815 int reservs_num;
3816 set_el_t *reserv_ptr_1;
3817 set_el_t *reserv_ptr_2;
3818
3819 gcc_assert (reservs_1 && reservs_2);
3820 reservs_num = els_in_reservs;
3821 reserv_ptr_1 = reservs_1;
3822 reserv_ptr_2 = reservs_2;
3823 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3824 {
3825 reservs_num--;
3826 reserv_ptr_1++;
3827 reserv_ptr_2++;
3828 }
3829 if (reservs_num == 0)
3830 return 0;
3831 else if (*reserv_ptr_1 < *reserv_ptr_2)
3832 return -1;
3833 else
3834 return 1;
3835 }
3836
3837 /* The function checks equality of the reservation sets. */
3838 static int
3839 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3840 {
3841 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3842 }
3843
3844 /* Set up in the reservation set that unit with UNIT_NUM is used on
3845 CYCLE_NUM. */
3846 static void
3847 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3848 {
3849 gcc_assert (cycle_num < max_cycles_num);
3850 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3851 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3852 }
3853
3854 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3855 used on CYCLE_NUM. */
3856 static int
3857 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3858 {
3859 gcc_assert (cycle_num < max_cycles_num);
3860 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3861 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3862 }
3863
3864 /* The function checks that the reservation set represents no one unit
3865 reservation. */
3866 static int
3867 it_is_empty_reserv_sets (reserv_sets_t operand)
3868 {
3869 set_el_t *reserv_ptr;
3870 int reservs_num;
3871
3872 gcc_assert (operand);
3873 for (reservs_num = els_in_reservs, reserv_ptr = operand;
3874 reservs_num != 0;
3875 reserv_ptr++, reservs_num--)
3876 if (*reserv_ptr != 0)
3877 return 0;
3878 return 1;
3879 }
3880
3881 /* The function checks that the reservation sets are intersected,
3882 i.e. there is a unit reservation on a cycle in both reservation
3883 sets. */
3884 static int
3885 reserv_sets_are_intersected (reserv_sets_t operand_1,
3886 reserv_sets_t operand_2)
3887 {
3888 set_el_t *el_ptr_1;
3889 set_el_t *el_ptr_2;
3890 set_el_t *cycle_ptr_1;
3891 set_el_t *cycle_ptr_2;
3892
3893 gcc_assert (operand_1 && operand_2);
3894 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3895 el_ptr_1 < operand_1 + els_in_reservs;
3896 el_ptr_1++, el_ptr_2++)
3897 if (*el_ptr_1 & *el_ptr_2)
3898 return 1;
3899 reserv_sets_or (temp_reserv, operand_1, operand_2);
3900 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3901 cycle_ptr_1 < operand_1 + els_in_reservs;
3902 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3903 {
3904 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3905 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3906 el_ptr_1++, el_ptr_2++)
3907 if (*el_ptr_1 & *el_ptr_2)
3908 return 1;
3909 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3910 return 1;
3911 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3912 - operand_2),
3913 cycle_ptr_2, TRUE))
3914 return 1;
3915 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3916 return 1;
3917 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3918 cycle_ptr_2, TRUE))
3919 return 1;
3920 }
3921 return 0;
3922 }
3923
3924 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3925 cpu cycle. The remaining bits of OPERAND (representing the last
3926 cycle unit reservations) are not changed. */
3927 static void
3928 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3929 {
3930 int i;
3931
3932 gcc_assert (result && operand && result != operand);
3933 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3934 result [i - els_in_cycle_reserv] = operand [i];
3935 }
3936
3937 /* OR of the reservation sets. */
3938 static void
3939 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3940 reserv_sets_t operand_2)
3941 {
3942 set_el_t *el_ptr_1;
3943 set_el_t *el_ptr_2;
3944 set_el_t *result_set_el_ptr;
3945
3946 gcc_assert (result && operand_1 && operand_2);
3947 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3948 el_ptr_1 < operand_1 + els_in_reservs;
3949 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3950 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3951 }
3952
3953 /* AND of the reservation sets. */
3954 static void
3955 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3956 reserv_sets_t operand_2)
3957 {
3958 set_el_t *el_ptr_1;
3959 set_el_t *el_ptr_2;
3960 set_el_t *result_set_el_ptr;
3961
3962 gcc_assert (result && operand_1 && operand_2);
3963 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3964 el_ptr_1 < operand_1 + els_in_reservs;
3965 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3966 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3967 }
3968
3969 /* The function outputs string representation of units reservation on
3970 cycle START_CYCLE in the reservation set. The function uses repeat
3971 construction if REPETITION_NUM > 1. */
3972 static void
3973 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3974 int repetition_num)
3975 {
3976 int unit_num;
3977 int reserved_units_num;
3978
3979 reserved_units_num = 0;
3980 for (unit_num = 0; unit_num < description->units_num; unit_num++)
3981 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3982 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3983 reserved_units_num++;
3984 gcc_assert (repetition_num > 0);
3985 if (repetition_num != 1 && reserved_units_num > 1)
3986 fprintf (f, "(");
3987 reserved_units_num = 0;
3988 for (unit_num = 0;
3989 unit_num < description->units_num;
3990 unit_num++)
3991 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3992 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3993 {
3994 if (reserved_units_num != 0)
3995 fprintf (f, "+");
3996 reserved_units_num++;
3997 fprintf (f, "%s", units_array [unit_num]->name);
3998 }
3999 if (reserved_units_num == 0)
4000 fprintf (f, NOTHING_NAME);
4001 gcc_assert (repetition_num > 0);
4002 if (repetition_num != 1 && reserved_units_num > 1)
4003 fprintf (f, ")");
4004 if (repetition_num != 1)
4005 fprintf (f, "*%d", repetition_num);
4006 }
4007
4008 /* The function outputs string representation of units reservation in
4009 the reservation set. */
4010 static void
4011 output_reserv_sets (FILE *f, reserv_sets_t reservs)
4012 {
4013 int start_cycle = 0;
4014 int cycle;
4015 int repetition_num;
4016
4017 repetition_num = 0;
4018 for (cycle = 0; cycle < max_cycles_num; cycle++)
4019 if (repetition_num == 0)
4020 {
4021 repetition_num++;
4022 start_cycle = cycle;
4023 }
4024 else if (memcmp
4025 ((char *) reservs + start_cycle * els_in_cycle_reserv
4026 * sizeof (set_el_t),
4027 (char *) reservs + cycle * els_in_cycle_reserv
4028 * sizeof (set_el_t),
4029 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
4030 repetition_num++;
4031 else
4032 {
4033 if (start_cycle != 0)
4034 fprintf (f, ", ");
4035 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4036 repetition_num = 1;
4037 start_cycle = cycle;
4038 }
4039 if (start_cycle < max_cycles_num)
4040 {
4041 if (start_cycle != 0)
4042 fprintf (f, ", ");
4043 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4044 }
4045 }
4046
4047 /* The following function returns free node state for AUTOMATON. It
4048 may be new allocated node or node freed earlier. The function also
4049 allocates reservation set if WITH_RESERVS has nonzero value. */
4050 static state_t
4051 get_free_state (int with_reservs, automaton_t automaton)
4052 {
4053 state_t result;
4054
4055 gcc_assert (max_cycles_num > 0 && automaton);
4056 if (VLA_PTR_LENGTH (free_states) != 0)
4057 {
4058 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
4059 VLA_PTR_SHORTEN (free_states, 1);
4060 result->automaton = automaton;
4061 result->first_out_arc = NULL;
4062 result->it_was_placed_in_stack_for_NDFA_forming = 0;
4063 result->it_was_placed_in_stack_for_DFA_forming = 0;
4064 result->component_states = NULL;
4065 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4066 }
4067 else
4068 {
4069 #ifndef NDEBUG
4070 allocated_states_num++;
4071 #endif
4072 result = create_node (sizeof (struct state));
4073 result->automaton = automaton;
4074 result->first_out_arc = NULL;
4075 result->unique_num = curr_unique_state_num;
4076 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4077 curr_unique_state_num++;
4078 }
4079 if (with_reservs)
4080 {
4081 if (result->reservs == NULL)
4082 result->reservs = alloc_empty_reserv_sets ();
4083 else
4084 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
4085 }
4086 return result;
4087 }
4088
4089 /* The function frees node STATE. */
4090 static void
4091 free_state (state_t state)
4092 {
4093 free_alt_states (state->component_states);
4094 VLA_PTR_ADD (free_states, state);
4095 }
4096
4097 /* Hash value of STATE. If STATE represents deterministic state it is
4098 simply hash value of the corresponding reservation set. Otherwise
4099 it is formed from hash values of the component deterministic
4100 states. One more key is order number of state automaton. */
4101 static hashval_t
4102 state_hash (const void *state)
4103 {
4104 unsigned int hash_value;
4105 alt_state_t alt_state;
4106
4107 if (((state_t) state)->component_states == NULL)
4108 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4109 else
4110 {
4111 hash_value = 0;
4112 for (alt_state = ((state_t) state)->component_states;
4113 alt_state != NULL;
4114 alt_state = alt_state->next_sorted_alt_state)
4115 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4116 | (hash_value << CHAR_BIT))
4117 + alt_state->state->unique_num);
4118 }
4119 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4120 | (hash_value << CHAR_BIT))
4121 + ((state_t) state)->automaton->automaton_order_num);
4122 return hash_value;
4123 }
4124
4125 /* Return nonzero value if the states are the same. */
4126 static int
4127 state_eq_p (const void *state_1, const void *state_2)
4128 {
4129 alt_state_t alt_state_1;
4130 alt_state_t alt_state_2;
4131
4132 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4133 return 0;
4134 else if (((state_t) state_1)->component_states == NULL
4135 && ((state_t) state_2)->component_states == NULL)
4136 return reserv_sets_eq (((state_t) state_1)->reservs,
4137 ((state_t) state_2)->reservs);
4138 else if (((state_t) state_1)->component_states != NULL
4139 && ((state_t) state_2)->component_states != NULL)
4140 {
4141 for (alt_state_1 = ((state_t) state_1)->component_states,
4142 alt_state_2 = ((state_t) state_2)->component_states;
4143 alt_state_1 != NULL && alt_state_2 != NULL;
4144 alt_state_1 = alt_state_1->next_sorted_alt_state,
4145 alt_state_2 = alt_state_2->next_sorted_alt_state)
4146 /* All state in the list must be already in the hash table.
4147 Also the lists must be sorted. */
4148 if (alt_state_1->state != alt_state_2->state)
4149 return 0;
4150 return alt_state_1 == alt_state_2;
4151 }
4152 else
4153 return 0;
4154 }
4155
4156 /* Insert STATE into the state table. */
4157 static state_t
4158 insert_state (state_t state)
4159 {
4160 void **entry_ptr;
4161
4162 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4163 if (*entry_ptr == NULL)
4164 *entry_ptr = (void *) state;
4165 return (state_t) *entry_ptr;
4166 }
4167
4168 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4169 deterministic STATE. */
4170 static void
4171 set_state_reserv (state_t state, int cycle_num, int unit_num)
4172 {
4173 set_unit_reserv (state->reservs, cycle_num, unit_num);
4174 }
4175
4176 /* Return nonzero value if the deterministic states contains a
4177 reservation of the same cpu unit on the same cpu cycle. */
4178 static int
4179 intersected_state_reservs_p (state_t state1, state_t state2)
4180 {
4181 gcc_assert (state1->automaton == state2->automaton);
4182 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4183 }
4184
4185 /* Return deterministic state (inserted into the table) which
4186 representing the automaton state which is union of reservations of
4187 the deterministic states masked by RESERVS. */
4188 static state_t
4189 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4190 {
4191 state_t result;
4192 state_t state_in_table;
4193
4194 gcc_assert (state1->automaton == state2->automaton);
4195 result = get_free_state (1, state1->automaton);
4196 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4197 reserv_sets_and (result->reservs, result->reservs, reservs);
4198 state_in_table = insert_state (result);
4199 if (result != state_in_table)
4200 {
4201 free_state (result);
4202 result = state_in_table;
4203 }
4204 return result;
4205 }
4206
4207 /* Return deterministic state (inserted into the table) which
4208 represent the automaton state is obtained from deterministic STATE
4209 by advancing cpu cycle and masking by RESERVS. */
4210 static state_t
4211 state_shift (state_t state, reserv_sets_t reservs)
4212 {
4213 state_t result;
4214 state_t state_in_table;
4215
4216 result = get_free_state (1, state->automaton);
4217 reserv_sets_shift (result->reservs, state->reservs);
4218 reserv_sets_and (result->reservs, result->reservs, reservs);
4219 state_in_table = insert_state (result);
4220 if (result != state_in_table)
4221 {
4222 free_state (result);
4223 result = state_in_table;
4224 }
4225 return result;
4226 }
4227
4228 /* Initialization of the abstract data. */
4229 static void
4230 initiate_states (void)
4231 {
4232 decl_t decl;
4233 int i;
4234
4235 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
4236 units_array
4237 = (description->decls_num && description->units_num
4238 ? VLA_PTR_BEGIN (units_container) : NULL);
4239 for (i = 0; i < description->decls_num; i++)
4240 {
4241 decl = description->decls [i];
4242 if (decl->mode == dm_unit)
4243 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4244 }
4245 max_cycles_num = description->max_insn_reserv_cycles;
4246 els_in_cycle_reserv
4247 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4248 / (sizeof (set_el_t) * CHAR_BIT));
4249 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4250 curr_unique_state_num = 0;
4251 initiate_alt_states ();
4252 VLA_PTR_CREATE (free_states, 1500, "free states");
4253 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4254 temp_reserv = alloc_empty_reserv_sets ();
4255 }
4256
4257 /* Finishing work with the abstract data. */
4258 static void
4259 finish_states (void)
4260 {
4261 VLA_PTR_DELETE (units_container);
4262 htab_delete (state_table);
4263 VLA_PTR_DELETE (free_states);
4264 finish_alt_states ();
4265 }
4266
4267 \f
4268
4269 /* Abstract data `arcs'. */
4270
4271 /* List of free arcs. */
4272 static arc_t first_free_arc;
4273
4274 #ifndef NDEBUG
4275 /* The following variables is maximal number of allocated nodes
4276 `arc'. */
4277 static int allocated_arcs_num = 0;
4278 #endif
4279
4280 /* The function frees node ARC. */
4281 static void
4282 free_arc (arc_t arc)
4283 {
4284 arc->next_out_arc = first_free_arc;
4285 first_free_arc = arc;
4286 }
4287
4288 /* The function removes and frees ARC staring from FROM_STATE. */
4289 static void
4290 remove_arc (state_t from_state, arc_t arc)
4291 {
4292 arc_t prev_arc;
4293 arc_t curr_arc;
4294
4295 gcc_assert (arc);
4296 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4297 curr_arc != NULL;
4298 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4299 if (curr_arc == arc)
4300 break;
4301 gcc_assert (curr_arc);
4302 if (prev_arc == NULL)
4303 from_state->first_out_arc = arc->next_out_arc;
4304 else
4305 prev_arc->next_out_arc = arc->next_out_arc;
4306 free_arc (arc);
4307 }
4308
4309 /* The functions returns arc with given characteristics (or NULL if
4310 the arc does not exist). */
4311 static arc_t
4312 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4313 {
4314 arc_t arc;
4315
4316 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4317 if (arc->to_state == to_state && arc->insn == insn)
4318 return arc;
4319 return NULL;
4320 }
4321
4322 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4323 and with given STATE_ALTS. The function returns added arc (or
4324 already existing arc). */
4325 static arc_t
4326 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4327 int state_alts)
4328 {
4329 arc_t new_arc;
4330
4331 new_arc = find_arc (from_state, to_state, ainsn);
4332 if (new_arc != NULL)
4333 return new_arc;
4334 if (first_free_arc == NULL)
4335 {
4336 #ifndef NDEBUG
4337 allocated_arcs_num++;
4338 #endif
4339 new_arc = create_node (sizeof (struct arc));
4340 new_arc->to_state = NULL;
4341 new_arc->insn = NULL;
4342 new_arc->next_out_arc = NULL;
4343 }
4344 else
4345 {
4346 new_arc = first_free_arc;
4347 first_free_arc = first_free_arc->next_out_arc;
4348 }
4349 new_arc->to_state = to_state;
4350 new_arc->insn = ainsn;
4351 ainsn->arc_exists_p = 1;
4352 new_arc->next_out_arc = from_state->first_out_arc;
4353 from_state->first_out_arc = new_arc;
4354 new_arc->next_arc_marked_by_insn = NULL;
4355 new_arc->state_alts = state_alts;
4356 return new_arc;
4357 }
4358
4359 /* The function returns the first arc starting from STATE. */
4360 static arc_t
4361 first_out_arc (state_t state)
4362 {
4363 return state->first_out_arc;
4364 }
4365
4366 /* The function returns next out arc after ARC. */
4367 static arc_t
4368 next_out_arc (arc_t arc)
4369 {
4370 return arc->next_out_arc;
4371 }
4372
4373 /* Initialization of the abstract data. */
4374 static void
4375 initiate_arcs (void)
4376 {
4377 first_free_arc = NULL;
4378 }
4379
4380 /* Finishing work with the abstract data. */
4381 static void
4382 finish_arcs (void)
4383 {
4384 }
4385
4386 \f
4387
4388 /* Abstract data `automata lists'. */
4389
4390 /* List of free states. */
4391 static automata_list_el_t first_free_automata_list_el;
4392
4393 /* The list being formed. */
4394 static automata_list_el_t current_automata_list;
4395
4396 /* Hash table of automata lists. */
4397 static htab_t automata_list_table;
4398
4399 /* The following function returns free automata list el. It may be
4400 new allocated node or node freed earlier. */
4401 static automata_list_el_t
4402 get_free_automata_list_el (void)
4403 {
4404 automata_list_el_t result;
4405
4406 if (first_free_automata_list_el != NULL)
4407 {
4408 result = first_free_automata_list_el;
4409 first_free_automata_list_el
4410 = first_free_automata_list_el->next_automata_list_el;
4411 }
4412 else
4413 result = create_node (sizeof (struct automata_list_el));
4414 result->automaton = NULL;
4415 result->next_automata_list_el = NULL;
4416 return result;
4417 }
4418
4419 /* The function frees node AUTOMATA_LIST_EL. */
4420 static void
4421 free_automata_list_el (automata_list_el_t automata_list_el)
4422 {
4423 if (automata_list_el == NULL)
4424 return;
4425 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4426 first_free_automata_list_el = automata_list_el;
4427 }
4428
4429 /* The function frees list AUTOMATA_LIST. */
4430 static void
4431 free_automata_list (automata_list_el_t automata_list)
4432 {
4433 automata_list_el_t curr_automata_list_el;
4434 automata_list_el_t next_automata_list_el;
4435
4436 for (curr_automata_list_el = automata_list;
4437 curr_automata_list_el != NULL;
4438 curr_automata_list_el = next_automata_list_el)
4439 {
4440 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4441 free_automata_list_el (curr_automata_list_el);
4442 }
4443 }
4444
4445 /* Hash value of AUTOMATA_LIST. */
4446 static hashval_t
4447 automata_list_hash (const void *automata_list)
4448 {
4449 unsigned int hash_value;
4450 automata_list_el_t curr_automata_list_el;
4451
4452 hash_value = 0;
4453 for (curr_automata_list_el = (automata_list_el_t) automata_list;
4454 curr_automata_list_el != NULL;
4455 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4456 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4457 | (hash_value << CHAR_BIT))
4458 + curr_automata_list_el->automaton->automaton_order_num);
4459 return hash_value;
4460 }
4461
4462 /* Return nonzero value if the automata_lists are the same. */
4463 static int
4464 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4465 {
4466 automata_list_el_t automata_list_el_1;
4467 automata_list_el_t automata_list_el_2;
4468
4469 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4470 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4471 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4472 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4473 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4474 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4475 return 0;
4476 return automata_list_el_1 == automata_list_el_2;
4477 }
4478
4479 /* Initialization of the abstract data. */
4480 static void
4481 initiate_automata_lists (void)
4482 {
4483 first_free_automata_list_el = NULL;
4484 automata_list_table = htab_create (1500, automata_list_hash,
4485 automata_list_eq_p, (htab_del) 0);
4486 }
4487
4488 /* The following function starts new automata list and makes it the
4489 current one. */
4490 static void
4491 automata_list_start (void)
4492 {
4493 current_automata_list = NULL;
4494 }
4495
4496 /* The following function adds AUTOMATON to the current list. */
4497 static void
4498 automata_list_add (automaton_t automaton)
4499 {
4500 automata_list_el_t el;
4501
4502 el = get_free_automata_list_el ();
4503 el->automaton = automaton;
4504 el->next_automata_list_el = current_automata_list;
4505 current_automata_list = el;
4506 }
4507
4508 /* The following function finishes forming the current list, inserts
4509 it into the table and returns it. */
4510 static automata_list_el_t
4511 automata_list_finish (void)
4512 {
4513 void **entry_ptr;
4514
4515 if (current_automata_list == NULL)
4516 return NULL;
4517 entry_ptr = htab_find_slot (automata_list_table,
4518 (void *) current_automata_list, 1);
4519 if (*entry_ptr == NULL)
4520 *entry_ptr = (void *) current_automata_list;
4521 else
4522 free_automata_list (current_automata_list);
4523 current_automata_list = NULL;
4524 return (automata_list_el_t) *entry_ptr;
4525 }
4526
4527 /* Finishing work with the abstract data. */
4528 static void
4529 finish_automata_lists (void)
4530 {
4531 htab_delete (automata_list_table);
4532 }
4533
4534 \f
4535
4536 /* The page contains abstract data for work with exclusion sets (see
4537 exclusion_set in file rtl.def). */
4538
4539 /* The following variable refers to an exclusion set returned by
4540 get_excl_set. This is bit string of length equal to cpu units
4541 number. If exclusion set for given unit contains 1 for a unit,
4542 then simultaneous reservation of the units is prohibited. */
4543 static reserv_sets_t excl_set;
4544
4545 /* The array contains exclusion sets for each unit. */
4546 static reserv_sets_t *unit_excl_set_table;
4547
4548 /* The following function forms the array containing exclusion sets
4549 for each unit. */
4550 static void
4551 initiate_excl_sets (void)
4552 {
4553 decl_t decl;
4554 reserv_sets_t unit_excl_set;
4555 unit_set_el_t el;
4556 int i;
4557
4558 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4559 excl_set = (reserv_sets_t) obstack_base (&irp);
4560 obstack_finish (&irp);
4561 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4562 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4563 obstack_finish (&irp);
4564 /* Evaluate unit exclusion sets. */
4565 for (i = 0; i < description->decls_num; i++)
4566 {
4567 decl = description->decls [i];
4568 if (decl->mode == dm_unit)
4569 {
4570 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4571 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4572 obstack_finish (&irp);
4573 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4574 for (el = DECL_UNIT (decl)->excl_list;
4575 el != NULL;
4576 el = el->next_unit_set_el)
4577 {
4578 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4579 el->unit_decl->in_set_p = TRUE;
4580 }
4581 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4582 }
4583 }
4584 }
4585
4586 /* The function sets up and return EXCL_SET which is union of
4587 exclusion sets for each unit in IN_SET. */
4588 static reserv_sets_t
4589 get_excl_set (reserv_sets_t in_set)
4590 {
4591 int excl_char_num;
4592 int chars_num;
4593 int i;
4594 int start_unit_num;
4595 int unit_num;
4596
4597 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4598 memset (excl_set, 0, chars_num);
4599 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4600 if (((unsigned char *) in_set) [excl_char_num])
4601 for (i = CHAR_BIT - 1; i >= 0; i--)
4602 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4603 {
4604 start_unit_num = excl_char_num * CHAR_BIT + i;
4605 if (start_unit_num >= description->units_num)
4606 return excl_set;
4607 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4608 {
4609 excl_set [unit_num]
4610 |= unit_excl_set_table [start_unit_num] [unit_num];
4611 }
4612 }
4613 return excl_set;
4614 }
4615
4616 \f
4617
4618 /* The page contains abstract data for work with presence/absence
4619 pattern sets (see presence_set/absence_set in file rtl.def). */
4620
4621 /* The following arrays contain correspondingly presence, final
4622 presence, absence, and final absence patterns for each unit. */
4623 static pattern_reserv_t *unit_presence_set_table;
4624 static pattern_reserv_t *unit_final_presence_set_table;
4625 static pattern_reserv_t *unit_absence_set_table;
4626 static pattern_reserv_t *unit_final_absence_set_table;
4627
4628 /* The following function forms list of reservation sets for given
4629 PATTERN_LIST. */
4630 static pattern_reserv_t
4631 form_reserv_sets_list (pattern_set_el_t pattern_list)
4632 {
4633 pattern_set_el_t el;
4634 pattern_reserv_t first, curr, prev;
4635 int i;
4636
4637 prev = first = NULL;
4638 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4639 {
4640 curr = create_node (sizeof (struct pattern_reserv));
4641 curr->reserv = alloc_empty_reserv_sets ();
4642 curr->next_pattern_reserv = NULL;
4643 for (i = 0; i < el->units_num; i++)
4644 {
4645 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4646 el->unit_decls [i]->in_set_p = TRUE;
4647 }
4648 if (prev != NULL)
4649 prev->next_pattern_reserv = curr;
4650 else
4651 first = curr;
4652 prev = curr;
4653 }
4654 return first;
4655 }
4656
4657 /* The following function forms the array containing presence and
4658 absence pattern sets for each unit. */
4659 static void
4660 initiate_presence_absence_pattern_sets (void)
4661 {
4662 decl_t decl;
4663 int i;
4664
4665 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4666 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4667 obstack_finish (&irp);
4668 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4669 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4670 obstack_finish (&irp);
4671 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4672 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4673 obstack_finish (&irp);
4674 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4675 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4676 obstack_finish (&irp);
4677 /* Evaluate unit presence/absence sets. */
4678 for (i = 0; i < description->decls_num; i++)
4679 {
4680 decl = description->decls [i];
4681 if (decl->mode == dm_unit)
4682 {
4683 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4684 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4685 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4686 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4687 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4688 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4689 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4690 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4691 }
4692 }
4693 }
4694
4695 /* The function checks that CHECKED_SET satisfies all presence pattern
4696 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4697 is ok. */
4698 static int
4699 check_presence_pattern_sets (reserv_sets_t checked_set,
4700 reserv_sets_t origional_set,
4701 int final_p)
4702 {
4703 int char_num;
4704 int chars_num;
4705 int i;
4706 int start_unit_num;
4707 int unit_num;
4708 int presence_p;
4709 pattern_reserv_t pat_reserv;
4710
4711 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4712 for (char_num = 0; char_num < chars_num; char_num++)
4713 if (((unsigned char *) origional_set) [char_num])
4714 for (i = CHAR_BIT - 1; i >= 0; i--)
4715 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4716 {
4717 start_unit_num = char_num * CHAR_BIT + i;
4718 if (start_unit_num >= description->units_num)
4719 break;
4720 if ((final_p
4721 && unit_final_presence_set_table [start_unit_num] == NULL)
4722 || (!final_p
4723 && unit_presence_set_table [start_unit_num] == NULL))
4724 continue;
4725 presence_p = FALSE;
4726 for (pat_reserv = (final_p
4727 ? unit_final_presence_set_table [start_unit_num]
4728 : unit_presence_set_table [start_unit_num]);
4729 pat_reserv != NULL;
4730 pat_reserv = pat_reserv->next_pattern_reserv)
4731 {
4732 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4733 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4734 != pat_reserv->reserv [unit_num])
4735 break;
4736 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4737 }
4738 if (!presence_p)
4739 return FALSE;
4740 }
4741 return TRUE;
4742 }
4743
4744 /* The function checks that CHECKED_SET satisfies all absence pattern
4745 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4746 is ok. */
4747 static int
4748 check_absence_pattern_sets (reserv_sets_t checked_set,
4749 reserv_sets_t origional_set,
4750 int final_p)
4751 {
4752 int char_num;
4753 int chars_num;
4754 int i;
4755 int start_unit_num;
4756 int unit_num;
4757 pattern_reserv_t pat_reserv;
4758
4759 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4760 for (char_num = 0; char_num < chars_num; char_num++)
4761 if (((unsigned char *) origional_set) [char_num])
4762 for (i = CHAR_BIT - 1; i >= 0; i--)
4763 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4764 {
4765 start_unit_num = char_num * CHAR_BIT + i;
4766 if (start_unit_num >= description->units_num)
4767 break;
4768 for (pat_reserv = (final_p
4769 ? unit_final_absence_set_table [start_unit_num]
4770 : unit_absence_set_table [start_unit_num]);
4771 pat_reserv != NULL;
4772 pat_reserv = pat_reserv->next_pattern_reserv)
4773 {
4774 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4775 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4776 != pat_reserv->reserv [unit_num]
4777 && pat_reserv->reserv [unit_num])
4778 break;
4779 if (unit_num >= els_in_cycle_reserv)
4780 return FALSE;
4781 }
4782 }
4783 return TRUE;
4784 }
4785
4786 \f
4787
4788 /* This page contains code for transformation of original reservations
4789 described in .md file. The main goal of transformations is
4790 simplifying reservation and lifting up all `|' on the top of IR
4791 reservation representation. */
4792
4793
4794 /* The following function makes copy of IR representation of
4795 reservation. The function also substitutes all reservations
4796 defined by define_reservation by corresponding value during making
4797 the copy. */
4798 static regexp_t
4799 copy_insn_regexp (regexp_t regexp)
4800 {
4801 regexp_t result;
4802 int i;
4803
4804 switch (regexp->mode)
4805 {
4806 case rm_reserv:
4807 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4808 break;
4809
4810 case rm_unit:
4811 result = copy_node (regexp, sizeof (struct regexp));
4812 break;
4813
4814 case rm_repeat:
4815 result = copy_node (regexp, sizeof (struct regexp));
4816 REGEXP_REPEAT (result)->regexp
4817 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4818 break;
4819
4820 case rm_sequence:
4821 result = copy_node (regexp,
4822 sizeof (struct regexp) + sizeof (regexp_t)
4823 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4824 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4825 REGEXP_SEQUENCE (result)->regexps [i]
4826 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4827 break;
4828
4829 case rm_allof:
4830 result = copy_node (regexp,
4831 sizeof (struct regexp) + sizeof (regexp_t)
4832 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4833 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4834 REGEXP_ALLOF (result)->regexps [i]
4835 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4836 break;
4837
4838 case rm_oneof:
4839 result = copy_node (regexp,
4840 sizeof (struct regexp) + sizeof (regexp_t)
4841 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4842 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4843 REGEXP_ONEOF (result)->regexps [i]
4844 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4845 break;
4846
4847 case rm_nothing:
4848 result = copy_node (regexp, sizeof (struct regexp));
4849 break;
4850
4851 default:
4852 gcc_unreachable ();
4853 }
4854 return result;
4855 }
4856
4857 /* The following variable is set up 1 if a transformation has been
4858 applied. */
4859 static int regexp_transformed_p;
4860
4861 /* The function makes transformation
4862 A*N -> A, A, ... */
4863 static regexp_t
4864 transform_1 (regexp_t regexp)
4865 {
4866 int i;
4867 int repeat_num;
4868 regexp_t operand;
4869 pos_t pos;
4870
4871 if (regexp->mode == rm_repeat)
4872 {
4873 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4874 gcc_assert (repeat_num > 1);
4875 operand = REGEXP_REPEAT (regexp)->regexp;
4876 pos = regexp->mode;
4877 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4878 * (repeat_num - 1));
4879 regexp->mode = rm_sequence;
4880 regexp->pos = pos;
4881 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4882 for (i = 0; i < repeat_num; i++)
4883 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4884 regexp_transformed_p = 1;
4885 }
4886 return regexp;
4887 }
4888
4889 /* The function makes transformations
4890 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4891 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4892 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4893 static regexp_t
4894 transform_2 (regexp_t regexp)
4895 {
4896 if (regexp->mode == rm_sequence)
4897 {
4898 regexp_t sequence = NULL;
4899 regexp_t result;
4900 int sequence_index = 0;
4901 int i, j;
4902
4903 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4904 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4905 {
4906 sequence_index = i;
4907 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4908 break;
4909 }
4910 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4911 {
4912 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4913 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
4914 result = create_node (sizeof (struct regexp)
4915 + sizeof (regexp_t)
4916 * (REGEXP_SEQUENCE (regexp)->regexps_num
4917 + REGEXP_SEQUENCE (sequence)->regexps_num
4918 - 2));
4919 result->mode = rm_sequence;
4920 result->pos = regexp->pos;
4921 REGEXP_SEQUENCE (result)->regexps_num
4922 = (REGEXP_SEQUENCE (regexp)->regexps_num
4923 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4924 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4925 if (i < sequence_index)
4926 REGEXP_SEQUENCE (result)->regexps [i]
4927 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4928 else if (i > sequence_index)
4929 REGEXP_SEQUENCE (result)->regexps
4930 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4931 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4932 else
4933 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4934 REGEXP_SEQUENCE (result)->regexps [i + j]
4935 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4936 regexp_transformed_p = 1;
4937 regexp = result;
4938 }
4939 }
4940 else if (regexp->mode == rm_allof)
4941 {
4942 regexp_t allof = NULL;
4943 regexp_t result;
4944 int allof_index = 0;
4945 int i, j;
4946
4947 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4948 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4949 {
4950 allof_index = i;
4951 allof = REGEXP_ALLOF (regexp)->regexps [i];
4952 break;
4953 }
4954 if (i < REGEXP_ALLOF (regexp)->regexps_num)
4955 {
4956 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4957 && REGEXP_ALLOF (regexp)->regexps_num > 1);
4958 result = create_node (sizeof (struct regexp)
4959 + sizeof (regexp_t)
4960 * (REGEXP_ALLOF (regexp)->regexps_num
4961 + REGEXP_ALLOF (allof)->regexps_num - 2));
4962 result->mode = rm_allof;
4963 result->pos = regexp->pos;
4964 REGEXP_ALLOF (result)->regexps_num
4965 = (REGEXP_ALLOF (regexp)->regexps_num
4966 + REGEXP_ALLOF (allof)->regexps_num - 1);
4967 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4968 if (i < allof_index)
4969 REGEXP_ALLOF (result)->regexps [i]
4970 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4971 else if (i > allof_index)
4972 REGEXP_ALLOF (result)->regexps
4973 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4974 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4975 else
4976 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4977 REGEXP_ALLOF (result)->regexps [i + j]
4978 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4979 regexp_transformed_p = 1;
4980 regexp = result;
4981 }
4982 }
4983 else if (regexp->mode == rm_oneof)
4984 {
4985 regexp_t oneof = NULL;
4986 regexp_t result;
4987 int oneof_index = 0;
4988 int i, j;
4989
4990 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4991 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4992 {
4993 oneof_index = i;
4994 oneof = REGEXP_ONEOF (regexp)->regexps [i];
4995 break;
4996 }
4997 if (i < REGEXP_ONEOF (regexp)->regexps_num)
4998 {
4999 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5000 && REGEXP_ONEOF (regexp)->regexps_num > 1);
5001 result = create_node (sizeof (struct regexp)
5002 + sizeof (regexp_t)
5003 * (REGEXP_ONEOF (regexp)->regexps_num
5004 + REGEXP_ONEOF (oneof)->regexps_num - 2));
5005 result->mode = rm_oneof;
5006 result->pos = regexp->pos;
5007 REGEXP_ONEOF (result)->regexps_num
5008 = (REGEXP_ONEOF (regexp)->regexps_num
5009 + REGEXP_ONEOF (oneof)->regexps_num - 1);
5010 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5011 if (i < oneof_index)
5012 REGEXP_ONEOF (result)->regexps [i]
5013 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5014 else if (i > oneof_index)
5015 REGEXP_ONEOF (result)->regexps
5016 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
5017 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5018 else
5019 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
5020 REGEXP_ONEOF (result)->regexps [i + j]
5021 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
5022 regexp_transformed_p = 1;
5023 regexp = result;
5024 }
5025 }
5026 return regexp;
5027 }
5028
5029 /* The function makes transformations
5030 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
5031 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
5032 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
5033 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
5034 static regexp_t
5035 transform_3 (regexp_t regexp)
5036 {
5037 if (regexp->mode == rm_sequence)
5038 {
5039 regexp_t oneof = NULL;
5040 int oneof_index = 0;
5041 regexp_t result;
5042 regexp_t sequence;
5043 int i, j;
5044
5045 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5046 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
5047 {
5048 oneof_index = i;
5049 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
5050 break;
5051 }
5052 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
5053 {
5054 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5055 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
5056 result = create_node (sizeof (struct regexp)
5057 + sizeof (regexp_t)
5058 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5059 result->mode = rm_oneof;
5060 result->pos = regexp->pos;
5061 REGEXP_ONEOF (result)->regexps_num
5062 = REGEXP_ONEOF (oneof)->regexps_num;
5063 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5064 {
5065 sequence
5066 = create_node (sizeof (struct regexp)
5067 + sizeof (regexp_t)
5068 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
5069 sequence->mode = rm_sequence;
5070 sequence->pos = regexp->pos;
5071 REGEXP_SEQUENCE (sequence)->regexps_num
5072 = REGEXP_SEQUENCE (regexp)->regexps_num;
5073 REGEXP_ONEOF (result)->regexps [i] = sequence;
5074 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
5075 if (j != oneof_index)
5076 REGEXP_SEQUENCE (sequence)->regexps [j]
5077 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
5078 else
5079 REGEXP_SEQUENCE (sequence)->regexps [j]
5080 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5081 }
5082 regexp_transformed_p = 1;
5083 regexp = result;
5084 }
5085 }
5086 else if (regexp->mode == rm_allof)
5087 {
5088 regexp_t oneof = NULL;
5089 regexp_t seq;
5090 int oneof_index = 0;
5091 int max_seq_length, allof_length;
5092 regexp_t result;
5093 regexp_t allof = NULL;
5094 regexp_t allof_op = NULL;
5095 int i, j;
5096
5097 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5098 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
5099 {
5100 oneof_index = i;
5101 oneof = REGEXP_ALLOF (regexp)->regexps [i];
5102 break;
5103 }
5104 if (i < REGEXP_ALLOF (regexp)->regexps_num)
5105 {
5106 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
5107 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5108 result = create_node (sizeof (struct regexp)
5109 + sizeof (regexp_t)
5110 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
5111 result->mode = rm_oneof;
5112 result->pos = regexp->pos;
5113 REGEXP_ONEOF (result)->regexps_num
5114 = REGEXP_ONEOF (oneof)->regexps_num;
5115 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5116 {
5117 allof
5118 = create_node (sizeof (struct regexp)
5119 + sizeof (regexp_t)
5120 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5121 allof->mode = rm_allof;
5122 allof->pos = regexp->pos;
5123 REGEXP_ALLOF (allof)->regexps_num
5124 = REGEXP_ALLOF (regexp)->regexps_num;
5125 REGEXP_ONEOF (result)->regexps [i] = allof;
5126 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5127 if (j != oneof_index)
5128 REGEXP_ALLOF (allof)->regexps [j]
5129 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5130 else
5131 REGEXP_ALLOF (allof)->regexps [j]
5132 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5133 }
5134 regexp_transformed_p = 1;
5135 regexp = result;
5136 }
5137 max_seq_length = 0;
5138 if (regexp->mode == rm_allof)
5139 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5140 {
5141 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
5142 {
5143 case rm_sequence:
5144 seq = REGEXP_ALLOF (regexp)->regexps [i];
5145 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5146 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5147 break;
5148
5149 case rm_unit:
5150 case rm_nothing:
5151 break;
5152
5153 default:
5154 max_seq_length = 0;
5155 goto break_for;
5156 }
5157 }
5158 break_for:
5159 if (max_seq_length != 0)
5160 {
5161 gcc_assert (max_seq_length != 1
5162 && REGEXP_ALLOF (regexp)->regexps_num > 1);
5163 result = create_node (sizeof (struct regexp)
5164 + sizeof (regexp_t) * (max_seq_length - 1));
5165 result->mode = rm_sequence;
5166 result->pos = regexp->pos;
5167 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5168 for (i = 0; i < max_seq_length; i++)
5169 {
5170 allof_length = 0;
5171 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5172 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
5173 {
5174 case rm_sequence:
5175 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5176 ->regexps [j])->regexps_num))
5177 {
5178 allof_op
5179 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5180 ->regexps [j])
5181 ->regexps [i]);
5182 allof_length++;
5183 }
5184 break;
5185 case rm_unit:
5186 case rm_nothing:
5187 if (i == 0)
5188 {
5189 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5190 allof_length++;
5191 }
5192 break;
5193 default:
5194 break;
5195 }
5196
5197 if (allof_length == 1)
5198 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5199 else
5200 {
5201 allof = create_node (sizeof (struct regexp)
5202 + sizeof (regexp_t)
5203 * (allof_length - 1));
5204 allof->mode = rm_allof;
5205 allof->pos = regexp->pos;
5206 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5207 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5208 allof_length = 0;
5209 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5210 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5211 && (i <
5212 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5213 ->regexps [j])->regexps_num)))
5214 {
5215 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5216 ->regexps [j])
5217 ->regexps [i]);
5218 REGEXP_ALLOF (allof)->regexps [allof_length]
5219 = allof_op;
5220 allof_length++;
5221 }
5222 else if (i == 0
5223 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5224 == rm_unit
5225 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5226 == rm_nothing)))
5227 {
5228 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5229 REGEXP_ALLOF (allof)->regexps [allof_length]
5230 = allof_op;
5231 allof_length++;
5232 }
5233 }
5234 }
5235 regexp_transformed_p = 1;
5236 regexp = result;
5237 }
5238 }
5239 return regexp;
5240 }
5241
5242 /* The function traverses IR of reservation and applies transformations
5243 implemented by FUNC. */
5244 static regexp_t
5245 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5246 {
5247 int i;
5248
5249 switch (regexp->mode)
5250 {
5251 case rm_sequence:
5252 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5253 REGEXP_SEQUENCE (regexp)->regexps [i]
5254 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
5255 func);
5256 break;
5257
5258 case rm_allof:
5259 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5260 REGEXP_ALLOF (regexp)->regexps [i]
5261 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5262 break;
5263
5264 case rm_oneof:
5265 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5266 REGEXP_ONEOF (regexp)->regexps [i]
5267 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5268 break;
5269
5270 case rm_repeat:
5271 REGEXP_REPEAT (regexp)->regexp
5272 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5273 break;
5274
5275 case rm_nothing:
5276 case rm_unit:
5277 break;
5278
5279 default:
5280 gcc_unreachable ();
5281 }
5282 return (*func) (regexp);
5283 }
5284
5285 /* The function applies all transformations for IR representation of
5286 reservation REGEXP. */
5287 static regexp_t
5288 transform_regexp (regexp_t regexp)
5289 {
5290 regexp = regexp_transform_func (regexp, transform_1);
5291 do
5292 {
5293 regexp_transformed_p = 0;
5294 regexp = regexp_transform_func (regexp, transform_2);
5295 regexp = regexp_transform_func (regexp, transform_3);
5296 }
5297 while (regexp_transformed_p);
5298 return regexp;
5299 }
5300
5301 /* The function applies all transformations for reservations of all
5302 insn declarations. */
5303 static void
5304 transform_insn_regexps (void)
5305 {
5306 decl_t decl;
5307 int i;
5308
5309 transform_time = create_ticker ();
5310 add_advance_cycle_insn_decl ();
5311 if (progress_flag)
5312 fprintf (stderr, "Reservation transformation...");
5313 for (i = 0; i < description->decls_num; i++)
5314 {
5315 decl = description->decls [i];
5316 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5317 DECL_INSN_RESERV (decl)->transformed_regexp
5318 = transform_regexp (copy_insn_regexp
5319 (DECL_INSN_RESERV (decl)->regexp));
5320 }
5321 if (progress_flag)
5322 fprintf (stderr, "done\n");
5323 ticker_off (&transform_time);
5324 }
5325
5326 \f
5327
5328 /* The following variable value is TRUE if the first annotated message
5329 about units to automata distribution has been output. */
5330 static int annotation_message_reported_p;
5331
5332 /* The following structure describes usage of a unit in a reservation. */
5333 struct unit_usage
5334 {
5335 unit_decl_t unit_decl;
5336 /* The following forms a list of units used on the same cycle in the
5337 same alternative. */
5338 struct unit_usage *next;
5339 };
5340
5341 /* Obstack for unit_usage structures. */
5342 static struct obstack unit_usages;
5343
5344 /* VLA for representation of array of pointers to unit usage
5345 structures. There is an element for each combination of
5346 (alternative number, cycle). Unit usages on given cycle in
5347 alternative with given number are referred through element with
5348 index equals to the cycle * number of all alternatives in the regexp
5349 + the alternative number. */
5350 static vla_ptr_t cycle_alt_unit_usages;
5351
5352 /* The following function creates the structure unit_usage for UNIT on
5353 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5354 accessed through cycle_alt_unit_usages. */
5355 static void
5356 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5357 int alt_num)
5358 {
5359 size_t i, length, old_length;
5360 unit_decl_t unit_decl;
5361 struct unit_usage *unit_usage_ptr;
5362 int index;
5363
5364 gcc_assert (regexp && regexp->mode == rm_oneof
5365 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
5366 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5367 old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
5368 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5369 if (old_length < length)
5370 {
5371 VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
5372 for (i = old_length; i < length; i++)
5373 VLA_PTR (cycle_alt_unit_usages, i) = NULL;
5374 }
5375 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5376 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5377 obstack_finish (&unit_usages);
5378 unit_usage_ptr->unit_decl = unit_decl;
5379 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5380 unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
5381 VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
5382 unit_decl->last_distribution_check_cycle = -1; /* undefined */
5383 }
5384
5385 /* The function processes given REGEXP to find units with the wrong
5386 distribution. */
5387 static void
5388 check_regexp_units_distribution (const char *insn_reserv_name,
5389 regexp_t regexp)
5390 {
5391 int i, j, k, cycle;
5392 regexp_t seq, allof, unit;
5393 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5394
5395 if (regexp == NULL || regexp->mode != rm_oneof)
5396 return;
5397 /* Store all unit usages in the regexp: */
5398 obstack_init (&unit_usages);
5399 VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
5400 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5401 {
5402 seq = REGEXP_ONEOF (regexp)->regexps [i];
5403 switch (seq->mode)
5404 {
5405 case rm_sequence:
5406 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5407 {
5408 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5409 switch (allof->mode)
5410 {
5411 case rm_allof:
5412 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5413 {
5414 unit = REGEXP_ALLOF (allof)->regexps [k];
5415 if (unit->mode == rm_unit)
5416 store_alt_unit_usage (regexp, unit, j, i);
5417 else
5418 gcc_assert (unit->mode == rm_nothing);
5419 }
5420 break;
5421
5422 case rm_unit:
5423 store_alt_unit_usage (regexp, allof, j, i);
5424 break;
5425
5426 case rm_nothing:
5427 break;
5428
5429 default:
5430 gcc_unreachable ();
5431 }
5432 }
5433 break;
5434
5435 case rm_allof:
5436 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5437 {
5438 unit = REGEXP_ALLOF (seq)->regexps [k];
5439 switch (unit->mode)
5440 {
5441 case rm_unit:
5442 store_alt_unit_usage (regexp, unit, 0, i);
5443 break;
5444
5445 case rm_nothing:
5446 break;
5447
5448 default:
5449 gcc_unreachable ();
5450 }
5451 }
5452 break;
5453
5454 case rm_unit:
5455 store_alt_unit_usage (regexp, seq, 0, i);
5456 break;
5457
5458 case rm_nothing:
5459 break;
5460
5461 default:
5462 gcc_unreachable ();
5463 }
5464 }
5465 /* Check distribution: */
5466 for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
5467 {
5468 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5469 for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
5470 unit_usage_ptr != NULL;
5471 unit_usage_ptr = unit_usage_ptr->next)
5472 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5473 {
5474 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5475 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5476 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5477 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5478 k++)
5479 {
5480 for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
5481 other_unit_usage_ptr != NULL;
5482 other_unit_usage_ptr = other_unit_usage_ptr->next)
5483 if (unit_usage_ptr->unit_decl->automaton_decl
5484 == other_unit_usage_ptr->unit_decl->automaton_decl)
5485 break;
5486 if (other_unit_usage_ptr == NULL
5487 && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
5488 break;
5489 }
5490 if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5491 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5492 {
5493 if (!annotation_message_reported_p)
5494 {
5495 fprintf (stderr, "\n");
5496 error ("The following units do not satisfy units-automata distribution rule");
5497 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5498 annotation_message_reported_p = TRUE;
5499 }
5500 error ("Unit %s, reserv. %s, cycle %d",
5501 unit_usage_ptr->unit_decl->name, insn_reserv_name,
5502 cycle);
5503 }
5504 }
5505 }
5506 VLA_PTR_DELETE (cycle_alt_unit_usages);
5507 obstack_free (&unit_usages, NULL);
5508 }
5509
5510 /* The function finds units which violates units to automata
5511 distribution rule. If the units exist, report about them. */
5512 static void
5513 check_unit_distributions_to_automata (void)
5514 {
5515 decl_t decl;
5516 int i;
5517
5518 if (progress_flag)
5519 fprintf (stderr, "Check unit distributions to automata...");
5520 annotation_message_reported_p = FALSE;
5521 for (i = 0; i < description->decls_num; i++)
5522 {
5523 decl = description->decls [i];
5524 if (decl->mode == dm_insn_reserv)
5525 check_regexp_units_distribution
5526 (DECL_INSN_RESERV (decl)->name,
5527 DECL_INSN_RESERV (decl)->transformed_regexp);
5528 }
5529 if (progress_flag)
5530 fprintf (stderr, "done\n");
5531 }
5532
5533 \f
5534
5535 /* The page contains code for building alt_states (see comments for
5536 IR) describing all possible insns reservations of an automaton. */
5537
5538 /* Current state being formed for which the current alt_state
5539 refers. */
5540 static state_t state_being_formed;
5541
5542 /* Current alt_state being formed. */
5543 static alt_state_t alt_state_being_formed;
5544
5545 /* This recursive function processes `,' and units in reservation
5546 REGEXP for forming alt_states of AUTOMATON. It is believed that
5547 CURR_CYCLE is start cycle of all reservation REGEXP. */
5548 static int
5549 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5550 int curr_cycle)
5551 {
5552 int i;
5553
5554 if (regexp == NULL)
5555 return curr_cycle;
5556
5557 switch (regexp->mode)
5558 {
5559 case rm_unit:
5560 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5561 == automaton->automaton_order_num)
5562 set_state_reserv (state_being_formed, curr_cycle,
5563 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5564 return curr_cycle;
5565
5566 case rm_sequence:
5567 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5568 curr_cycle
5569 = process_seq_for_forming_states
5570 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5571 return curr_cycle;
5572
5573 case rm_allof:
5574 {
5575 int finish_cycle = 0;
5576 int cycle;
5577
5578 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5579 {
5580 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5581 ->regexps [i],
5582 automaton, curr_cycle);
5583 if (finish_cycle < cycle)
5584 finish_cycle = cycle;
5585 }
5586 return finish_cycle;
5587 }
5588
5589 case rm_nothing:
5590 return curr_cycle;
5591
5592 default:
5593 gcc_unreachable ();
5594 }
5595 }
5596
5597 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5598 inserts alt_state into the table. */
5599 static void
5600 finish_forming_alt_state (alt_state_t alt_state,
5601 automaton_t automaton ATTRIBUTE_UNUSED)
5602 {
5603 state_t state_in_table;
5604 state_t corresponding_state;
5605
5606 corresponding_state = alt_state->state;
5607 state_in_table = insert_state (corresponding_state);
5608 if (state_in_table != corresponding_state)
5609 {
5610 free_state (corresponding_state);
5611 alt_state->state = state_in_table;
5612 }
5613 }
5614
5615 /* The following variable value is current automaton insn for whose
5616 reservation the alt states are created. */
5617 static ainsn_t curr_ainsn;
5618
5619 /* This recursive function processes `|' in reservation REGEXP for
5620 forming alt_states of AUTOMATON. List of the alt states should
5621 have the same order as in the description. */
5622 static void
5623 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5624 int inside_oneof_p)
5625 {
5626 int i;
5627
5628 if (regexp->mode != rm_oneof)
5629 {
5630 alt_state_being_formed = get_free_alt_state ();
5631 state_being_formed = get_free_state (1, automaton);
5632 alt_state_being_formed->state = state_being_formed;
5633 /* We inserts in reverse order but we process alternatives also
5634 in reverse order. So we have the same order of alternative
5635 as in the description. */
5636 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5637 curr_ainsn->alt_states = alt_state_being_formed;
5638 (void) process_seq_for_forming_states (regexp, automaton, 0);
5639 finish_forming_alt_state (alt_state_being_formed, automaton);
5640 }
5641 else
5642 {
5643 gcc_assert (!inside_oneof_p);
5644 /* We processes it in reverse order to get list with the same
5645 order as in the description. See also the previous
5646 commentary. */
5647 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5648 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5649 automaton, 1);
5650 }
5651 }
5652
5653 /* Create nodes alt_state for all AUTOMATON insns. */
5654 static void
5655 create_alt_states (automaton_t automaton)
5656 {
5657 struct insn_reserv_decl *reserv_decl;
5658
5659 for (curr_ainsn = automaton->ainsn_list;
5660 curr_ainsn != NULL;
5661 curr_ainsn = curr_ainsn->next_ainsn)
5662 {
5663 reserv_decl = curr_ainsn->insn_reserv_decl;
5664 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5665 {
5666 curr_ainsn->alt_states = NULL;
5667 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5668 automaton, 0);
5669 curr_ainsn->sorted_alt_states
5670 = uniq_sort_alt_states (curr_ainsn->alt_states);
5671 }
5672 }
5673 }
5674
5675 \f
5676
5677 /* The page contains major code for building DFA(s) for fast pipeline
5678 hazards recognition. */
5679
5680 /* The function forms list of ainsns of AUTOMATON with the same
5681 reservation. */
5682 static void
5683 form_ainsn_with_same_reservs (automaton_t automaton)
5684 {
5685 ainsn_t curr_ainsn;
5686 size_t i;
5687 vla_ptr_t first_insns;
5688 vla_ptr_t last_insns;
5689
5690 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5691 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5692 for (curr_ainsn = automaton->ainsn_list;
5693 curr_ainsn != NULL;
5694 curr_ainsn = curr_ainsn->next_ainsn)
5695 if (curr_ainsn->insn_reserv_decl
5696 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5697 {
5698 curr_ainsn->next_same_reservs_insn = NULL;
5699 curr_ainsn->first_insn_with_same_reservs = 1;
5700 }
5701 else
5702 {
5703 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5704 if (alt_states_eq
5705 (curr_ainsn->sorted_alt_states,
5706 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5707 break;
5708 curr_ainsn->next_same_reservs_insn = NULL;
5709 if (i < VLA_PTR_LENGTH (first_insns))
5710 {
5711 curr_ainsn->first_insn_with_same_reservs = 0;
5712 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5713 = curr_ainsn;
5714 VLA_PTR (last_insns, i) = curr_ainsn;
5715 }
5716 else
5717 {
5718 VLA_PTR_ADD (first_insns, curr_ainsn);
5719 VLA_PTR_ADD (last_insns, curr_ainsn);
5720 curr_ainsn->first_insn_with_same_reservs = 1;
5721 }
5722 }
5723 VLA_PTR_DELETE (first_insns);
5724 VLA_PTR_DELETE (last_insns);
5725 }
5726
5727 /* Forming unit reservations which can affect creating the automaton
5728 states achieved from a given state. It permits to build smaller
5729 automata in many cases. We would have the same automata after
5730 the minimization without such optimization, but the automaton
5731 right after the building could be huge. So in other words, usage
5732 of reservs_matter means some minimization during building the
5733 automaton. */
5734 static reserv_sets_t
5735 form_reservs_matter (automaton_t automaton)
5736 {
5737 int cycle, unit;
5738 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5739
5740 for (cycle = 0; cycle < max_cycles_num; cycle++)
5741 for (unit = 0; unit < description->units_num; unit++)
5742 if (units_array [unit]->automaton_decl
5743 == automaton->corresponding_automaton_decl
5744 && (cycle >= units_array [unit]->min_occ_cycle_num
5745 /* We can not remove queried unit from reservations. */
5746 || units_array [unit]->query_p
5747 /* We can not remove units which are used
5748 `exclusion_set', `presence_set',
5749 `final_presence_set', `absence_set', and
5750 `final_absence_set'. */
5751 || units_array [unit]->in_set_p))
5752 set_unit_reserv (reservs_matter, cycle, unit);
5753 return reservs_matter;
5754 }
5755
5756 /* The following function creates all states of nondeterministic (if
5757 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5758 static void
5759 make_automaton (automaton_t automaton)
5760 {
5761 ainsn_t ainsn;
5762 struct insn_reserv_decl *insn_reserv_decl;
5763 alt_state_t alt_state;
5764 state_t state;
5765 state_t start_state;
5766 state_t state2;
5767 ainsn_t advance_cycle_ainsn;
5768 arc_t added_arc;
5769 vla_ptr_t state_stack;
5770 int states_n;
5771 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5772
5773 VLA_PTR_CREATE (state_stack, 150, "state stack");
5774 /* Create the start state (empty state). */
5775 start_state = insert_state (get_free_state (1, automaton));
5776 automaton->start_state = start_state;
5777 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5778 VLA_PTR_ADD (state_stack, start_state);
5779 states_n = 1;
5780 while (VLA_PTR_LENGTH (state_stack) != 0)
5781 {
5782 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5783 VLA_PTR_SHORTEN (state_stack, 1);
5784 advance_cycle_ainsn = NULL;
5785 for (ainsn = automaton->ainsn_list;
5786 ainsn != NULL;
5787 ainsn = ainsn->next_ainsn)
5788 if (ainsn->first_insn_with_same_reservs)
5789 {
5790 insn_reserv_decl = ainsn->insn_reserv_decl;
5791 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5792 {
5793 /* We process alt_states in the same order as they are
5794 present in the description. */
5795 added_arc = NULL;
5796 for (alt_state = ainsn->alt_states;
5797 alt_state != NULL;
5798 alt_state = alt_state->next_alt_state)
5799 {
5800 state2 = alt_state->state;
5801 if (!intersected_state_reservs_p (state, state2))
5802 {
5803 state2 = states_union (state, state2, reservs_matter);
5804 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5805 {
5806 state2->it_was_placed_in_stack_for_NDFA_forming
5807 = 1;
5808 VLA_PTR_ADD (state_stack, state2);
5809 states_n++;
5810 if (progress_flag && states_n % 100 == 0)
5811 fprintf (stderr, ".");
5812 }
5813 added_arc = add_arc (state, state2, ainsn, 1);
5814 if (!ndfa_flag)
5815 break;
5816 }
5817 }
5818 if (!ndfa_flag && added_arc != NULL)
5819 {
5820 added_arc->state_alts = 0;
5821 for (alt_state = ainsn->alt_states;
5822 alt_state != NULL;
5823 alt_state = alt_state->next_alt_state)
5824 {
5825 state2 = alt_state->state;
5826 if (!intersected_state_reservs_p (state, state2))
5827 added_arc->state_alts++;
5828 }
5829 }
5830 }
5831 else
5832 advance_cycle_ainsn = ainsn;
5833 }
5834 /* Add transition to advance cycle. */
5835 state2 = state_shift (state, reservs_matter);
5836 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5837 {
5838 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5839 VLA_PTR_ADD (state_stack, state2);
5840 states_n++;
5841 if (progress_flag && states_n % 100 == 0)
5842 fprintf (stderr, ".");
5843 }
5844 gcc_assert (advance_cycle_ainsn);
5845 add_arc (state, state2, advance_cycle_ainsn, 1);
5846 }
5847 VLA_PTR_DELETE (state_stack);
5848 }
5849
5850 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5851 static void
5852 form_arcs_marked_by_insn (state_t state)
5853 {
5854 decl_t decl;
5855 arc_t arc;
5856 int i;
5857
5858 for (i = 0; i < description->decls_num; i++)
5859 {
5860 decl = description->decls [i];
5861 if (decl->mode == dm_insn_reserv)
5862 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5863 }
5864 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5865 {
5866 gcc_assert (arc->insn);
5867 arc->next_arc_marked_by_insn
5868 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5869 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5870 }
5871 }
5872
5873 /* The function creates composed state (see comments for IR) from
5874 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5875 same insn. If the composed state is not in STATE_STACK yet, it is
5876 pushed into STATE_STACK. */
5877 static int
5878 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5879 vla_ptr_t *state_stack)
5880 {
5881 state_t state;
5882 alt_state_t alt_state, curr_alt_state;
5883 alt_state_t new_alt_state;
5884 arc_t curr_arc;
5885 arc_t next_arc;
5886 state_t state_in_table;
5887 state_t temp_state;
5888 alt_state_t canonical_alt_states_list;
5889 int alts_number;
5890 int new_state_p = 0;
5891
5892 if (arcs_marked_by_insn == NULL)
5893 return new_state_p;
5894 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5895 state = arcs_marked_by_insn->to_state;
5896 else
5897 {
5898 gcc_assert (ndfa_flag);
5899 /* Create composed state. */
5900 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5901 curr_alt_state = NULL;
5902 for (curr_arc = arcs_marked_by_insn;
5903 curr_arc != NULL;
5904 curr_arc = curr_arc->next_arc_marked_by_insn)
5905 if (curr_arc->to_state->component_states == NULL)
5906 {
5907 new_alt_state = get_free_alt_state ();
5908 new_alt_state->next_alt_state = curr_alt_state;
5909 new_alt_state->state = curr_arc->to_state;
5910 curr_alt_state = new_alt_state;
5911 }
5912 else
5913 for (alt_state = curr_arc->to_state->component_states;
5914 alt_state != NULL;
5915 alt_state = alt_state->next_sorted_alt_state)
5916 {
5917 new_alt_state = get_free_alt_state ();
5918 new_alt_state->next_alt_state = curr_alt_state;
5919 new_alt_state->state = alt_state->state;
5920 gcc_assert (!alt_state->state->component_states);
5921 curr_alt_state = new_alt_state;
5922 }
5923 /* There are not identical sets in the alt state list. */
5924 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5925 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5926 {
5927 temp_state = state;
5928 state = canonical_alt_states_list->state;
5929 free_state (temp_state);
5930 }
5931 else
5932 {
5933 state->component_states = canonical_alt_states_list;
5934 state_in_table = insert_state (state);
5935 if (state_in_table != state)
5936 {
5937 gcc_assert
5938 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
5939 free_state (state);
5940 state = state_in_table;
5941 }
5942 else
5943 {
5944 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
5945 new_state_p = 1;
5946 for (curr_alt_state = state->component_states;
5947 curr_alt_state != NULL;
5948 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5949 for (curr_arc = first_out_arc (curr_alt_state->state);
5950 curr_arc != NULL;
5951 curr_arc = next_out_arc (curr_arc))
5952 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5953 }
5954 arcs_marked_by_insn->to_state = state;
5955 for (alts_number = 0,
5956 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5957 curr_arc != NULL;
5958 curr_arc = next_arc)
5959 {
5960 next_arc = curr_arc->next_arc_marked_by_insn;
5961 remove_arc (original_state, curr_arc);
5962 alts_number++;
5963 }
5964 arcs_marked_by_insn->state_alts = alts_number;
5965 }
5966 }
5967 if (!state->it_was_placed_in_stack_for_DFA_forming)
5968 {
5969 state->it_was_placed_in_stack_for_DFA_forming = 1;
5970 VLA_PTR_ADD (*state_stack, state);
5971 }
5972 return new_state_p;
5973 }
5974
5975 /* The function transforms nondeterministic AUTOMATON into
5976 deterministic. */
5977 static void
5978 NDFA_to_DFA (automaton_t automaton)
5979 {
5980 state_t start_state;
5981 state_t state;
5982 decl_t decl;
5983 vla_ptr_t state_stack;
5984 int i;
5985 int states_n;
5986
5987 VLA_PTR_CREATE (state_stack, 150, "state stack");
5988 /* Create the start state (empty state). */
5989 start_state = automaton->start_state;
5990 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5991 VLA_PTR_ADD (state_stack, start_state);
5992 states_n = 1;
5993 while (VLA_PTR_LENGTH (state_stack) != 0)
5994 {
5995 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5996 VLA_PTR_SHORTEN (state_stack, 1);
5997 form_arcs_marked_by_insn (state);
5998 for (i = 0; i < description->decls_num; i++)
5999 {
6000 decl = description->decls [i];
6001 if (decl->mode == dm_insn_reserv
6002 && create_composed_state
6003 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
6004 &state_stack))
6005 {
6006 states_n++;
6007 if (progress_flag && states_n % 100 == 0)
6008 fprintf (stderr, ".");
6009 }
6010 }
6011 }
6012 VLA_PTR_DELETE (state_stack);
6013 }
6014
6015 /* The following variable value is current number (1, 2, ...) of passing
6016 graph of states. */
6017 static int curr_state_graph_pass_num;
6018
6019 /* This recursive function passes all states achieved from START_STATE
6020 and applies APPLIED_FUNC to them. */
6021 static void
6022 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
6023 {
6024 arc_t arc;
6025
6026 if (start_state->pass_num == curr_state_graph_pass_num)
6027 return;
6028 start_state->pass_num = curr_state_graph_pass_num;
6029 (*applied_func) (start_state);
6030 for (arc = first_out_arc (start_state);
6031 arc != NULL;
6032 arc = next_out_arc (arc))
6033 pass_state_graph (arc->to_state, applied_func);
6034 }
6035
6036 /* This recursive function passes all states of AUTOMATON and applies
6037 APPLIED_FUNC to them. */
6038 static void
6039 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
6040 {
6041 curr_state_graph_pass_num++;
6042 pass_state_graph (automaton->start_state, applied_func);
6043 }
6044
6045 /* The function initializes code for passing of all states. */
6046 static void
6047 initiate_pass_states (void)
6048 {
6049 curr_state_graph_pass_num = 0;
6050 }
6051
6052 /* The following vla is used for storing pointers to all achieved
6053 states. */
6054 static vla_ptr_t all_achieved_states;
6055
6056 /* This function is called by function pass_states to add an achieved
6057 STATE. */
6058 static void
6059 add_achieved_state (state_t state)
6060 {
6061 VLA_PTR_ADD (all_achieved_states, state);
6062 }
6063
6064 /* The function sets up equivalence numbers of insns which mark all
6065 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6066 nonzero value) or by equiv_class_num_2 of the destination state.
6067 The function returns number of out arcs of STATE. */
6068 static int
6069 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
6070 {
6071 int state_out_arcs_num;
6072 arc_t arc;
6073
6074 state_out_arcs_num = 0;
6075 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6076 {
6077 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
6078 && !arc->insn->insn_reserv_decl->state_alts);
6079 state_out_arcs_num++;
6080 arc->insn->insn_reserv_decl->equiv_class_num
6081 = (odd_iteration_flag
6082 ? arc->to_state->equiv_class_num_1
6083 : arc->to_state->equiv_class_num_2);
6084 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6085 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
6086 && arc->insn->insn_reserv_decl->state_alts > 0);
6087 }
6088 return state_out_arcs_num;
6089 }
6090
6091 /* The function clears equivalence numbers and alt_states in all insns
6092 which mark all out arcs of STATE. */
6093 static void
6094 clear_arc_insns_equiv_num (state_t state)
6095 {
6096 arc_t arc;
6097
6098 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6099 {
6100 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6101 arc->insn->insn_reserv_decl->state_alts = 0;
6102 }
6103 }
6104
6105 /* The function copies pointers to equivalent states from vla FROM
6106 into vla TO. */
6107 static void
6108 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
6109 {
6110 state_t *class_ptr;
6111
6112 VLA_PTR_NULLIFY (*to);
6113 for (class_ptr = VLA_PTR_BEGIN (*from);
6114 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6115 class_ptr++)
6116 VLA_PTR_ADD (*to, *class_ptr);
6117 }
6118
6119 /* The following function returns TRUE if STATE reserves the unit with
6120 UNIT_NUM on the first cycle. */
6121 static int
6122 first_cycle_unit_presence (state_t state, int unit_num)
6123 {
6124 alt_state_t alt_state;
6125
6126 if (state->component_states == NULL)
6127 return test_unit_reserv (state->reservs, 0, unit_num);
6128 else
6129 {
6130 for (alt_state = state->component_states;
6131 alt_state != NULL;
6132 alt_state = alt_state->next_sorted_alt_state)
6133 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
6134 return true;
6135 }
6136 return false;
6137 }
6138
6139 /* The function returns nonzero value if STATE is not equivalent to
6140 ANOTHER_STATE from the same current partition on equivalence
6141 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6142 output arcs. Iteration of making equivalence partition is defined
6143 by ODD_ITERATION_FLAG. */
6144 static int
6145 state_is_differed (state_t state, state_t another_state,
6146 int another_state_out_arcs_num, int odd_iteration_flag)
6147 {
6148 arc_t arc;
6149 int state_out_arcs_num;
6150 int i, presence1_p, presence2_p;
6151
6152 state_out_arcs_num = 0;
6153 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6154 {
6155 state_out_arcs_num++;
6156 if ((odd_iteration_flag
6157 ? arc->to_state->equiv_class_num_1
6158 : arc->to_state->equiv_class_num_2)
6159 != arc->insn->insn_reserv_decl->equiv_class_num
6160 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6161 return 1;
6162 }
6163 if (state_out_arcs_num != another_state_out_arcs_num)
6164 return 1;
6165 /* Now we are looking at the states with the point of view of query
6166 units. */
6167 for (i = 0; i < description->units_num; i++)
6168 if (units_array [i]->query_p)
6169 {
6170 presence1_p = first_cycle_unit_presence (state, i);
6171 presence2_p = first_cycle_unit_presence (another_state, i);
6172 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6173 return 1;
6174 }
6175 return 0;
6176 }
6177
6178 /* The function makes initial partition of STATES on equivalent
6179 classes. */
6180 static state_t
6181 init_equiv_class (state_t *states, int states_num)
6182 {
6183 state_t *state_ptr;
6184 state_t result_equiv_class;
6185
6186 result_equiv_class = NULL;
6187 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6188 {
6189 (*state_ptr)->equiv_class_num_1 = 1;
6190 (*state_ptr)->next_equiv_class_state = result_equiv_class;
6191 result_equiv_class = *state_ptr;
6192 }
6193 return result_equiv_class;
6194 }
6195
6196 /* The function processes equivalence class given by its pointer
6197 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6198 are not equivalent states, the function partitions the class
6199 removing nonequivalent states and placing them in
6200 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6201 assigns it to the state equivalence number. If the class has been
6202 partitioned, the function returns nonzero value. */
6203 static int
6204 partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
6205 vla_ptr_t *next_iteration_classes,
6206 int *new_equiv_class_num_ptr)
6207 {
6208 state_t new_equiv_class;
6209 int partition_p;
6210 state_t first_state;
6211 state_t curr_state;
6212 state_t prev_state;
6213 state_t next_state;
6214 int out_arcs_num;
6215
6216 partition_p = 0;
6217 gcc_assert (*equiv_class_ptr);
6218 for (first_state = *equiv_class_ptr;
6219 first_state != NULL;
6220 first_state = new_equiv_class)
6221 {
6222 new_equiv_class = NULL;
6223 if (first_state->next_equiv_class_state != NULL)
6224 {
6225 /* There are more one states in the class equivalence. */
6226 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6227 odd_iteration_flag);
6228 for (prev_state = first_state,
6229 curr_state = first_state->next_equiv_class_state;
6230 curr_state != NULL;
6231 curr_state = next_state)
6232 {
6233 next_state = curr_state->next_equiv_class_state;
6234 if (state_is_differed (curr_state, first_state, out_arcs_num,
6235 odd_iteration_flag))
6236 {
6237 /* Remove curr state from the class equivalence. */
6238 prev_state->next_equiv_class_state = next_state;
6239 /* Add curr state to the new class equivalence. */
6240 curr_state->next_equiv_class_state = new_equiv_class;
6241 if (new_equiv_class == NULL)
6242 (*new_equiv_class_num_ptr)++;
6243 if (odd_iteration_flag)
6244 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6245 else
6246 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6247 new_equiv_class = curr_state;
6248 partition_p = 1;
6249 }
6250 else
6251 prev_state = curr_state;
6252 }
6253 clear_arc_insns_equiv_num (first_state);
6254 }
6255 if (new_equiv_class != NULL)
6256 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
6257 }
6258 return partition_p;
6259 }
6260
6261 /* The function finds equivalent states of AUTOMATON. */
6262 static void
6263 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
6264 {
6265 state_t new_equiv_class;
6266 int new_equiv_class_num;
6267 int odd_iteration_flag;
6268 int finish_flag;
6269 vla_ptr_t next_iteration_classes;
6270 state_t *equiv_class_ptr;
6271 state_t *state_ptr;
6272
6273 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6274 pass_states (automaton, add_achieved_state);
6275 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6276 VLA_PTR_LENGTH (all_achieved_states));
6277 odd_iteration_flag = 0;
6278 new_equiv_class_num = 1;
6279 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6280 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6281 do
6282 {
6283 odd_iteration_flag = !odd_iteration_flag;
6284 finish_flag = 1;
6285 copy_equiv_class (equiv_classes, &next_iteration_classes);
6286 /* Transfer equiv numbers for the next iteration. */
6287 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6288 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6289 state_ptr++)
6290 if (odd_iteration_flag)
6291 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6292 else
6293 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6294 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6295 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6296 equiv_class_ptr++)
6297 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6298 &next_iteration_classes,
6299 &new_equiv_class_num))
6300 finish_flag = 0;
6301 }
6302 while (!finish_flag);
6303 VLA_PTR_DELETE (next_iteration_classes);
6304 VLA_PTR_DELETE (all_achieved_states);
6305 }
6306
6307 /* The function merges equivalent states of AUTOMATON. */
6308 static void
6309 merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
6310 {
6311 state_t *equiv_class_ptr;
6312 state_t curr_state;
6313 state_t new_state;
6314 state_t first_class_state;
6315 alt_state_t alt_states;
6316 alt_state_t alt_state, new_alt_state;
6317 arc_t curr_arc;
6318 arc_t next_arc;
6319
6320 /* Create states corresponding to equivalence classes containing two
6321 or more states. */
6322 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6323 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6324 equiv_class_ptr++)
6325 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6326 {
6327 /* There are more one states in the class equivalence. */
6328 /* Create new compound state. */
6329 new_state = get_free_state (0, automaton);
6330 alt_states = NULL;
6331 first_class_state = *equiv_class_ptr;
6332 for (curr_state = first_class_state;
6333 curr_state != NULL;
6334 curr_state = curr_state->next_equiv_class_state)
6335 {
6336 curr_state->equiv_class_state = new_state;
6337 if (curr_state->component_states == NULL)
6338 {
6339 new_alt_state = get_free_alt_state ();
6340 new_alt_state->state = curr_state;
6341 new_alt_state->next_alt_state = alt_states;
6342 alt_states = new_alt_state;
6343 }
6344 else
6345 for (alt_state = curr_state->component_states;
6346 alt_state != NULL;
6347 alt_state = alt_state->next_sorted_alt_state)
6348 {
6349 new_alt_state = get_free_alt_state ();
6350 new_alt_state->state = alt_state->state;
6351 new_alt_state->next_alt_state = alt_states;
6352 alt_states = new_alt_state;
6353 }
6354 }
6355 /* Its is important that alt states were sorted before and
6356 after merging to have the same querying results. */
6357 new_state->component_states = uniq_sort_alt_states (alt_states);
6358 }
6359 else
6360 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6361 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6362 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6363 equiv_class_ptr++)
6364 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6365 {
6366 first_class_state = *equiv_class_ptr;
6367 /* Create new arcs output from the state corresponding to
6368 equiv class. */
6369 for (curr_arc = first_out_arc (first_class_state);
6370 curr_arc != NULL;
6371 curr_arc = next_out_arc (curr_arc))
6372 add_arc (first_class_state->equiv_class_state,
6373 curr_arc->to_state->equiv_class_state,
6374 curr_arc->insn, curr_arc->state_alts);
6375 /* Delete output arcs from states of given class equivalence. */
6376 for (curr_state = first_class_state;
6377 curr_state != NULL;
6378 curr_state = curr_state->next_equiv_class_state)
6379 {
6380 if (automaton->start_state == curr_state)
6381 automaton->start_state = curr_state->equiv_class_state;
6382 /* Delete the state and its output arcs. */
6383 for (curr_arc = first_out_arc (curr_state);
6384 curr_arc != NULL;
6385 curr_arc = next_arc)
6386 {
6387 next_arc = next_out_arc (curr_arc);
6388 free_arc (curr_arc);
6389 }
6390 }
6391 }
6392 else
6393 {
6394 /* Change `to_state' of arcs output from the state of given
6395 equivalence class. */
6396 for (curr_arc = first_out_arc (*equiv_class_ptr);
6397 curr_arc != NULL;
6398 curr_arc = next_out_arc (curr_arc))
6399 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6400 }
6401 }
6402
6403 /* The function sets up new_cycle_p for states if there is arc to the
6404 state marked by advance_cycle_insn_decl. */
6405 static void
6406 set_new_cycle_flags (state_t state)
6407 {
6408 arc_t arc;
6409
6410 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6411 if (arc->insn->insn_reserv_decl
6412 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6413 arc->to_state->new_cycle_p = 1;
6414 }
6415
6416 /* The top level function for minimization of deterministic
6417 AUTOMATON. */
6418 static void
6419 minimize_DFA (automaton_t automaton)
6420 {
6421 vla_ptr_t equiv_classes;
6422
6423 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6424 evaluate_equiv_classes (automaton, &equiv_classes);
6425 merge_states (automaton, &equiv_classes);
6426 pass_states (automaton, set_new_cycle_flags);
6427 VLA_PTR_DELETE (equiv_classes);
6428 }
6429
6430 /* Values of two variables are counted number of states and arcs in an
6431 automaton. */
6432 static int curr_counted_states_num;
6433 static int curr_counted_arcs_num;
6434
6435 /* The function is called by function `pass_states' to count states
6436 and arcs of an automaton. */
6437 static void
6438 incr_states_and_arcs_nums (state_t state)
6439 {
6440 arc_t arc;
6441
6442 curr_counted_states_num++;
6443 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6444 curr_counted_arcs_num++;
6445 }
6446
6447 /* The function counts states and arcs of AUTOMATON. */
6448 static void
6449 count_states_and_arcs (automaton_t automaton, int *states_num,
6450 int *arcs_num)
6451 {
6452 curr_counted_states_num = 0;
6453 curr_counted_arcs_num = 0;
6454 pass_states (automaton, incr_states_and_arcs_nums);
6455 *states_num = curr_counted_states_num;
6456 *arcs_num = curr_counted_arcs_num;
6457 }
6458
6459 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6460 recognition after checking and simplifying IR of the
6461 description. */
6462 static void
6463 build_automaton (automaton_t automaton)
6464 {
6465 int states_num;
6466 int arcs_num;
6467
6468 ticker_on (&NDFA_time);
6469 if (progress_flag)
6470 {
6471 if (automaton->corresponding_automaton_decl == NULL)
6472 fprintf (stderr, "Create anonymous automaton");
6473 else
6474 fprintf (stderr, "Create automaton `%s'",
6475 automaton->corresponding_automaton_decl->name);
6476 fprintf (stderr, " (1 dot is 100 new states):");
6477 }
6478 make_automaton (automaton);
6479 if (progress_flag)
6480 fprintf (stderr, " done\n");
6481 ticker_off (&NDFA_time);
6482 count_states_and_arcs (automaton, &states_num, &arcs_num);
6483 automaton->NDFA_states_num = states_num;
6484 automaton->NDFA_arcs_num = arcs_num;
6485 ticker_on (&NDFA_to_DFA_time);
6486 if (progress_flag)
6487 {
6488 if (automaton->corresponding_automaton_decl == NULL)
6489 fprintf (stderr, "Make anonymous DFA");
6490 else
6491 fprintf (stderr, "Make DFA `%s'",
6492 automaton->corresponding_automaton_decl->name);
6493 fprintf (stderr, " (1 dot is 100 new states):");
6494 }
6495 NDFA_to_DFA (automaton);
6496 if (progress_flag)
6497 fprintf (stderr, " done\n");
6498 ticker_off (&NDFA_to_DFA_time);
6499 count_states_and_arcs (automaton, &states_num, &arcs_num);
6500 automaton->DFA_states_num = states_num;
6501 automaton->DFA_arcs_num = arcs_num;
6502 if (!no_minimization_flag)
6503 {
6504 ticker_on (&minimize_time);
6505 if (progress_flag)
6506 {
6507 if (automaton->corresponding_automaton_decl == NULL)
6508 fprintf (stderr, "Minimize anonymous DFA...");
6509 else
6510 fprintf (stderr, "Minimize DFA `%s'...",
6511 automaton->corresponding_automaton_decl->name);
6512 }
6513 minimize_DFA (automaton);
6514 if (progress_flag)
6515 fprintf (stderr, "done\n");
6516 ticker_off (&minimize_time);
6517 count_states_and_arcs (automaton, &states_num, &arcs_num);
6518 automaton->minimal_DFA_states_num = states_num;
6519 automaton->minimal_DFA_arcs_num = arcs_num;
6520 }
6521 }
6522
6523 \f
6524
6525 /* The page contains code for enumeration of all states of an automaton. */
6526
6527 /* Variable used for enumeration of all states of an automaton. Its
6528 value is current number of automaton states. */
6529 static int curr_state_order_num;
6530
6531 /* The function is called by function `pass_states' for enumerating
6532 states. */
6533 static void
6534 set_order_state_num (state_t state)
6535 {
6536 state->order_state_num = curr_state_order_num;
6537 curr_state_order_num++;
6538 }
6539
6540 /* The function enumerates all states of AUTOMATON. */
6541 static void
6542 enumerate_states (automaton_t automaton)
6543 {
6544 curr_state_order_num = 0;
6545 pass_states (automaton, set_order_state_num);
6546 automaton->achieved_states_num = curr_state_order_num;
6547 }
6548
6549 \f
6550
6551 /* The page contains code for finding equivalent automaton insns
6552 (ainsns). */
6553
6554 /* The function inserts AINSN into cyclic list
6555 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6556 static ainsn_t
6557 insert_ainsn_into_equiv_class (ainsn_t ainsn,
6558 ainsn_t cyclic_equiv_class_insn_list)
6559 {
6560 if (cyclic_equiv_class_insn_list == NULL)
6561 ainsn->next_equiv_class_insn = ainsn;
6562 else
6563 {
6564 ainsn->next_equiv_class_insn
6565 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6566 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6567 }
6568 return ainsn;
6569 }
6570
6571 /* The function deletes equiv_class_insn into cyclic list of
6572 equivalent ainsns. */
6573 static void
6574 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6575 {
6576 ainsn_t curr_equiv_class_insn;
6577 ainsn_t prev_equiv_class_insn;
6578
6579 prev_equiv_class_insn = equiv_class_insn;
6580 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6581 curr_equiv_class_insn != equiv_class_insn;
6582 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6583 prev_equiv_class_insn = curr_equiv_class_insn;
6584 if (prev_equiv_class_insn != equiv_class_insn)
6585 prev_equiv_class_insn->next_equiv_class_insn
6586 = equiv_class_insn->next_equiv_class_insn;
6587 }
6588
6589 /* The function processes AINSN of a state in order to find equivalent
6590 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6591 state. */
6592 static void
6593 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6594 {
6595 ainsn_t next_insn;
6596 ainsn_t curr_insn;
6597 ainsn_t cyclic_insn_list;
6598 arc_t arc;
6599
6600 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
6601 curr_insn = ainsn;
6602 /* New class of ainsns which are not equivalent to given ainsn. */
6603 cyclic_insn_list = NULL;
6604 do
6605 {
6606 next_insn = curr_insn->next_equiv_class_insn;
6607 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6608 if (arc == NULL
6609 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6610 != arc->to_state))
6611 {
6612 delete_ainsn_from_equiv_class (curr_insn);
6613 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6614 cyclic_insn_list);
6615 }
6616 curr_insn = next_insn;
6617 }
6618 while (curr_insn != ainsn);
6619 }
6620
6621 /* The function processes STATE in order to find equivalent ainsns. */
6622 static void
6623 process_state_for_insn_equiv_partition (state_t state)
6624 {
6625 arc_t arc;
6626 arc_t *insn_arcs_array;
6627 int i;
6628 vla_ptr_t insn_arcs_vect;
6629
6630 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6631 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6632 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6633 /* Process insns of the arcs. */
6634 for (i = 0; i < description->insns_num; i++)
6635 insn_arcs_array [i] = NULL;
6636 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6637 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6638 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6639 process_insn_equiv_class (arc->insn, insn_arcs_array);
6640 VLA_PTR_DELETE (insn_arcs_vect);
6641 }
6642
6643 /* The function searches for equivalent ainsns of AUTOMATON. */
6644 static void
6645 set_insn_equiv_classes (automaton_t automaton)
6646 {
6647 ainsn_t ainsn;
6648 ainsn_t first_insn;
6649 ainsn_t curr_insn;
6650 ainsn_t cyclic_insn_list;
6651 ainsn_t insn_with_same_reservs;
6652 int equiv_classes_num;
6653
6654 /* All insns are included in one equivalence class. */
6655 cyclic_insn_list = NULL;
6656 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6657 if (ainsn->first_insn_with_same_reservs)
6658 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6659 cyclic_insn_list);
6660 /* Process insns in order to make equivalence partition. */
6661 pass_states (automaton, process_state_for_insn_equiv_partition);
6662 /* Enumerate equiv classes. */
6663 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6664 /* Set undefined value. */
6665 ainsn->insn_equiv_class_num = -1;
6666 equiv_classes_num = 0;
6667 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6668 if (ainsn->insn_equiv_class_num < 0)
6669 {
6670 first_insn = ainsn;
6671 gcc_assert (first_insn->first_insn_with_same_reservs);
6672 first_insn->first_ainsn_with_given_equivalence_num = 1;
6673 curr_insn = first_insn;
6674 do
6675 {
6676 for (insn_with_same_reservs = curr_insn;
6677 insn_with_same_reservs != NULL;
6678 insn_with_same_reservs
6679 = insn_with_same_reservs->next_same_reservs_insn)
6680 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6681 curr_insn = curr_insn->next_equiv_class_insn;
6682 }
6683 while (curr_insn != first_insn);
6684 equiv_classes_num++;
6685 }
6686 automaton->insn_equiv_classes_num = equiv_classes_num;
6687 }
6688
6689 \f
6690
6691 /* This page contains code for creating DFA(s) and calls functions
6692 building them. */
6693
6694
6695 /* The following value is used to prevent floating point overflow for
6696 estimating an automaton bound. The value should be less DBL_MAX on
6697 the host machine. We use here approximate minimum of maximal
6698 double floating point value required by ANSI C standard. It
6699 will work for non ANSI sun compiler too. */
6700
6701 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6702
6703 /* The function estimate size of the single DFA used by PHR (pipeline
6704 hazards recognizer). */
6705 static double
6706 estimate_one_automaton_bound (void)
6707 {
6708 decl_t decl;
6709 double one_automaton_estimation_bound;
6710 double root_value;
6711 int i;
6712
6713 one_automaton_estimation_bound = 1.0;
6714 for (i = 0; i < description->decls_num; i++)
6715 {
6716 decl = description->decls [i];
6717 if (decl->mode == dm_unit)
6718 {
6719 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6720 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6721 / automata_num);
6722 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6723 > one_automaton_estimation_bound)
6724 one_automaton_estimation_bound *= root_value;
6725 }
6726 }
6727 return one_automaton_estimation_bound;
6728 }
6729
6730 /* The function compares unit declarations according to their maximal
6731 cycle in reservations. */
6732 static int
6733 compare_max_occ_cycle_nums (const void *unit_decl_1,
6734 const void *unit_decl_2)
6735 {
6736 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6737 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6738 return 1;
6739 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6740 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6741 return 0;
6742 else
6743 return -1;
6744 }
6745
6746 /* The function makes heuristic assigning automata to units. Actually
6747 efficacy of the algorithm has been checked yet??? */
6748 static void
6749 units_to_automata_heuristic_distr (void)
6750 {
6751 double estimation_bound;
6752 decl_t decl;
6753 decl_t *unit_decl_ptr;
6754 int automaton_num;
6755 int rest_units_num;
6756 double bound_value;
6757 vla_ptr_t unit_decls;
6758 int i;
6759
6760 if (description->units_num == 0)
6761 return;
6762 estimation_bound = estimate_one_automaton_bound ();
6763 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6764 for (i = 0; i < description->decls_num; i++)
6765 {
6766 decl = description->decls [i];
6767 if (decl->mode == dm_unit)
6768 VLA_PTR_ADD (unit_decls, decl);
6769 }
6770 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6771 sizeof (decl_t), compare_max_occ_cycle_nums);
6772 automaton_num = 0;
6773 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6774 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6775 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6776 for (unit_decl_ptr++;
6777 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6778 unit_decl_ptr++)
6779 {
6780 rest_units_num
6781 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6782 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
6783 if (automaton_num < automata_num - 1
6784 && ((automata_num - automaton_num - 1 == rest_units_num)
6785 || (bound_value
6786 > (estimation_bound
6787 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6788 {
6789 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6790 automaton_num++;
6791 }
6792 else
6793 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6794 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6795 }
6796 gcc_assert (automaton_num == automata_num - 1);
6797 VLA_PTR_DELETE (unit_decls);
6798 }
6799
6800 /* The functions creates automaton insns for each automata. Automaton
6801 insn is simply insn for given automaton which makes reservation
6802 only of units of the automaton. */
6803 static ainsn_t
6804 create_ainsns (void)
6805 {
6806 decl_t decl;
6807 ainsn_t first_ainsn;
6808 ainsn_t curr_ainsn;
6809 ainsn_t prev_ainsn;
6810 int i;
6811
6812 first_ainsn = NULL;
6813 prev_ainsn = NULL;
6814 for (i = 0; i < description->decls_num; i++)
6815 {
6816 decl = description->decls [i];
6817 if (decl->mode == dm_insn_reserv)
6818 {
6819 curr_ainsn = create_node (sizeof (struct ainsn));
6820 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6821 curr_ainsn->important_p = FALSE;
6822 curr_ainsn->next_ainsn = NULL;
6823 if (prev_ainsn == NULL)
6824 first_ainsn = curr_ainsn;
6825 else
6826 prev_ainsn->next_ainsn = curr_ainsn;
6827 prev_ainsn = curr_ainsn;
6828 }
6829 }
6830 return first_ainsn;
6831 }
6832
6833 /* The function assigns automata to units according to constructions
6834 `define_automaton' in the description. */
6835 static void
6836 units_to_automata_distr (void)
6837 {
6838 decl_t decl;
6839 int i;
6840
6841 for (i = 0; i < description->decls_num; i++)
6842 {
6843 decl = description->decls [i];
6844 if (decl->mode == dm_unit)
6845 {
6846 if (DECL_UNIT (decl)->automaton_decl == NULL
6847 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6848 == NULL))
6849 /* Distribute to the first automaton. */
6850 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6851 else
6852 DECL_UNIT (decl)->corresponding_automaton_num
6853 = (DECL_UNIT (decl)->automaton_decl
6854 ->corresponding_automaton->automaton_order_num);
6855 }
6856 }
6857 }
6858
6859 /* The function creates DFA(s) for fast pipeline hazards recognition
6860 after checking and simplifying IR of the description. */
6861 static void
6862 create_automata (void)
6863 {
6864 automaton_t curr_automaton;
6865 automaton_t prev_automaton;
6866 decl_t decl;
6867 int curr_automaton_num;
6868 int i;
6869
6870 if (automata_num != 0)
6871 {
6872 units_to_automata_heuristic_distr ();
6873 for (prev_automaton = NULL, curr_automaton_num = 0;
6874 curr_automaton_num < automata_num;
6875 curr_automaton_num++, prev_automaton = curr_automaton)
6876 {
6877 curr_automaton = create_node (sizeof (struct automaton));
6878 curr_automaton->ainsn_list = create_ainsns ();
6879 curr_automaton->corresponding_automaton_decl = NULL;
6880 curr_automaton->next_automaton = NULL;
6881 curr_automaton->automaton_order_num = curr_automaton_num;
6882 if (prev_automaton == NULL)
6883 description->first_automaton = curr_automaton;
6884 else
6885 prev_automaton->next_automaton = curr_automaton;
6886 }
6887 }
6888 else
6889 {
6890 curr_automaton_num = 0;
6891 prev_automaton = NULL;
6892 for (i = 0; i < description->decls_num; i++)
6893 {
6894 decl = description->decls [i];
6895 if (decl->mode == dm_automaton
6896 && DECL_AUTOMATON (decl)->automaton_is_used)
6897 {
6898 curr_automaton = create_node (sizeof (struct automaton));
6899 curr_automaton->ainsn_list = create_ainsns ();
6900 curr_automaton->corresponding_automaton_decl
6901 = DECL_AUTOMATON (decl);
6902 curr_automaton->next_automaton = NULL;
6903 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6904 curr_automaton->automaton_order_num = curr_automaton_num;
6905 if (prev_automaton == NULL)
6906 description->first_automaton = curr_automaton;
6907 else
6908 prev_automaton->next_automaton = curr_automaton;
6909 curr_automaton_num++;
6910 prev_automaton = curr_automaton;
6911 }
6912 }
6913 if (curr_automaton_num == 0)
6914 {
6915 curr_automaton = create_node (sizeof (struct automaton));
6916 curr_automaton->ainsn_list = create_ainsns ();
6917 curr_automaton->corresponding_automaton_decl = NULL;
6918 curr_automaton->next_automaton = NULL;
6919 description->first_automaton = curr_automaton;
6920 }
6921 units_to_automata_distr ();
6922 }
6923 NDFA_time = create_ticker ();
6924 ticker_off (&NDFA_time);
6925 NDFA_to_DFA_time = create_ticker ();
6926 ticker_off (&NDFA_to_DFA_time);
6927 minimize_time = create_ticker ();
6928 ticker_off (&minimize_time);
6929 equiv_time = create_ticker ();
6930 ticker_off (&equiv_time);
6931 for (curr_automaton = description->first_automaton;
6932 curr_automaton != NULL;
6933 curr_automaton = curr_automaton->next_automaton)
6934 {
6935 if (progress_flag)
6936 {
6937 if (curr_automaton->corresponding_automaton_decl == NULL)
6938 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6939 else
6940 fprintf (stderr, "Prepare automaton `%s' creation...",
6941 curr_automaton->corresponding_automaton_decl->name);
6942 }
6943 create_alt_states (curr_automaton);
6944 form_ainsn_with_same_reservs (curr_automaton);
6945 if (progress_flag)
6946 fprintf (stderr, "done\n");
6947 build_automaton (curr_automaton);
6948 enumerate_states (curr_automaton);
6949 ticker_on (&equiv_time);
6950 set_insn_equiv_classes (curr_automaton);
6951 ticker_off (&equiv_time);
6952 }
6953 }
6954
6955 \f
6956
6957 /* This page contains code for forming string representation of
6958 regexp. The representation is formed on IR obstack. So you should
6959 not work with IR obstack between regexp_representation and
6960 finish_regexp_representation calls. */
6961
6962 /* This recursive function forms string representation of regexp
6963 (without tailing '\0'). */
6964 static void
6965 form_regexp (regexp_t regexp)
6966 {
6967 int i;
6968
6969 switch (regexp->mode)
6970 {
6971 case rm_unit: case rm_reserv:
6972 {
6973 const char *name = (regexp->mode == rm_unit
6974 ? REGEXP_UNIT (regexp)->name
6975 : REGEXP_RESERV (regexp)->name);
6976
6977 obstack_grow (&irp, name, strlen (name));
6978 break;
6979 }
6980
6981 case rm_sequence:
6982 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6983 {
6984 if (i != 0)
6985 obstack_1grow (&irp, ',');
6986 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6987 }
6988 break;
6989
6990 case rm_allof:
6991 obstack_1grow (&irp, '(');
6992 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6993 {
6994 if (i != 0)
6995 obstack_1grow (&irp, '+');
6996 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6997 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6998 obstack_1grow (&irp, '(');
6999 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
7000 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
7001 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
7002 obstack_1grow (&irp, ')');
7003 }
7004 obstack_1grow (&irp, ')');
7005 break;
7006
7007 case rm_oneof:
7008 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
7009 {
7010 if (i != 0)
7011 obstack_1grow (&irp, '|');
7012 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7013 obstack_1grow (&irp, '(');
7014 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
7015 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7016 obstack_1grow (&irp, ')');
7017 }
7018 break;
7019
7020 case rm_repeat:
7021 {
7022 char digits [30];
7023
7024 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7025 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7026 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7027 obstack_1grow (&irp, '(');
7028 form_regexp (REGEXP_REPEAT (regexp)->regexp);
7029 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7030 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7031 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7032 obstack_1grow (&irp, ')');
7033 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
7034 obstack_grow (&irp, digits, strlen (digits));
7035 break;
7036 }
7037
7038 case rm_nothing:
7039 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
7040 break;
7041
7042 default:
7043 gcc_unreachable ();
7044 }
7045 }
7046
7047 /* The function returns string representation of REGEXP on IR
7048 obstack. */
7049 static const char *
7050 regexp_representation (regexp_t regexp)
7051 {
7052 form_regexp (regexp);
7053 obstack_1grow (&irp, '\0');
7054 return obstack_base (&irp);
7055 }
7056
7057 /* The function frees memory allocated for last formed string
7058 representation of regexp. */
7059 static void
7060 finish_regexp_representation (void)
7061 {
7062 int length = obstack_object_size (&irp);
7063
7064 obstack_blank_fast (&irp, -length);
7065 }
7066
7067 \f
7068
7069 /* This page contains code for output PHR (pipeline hazards recognizer). */
7070
7071 /* The function outputs minimal C type which is sufficient for
7072 representation numbers in range min_range_value and
7073 max_range_value. Because host machine and build machine may be
7074 different, we use here minimal values required by ANSI C standard
7075 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7076 approximation. */
7077
7078 static void
7079 output_range_type (FILE *f, long int min_range_value,
7080 long int max_range_value)
7081 {
7082 if (min_range_value >= 0 && max_range_value <= 255)
7083 fprintf (f, "unsigned char");
7084 else if (min_range_value >= -127 && max_range_value <= 127)
7085 fprintf (f, "signed char");
7086 else if (min_range_value >= 0 && max_range_value <= 65535)
7087 fprintf (f, "unsigned short");
7088 else if (min_range_value >= -32767 && max_range_value <= 32767)
7089 fprintf (f, "short");
7090 else
7091 fprintf (f, "int");
7092 }
7093
7094 /* The following macro value is used as value of member
7095 `longest_path_length' of state when we are processing path and the
7096 state on the path. */
7097
7098 #define ON_THE_PATH -2
7099
7100 /* The following recursive function searches for the length of the
7101 longest path starting from STATE which does not contain cycles and
7102 `cycle advance' arcs. */
7103
7104 static int
7105 longest_path_length (state_t state)
7106 {
7107 arc_t arc;
7108 int length, result;
7109
7110 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7111 {
7112 /* We don't expect the path cycle here. Our graph may contain
7113 only cycles with one state on the path not containing `cycle
7114 advance' arcs -- see comment below. */
7115 gcc_assert (state->longest_path_length != ON_THE_PATH);
7116
7117 /* We already visited the state. */
7118 return state->longest_path_length;
7119 }
7120
7121 result = 0;
7122 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7123 /* Ignore cycles containing one state and `cycle advance' arcs. */
7124 if (arc->to_state != state
7125 && (arc->insn->insn_reserv_decl
7126 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7127 {
7128 length = longest_path_length (arc->to_state);
7129 if (length > result)
7130 result = length;
7131 }
7132 state->longest_path_length = result + 1;
7133 return result;
7134 }
7135
7136 /* The following variable value is value of the corresponding global
7137 variable in the automaton based pipeline interface. */
7138
7139 static int max_dfa_issue_rate;
7140
7141 /* The following function processes the longest path length staring
7142 from STATE to find MAX_DFA_ISSUE_RATE. */
7143
7144 static void
7145 process_state_longest_path_length (state_t state)
7146 {
7147 int value;
7148
7149 value = longest_path_length (state);
7150 if (value > max_dfa_issue_rate)
7151 max_dfa_issue_rate = value;
7152 }
7153
7154 /* The following macro value is name of the corresponding global
7155 variable in the automaton based pipeline interface. */
7156
7157 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7158
7159 /* The following function calculates value of the corresponding
7160 global variable and outputs its declaration. */
7161
7162 static void
7163 output_dfa_max_issue_rate (void)
7164 {
7165 automaton_t automaton;
7166
7167 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
7168 max_dfa_issue_rate = 0;
7169 for (automaton = description->first_automaton;
7170 automaton != NULL;
7171 automaton = automaton->next_automaton)
7172 pass_states (automaton, process_state_longest_path_length);
7173 fprintf (output_file, "\nint %s = %d;\n",
7174 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7175 }
7176
7177 /* The function outputs all initialization values of VECT with length
7178 vect_length. */
7179 static void
7180 output_vect (vect_el_t *vect, int vect_length)
7181 {
7182 int els_on_line;
7183
7184 els_on_line = 1;
7185 if (vect_length == 0)
7186 fprintf (output_file,
7187 "0 /* This is dummy el because the vect is empty */");
7188 else
7189 {
7190 do
7191 {
7192 fprintf (output_file, "%5ld", (long) *vect);
7193 vect_length--;
7194 if (els_on_line == 10)
7195 {
7196 els_on_line = 0;
7197 fprintf (output_file, ",\n");
7198 }
7199 else if (vect_length != 0)
7200 fprintf (output_file, ", ");
7201 els_on_line++;
7202 vect++;
7203 }
7204 while (vect_length != 0);
7205 }
7206 }
7207
7208 /* The following is name of the structure which represents DFA(s) for
7209 PHR. */
7210 #define CHIP_NAME "DFA_chip"
7211
7212 /* The following is name of member which represents state of a DFA for
7213 PHR. */
7214 static void
7215 output_chip_member_name (FILE *f, automaton_t automaton)
7216 {
7217 if (automaton->corresponding_automaton_decl == NULL)
7218 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7219 else
7220 fprintf (f, "%s_automaton_state",
7221 automaton->corresponding_automaton_decl->name);
7222 }
7223
7224 /* The following is name of temporary variable which stores state of a
7225 DFA for PHR. */
7226 static void
7227 output_temp_chip_member_name (FILE *f, automaton_t automaton)
7228 {
7229 fprintf (f, "_");
7230 output_chip_member_name (f, automaton);
7231 }
7232
7233 /* This is name of macro value which is code of pseudo_insn
7234 representing advancing cpu cycle. Its value is used as internal
7235 code unknown insn. */
7236 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7237
7238 /* Output name of translate vector for given automaton. */
7239 static void
7240 output_translate_vect_name (FILE *f, automaton_t automaton)
7241 {
7242 if (automaton->corresponding_automaton_decl == NULL)
7243 fprintf (f, "translate_%d", automaton->automaton_order_num);
7244 else
7245 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7246 }
7247
7248 /* Output name for simple transition table representation. */
7249 static void
7250 output_trans_full_vect_name (FILE *f, automaton_t automaton)
7251 {
7252 if (automaton->corresponding_automaton_decl == NULL)
7253 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7254 else
7255 fprintf (f, "%s_transitions",
7256 automaton->corresponding_automaton_decl->name);
7257 }
7258
7259 /* Output name of comb vector of the transition table for given
7260 automaton. */
7261 static void
7262 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7263 {
7264 if (automaton->corresponding_automaton_decl == NULL)
7265 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7266 else
7267 fprintf (f, "%s_transitions",
7268 automaton->corresponding_automaton_decl->name);
7269 }
7270
7271 /* Output name of check vector of the transition table for given
7272 automaton. */
7273 static void
7274 output_trans_check_vect_name (FILE *f, automaton_t automaton)
7275 {
7276 if (automaton->corresponding_automaton_decl == NULL)
7277 fprintf (f, "check_%d", automaton->automaton_order_num);
7278 else
7279 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7280 }
7281
7282 /* Output name of base vector of the transition table for given
7283 automaton. */
7284 static void
7285 output_trans_base_vect_name (FILE *f, automaton_t automaton)
7286 {
7287 if (automaton->corresponding_automaton_decl == NULL)
7288 fprintf (f, "base_%d", automaton->automaton_order_num);
7289 else
7290 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7291 }
7292
7293 /* Output name for simple alternatives number representation. */
7294 static void
7295 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7296 {
7297 if (automaton->corresponding_automaton_decl == NULL)
7298 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7299 else
7300 fprintf (f, "%s_state_alts",
7301 automaton->corresponding_automaton_decl->name);
7302 }
7303
7304 /* Output name of comb vector of the alternatives number table for given
7305 automaton. */
7306 static void
7307 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7308 {
7309 if (automaton->corresponding_automaton_decl == NULL)
7310 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7311 else
7312 fprintf (f, "%s_state_alts",
7313 automaton->corresponding_automaton_decl->name);
7314 }
7315
7316 /* Output name of check vector of the alternatives number table for given
7317 automaton. */
7318 static void
7319 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7320 {
7321 if (automaton->corresponding_automaton_decl == NULL)
7322 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7323 else
7324 fprintf (f, "%s_check_state_alts",
7325 automaton->corresponding_automaton_decl->name);
7326 }
7327
7328 /* Output name of base vector of the alternatives number table for given
7329 automaton. */
7330 static void
7331 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7332 {
7333 if (automaton->corresponding_automaton_decl == NULL)
7334 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7335 else
7336 fprintf (f, "%s_base_state_alts",
7337 automaton->corresponding_automaton_decl->name);
7338 }
7339
7340 /* Output name of simple min issue delay table representation. */
7341 static void
7342 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7343 {
7344 if (automaton->corresponding_automaton_decl == NULL)
7345 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7346 else
7347 fprintf (f, "%s_min_issue_delay",
7348 automaton->corresponding_automaton_decl->name);
7349 }
7350
7351 /* Output name of deadlock vector for given automaton. */
7352 static void
7353 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7354 {
7355 if (automaton->corresponding_automaton_decl == NULL)
7356 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7357 else
7358 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7359 }
7360
7361 /* Output name of reserved units table for AUTOMATON into file F. */
7362 static void
7363 output_reserved_units_table_name (FILE *f, automaton_t automaton)
7364 {
7365 if (automaton->corresponding_automaton_decl == NULL)
7366 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7367 else
7368 fprintf (f, "%s_reserved_units",
7369 automaton->corresponding_automaton_decl->name);
7370 }
7371
7372 /* Name of the PHR interface macro. */
7373 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7374
7375 /* Name of the PHR interface macro. */
7376 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7377
7378 /* Names of an internal functions: */
7379 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7380
7381 /* This is external type of DFA(s) state. */
7382 #define STATE_TYPE_NAME "state_t"
7383
7384 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7385
7386 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7387
7388 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7389
7390 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7391
7392 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7393
7394 /* Name of cache of insn dfa codes. */
7395 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7396
7397 /* Name of length of cache of insn dfa codes. */
7398 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7399
7400 /* Names of the PHR interface functions: */
7401 #define SIZE_FUNC_NAME "state_size"
7402
7403 #define TRANSITION_FUNC_NAME "state_transition"
7404
7405 #define STATE_ALTS_FUNC_NAME "state_alts"
7406
7407 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7408
7409 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7410
7411 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7412
7413 #define RESET_FUNC_NAME "state_reset"
7414
7415 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7416
7417 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7418
7419 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7420
7421 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7422
7423 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7424
7425 #define DFA_START_FUNC_NAME "dfa_start"
7426
7427 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7428
7429 /* Names of parameters of the PHR interface functions. */
7430 #define STATE_NAME "state"
7431
7432 #define INSN_PARAMETER_NAME "insn"
7433
7434 #define INSN2_PARAMETER_NAME "insn2"
7435
7436 #define CHIP_PARAMETER_NAME "chip"
7437
7438 #define FILE_PARAMETER_NAME "f"
7439
7440 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7441
7442 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7443
7444 /* Names of the variables whose values are internal insn code of rtx
7445 insn. */
7446 #define INTERNAL_INSN_CODE_NAME "insn_code"
7447
7448 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7449
7450 /* Names of temporary variables in some functions. */
7451 #define TEMPORARY_VARIABLE_NAME "temp"
7452
7453 #define I_VARIABLE_NAME "i"
7454
7455 /* Name of result variable in some functions. */
7456 #define RESULT_VARIABLE_NAME "res"
7457
7458 /* Name of function (attribute) to translate insn into internal insn
7459 code. */
7460 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7461
7462 /* Name of function (attribute) to translate insn into internal insn
7463 code with caching. */
7464 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7465
7466 /* Name of function (attribute) to translate insn into internal insn
7467 code. */
7468 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7469
7470 /* Name of function (attribute) to translate insn into internal insn
7471 code. */
7472 #define BYPASS_P_FUNC_NAME "bypass_p"
7473
7474 /* Output C type which is used for representation of codes of states
7475 of AUTOMATON. */
7476 static void
7477 output_state_member_type (FILE *f, automaton_t automaton)
7478 {
7479 output_range_type (f, 0, automaton->achieved_states_num);
7480 }
7481
7482 /* Output definition of the structure representing current DFA(s)
7483 state(s). */
7484 static void
7485 output_chip_definitions (void)
7486 {
7487 automaton_t automaton;
7488
7489 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7490 for (automaton = description->first_automaton;
7491 automaton != NULL;
7492 automaton = automaton->next_automaton)
7493 {
7494 fprintf (output_file, " ");
7495 output_state_member_type (output_file, automaton);
7496 fprintf (output_file, " ");
7497 output_chip_member_name (output_file, automaton);
7498 fprintf (output_file, ";\n");
7499 }
7500 fprintf (output_file, "};\n\n");
7501 #if 0
7502 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7503 #endif
7504 }
7505
7506
7507 /* The function outputs translate vector of internal insn code into
7508 insn equivalence class number. The equivalence class number is
7509 used to access to table and vectors representing DFA(s). */
7510 static void
7511 output_translate_vect (automaton_t automaton)
7512 {
7513 ainsn_t ainsn;
7514 int insn_value;
7515 vla_hwint_t translate_vect;
7516
7517 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7518 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7519 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7520 /* Undefined value */
7521 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7522 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7523 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7524 = ainsn->insn_equiv_class_num;
7525 fprintf (output_file,
7526 "/* Vector translating external insn codes to internal ones.*/\n");
7527 fprintf (output_file, "static const ");
7528 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7529 fprintf (output_file, " ");
7530 output_translate_vect_name (output_file, automaton);
7531 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7532 output_vect (VLA_HWINT_BEGIN (translate_vect),
7533 VLA_HWINT_LENGTH (translate_vect));
7534 fprintf (output_file, "};\n\n");
7535 VLA_HWINT_DELETE (translate_vect);
7536 }
7537
7538 /* The value in a table state x ainsn -> something which represents
7539 undefined value. */
7540 static int undefined_vect_el_value;
7541
7542 /* The following function returns nonzero value if the best
7543 representation of the table is comb vector. */
7544 static int
7545 comb_vect_p (state_ainsn_table_t tab)
7546 {
7547 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7548 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7549 }
7550
7551 /* The following function creates new table for AUTOMATON. */
7552 static state_ainsn_table_t
7553 create_state_ainsn_table (automaton_t automaton)
7554 {
7555 state_ainsn_table_t tab;
7556 int full_vect_length;
7557 int i;
7558
7559 tab = create_node (sizeof (struct state_ainsn_table));
7560 tab->automaton = automaton;
7561 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7562 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7563 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7564 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7565 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7566 full_vect_length = (automaton->insn_equiv_classes_num
7567 * automaton->achieved_states_num);
7568 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7569 for (i = 0; i < full_vect_length; i++)
7570 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7571 tab->min_base_vect_el_value = 0;
7572 tab->max_base_vect_el_value = 0;
7573 tab->min_comb_vect_el_value = 0;
7574 tab->max_comb_vect_el_value = 0;
7575 return tab;
7576 }
7577
7578 /* The following function outputs the best C representation of the
7579 table TAB of given TABLE_NAME. */
7580 static void
7581 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
7582 void (*output_full_vect_name_func) (FILE *, automaton_t),
7583 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7584 void (*output_check_vect_name_func) (FILE *, automaton_t),
7585 void (*output_base_vect_name_func) (FILE *, automaton_t))
7586 {
7587 if (!comb_vect_p (tab))
7588 {
7589 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7590 fprintf (output_file, "static const ");
7591 output_range_type (output_file, tab->min_comb_vect_el_value,
7592 tab->max_comb_vect_el_value);
7593 fprintf (output_file, " ");
7594 (*output_full_vect_name_func) (output_file, tab->automaton);
7595 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7596 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7597 VLA_HWINT_LENGTH (tab->full_vect));
7598 fprintf (output_file, "};\n\n");
7599 }
7600 else
7601 {
7602 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7603 fprintf (output_file, "static const ");
7604 output_range_type (output_file, tab->min_comb_vect_el_value,
7605 tab->max_comb_vect_el_value);
7606 fprintf (output_file, " ");
7607 (*output_comb_vect_name_func) (output_file, tab->automaton);
7608 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7609 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7610 VLA_HWINT_LENGTH (tab->comb_vect));
7611 fprintf (output_file, "};\n\n");
7612 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7613 fprintf (output_file, "static const ");
7614 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7615 fprintf (output_file, " ");
7616 (*output_check_vect_name_func) (output_file, tab->automaton);
7617 fprintf (output_file, "[] = {\n");
7618 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7619 VLA_HWINT_LENGTH (tab->check_vect));
7620 fprintf (output_file, "};\n\n");
7621 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7622 fprintf (output_file, "static const ");
7623 output_range_type (output_file, tab->min_base_vect_el_value,
7624 tab->max_base_vect_el_value);
7625 fprintf (output_file, " ");
7626 (*output_base_vect_name_func) (output_file, tab->automaton);
7627 fprintf (output_file, "[] = {\n");
7628 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7629 VLA_HWINT_LENGTH (tab->base_vect));
7630 fprintf (output_file, "};\n\n");
7631 }
7632 }
7633
7634 /* The following function adds vector with length VECT_LENGTH and
7635 elements pointed to by VECT to table TAB as its line with number
7636 VECT_NUM. */
7637 static void
7638 add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
7639 int vect_length)
7640 {
7641 int real_vect_length;
7642 vect_el_t *comb_vect_start;
7643 vect_el_t *check_vect_start;
7644 int comb_vect_index;
7645 int comb_vect_els_num;
7646 int vect_index;
7647 int first_unempty_vect_index;
7648 int additional_els_num;
7649 int no_state_value;
7650 vect_el_t vect_el;
7651 int i;
7652 unsigned long vect_mask, comb_vect_mask;
7653
7654 gcc_assert (vect_length);
7655 real_vect_length = tab->automaton->insn_equiv_classes_num;
7656 gcc_assert (vect [vect_length - 1] != undefined_vect_el_value);
7657 /* Form full vector in the table: */
7658 for (i = 0; i < vect_length; i++)
7659 VLA_HWINT (tab->full_vect,
7660 i + tab->automaton->insn_equiv_classes_num * vect_num)
7661 = vect [i];
7662 /* Form comb vector in the table: */
7663 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7664 == VLA_HWINT_LENGTH (tab->check_vect));
7665 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7666 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7667 for (first_unempty_vect_index = 0;
7668 first_unempty_vect_index < vect_length;
7669 first_unempty_vect_index++)
7670 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7671 break;
7672
7673 /* Search for the place in comb vect for the inserted vect. */
7674
7675 /* Slow case. */
7676 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7677 {
7678 for (comb_vect_index = 0;
7679 comb_vect_index < comb_vect_els_num;
7680 comb_vect_index++)
7681 {
7682 for (vect_index = first_unempty_vect_index;
7683 vect_index < vect_length
7684 && vect_index + comb_vect_index < comb_vect_els_num;
7685 vect_index++)
7686 if (vect [vect_index] != undefined_vect_el_value
7687 && (comb_vect_start [vect_index + comb_vect_index]
7688 != undefined_vect_el_value))
7689 break;
7690 if (vect_index >= vect_length
7691 || vect_index + comb_vect_index >= comb_vect_els_num)
7692 break;
7693 }
7694 goto found;
7695 }
7696
7697 /* Fast case. */
7698 vect_mask = 0;
7699 for (vect_index = first_unempty_vect_index;
7700 vect_index < vect_length;
7701 vect_index++)
7702 {
7703 vect_mask = vect_mask << 1;
7704 if (vect [vect_index] != undefined_vect_el_value)
7705 vect_mask |= 1;
7706 }
7707
7708 /* Search for the place in comb vect for the inserted vect. */
7709 comb_vect_index = 0;
7710 if (comb_vect_els_num == 0)
7711 goto found;
7712
7713 comb_vect_mask = 0;
7714 for (vect_index = first_unempty_vect_index;
7715 vect_index < vect_length && vect_index < comb_vect_els_num;
7716 vect_index++)
7717 {
7718 comb_vect_mask <<= 1;
7719 if (vect_index + comb_vect_index < comb_vect_els_num
7720 && comb_vect_start [vect_index + comb_vect_index]
7721 != undefined_vect_el_value)
7722 comb_vect_mask |= 1;
7723 }
7724 if ((vect_mask & comb_vect_mask) == 0)
7725 goto found;
7726
7727 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7728 comb_vect_index++, i++)
7729 {
7730 comb_vect_mask = (comb_vect_mask << 1) | 1;
7731 comb_vect_mask ^= comb_vect_start [i] == undefined_vect_el_value;
7732 if ((vect_mask & comb_vect_mask) == 0)
7733 goto found;
7734 }
7735 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7736 {
7737 comb_vect_mask <<= 1;
7738 if ((vect_mask & comb_vect_mask) == 0)
7739 goto found;
7740 }
7741
7742 found:
7743 /* Slot was found. */
7744 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7745 if (additional_els_num < 0)
7746 additional_els_num = 0;
7747 /* Expand comb and check vectors. */
7748 vect_el = undefined_vect_el_value;
7749 no_state_value = tab->automaton->achieved_states_num;
7750 while (additional_els_num > 0)
7751 {
7752 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7753 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7754 additional_els_num--;
7755 }
7756 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7757 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7758 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
7759 >= (size_t) (comb_vect_index + real_vect_length));
7760 /* Fill comb and check vectors. */
7761 for (vect_index = 0; vect_index < vect_length; vect_index++)
7762 if (vect [vect_index] != undefined_vect_el_value)
7763 {
7764 gcc_assert (comb_vect_start [comb_vect_index + vect_index]
7765 == undefined_vect_el_value);
7766 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7767 gcc_assert (vect [vect_index] >= 0);
7768 if (tab->max_comb_vect_el_value < vect [vect_index])
7769 tab->max_comb_vect_el_value = vect [vect_index];
7770 if (tab->min_comb_vect_el_value > vect [vect_index])
7771 tab->min_comb_vect_el_value = vect [vect_index];
7772 check_vect_start [comb_vect_index + vect_index] = vect_num;
7773 }
7774 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7775 tab->max_comb_vect_el_value = undefined_vect_el_value;
7776 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7777 tab->min_comb_vect_el_value = undefined_vect_el_value;
7778 if (tab->max_base_vect_el_value < comb_vect_index)
7779 tab->max_base_vect_el_value = comb_vect_index;
7780 if (tab->min_base_vect_el_value > comb_vect_index)
7781 tab->min_base_vect_el_value = comb_vect_index;
7782 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7783 }
7784
7785 /* Return number of out arcs of STATE. */
7786 static int
7787 out_state_arcs_num (state_t state)
7788 {
7789 int result;
7790 arc_t arc;
7791
7792 result = 0;
7793 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7794 {
7795 gcc_assert (arc->insn);
7796 if (arc->insn->first_ainsn_with_given_equivalence_num)
7797 result++;
7798 }
7799 return result;
7800 }
7801
7802 /* Compare number of possible transitions from the states. */
7803 static int
7804 compare_transition_els_num (const void *state_ptr_1,
7805 const void *state_ptr_2)
7806 {
7807 int transition_els_num_1;
7808 int transition_els_num_2;
7809
7810 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7811 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7812 if (transition_els_num_1 < transition_els_num_2)
7813 return 1;
7814 else if (transition_els_num_1 == transition_els_num_2)
7815 return 0;
7816 else
7817 return -1;
7818 }
7819
7820 /* The function adds element EL_VALUE to vector VECT for a table state
7821 x AINSN. */
7822 static void
7823 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7824 {
7825 int equiv_class_num;
7826 int vect_index;
7827
7828 gcc_assert (ainsn);
7829 equiv_class_num = ainsn->insn_equiv_class_num;
7830 for (vect_index = VLA_HWINT_LENGTH (*vect);
7831 vect_index <= equiv_class_num;
7832 vect_index++)
7833 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7834 VLA_HWINT (*vect, equiv_class_num) = el_value;
7835 }
7836
7837 /* This is for forming vector of states of an automaton. */
7838 static vla_ptr_t output_states_vect;
7839
7840 /* The function is called by function pass_states. The function adds
7841 STATE to `output_states_vect'. */
7842 static void
7843 add_states_vect_el (state_t state)
7844 {
7845 VLA_PTR_ADD (output_states_vect, state);
7846 }
7847
7848 /* Form and output vectors (comb, check, base or full vector)
7849 representing transition table of AUTOMATON. */
7850 static void
7851 output_trans_table (automaton_t automaton)
7852 {
7853 state_t *state_ptr;
7854 arc_t arc;
7855 vla_hwint_t transition_vect;
7856
7857 undefined_vect_el_value = automaton->achieved_states_num;
7858 automaton->trans_table = create_state_ainsn_table (automaton);
7859 /* Create vect of pointers to states ordered by num of transitions
7860 from the state (state with the maximum num is the first). */
7861 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7862 pass_states (automaton, add_states_vect_el);
7863 qsort (VLA_PTR_BEGIN (output_states_vect),
7864 VLA_PTR_LENGTH (output_states_vect),
7865 sizeof (state_t), compare_transition_els_num);
7866 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7867 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7868 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7869 state_ptr++)
7870 {
7871 VLA_HWINT_NULLIFY (transition_vect);
7872 for (arc = first_out_arc (*state_ptr);
7873 arc != NULL;
7874 arc = next_out_arc (arc))
7875 {
7876 gcc_assert (arc->insn);
7877 if (arc->insn->first_ainsn_with_given_equivalence_num)
7878 add_vect_el (&transition_vect, arc->insn,
7879 arc->to_state->order_state_num);
7880 }
7881 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7882 VLA_HWINT_BEGIN (transition_vect),
7883 VLA_HWINT_LENGTH (transition_vect));
7884 }
7885 output_state_ainsn_table
7886 (automaton->trans_table, (char *) "state transitions",
7887 output_trans_full_vect_name, output_trans_comb_vect_name,
7888 output_trans_check_vect_name, output_trans_base_vect_name);
7889 VLA_PTR_DELETE (output_states_vect);
7890 VLA_HWINT_DELETE (transition_vect);
7891 }
7892
7893 /* Form and output vectors (comb, check, base or simple vect)
7894 representing alts number table of AUTOMATON. The table is state x
7895 ainsn -> number of possible alternative reservations by the
7896 ainsn. */
7897 static void
7898 output_state_alts_table (automaton_t automaton)
7899 {
7900 state_t *state_ptr;
7901 arc_t arc;
7902 vla_hwint_t state_alts_vect;
7903
7904 undefined_vect_el_value = 0; /* no alts when transition is not possible */
7905 automaton->state_alts_table = create_state_ainsn_table (automaton);
7906 /* Create vect of pointers to states ordered by num of transitions
7907 from the state (state with the maximum num is the first). */
7908 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7909 pass_states (automaton, add_states_vect_el);
7910 qsort (VLA_PTR_BEGIN (output_states_vect),
7911 VLA_PTR_LENGTH (output_states_vect),
7912 sizeof (state_t), compare_transition_els_num);
7913 /* Create base, comb, and check vectors. */
7914 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7915 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7916 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7917 state_ptr++)
7918 {
7919 VLA_HWINT_NULLIFY (state_alts_vect);
7920 for (arc = first_out_arc (*state_ptr);
7921 arc != NULL;
7922 arc = next_out_arc (arc))
7923 {
7924 gcc_assert (arc->insn);
7925 if (arc->insn->first_ainsn_with_given_equivalence_num)
7926 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7927 }
7928 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7929 VLA_HWINT_BEGIN (state_alts_vect),
7930 VLA_HWINT_LENGTH (state_alts_vect));
7931 }
7932 output_state_ainsn_table
7933 (automaton->state_alts_table, (char *) "state insn alternatives",
7934 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7935 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7936 VLA_PTR_DELETE (output_states_vect);
7937 VLA_HWINT_DELETE (state_alts_vect);
7938 }
7939
7940 /* The current number of passing states to find minimal issue delay
7941 value for an ainsn and state. */
7942 static int curr_state_pass_num;
7943
7944 /* This recursive function passes states to find minimal issue delay
7945 value for AINSN. The state being visited is STATE. The function
7946 returns minimal issue delay value for AINSN in STATE or -1 if we
7947 enter into a loop. */
7948 static int
7949 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7950 {
7951 arc_t arc;
7952 int min_insn_issue_delay, insn_issue_delay;
7953
7954 if (state->state_pass_num == curr_state_pass_num
7955 || state->min_insn_issue_delay != -1)
7956 /* We've entered into a loop or already have the correct value for
7957 given state and ainsn. */
7958 return state->min_insn_issue_delay;
7959 state->state_pass_num = curr_state_pass_num;
7960 min_insn_issue_delay = -1;
7961 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7962 if (arc->insn == ainsn)
7963 {
7964 min_insn_issue_delay = 0;
7965 break;
7966 }
7967 else
7968 {
7969 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7970 if (insn_issue_delay != -1)
7971 {
7972 if (arc->insn->insn_reserv_decl
7973 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7974 insn_issue_delay++;
7975 if (min_insn_issue_delay == -1
7976 || min_insn_issue_delay > insn_issue_delay)
7977 {
7978 min_insn_issue_delay = insn_issue_delay;
7979 if (insn_issue_delay == 0)
7980 break;
7981 }
7982 }
7983 }
7984 return min_insn_issue_delay;
7985 }
7986
7987 /* The function searches minimal issue delay value for AINSN in STATE.
7988 The function can return negative value if we can not issue AINSN. We
7989 will report about it later. */
7990 static int
7991 min_issue_delay (state_t state, ainsn_t ainsn)
7992 {
7993 curr_state_pass_num++;
7994 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7995 return state->min_insn_issue_delay;
7996 }
7997
7998 /* The function initiates code for finding minimal issue delay values.
7999 It should be called only once. */
8000 static void
8001 initiate_min_issue_delay_pass_states (void)
8002 {
8003 curr_state_pass_num = 0;
8004 }
8005
8006 /* Form and output vectors representing minimal issue delay table of
8007 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8008 the ainsn. */
8009 static void
8010 output_min_issue_delay_table (automaton_t automaton)
8011 {
8012 vla_hwint_t min_issue_delay_vect;
8013 vla_hwint_t compressed_min_issue_delay_vect;
8014 vect_el_t min_delay;
8015 ainsn_t ainsn;
8016 state_t *state_ptr;
8017 int i;
8018
8019 /* Create vect of pointers to states ordered by num of transitions
8020 from the state (state with the maximum num is the first). */
8021 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8022 pass_states (automaton, add_states_vect_el);
8023 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
8024 VLA_HWINT_EXPAND (min_issue_delay_vect,
8025 VLA_HWINT_LENGTH (output_states_vect)
8026 * automaton->insn_equiv_classes_num);
8027 for (i = 0;
8028 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
8029 * automaton->insn_equiv_classes_num);
8030 i++)
8031 VLA_HWINT (min_issue_delay_vect, i) = 0;
8032 automaton->max_min_delay = 0;
8033 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
8034 if (ainsn->first_ainsn_with_given_equivalence_num)
8035 {
8036 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8037 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8038 state_ptr++)
8039 (*state_ptr)->min_insn_issue_delay = -1;
8040 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8041 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8042 state_ptr++)
8043 {
8044 min_delay = min_issue_delay (*state_ptr, ainsn);
8045 if (automaton->max_min_delay < min_delay)
8046 automaton->max_min_delay = min_delay;
8047 VLA_HWINT (min_issue_delay_vect,
8048 (*state_ptr)->order_state_num
8049 * automaton->insn_equiv_classes_num
8050 + ainsn->insn_equiv_class_num) = min_delay;
8051 }
8052 }
8053 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
8054 fprintf (output_file, "static const ");
8055 output_range_type (output_file, 0, automaton->max_min_delay);
8056 fprintf (output_file, " ");
8057 output_min_issue_delay_vect_name (output_file, automaton);
8058 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
8059 /* Compress the vector. */
8060 if (automaton->max_min_delay < 2)
8061 automaton->min_issue_delay_table_compression_factor = 8;
8062 else if (automaton->max_min_delay < 4)
8063 automaton->min_issue_delay_table_compression_factor = 4;
8064 else if (automaton->max_min_delay < 16)
8065 automaton->min_issue_delay_table_compression_factor = 2;
8066 else
8067 automaton->min_issue_delay_table_compression_factor = 1;
8068 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
8069 "compressed min issue delay vector");
8070 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
8071 (VLA_HWINT_LENGTH (min_issue_delay_vect)
8072 + automaton->min_issue_delay_table_compression_factor
8073 - 1)
8074 / automaton->min_issue_delay_table_compression_factor);
8075 for (i = 0;
8076 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
8077 i++)
8078 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
8079 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
8080 VLA_HWINT (compressed_min_issue_delay_vect,
8081 i / automaton->min_issue_delay_table_compression_factor)
8082 |= (VLA_HWINT (min_issue_delay_vect, i)
8083 << (8 - (i % automaton->min_issue_delay_table_compression_factor
8084 + 1)
8085 * (8 / automaton->min_issue_delay_table_compression_factor)));
8086 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
8087 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
8088 fprintf (output_file, "};\n\n");
8089 VLA_PTR_DELETE (output_states_vect);
8090 VLA_HWINT_DELETE (min_issue_delay_vect);
8091 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
8092 }
8093
8094 #ifndef NDEBUG
8095 /* Number of states which contains transition only by advancing cpu
8096 cycle. */
8097 static int locked_states_num;
8098 #endif
8099
8100 /* Form and output vector representing the locked states of
8101 AUTOMATON. */
8102 static void
8103 output_dead_lock_vect (automaton_t automaton)
8104 {
8105 state_t *state_ptr;
8106 arc_t arc;
8107 vla_hwint_t dead_lock_vect;
8108
8109 /* Create vect of pointers to states ordered by num of
8110 transitions from the state (state with the maximum num is the
8111 first). */
8112 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8113 pass_states (automaton, add_states_vect_el);
8114 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
8115 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
8116 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8117 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8118 state_ptr++)
8119 {
8120 arc = first_out_arc (*state_ptr);
8121 gcc_assert (arc);
8122 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8123 = (next_out_arc (arc) == NULL
8124 && (arc->insn->insn_reserv_decl
8125 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8126 #ifndef NDEBUG
8127 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8128 locked_states_num++;
8129 #endif
8130 }
8131 fprintf (output_file, "/* Vector for locked state flags. */\n");
8132 fprintf (output_file, "static const ");
8133 output_range_type (output_file, 0, 1);
8134 fprintf (output_file, " ");
8135 output_dead_lock_vect_name (output_file, automaton);
8136 fprintf (output_file, "[] = {\n");
8137 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8138 VLA_HWINT_LENGTH (dead_lock_vect));
8139 fprintf (output_file, "};\n\n");
8140 VLA_HWINT_DELETE (dead_lock_vect);
8141 VLA_PTR_DELETE (output_states_vect);
8142 }
8143
8144 /* Form and output vector representing reserved units of the states of
8145 AUTOMATON. */
8146 static void
8147 output_reserved_units_table (automaton_t automaton)
8148 {
8149 state_t *curr_state_ptr;
8150 vla_hwint_t reserved_units_table;
8151 size_t state_byte_size;
8152 int i;
8153
8154 /* Create vect of pointers to states. */
8155 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8156 pass_states (automaton, add_states_vect_el);
8157 /* Create vector. */
8158 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8159 state_byte_size = (description->query_units_num + 7) / 8;
8160 VLA_HWINT_EXPAND (reserved_units_table,
8161 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8162 for (i = 0;
8163 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8164 i++)
8165 VLA_HWINT (reserved_units_table, i) = 0;
8166 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8167 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8168 curr_state_ptr++)
8169 {
8170 for (i = 0; i < description->units_num; i++)
8171 if (units_array [i]->query_p
8172 && first_cycle_unit_presence (*curr_state_ptr, i))
8173 VLA_HWINT (reserved_units_table,
8174 (*curr_state_ptr)->order_state_num * state_byte_size
8175 + units_array [i]->query_num / 8)
8176 += (1 << (units_array [i]->query_num % 8));
8177 }
8178 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8179 fprintf (output_file, "static const ");
8180 output_range_type (output_file, 0, 255);
8181 fprintf (output_file, " ");
8182 output_reserved_units_table_name (output_file, automaton);
8183 fprintf (output_file, "[] = {\n");
8184 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8185 VLA_HWINT_LENGTH (reserved_units_table));
8186 fprintf (output_file, "};\n\n");
8187 VLA_HWINT_DELETE (reserved_units_table);
8188 VLA_PTR_DELETE (output_states_vect);
8189 }
8190
8191 /* The function outputs all tables representing DFA(s) used for fast
8192 pipeline hazards recognition. */
8193 static void
8194 output_tables (void)
8195 {
8196 automaton_t automaton;
8197
8198 #ifndef NDEBUG
8199 locked_states_num = 0;
8200 #endif
8201 initiate_min_issue_delay_pass_states ();
8202 for (automaton = description->first_automaton;
8203 automaton != NULL;
8204 automaton = automaton->next_automaton)
8205 {
8206 output_translate_vect (automaton);
8207 output_trans_table (automaton);
8208 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8209 output_state_alts_table (automaton);
8210 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8211 AUTOMATON_STATE_ALTS_MACRO_NAME);
8212 output_min_issue_delay_table (automaton);
8213 output_dead_lock_vect (automaton);
8214 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8215 output_reserved_units_table (automaton);
8216 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8217 CPU_UNITS_QUERY_MACRO_NAME);
8218 }
8219 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8220 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8221 }
8222
8223 /* The function outputs definition and value of PHR interface variable
8224 `max_insn_queue_index'. Its value is not less than maximal queue
8225 length needed for the insn scheduler. */
8226 static void
8227 output_max_insn_queue_index_def (void)
8228 {
8229 int i, max, latency;
8230 decl_t decl;
8231
8232 max = description->max_insn_reserv_cycles;
8233 for (i = 0; i < description->decls_num; i++)
8234 {
8235 decl = description->decls [i];
8236 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8237 {
8238 latency = DECL_INSN_RESERV (decl)->default_latency;
8239 if (latency > max)
8240 max = latency;
8241 }
8242 else if (decl->mode == dm_bypass)
8243 {
8244 latency = DECL_BYPASS (decl)->latency;
8245 if (latency > max)
8246 max = latency;
8247 }
8248 }
8249 for (i = 0; (1 << i) <= max; i++)
8250 ;
8251 gcc_assert (i >= 0);
8252 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8253 }
8254
8255
8256 /* The function outputs switch cases for insn reservations using
8257 function *output_automata_list_code. */
8258 static void
8259 output_insn_code_cases (void (*output_automata_list_code)
8260 (automata_list_el_t))
8261 {
8262 decl_t decl, decl2;
8263 int i, j;
8264
8265 for (i = 0; i < description->decls_num; i++)
8266 {
8267 decl = description->decls [i];
8268 if (decl->mode == dm_insn_reserv)
8269 DECL_INSN_RESERV (decl)->processed_p = FALSE;
8270 }
8271 for (i = 0; i < description->decls_num; i++)
8272 {
8273 decl = description->decls [i];
8274 if (decl->mode == dm_insn_reserv
8275 && !DECL_INSN_RESERV (decl)->processed_p)
8276 {
8277 for (j = i; j < description->decls_num; j++)
8278 {
8279 decl2 = description->decls [j];
8280 if (decl2->mode == dm_insn_reserv
8281 && (DECL_INSN_RESERV (decl2)->important_automata_list
8282 == DECL_INSN_RESERV (decl)->important_automata_list))
8283 {
8284 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8285 fprintf (output_file, " case %d: /* %s */\n",
8286 DECL_INSN_RESERV (decl2)->insn_num,
8287 DECL_INSN_RESERV (decl2)->name);
8288 }
8289 }
8290 (*output_automata_list_code)
8291 (DECL_INSN_RESERV (decl)->important_automata_list);
8292 }
8293 }
8294 }
8295
8296
8297 /* The function outputs a code for evaluation of a minimal delay of
8298 issue of insns which have reservations in given AUTOMATA_LIST. */
8299 static void
8300 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8301 {
8302 automata_list_el_t el;
8303 automaton_t automaton;
8304
8305 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8306 {
8307 automaton = el->automaton;
8308 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8309 output_min_issue_delay_vect_name (output_file, automaton);
8310 fprintf (output_file,
8311 (automaton->min_issue_delay_table_compression_factor != 1
8312 ? " [(" : " ["));
8313 output_translate_vect_name (output_file, automaton);
8314 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8315 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8316 output_chip_member_name (output_file, automaton);
8317 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8318 if (automaton->min_issue_delay_table_compression_factor == 1)
8319 fprintf (output_file, "];\n");
8320 else
8321 {
8322 fprintf (output_file, ") / %d];\n",
8323 automaton->min_issue_delay_table_compression_factor);
8324 fprintf (output_file, " %s = (%s >> (8 - (",
8325 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8326 output_translate_vect_name (output_file, automaton);
8327 fprintf
8328 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8329 INTERNAL_INSN_CODE_NAME,
8330 automaton->min_issue_delay_table_compression_factor,
8331 8 / automaton->min_issue_delay_table_compression_factor,
8332 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8333 - 1);
8334 }
8335 if (el == automata_list)
8336 fprintf (output_file, " %s = %s;\n",
8337 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8338 else
8339 {
8340 fprintf (output_file, " if (%s > %s)\n",
8341 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8342 fprintf (output_file, " %s = %s;\n",
8343 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8344 }
8345 }
8346 fprintf (output_file, " break;\n\n");
8347 }
8348
8349 /* Output function `internal_min_issue_delay'. */
8350 static void
8351 output_internal_min_issue_delay_func (void)
8352 {
8353 fprintf (output_file,
8354 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8355 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8356 CHIP_NAME, CHIP_PARAMETER_NAME);
8357 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8358 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8359 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8360 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8361 fprintf (output_file,
8362 "\n default:\n %s = -1;\n break;\n }\n",
8363 RESULT_VARIABLE_NAME);
8364 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8365 fprintf (output_file, "}\n\n");
8366 }
8367
8368 /* The function outputs a code changing state after issue of insns
8369 which have reservations in given AUTOMATA_LIST. */
8370 static void
8371 output_automata_list_transition_code (automata_list_el_t automata_list)
8372 {
8373 automata_list_el_t el, next_el;
8374
8375 fprintf (output_file, " {\n");
8376 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8377 for (el = automata_list;; el = next_el)
8378 {
8379 next_el = el->next_automata_list_el;
8380 if (next_el == NULL)
8381 break;
8382 fprintf (output_file, " ");
8383 output_state_member_type (output_file, el->automaton);
8384 fprintf (output_file, " ");
8385 output_temp_chip_member_name (output_file, el->automaton);
8386 fprintf (output_file, ";\n");
8387 }
8388 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8389 if (comb_vect_p (el->automaton->trans_table))
8390 {
8391 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8392 output_trans_base_vect_name (output_file, el->automaton);
8393 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8394 output_chip_member_name (output_file, el->automaton);
8395 fprintf (output_file, "] + ");
8396 output_translate_vect_name (output_file, el->automaton);
8397 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8398 fprintf (output_file, " if (");
8399 output_trans_check_vect_name (output_file, el->automaton);
8400 fprintf (output_file, " [%s] != %s->",
8401 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8402 output_chip_member_name (output_file, el->automaton);
8403 fprintf (output_file, ")\n");
8404 fprintf (output_file, " return %s (%s, %s);\n",
8405 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8406 CHIP_PARAMETER_NAME);
8407 fprintf (output_file, " else\n");
8408 fprintf (output_file, " ");
8409 if (el->next_automata_list_el != NULL)
8410 output_temp_chip_member_name (output_file, el->automaton);
8411 else
8412 {
8413 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8414 output_chip_member_name (output_file, el->automaton);
8415 }
8416 fprintf (output_file, " = ");
8417 output_trans_comb_vect_name (output_file, el->automaton);
8418 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8419 }
8420 else
8421 {
8422 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8423 output_trans_full_vect_name (output_file, el->automaton);
8424 fprintf (output_file, " [");
8425 output_translate_vect_name (output_file, el->automaton);
8426 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8427 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8428 output_chip_member_name (output_file, el->automaton);
8429 fprintf (output_file, " * %d];\n",
8430 el->automaton->insn_equiv_classes_num);
8431 fprintf (output_file, " if (%s >= %d)\n",
8432 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8433 fprintf (output_file, " return %s (%s, %s);\n",
8434 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8435 CHIP_PARAMETER_NAME);
8436 fprintf (output_file, " else\n ");
8437 if (el->next_automata_list_el != NULL)
8438 output_temp_chip_member_name (output_file, el->automaton);
8439 else
8440 {
8441 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8442 output_chip_member_name (output_file, el->automaton);
8443 }
8444 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8445 }
8446 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8447 for (el = automata_list;; el = next_el)
8448 {
8449 next_el = el->next_automata_list_el;
8450 if (next_el == NULL)
8451 break;
8452 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8453 output_chip_member_name (output_file, el->automaton);
8454 fprintf (output_file, " = ");
8455 output_temp_chip_member_name (output_file, el->automaton);
8456 fprintf (output_file, ";\n");
8457 }
8458 fprintf (output_file, " return -1;\n");
8459 fprintf (output_file, " }\n");
8460 }
8461
8462 /* Output function `internal_state_transition'. */
8463 static void
8464 output_internal_trans_func (void)
8465 {
8466 fprintf (output_file,
8467 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8468 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8469 CHIP_NAME, CHIP_PARAMETER_NAME);
8470 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8471 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8472 output_insn_code_cases (output_automata_list_transition_code);
8473 fprintf (output_file, "\n default:\n return -1;\n }\n");
8474 fprintf (output_file, "}\n\n");
8475 }
8476
8477 /* Output code
8478
8479 if (insn != 0)
8480 {
8481 insn_code = dfa_insn_code (insn);
8482 if (insn_code > DFA__ADVANCE_CYCLE)
8483 return code;
8484 }
8485 else
8486 insn_code = DFA__ADVANCE_CYCLE;
8487
8488 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8489 code denotes CODE. */
8490 static void
8491 output_internal_insn_code_evaluation (const char *insn_name,
8492 const char *insn_code_name,
8493 int code)
8494 {
8495 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8496 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8497 DFA_INSN_CODE_FUNC_NAME, insn_name);
8498 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8499 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8500 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8501 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8502 }
8503
8504
8505 /* This function outputs `dfa_insn_code' and its helper function
8506 `dfa_insn_code_enlarge'. */
8507 static void
8508 output_dfa_insn_code_func (void)
8509 {
8510 /* Emacs c-mode gets really confused if there's a { or } in column 0
8511 inside a string, so don't do that. */
8512 fprintf (output_file, "\
8513 static void\n\
8514 dfa_insn_code_enlarge (int uid)\n\
8515 {\n\
8516 int i = %s;\n\
8517 %s = 2 * uid;\n\
8518 %s = xrealloc (%s,\n\
8519 %s * sizeof(int));\n\
8520 for (; i < %s; i++)\n\
8521 %s[i] = -1;\n}\n\n",
8522 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8523 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8524 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8525 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8526 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8527 DFA_INSN_CODES_VARIABLE_NAME);
8528 fprintf (output_file, "\
8529 static inline int\n%s (rtx %s)\n\
8530 {\n\
8531 int uid = INSN_UID (%s);\n\
8532 int %s;\n\n",
8533 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8534 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8535
8536 fprintf (output_file,
8537 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8538 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8539 fprintf (output_file, " %s = %s[uid];\n",
8540 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8541 fprintf (output_file, "\
8542 if (%s < 0)\n\
8543 {\n\
8544 %s = %s (%s);\n\
8545 %s[uid] = %s;\n\
8546 }\n",
8547 INTERNAL_INSN_CODE_NAME,
8548 INTERNAL_INSN_CODE_NAME,
8549 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8550 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8551 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8552 }
8553
8554 /* The function outputs PHR interface function `state_transition'. */
8555 static void
8556 output_trans_func (void)
8557 {
8558 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8559 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8560 INSN_PARAMETER_NAME);
8561 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8562 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8563 INTERNAL_INSN_CODE_NAME, -1);
8564 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8565 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8566 }
8567
8568 /* The function outputs a code for evaluation of alternative states
8569 number for insns which have reservations in given AUTOMATA_LIST. */
8570 static void
8571 output_automata_list_state_alts_code (automata_list_el_t automata_list)
8572 {
8573 automata_list_el_t el;
8574 automaton_t automaton;
8575
8576 fprintf (output_file, " {\n");
8577 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8578 if (comb_vect_p (el->automaton->state_alts_table))
8579 {
8580 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8581 break;
8582 }
8583 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8584 {
8585 automaton = el->automaton;
8586 if (comb_vect_p (automaton->state_alts_table))
8587 {
8588 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8589 output_state_alts_base_vect_name (output_file, automaton);
8590 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8591 output_chip_member_name (output_file, automaton);
8592 fprintf (output_file, "] + ");
8593 output_translate_vect_name (output_file, automaton);
8594 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8595 fprintf (output_file, " if (");
8596 output_state_alts_check_vect_name (output_file, automaton);
8597 fprintf (output_file, " [%s] != %s->",
8598 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8599 output_chip_member_name (output_file, automaton);
8600 fprintf (output_file, ")\n");
8601 fprintf (output_file, " return 0;\n");
8602 fprintf (output_file, " else\n");
8603 fprintf (output_file,
8604 (el == automata_list
8605 ? " %s = " : " %s += "),
8606 RESULT_VARIABLE_NAME);
8607 output_state_alts_comb_vect_name (output_file, automaton);
8608 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8609 }
8610 else
8611 {
8612 fprintf (output_file,
8613 (el == automata_list
8614 ? "\n %s = " : " %s += "),
8615 RESULT_VARIABLE_NAME);
8616 output_state_alts_full_vect_name (output_file, automaton);
8617 fprintf (output_file, " [");
8618 output_translate_vect_name (output_file, automaton);
8619 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8620 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8621 output_chip_member_name (output_file, automaton);
8622 fprintf (output_file, " * %d];\n",
8623 automaton->insn_equiv_classes_num);
8624 }
8625 }
8626 fprintf (output_file, " break;\n }\n\n");
8627 }
8628
8629 /* Output function `internal_state_alts'. */
8630 static void
8631 output_internal_state_alts_func (void)
8632 {
8633 fprintf (output_file,
8634 "static int\n%s (int %s, struct %s *%s)\n",
8635 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8636 CHIP_NAME, CHIP_PARAMETER_NAME);
8637 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8638 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8639 output_insn_code_cases (output_automata_list_state_alts_code);
8640 fprintf (output_file,
8641 "\n default:\n %s = 0;\n break;\n }\n",
8642 RESULT_VARIABLE_NAME);
8643 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8644 fprintf (output_file, "}\n\n");
8645 }
8646
8647 /* The function outputs PHR interface function `state_alts'. */
8648 static void
8649 output_state_alts_func (void)
8650 {
8651 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8652 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8653 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8654 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8655 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8656 INTERNAL_INSN_CODE_NAME, 0);
8657 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8658 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8659 }
8660
8661 /* Output function `min_issue_delay'. */
8662 static void
8663 output_min_issue_delay_func (void)
8664 {
8665 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8666 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8667 INSN_PARAMETER_NAME);
8668 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8669 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8670 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8671 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8672 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8673 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8674 fprintf (output_file, " }\n else\n %s = %s;\n",
8675 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8676 fprintf (output_file, "\n return %s (%s, %s);\n",
8677 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8678 STATE_NAME);
8679 fprintf (output_file, "}\n\n");
8680 }
8681
8682 /* Output function `internal_dead_lock'. */
8683 static void
8684 output_internal_dead_lock_func (void)
8685 {
8686 automaton_t automaton;
8687
8688 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8689 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8690 fprintf (output_file, "{\n");
8691 for (automaton = description->first_automaton;
8692 automaton != NULL;
8693 automaton = automaton->next_automaton)
8694 {
8695 fprintf (output_file, " if (");
8696 output_dead_lock_vect_name (output_file, automaton);
8697 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8698 output_chip_member_name (output_file, automaton);
8699 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8700 }
8701 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8702 }
8703
8704 /* The function outputs PHR interface function `state_dead_lock_p'. */
8705 static void
8706 output_dead_lock_func (void)
8707 {
8708 fprintf (output_file, "int\n%s (%s %s)\n",
8709 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8710 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8711 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8712 }
8713
8714 /* Output function `internal_reset'. */
8715 static void
8716 output_internal_reset_func (void)
8717 {
8718 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8719 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8720 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8721 CHIP_PARAMETER_NAME, CHIP_NAME);
8722 }
8723
8724 /* The function outputs PHR interface function `state_size'. */
8725 static void
8726 output_size_func (void)
8727 {
8728 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8729 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8730 }
8731
8732 /* The function outputs PHR interface function `state_reset'. */
8733 static void
8734 output_reset_func (void)
8735 {
8736 fprintf (output_file, "void\n%s (%s %s)\n",
8737 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8738 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8739 STATE_NAME);
8740 }
8741
8742 /* Output function `min_insn_conflict_delay'. */
8743 static void
8744 output_min_insn_conflict_delay_func (void)
8745 {
8746 fprintf (output_file,
8747 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8748 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8749 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8750 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
8751 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8752 INTERNAL_INSN2_CODE_NAME);
8753 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8754 INTERNAL_INSN_CODE_NAME, 0);
8755 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8756 INTERNAL_INSN2_CODE_NAME, 0);
8757 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8758 CHIP_NAME, STATE_NAME, CHIP_NAME);
8759 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8760 fprintf (output_file, " transition = %s (%s, &%s);\n",
8761 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8762 fprintf (output_file, " gcc_assert (transition <= 0);\n");
8763 fprintf (output_file, " return %s (%s, &%s);\n",
8764 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8765 CHIP_NAME);
8766 fprintf (output_file, "}\n\n");
8767 }
8768
8769 /* Output function `internal_insn_latency'. */
8770 static void
8771 output_internal_insn_latency_func (void)
8772 {
8773 decl_t decl;
8774 struct bypass_decl *bypass;
8775 int i, j, col;
8776 const char *tabletype = "unsigned char";
8777
8778 /* Find the smallest integer type that can hold all the default
8779 latency values. */
8780 for (i = 0; i < description->decls_num; i++)
8781 if (description->decls[i]->mode == dm_insn_reserv)
8782 {
8783 decl = description->decls[i];
8784 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8785 && tabletype[0] != 'i') /* Don't shrink it. */
8786 tabletype = "unsigned short";
8787 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8788 tabletype = "int";
8789 }
8790
8791 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8792 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8793 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8794 INSN2_PARAMETER_NAME);
8795 fprintf (output_file, "{\n");
8796
8797 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8798 {
8799 fputs (" return 0;\n}\n\n", output_file);
8800 return;
8801 }
8802
8803 fprintf (output_file, " static const %s default_latencies[] =\n {",
8804 tabletype);
8805
8806 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8807 if (description->decls[i]->mode == dm_insn_reserv
8808 && description->decls[i] != advance_cycle_insn_decl)
8809 {
8810 if ((col = (col+1) % 8) == 0)
8811 fputs ("\n ", output_file);
8812 decl = description->decls[i];
8813 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
8814 fprintf (output_file, "% 4d,",
8815 DECL_INSN_RESERV (decl)->default_latency);
8816 }
8817 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8818 fputs ("\n };\n", output_file);
8819
8820 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8821 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8822 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8823
8824 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8825 for (i = 0; i < description->decls_num; i++)
8826 if (description->decls[i]->mode == dm_insn_reserv
8827 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8828 {
8829 decl = description->decls [i];
8830 fprintf (output_file,
8831 " case %d:\n switch (%s)\n {\n",
8832 DECL_INSN_RESERV (decl)->insn_num,
8833 INTERNAL_INSN2_CODE_NAME);
8834 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8835 bypass != NULL;
8836 bypass = bypass->next)
8837 {
8838 gcc_assert (bypass->in_insn_reserv->insn_num
8839 != (DECL_INSN_RESERV
8840 (advance_cycle_insn_decl)->insn_num));
8841 fprintf (output_file, " case %d:\n",
8842 bypass->in_insn_reserv->insn_num);
8843 if (bypass->bypass_guard_name == NULL)
8844 fprintf (output_file, " return %d;\n",
8845 bypass->latency);
8846 else
8847 {
8848 fprintf (output_file,
8849 " if (%s (%s, %s))\n",
8850 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8851 INSN2_PARAMETER_NAME);
8852 fprintf (output_file,
8853 " return %d;\n break;\n",
8854 bypass->latency);
8855 }
8856 }
8857 fputs (" }\n break;\n", output_file);
8858 }
8859
8860 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8861 INTERNAL_INSN_CODE_NAME);
8862 }
8863
8864 /* The function outputs PHR interface function `insn_latency'. */
8865 static void
8866 output_insn_latency_func (void)
8867 {
8868 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8869 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8870 fprintf (output_file, "{\n int %s, %s;\n",
8871 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8872 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8873 INTERNAL_INSN_CODE_NAME, 0);
8874 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8875 INTERNAL_INSN2_CODE_NAME, 0);
8876 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8877 INTERNAL_INSN_LATENCY_FUNC_NAME,
8878 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8879 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8880 }
8881
8882 /* The function outputs PHR interface function `print_reservation'. */
8883 static void
8884 output_print_reservation_func (void)
8885 {
8886 decl_t decl;
8887 int i, j;
8888
8889 fprintf (output_file,
8890 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8891 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8892 INSN_PARAMETER_NAME);
8893
8894 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8895 {
8896 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8897 NOTHING_NAME, FILE_PARAMETER_NAME);
8898 return;
8899 }
8900
8901
8902 fputs (" static const char *const reservation_names[] =\n {",
8903 output_file);
8904
8905 for (i = 0, j = 0; i < description->decls_num; i++)
8906 {
8907 decl = description->decls [i];
8908 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8909 {
8910 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8911 j++;
8912
8913 fprintf (output_file, "\n \"%s\",",
8914 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8915 finish_regexp_representation ();
8916 }
8917 }
8918 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8919
8920 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8921 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8922
8923 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8924 INSN_PARAMETER_NAME,
8925 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8926 fprintf (output_file, " else\n\
8927 {\n\
8928 %s = %s (%s);\n\
8929 if (%s > %s)\n\
8930 %s = %s;\n\
8931 }\n",
8932 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8933 INSN_PARAMETER_NAME,
8934 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8935 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8936
8937 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8938 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8939 }
8940
8941 /* The following function is used to sort unit declaration by their
8942 names. */
8943 static int
8944 units_cmp (const void *unit1, const void *unit2)
8945 {
8946 const unit_decl_t u1 = *(unit_decl_t *) unit1;
8947 const unit_decl_t u2 = *(unit_decl_t *) unit2;
8948
8949 return strcmp (u1->name, u2->name);
8950 }
8951
8952 /* The following macro value is name of struct containing unit name
8953 and unit code. */
8954 #define NAME_CODE_STRUCT_NAME "name_code"
8955
8956 /* The following macro value is name of table of struct name_code. */
8957 #define NAME_CODE_TABLE_NAME "name_code_table"
8958
8959 /* The following macro values are member names for struct name_code. */
8960 #define NAME_MEMBER_NAME "name"
8961 #define CODE_MEMBER_NAME "code"
8962
8963 /* The following macro values are local variable names for function
8964 `get_cpu_unit_code'. */
8965 #define CMP_VARIABLE_NAME "cmp"
8966 #define LOW_VARIABLE_NAME "l"
8967 #define MIDDLE_VARIABLE_NAME "m"
8968 #define HIGH_VARIABLE_NAME "h"
8969
8970 /* The following function outputs function to obtain internal cpu unit
8971 code by the cpu unit name. */
8972 static void
8973 output_get_cpu_unit_code_func (void)
8974 {
8975 int i;
8976 unit_decl_t *units;
8977
8978 fprintf (output_file, "int\n%s (const char *%s)\n",
8979 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
8980 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8981 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8982 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8983 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8984 fprintf (output_file, " static struct %s %s [] =\n {\n",
8985 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8986 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8987 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8988 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8989 for (i = 0; i < description->units_num; i++)
8990 if (units [i]->query_p)
8991 fprintf (output_file, " {\"%s\", %d},\n",
8992 units[i]->name, units[i]->query_num);
8993 fprintf (output_file, " };\n\n");
8994 fprintf (output_file, " /* The following is binary search: */\n");
8995 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8996 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8997 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8998 fprintf (output_file, " while (%s <= %s)\n {\n",
8999 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9000 fprintf (output_file, " %s = (%s + %s) / 2;\n",
9001 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9002 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
9003 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
9004 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
9005 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
9006 fprintf (output_file, " %s = %s - 1;\n",
9007 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9008 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
9009 fprintf (output_file, " %s = %s + 1;\n",
9010 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9011 fprintf (output_file, " else\n");
9012 fprintf (output_file, " return %s [%s].%s;\n }\n",
9013 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
9014 fprintf (output_file, " return -1;\n}\n\n");
9015 free (units);
9016 }
9017
9018 /* The following function outputs function to check reservation of cpu
9019 unit (its internal code will be passed as the function argument) in
9020 given cpu state. */
9021 static void
9022 output_cpu_unit_reservation_p (void)
9023 {
9024 automaton_t automaton;
9025
9026 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
9027 CPU_UNIT_RESERVATION_P_FUNC_NAME,
9028 STATE_TYPE_NAME, STATE_NAME,
9029 CPU_CODE_PARAMETER_NAME);
9030 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
9031 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
9032 description->query_units_num);
9033 for (automaton = description->first_automaton;
9034 automaton != NULL;
9035 automaton = automaton->next_automaton)
9036 {
9037 fprintf (output_file, " if ((");
9038 output_reserved_units_table_name (output_file, automaton);
9039 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
9040 output_chip_member_name (output_file, automaton);
9041 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9042 (description->query_units_num + 7) / 8,
9043 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
9044 fprintf (output_file, " return 1;\n");
9045 }
9046 fprintf (output_file, " return 0;\n}\n\n");
9047 }
9048
9049 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9050 static void
9051 output_dfa_clean_insn_cache_func (void)
9052 {
9053 fprintf (output_file,
9054 "void\n%s (void)\n{\n int %s;\n\n",
9055 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
9056 fprintf (output_file,
9057 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9058 I_VARIABLE_NAME, I_VARIABLE_NAME,
9059 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
9060 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
9061 }
9062
9063 /* The function outputs PHR interface function `dfa_start'. */
9064 static void
9065 output_dfa_start_func (void)
9066 {
9067 fprintf (output_file,
9068 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
9069 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9070 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
9071 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9072 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
9073 }
9074
9075 /* The function outputs PHR interface function `dfa_finish'. */
9076 static void
9077 output_dfa_finish_func (void)
9078 {
9079 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
9080 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
9081 }
9082
9083 \f
9084
9085 /* The page contains code for output description file (readable
9086 representation of original description and generated DFA(s). */
9087
9088 /* The function outputs string representation of IR reservation. */
9089 static void
9090 output_regexp (regexp_t regexp)
9091 {
9092 fprintf (output_description_file, "%s", regexp_representation (regexp));
9093 finish_regexp_representation ();
9094 }
9095
9096 /* Output names of units in LIST separated by comma. */
9097 static void
9098 output_unit_set_el_list (unit_set_el_t list)
9099 {
9100 unit_set_el_t el;
9101
9102 for (el = list; el != NULL; el = el->next_unit_set_el)
9103 {
9104 if (el != list)
9105 fprintf (output_description_file, ", ");
9106 fprintf (output_description_file, "%s", el->unit_decl->name);
9107 }
9108 }
9109
9110 /* Output patterns in LIST separated by comma. */
9111 static void
9112 output_pattern_set_el_list (pattern_set_el_t list)
9113 {
9114 pattern_set_el_t el;
9115 int i;
9116
9117 for (el = list; el != NULL; el = el->next_pattern_set_el)
9118 {
9119 if (el != list)
9120 fprintf (output_description_file, ", ");
9121 for (i = 0; i < el->units_num; i++)
9122 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9123 el->unit_decls [i]->name);
9124 }
9125 }
9126
9127 /* The function outputs string representation of IR define_reservation
9128 and define_insn_reservation. */
9129 static void
9130 output_description (void)
9131 {
9132 decl_t decl;
9133 int i;
9134
9135 for (i = 0; i < description->decls_num; i++)
9136 {
9137 decl = description->decls [i];
9138 if (decl->mode == dm_unit)
9139 {
9140 if (DECL_UNIT (decl)->excl_list != NULL)
9141 {
9142 fprintf (output_description_file, "unit %s exlusion_set: ",
9143 DECL_UNIT (decl)->name);
9144 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9145 fprintf (output_description_file, "\n");
9146 }
9147 if (DECL_UNIT (decl)->presence_list != NULL)
9148 {
9149 fprintf (output_description_file, "unit %s presence_set: ",
9150 DECL_UNIT (decl)->name);
9151 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9152 fprintf (output_description_file, "\n");
9153 }
9154 if (DECL_UNIT (decl)->final_presence_list != NULL)
9155 {
9156 fprintf (output_description_file, "unit %s final_presence_set: ",
9157 DECL_UNIT (decl)->name);
9158 output_pattern_set_el_list
9159 (DECL_UNIT (decl)->final_presence_list);
9160 fprintf (output_description_file, "\n");
9161 }
9162 if (DECL_UNIT (decl)->absence_list != NULL)
9163 {
9164 fprintf (output_description_file, "unit %s absence_set: ",
9165 DECL_UNIT (decl)->name);
9166 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9167 fprintf (output_description_file, "\n");
9168 }
9169 if (DECL_UNIT (decl)->final_absence_list != NULL)
9170 {
9171 fprintf (output_description_file, "unit %s final_absence_set: ",
9172 DECL_UNIT (decl)->name);
9173 output_pattern_set_el_list
9174 (DECL_UNIT (decl)->final_absence_list);
9175 fprintf (output_description_file, "\n");
9176 }
9177 }
9178 }
9179 fprintf (output_description_file, "\n");
9180 for (i = 0; i < description->decls_num; i++)
9181 {
9182 decl = description->decls [i];
9183 if (decl->mode == dm_reserv)
9184 {
9185 fprintf (output_description_file, "reservation %s: ",
9186 DECL_RESERV (decl)->name);
9187 output_regexp (DECL_RESERV (decl)->regexp);
9188 fprintf (output_description_file, "\n");
9189 }
9190 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9191 {
9192 fprintf (output_description_file, "insn reservation %s ",
9193 DECL_INSN_RESERV (decl)->name);
9194 print_rtl (output_description_file,
9195 DECL_INSN_RESERV (decl)->condexp);
9196 fprintf (output_description_file, ": ");
9197 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9198 fprintf (output_description_file, "\n");
9199 }
9200 else if (decl->mode == dm_bypass)
9201 fprintf (output_description_file, "bypass %d %s %s\n",
9202 DECL_BYPASS (decl)->latency,
9203 DECL_BYPASS (decl)->out_insn_name,
9204 DECL_BYPASS (decl)->in_insn_name);
9205 }
9206 fprintf (output_description_file, "\n\f\n");
9207 }
9208
9209 /* The function outputs name of AUTOMATON. */
9210 static void
9211 output_automaton_name (FILE *f, automaton_t automaton)
9212 {
9213 if (automaton->corresponding_automaton_decl == NULL)
9214 fprintf (f, "#%d", automaton->automaton_order_num);
9215 else
9216 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9217 }
9218
9219 /* Maximal length of line for pretty printing into description
9220 file. */
9221 #define MAX_LINE_LENGTH 70
9222
9223 /* The function outputs units name belonging to AUTOMATON. */
9224 static void
9225 output_automaton_units (automaton_t automaton)
9226 {
9227 decl_t decl;
9228 char *name;
9229 int curr_line_length;
9230 int there_is_an_automaton_unit;
9231 int i;
9232
9233 fprintf (output_description_file, "\n Corresponding units:\n");
9234 fprintf (output_description_file, " ");
9235 curr_line_length = 4;
9236 there_is_an_automaton_unit = 0;
9237 for (i = 0; i < description->decls_num; i++)
9238 {
9239 decl = description->decls [i];
9240 if (decl->mode == dm_unit
9241 && (DECL_UNIT (decl)->corresponding_automaton_num
9242 == automaton->automaton_order_num))
9243 {
9244 there_is_an_automaton_unit = 1;
9245 name = DECL_UNIT (decl)->name;
9246 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9247 {
9248 curr_line_length = strlen (name) + 4;
9249 fprintf (output_description_file, "\n ");
9250 }
9251 else
9252 {
9253 curr_line_length += strlen (name) + 1;
9254 fprintf (output_description_file, " ");
9255 }
9256 fprintf (output_description_file, "%s", name);
9257 }
9258 }
9259 if (!there_is_an_automaton_unit)
9260 fprintf (output_description_file, "<None>");
9261 fprintf (output_description_file, "\n\n");
9262 }
9263
9264 /* The following variable is used for forming array of all possible cpu unit
9265 reservations described by the current DFA state. */
9266 static vla_ptr_t state_reservs;
9267
9268 /* The function forms `state_reservs' for STATE. */
9269 static void
9270 add_state_reservs (state_t state)
9271 {
9272 alt_state_t curr_alt_state;
9273 reserv_sets_t reservs;
9274
9275 if (state->component_states != NULL)
9276 for (curr_alt_state = state->component_states;
9277 curr_alt_state != NULL;
9278 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9279 add_state_reservs (curr_alt_state->state);
9280 else
9281 {
9282 reservs = state->reservs;
9283 VLA_PTR_ADD (state_reservs, reservs);
9284 }
9285 }
9286
9287 /* The function outputs readable representation of all out arcs of
9288 STATE. */
9289 static void
9290 output_state_arcs (state_t state)
9291 {
9292 arc_t arc;
9293 ainsn_t ainsn;
9294 char *insn_name;
9295 int curr_line_length;
9296
9297 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9298 {
9299 ainsn = arc->insn;
9300 gcc_assert (ainsn->first_insn_with_same_reservs);
9301 fprintf (output_description_file, " ");
9302 curr_line_length = 7;
9303 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9304 do
9305 {
9306 insn_name = ainsn->insn_reserv_decl->name;
9307 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9308 {
9309 if (ainsn != arc->insn)
9310 {
9311 fprintf (output_description_file, ",\n ");
9312 curr_line_length = strlen (insn_name) + 6;
9313 }
9314 else
9315 curr_line_length += strlen (insn_name);
9316 }
9317 else
9318 {
9319 curr_line_length += strlen (insn_name);
9320 if (ainsn != arc->insn)
9321 {
9322 curr_line_length += 2;
9323 fprintf (output_description_file, ", ");
9324 }
9325 }
9326 fprintf (output_description_file, "%s", insn_name);
9327 ainsn = ainsn->next_same_reservs_insn;
9328 }
9329 while (ainsn != NULL);
9330 fprintf (output_description_file, " %d (%d)\n",
9331 arc->to_state->order_state_num, arc->state_alts);
9332 }
9333 fprintf (output_description_file, "\n");
9334 }
9335
9336 /* The following function is used for sorting possible cpu unit
9337 reservation of a DFA state. */
9338 static int
9339 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9340 {
9341 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9342 *(reserv_sets_t *) reservs_ptr_2);
9343 }
9344
9345 /* The following function is used for sorting possible cpu unit
9346 reservation of a DFA state. */
9347 static void
9348 remove_state_duplicate_reservs (void)
9349 {
9350 reserv_sets_t *reservs_ptr;
9351 reserv_sets_t *last_formed_reservs_ptr;
9352
9353 last_formed_reservs_ptr = NULL;
9354 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9355 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9356 reservs_ptr++)
9357 if (last_formed_reservs_ptr == NULL)
9358 last_formed_reservs_ptr = reservs_ptr;
9359 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9360 {
9361 ++last_formed_reservs_ptr;
9362 *last_formed_reservs_ptr = *reservs_ptr;
9363 }
9364 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9365 }
9366
9367 /* The following function output readable representation of DFA(s)
9368 state used for fast recognition of pipeline hazards. State is
9369 described by possible (current and scheduled) cpu unit
9370 reservations. */
9371 static void
9372 output_state (state_t state)
9373 {
9374 reserv_sets_t *reservs_ptr;
9375
9376 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9377 fprintf (output_description_file, " State #%d", state->order_state_num);
9378 fprintf (output_description_file,
9379 state->new_cycle_p ? " (new cycle)\n" : "\n");
9380 add_state_reservs (state);
9381 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9382 sizeof (reserv_sets_t), state_reservs_cmp);
9383 remove_state_duplicate_reservs ();
9384 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9385 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9386 reservs_ptr++)
9387 {
9388 fprintf (output_description_file, " ");
9389 output_reserv_sets (output_description_file, *reservs_ptr);
9390 fprintf (output_description_file, "\n");
9391 }
9392 fprintf (output_description_file, "\n");
9393 output_state_arcs (state);
9394 VLA_PTR_DELETE (state_reservs);
9395 }
9396
9397 /* The following function output readable representation of
9398 DFAs used for fast recognition of pipeline hazards. */
9399 static void
9400 output_automaton_descriptions (void)
9401 {
9402 automaton_t automaton;
9403
9404 for (automaton = description->first_automaton;
9405 automaton != NULL;
9406 automaton = automaton->next_automaton)
9407 {
9408 fprintf (output_description_file, "\nAutomaton ");
9409 output_automaton_name (output_description_file, automaton);
9410 fprintf (output_description_file, "\n");
9411 output_automaton_units (automaton);
9412 pass_states (automaton, output_state);
9413 }
9414 }
9415
9416 \f
9417
9418 /* The page contains top level function for generation DFA(s) used for
9419 PHR. */
9420
9421 /* The function outputs statistics about work of different phases of
9422 DFA generator. */
9423 static void
9424 output_statistics (FILE *f)
9425 {
9426 automaton_t automaton;
9427 int states_num;
9428 #ifndef NDEBUG
9429 int transition_comb_vect_els = 0;
9430 int transition_full_vect_els = 0;
9431 int state_alts_comb_vect_els = 0;
9432 int state_alts_full_vect_els = 0;
9433 int min_issue_delay_vect_els = 0;
9434 #endif
9435
9436 for (automaton = description->first_automaton;
9437 automaton != NULL;
9438 automaton = automaton->next_automaton)
9439 {
9440 fprintf (f, "\nAutomaton ");
9441 output_automaton_name (f, automaton);
9442 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9443 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9444 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9445 automaton->DFA_states_num, automaton->DFA_arcs_num);
9446 states_num = automaton->DFA_states_num;
9447 if (!no_minimization_flag)
9448 {
9449 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9450 automaton->minimal_DFA_states_num,
9451 automaton->minimal_DFA_arcs_num);
9452 states_num = automaton->minimal_DFA_states_num;
9453 }
9454 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9455 description->insns_num, automaton->insn_equiv_classes_num);
9456 #ifndef NDEBUG
9457 fprintf
9458 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9459 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9460 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9461 (comb_vect_p (automaton->trans_table)
9462 ? "use comb vect" : "use simple vect"));
9463 fprintf
9464 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9465 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9466 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9467 (comb_vect_p (automaton->state_alts_table)
9468 ? "use comb vect" : "use simple vect"));
9469 fprintf
9470 (f, "%5ld min delay table els, compression factor %d\n",
9471 (long) states_num * automaton->insn_equiv_classes_num,
9472 automaton->min_issue_delay_table_compression_factor);
9473 transition_comb_vect_els
9474 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9475 transition_full_vect_els
9476 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9477 state_alts_comb_vect_els
9478 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9479 state_alts_full_vect_els
9480 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9481 min_issue_delay_vect_els
9482 += states_num * automaton->insn_equiv_classes_num;
9483 #endif
9484 }
9485 #ifndef NDEBUG
9486 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9487 allocated_states_num, allocated_arcs_num);
9488 fprintf (f, "%5d all allocated alternative states\n",
9489 allocated_alt_states_num);
9490 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9491 transition_comb_vect_els, transition_full_vect_els);
9492 fprintf
9493 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9494 state_alts_comb_vect_els, state_alts_full_vect_els);
9495 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9496 fprintf (f, "%5d locked states num\n", locked_states_num);
9497 #endif
9498 }
9499
9500 /* The function output times of work of different phases of DFA
9501 generator. */
9502 static void
9503 output_time_statistics (FILE *f)
9504 {
9505 fprintf (f, "\n transformation: ");
9506 print_active_time (f, transform_time);
9507 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9508 print_active_time (f, NDFA_time);
9509 if (ndfa_flag)
9510 {
9511 fprintf (f, ", NDFA -> DFA: ");
9512 print_active_time (f, NDFA_to_DFA_time);
9513 }
9514 fprintf (f, "\n DFA minimization: ");
9515 print_active_time (f, minimize_time);
9516 fprintf (f, ", making insn equivalence: ");
9517 print_active_time (f, equiv_time);
9518 fprintf (f, "\n all automaton generation: ");
9519 print_active_time (f, automaton_generation_time);
9520 fprintf (f, ", output: ");
9521 print_active_time (f, output_time);
9522 fprintf (f, "\n");
9523 }
9524
9525 /* The function generates DFA (deterministic finite state automaton)
9526 for fast recognition of pipeline hazards. No errors during
9527 checking must be fixed before this function call. */
9528 static void
9529 generate (void)
9530 {
9531 automata_num = split_argument;
9532 if (description->units_num < automata_num)
9533 automata_num = description->units_num;
9534 initiate_states ();
9535 initiate_arcs ();
9536 initiate_automata_lists ();
9537 initiate_pass_states ();
9538 initiate_excl_sets ();
9539 initiate_presence_absence_pattern_sets ();
9540 automaton_generation_time = create_ticker ();
9541 create_automata ();
9542 ticker_off (&automaton_generation_time);
9543 }
9544
9545 \f
9546
9547 /* The following function creates insn attribute whose values are
9548 number alternatives in insn reservations. */
9549 static void
9550 make_insn_alts_attr (void)
9551 {
9552 int i, insn_num;
9553 decl_t decl;
9554 rtx condexp;
9555
9556 condexp = rtx_alloc (COND);
9557 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9558 XEXP (condexp, 1) = make_numeric_value (0);
9559 for (i = insn_num = 0; i < description->decls_num; i++)
9560 {
9561 decl = description->decls [i];
9562 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9563 {
9564 XVECEXP (condexp, 0, 2 * insn_num)
9565 = DECL_INSN_RESERV (decl)->condexp;
9566 XVECEXP (condexp, 0, 2 * insn_num + 1)
9567 = make_numeric_value
9568 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9569 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9570 ->transformed_regexp)->regexps_num);
9571 insn_num++;
9572 }
9573 }
9574 gcc_assert (description->insns_num == insn_num + 1);
9575 make_internal_attr (attr_printf (sizeof ("*")
9576 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9577 "*%s", INSN_ALTS_FUNC_NAME),
9578 condexp, ATTR_NONE);
9579 }
9580
9581 \f
9582
9583 /* The following function creates attribute which is order number of
9584 insn in pipeline hazard description translator. */
9585 static void
9586 make_internal_dfa_insn_code_attr (void)
9587 {
9588 int i, insn_num;
9589 decl_t decl;
9590 rtx condexp;
9591
9592 condexp = rtx_alloc (COND);
9593 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9594 XEXP (condexp, 1)
9595 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9596 ->insn_num + 1);
9597 for (i = insn_num = 0; i < description->decls_num; i++)
9598 {
9599 decl = description->decls [i];
9600 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9601 {
9602 XVECEXP (condexp, 0, 2 * insn_num)
9603 = DECL_INSN_RESERV (decl)->condexp;
9604 XVECEXP (condexp, 0, 2 * insn_num + 1)
9605 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9606 insn_num++;
9607 }
9608 }
9609 gcc_assert (description->insns_num == insn_num + 1);
9610 make_internal_attr
9611 (attr_printf (sizeof ("*")
9612 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9613 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9614 condexp, ATTR_STATIC);
9615 }
9616
9617 \f
9618
9619 /* The following function creates attribute which order number of insn
9620 in pipeline hazard description translator. */
9621 static void
9622 make_default_insn_latency_attr (void)
9623 {
9624 int i, insn_num;
9625 decl_t decl;
9626 rtx condexp;
9627
9628 condexp = rtx_alloc (COND);
9629 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9630 XEXP (condexp, 1) = make_numeric_value (0);
9631 for (i = insn_num = 0; i < description->decls_num; i++)
9632 {
9633 decl = description->decls [i];
9634 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9635 {
9636 XVECEXP (condexp, 0, 2 * insn_num)
9637 = DECL_INSN_RESERV (decl)->condexp;
9638 XVECEXP (condexp, 0, 2 * insn_num + 1)
9639 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9640 insn_num++;
9641 }
9642 }
9643 gcc_assert (description->insns_num == insn_num + 1);
9644 make_internal_attr (attr_printf (sizeof ("*")
9645 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9646 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9647 condexp, ATTR_NONE);
9648 }
9649
9650 \f
9651
9652 /* The following function creates attribute which returns 1 if given
9653 output insn has bypassing and 0 otherwise. */
9654 static void
9655 make_bypass_attr (void)
9656 {
9657 int i, bypass_insn;
9658 int bypass_insns_num = 0;
9659 decl_t decl;
9660 rtx result_rtx;
9661
9662 for (i = 0; i < description->decls_num; i++)
9663 {
9664 decl = description->decls [i];
9665 if (decl->mode == dm_insn_reserv
9666 && DECL_INSN_RESERV (decl)->condexp != NULL
9667 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9668 bypass_insns_num++;
9669 }
9670 if (bypass_insns_num == 0)
9671 result_rtx = make_numeric_value (0);
9672 else
9673 {
9674 result_rtx = rtx_alloc (COND);
9675 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9676 XEXP (result_rtx, 1) = make_numeric_value (0);
9677
9678 for (i = bypass_insn = 0; i < description->decls_num; i++)
9679 {
9680 decl = description->decls [i];
9681 if (decl->mode == dm_insn_reserv
9682 && DECL_INSN_RESERV (decl)->condexp != NULL
9683 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9684 {
9685 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9686 = DECL_INSN_RESERV (decl)->condexp;
9687 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9688 = make_numeric_value (1);
9689 bypass_insn++;
9690 }
9691 }
9692 }
9693 make_internal_attr (attr_printf (sizeof ("*")
9694 + strlen (BYPASS_P_FUNC_NAME) + 1,
9695 "*%s", BYPASS_P_FUNC_NAME),
9696 result_rtx, ATTR_NONE);
9697 }
9698
9699 \f
9700
9701 /* This page mainly contains top level functions of pipeline hazards
9702 description translator. */
9703
9704 /* The following macro value is suffix of name of description file of
9705 pipeline hazards description translator. */
9706 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9707
9708 /* The function returns suffix of given file name. The returned
9709 string can not be changed. */
9710 static const char *
9711 file_name_suffix (const char *file_name)
9712 {
9713 const char *last_period;
9714
9715 for (last_period = NULL; *file_name != '\0'; file_name++)
9716 if (*file_name == '.')
9717 last_period = file_name;
9718 return (last_period == NULL ? file_name : last_period);
9719 }
9720
9721 /* The function returns base name of given file name, i.e. pointer to
9722 first char after last `/' (or `\' for WIN32) in given file name,
9723 given file name itself if the directory name is absent. The
9724 returned string can not be changed. */
9725 static const char *
9726 base_file_name (const char *file_name)
9727 {
9728 int directory_name_length;
9729
9730 directory_name_length = strlen (file_name);
9731 #ifdef WIN32
9732 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9733 && file_name[directory_name_length] != '\\')
9734 #else
9735 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9736 #endif
9737 directory_name_length--;
9738 return file_name + directory_name_length + 1;
9739 }
9740
9741 /* The following is top level function to initialize the work of
9742 pipeline hazards description translator. */
9743 void
9744 initiate_automaton_gen (int argc, char **argv)
9745 {
9746 const char *base_name;
9747 int i;
9748
9749 ndfa_flag = 0;
9750 split_argument = 0; /* default value */
9751 no_minimization_flag = 0;
9752 time_flag = 0;
9753 v_flag = 0;
9754 w_flag = 0;
9755 progress_flag = 0;
9756 for (i = 2; i < argc; i++)
9757 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9758 no_minimization_flag = 1;
9759 else if (strcmp (argv [i], TIME_OPTION) == 0)
9760 time_flag = 1;
9761 else if (strcmp (argv [i], V_OPTION) == 0)
9762 v_flag = 1;
9763 else if (strcmp (argv [i], W_OPTION) == 0)
9764 w_flag = 1;
9765 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9766 ndfa_flag = 1;
9767 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9768 progress_flag = 1;
9769 else if (strcmp (argv [i], "-split") == 0)
9770 {
9771 if (i + 1 >= argc)
9772 fatal ("-split has no argument.");
9773 fatal ("option `-split' has not been implemented yet\n");
9774 /* split_argument = atoi (argument_vect [i + 1]); */
9775 }
9776 VLA_PTR_CREATE (decls, 150, "decls");
9777 /* Initialize IR storage. */
9778 obstack_init (&irp);
9779 initiate_automaton_decl_table ();
9780 initiate_insn_decl_table ();
9781 initiate_decl_table ();
9782 output_file = stdout;
9783 output_description_file = NULL;
9784 base_name = base_file_name (argv[1]);
9785 obstack_grow (&irp, base_name,
9786 strlen (base_name) - strlen (file_name_suffix (base_name)));
9787 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9788 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9789 obstack_1grow (&irp, '\0');
9790 output_description_file_name = obstack_base (&irp);
9791 obstack_finish (&irp);
9792 }
9793
9794 /* The following function checks existence at least one arc marked by
9795 each insn. */
9796 static void
9797 check_automata_insn_issues (void)
9798 {
9799 automaton_t automaton;
9800 ainsn_t ainsn, reserv_ainsn;
9801
9802 for (automaton = description->first_automaton;
9803 automaton != NULL;
9804 automaton = automaton->next_automaton)
9805 {
9806 for (ainsn = automaton->ainsn_list;
9807 ainsn != NULL;
9808 ainsn = ainsn->next_ainsn)
9809 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9810 {
9811 for (reserv_ainsn = ainsn;
9812 reserv_ainsn != NULL;
9813 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9814 if (automaton->corresponding_automaton_decl != NULL)
9815 {
9816 if (!w_flag)
9817 error ("Automaton `%s': Insn `%s' will never be issued",
9818 automaton->corresponding_automaton_decl->name,
9819 reserv_ainsn->insn_reserv_decl->name);
9820 else
9821 warning
9822 (0, "Automaton `%s': Insn `%s' will never be issued",
9823 automaton->corresponding_automaton_decl->name,
9824 reserv_ainsn->insn_reserv_decl->name);
9825 }
9826 else
9827 {
9828 if (!w_flag)
9829 error ("Insn `%s' will never be issued",
9830 reserv_ainsn->insn_reserv_decl->name);
9831 else
9832 warning (0, "Insn `%s' will never be issued",
9833 reserv_ainsn->insn_reserv_decl->name);
9834 }
9835 }
9836 }
9837 }
9838
9839 /* The following vla is used for storing pointers to all achieved
9840 states. */
9841 static vla_ptr_t automaton_states;
9842
9843 /* This function is called by function pass_states to add an achieved
9844 STATE. */
9845 static void
9846 add_automaton_state (state_t state)
9847 {
9848 VLA_PTR_ADD (automaton_states, state);
9849 }
9850
9851 /* The following function forms list of important automata (whose
9852 states may be changed after the insn issue) for each insn. */
9853 static void
9854 form_important_insn_automata_lists (void)
9855 {
9856 automaton_t automaton;
9857 state_t *state_ptr;
9858 decl_t decl;
9859 ainsn_t ainsn;
9860 arc_t arc;
9861 int i;
9862
9863 VLA_PTR_CREATE (automaton_states, 1500,
9864 "automaton states for forming important insn automata sets");
9865 /* Mark important ainsns. */
9866 for (automaton = description->first_automaton;
9867 automaton != NULL;
9868 automaton = automaton->next_automaton)
9869 {
9870 VLA_PTR_NULLIFY (automaton_states);
9871 pass_states (automaton, add_automaton_state);
9872 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9873 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9874 state_ptr++)
9875 {
9876 for (arc = first_out_arc (*state_ptr);
9877 arc != NULL;
9878 arc = next_out_arc (arc))
9879 if (arc->to_state != *state_ptr)
9880 {
9881 gcc_assert (arc->insn->first_insn_with_same_reservs);
9882 for (ainsn = arc->insn;
9883 ainsn != NULL;
9884 ainsn = ainsn->next_same_reservs_insn)
9885 ainsn->important_p = TRUE;
9886 }
9887 }
9888 }
9889 VLA_PTR_DELETE (automaton_states);
9890 /* Create automata sets for the insns. */
9891 for (i = 0; i < description->decls_num; i++)
9892 {
9893 decl = description->decls [i];
9894 if (decl->mode == dm_insn_reserv)
9895 {
9896 automata_list_start ();
9897 for (automaton = description->first_automaton;
9898 automaton != NULL;
9899 automaton = automaton->next_automaton)
9900 for (ainsn = automaton->ainsn_list;
9901 ainsn != NULL;
9902 ainsn = ainsn->next_ainsn)
9903 if (ainsn->important_p
9904 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9905 {
9906 automata_list_add (automaton);
9907 break;
9908 }
9909 DECL_INSN_RESERV (decl)->important_automata_list
9910 = automata_list_finish ();
9911 }
9912 }
9913 }
9914
9915
9916 /* The following is top level function to generate automat(a,on) for
9917 fast recognition of pipeline hazards. */
9918 void
9919 expand_automata (void)
9920 {
9921 int i;
9922
9923 description = create_node (sizeof (struct description)
9924 /* One entry for cycle advancing insn. */
9925 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9926 description->decls_num = VLA_PTR_LENGTH (decls);
9927 description->query_units_num = 0;
9928 for (i = 0; i < description->decls_num; i++)
9929 {
9930 description->decls [i] = VLA_PTR (decls, i);
9931 if (description->decls [i]->mode == dm_unit
9932 && DECL_UNIT (description->decls [i])->query_p)
9933 DECL_UNIT (description->decls [i])->query_num
9934 = description->query_units_num++;
9935 }
9936 all_time = create_ticker ();
9937 check_time = create_ticker ();
9938 if (progress_flag)
9939 fprintf (stderr, "Check description...");
9940 check_all_description ();
9941 if (progress_flag)
9942 fprintf (stderr, "done\n");
9943 ticker_off (&check_time);
9944 generation_time = create_ticker ();
9945 if (!have_error)
9946 {
9947 transform_insn_regexps ();
9948 check_unit_distributions_to_automata ();
9949 }
9950 if (!have_error)
9951 {
9952 generate ();
9953 check_automata_insn_issues ();
9954 }
9955 if (!have_error)
9956 {
9957 form_important_insn_automata_lists ();
9958 if (progress_flag)
9959 fprintf (stderr, "Generation of attributes...");
9960 make_internal_dfa_insn_code_attr ();
9961 make_insn_alts_attr ();
9962 make_default_insn_latency_attr ();
9963 make_bypass_attr ();
9964 if (progress_flag)
9965 fprintf (stderr, "done\n");
9966 }
9967 ticker_off (&generation_time);
9968 ticker_off (&all_time);
9969 if (progress_flag)
9970 fprintf (stderr, "All other genattrtab stuff...");
9971 }
9972
9973 /* The following is top level function to output PHR and to finish
9974 work with pipeline description translator. */
9975 void
9976 write_automata (void)
9977 {
9978 if (progress_flag)
9979 fprintf (stderr, "done\n");
9980 if (have_error)
9981 fatal ("Errors in DFA description");
9982 ticker_on (&all_time);
9983 output_time = create_ticker ();
9984 if (progress_flag)
9985 fprintf (stderr, "Forming and outputting automata tables...");
9986 output_dfa_max_issue_rate ();
9987 output_tables ();
9988 if (progress_flag)
9989 {
9990 fprintf (stderr, "done\n");
9991 fprintf (stderr, "Output functions to work with automata...");
9992 }
9993 output_chip_definitions ();
9994 output_max_insn_queue_index_def ();
9995 output_internal_min_issue_delay_func ();
9996 output_internal_trans_func ();
9997 /* Cache of insn dfa codes: */
9998 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9999 fprintf (output_file, "\nstatic int %s;\n\n",
10000 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
10001 output_dfa_insn_code_func ();
10002 output_trans_func ();
10003 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
10004 output_internal_state_alts_func ();
10005 output_state_alts_func ();
10006 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10007 AUTOMATON_STATE_ALTS_MACRO_NAME);
10008 output_min_issue_delay_func ();
10009 output_internal_dead_lock_func ();
10010 output_dead_lock_func ();
10011 output_size_func ();
10012 output_internal_reset_func ();
10013 output_reset_func ();
10014 output_min_insn_conflict_delay_func ();
10015 output_internal_insn_latency_func ();
10016 output_insn_latency_func ();
10017 output_print_reservation_func ();
10018 /* Output function get_cpu_unit_code. */
10019 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10020 output_get_cpu_unit_code_func ();
10021 output_cpu_unit_reservation_p ();
10022 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10023 CPU_UNITS_QUERY_MACRO_NAME);
10024 output_dfa_clean_insn_cache_func ();
10025 output_dfa_start_func ();
10026 output_dfa_finish_func ();
10027 if (progress_flag)
10028 fprintf (stderr, "done\n");
10029 if (v_flag)
10030 {
10031 output_description_file = fopen (output_description_file_name, "w");
10032 if (output_description_file == NULL)
10033 {
10034 perror (output_description_file_name);
10035 exit (FATAL_EXIT_CODE);
10036 }
10037 if (progress_flag)
10038 fprintf (stderr, "Output automata description...");
10039 output_description ();
10040 output_automaton_descriptions ();
10041 if (progress_flag)
10042 fprintf (stderr, "done\n");
10043 output_statistics (output_description_file);
10044 }
10045 output_statistics (stderr);
10046 ticker_off (&output_time);
10047 output_time_statistics (stderr);
10048 finish_states ();
10049 finish_arcs ();
10050 finish_automata_lists ();
10051 if (time_flag)
10052 {
10053 fprintf (stderr, "Summary:\n");
10054 fprintf (stderr, " check time ");
10055 print_active_time (stderr, check_time);
10056 fprintf (stderr, ", generation time ");
10057 print_active_time (stderr, generation_time);
10058 fprintf (stderr, ", all time ");
10059 print_active_time (stderr, all_time);
10060 fprintf (stderr, "\n");
10061 }
10062 /* Finish all work. */
10063 if (output_description_file != NULL)
10064 {
10065 fflush (output_description_file);
10066 if (ferror (stdout) != 0)
10067 fatal ("Error in writing DFA description file %s",
10068 output_description_file_name);
10069 fclose (output_description_file);
10070 }
10071 finish_automaton_decl_table ();
10072 finish_insn_decl_table ();
10073 finish_decl_table ();
10074 obstack_free (&irp, NULL);
10075 if (have_error && output_description_file != NULL)
10076 remove (output_description_file_name);
10077 }