1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 Written by Vladimir Makarov <vmakarov@redhat.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 1. Detecting pipeline structural hazards quickly. T. Proebsting,
27 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
28 Principles of Programming Languages, pages 280--286, 1994.
30 This article is a good start point to understand usage of finite
31 state automata for pipeline hazard recognizers. But I'd
32 recommend the 2nd article for more deep understanding.
34 2. Efficient Instruction Scheduling Using Finite State Automata:
35 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
36 article about usage of finite state automata for pipeline hazard
39 The current implementation is different from the 2nd article in the
42 1. New operator `|' (alternative) is permitted in functional unit
43 reservation which can be treated deterministically and
44 non-deterministically.
46 2. Possibility of usage of nondeterministic automata too.
48 3. Possibility to query functional unit reservations for given
51 4. Several constructions to describe impossible reservations
52 (`exclusion_set', `presence_set', `final_presence_set',
53 `absence_set', and `final_absence_set').
55 5. No reverse automata are generated. Trace instruction scheduling
56 requires this. It can be easily added in the future if we
59 6. Union of automaton states are not generated yet. It is planned
60 to be implemented. Such feature is needed to make more accurate
61 interlock insn scheduling to get state describing functional
62 unit reservation in a joint CFG point. */
64 /* This file code processes constructions of machine description file
65 which describes automaton used for recognition of processor pipeline
66 hazards by insn scheduler and can be used for other tasks (such as
69 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
70 `gen_bypass', `gen_excl_set', `gen_presence_set',
71 `gen_final_presence_set', `gen_absence_set',
72 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
73 `gen_reserv', `gen_insn_reserv' are called from file
74 `genattrtab.c'. They transform RTL constructions describing
75 automata in .md file into internal representation convenient for
78 The translator major function `expand_automata' processes the
79 description internal representation into finite state automaton.
82 o checking correctness of the automaton pipeline description
83 (major function is `check_all_description').
85 o generating automaton (automata) from the description (major
86 function is `make_automaton').
88 o optional transformation of nondeterministic finite state
89 automata into deterministic ones if the alternative operator
90 `|' is treated nondeterministically in the description (major
91 function is NDFA_to_DFA).
93 o optional minimization of the finite state automata by merging
94 equivalent automaton states (major function is `minimize_DFA').
96 o forming tables (some as comb vectors) and attributes
97 representing the automata (functions output_..._table).
99 Function `write_automata' outputs the created finite state
100 automaton as different tables and functions which works with the
101 automata to inquire automaton state and to change its state. These
102 function are used by gcc instruction scheduler and may be some
107 #include "coretypes.h"
121 #include "genattrtab.h"
123 /* Positions in machine description file. Now they are not used. But
124 they could be used in the future for better diagnostic messages. */
127 /* The following is element of vector of current (and planned in the
128 future) functional unit reservations. */
129 typedef unsigned HOST_WIDE_INT set_el_t
;
131 /* Reservations of function units are represented by value of the following
133 typedef set_el_t
*reserv_sets_t
;
135 /* The following structure represents variable length array (vla) of
136 pointers and HOST WIDE INTs. We could be use only varray. But we
137 add new lay because we add elements very frequently and this could
138 stress OS allocator when varray is used only. */
140 size_t length
; /* current size of vla. */
141 varray_type varray
; /* container for vla. */
144 typedef vla_ptr_t vla_hwint_t
;
146 /* The following structure describes a ticker. */
149 /* The following member value is time of the ticker creation with
150 taking into account time when the ticker is off. Active time of
151 the ticker is current time minus the value. */
152 int modified_creation_time
;
153 /* The following member value is time (incremented by one) when the
154 ticker was off. Zero value means that now the ticker is on. */
155 int incremented_off_time
;
158 /* The ticker is represented by the following type. */
159 typedef struct ticker ticker_t
;
161 /* The following type describes elements of output vectors. */
162 typedef HOST_WIDE_INT vect_el_t
;
164 /* Forward declaration of structures of internal representation of
165 pipeline description based on NDFA. */
170 struct automaton_decl
;
171 struct unit_pattern_rel_decl
;
173 struct insn_reserv_decl
;
176 struct result_regexp
;
177 struct reserv_regexp
;
178 struct nothing_regexp
;
179 struct sequence_regexp
;
180 struct repeat_regexp
;
186 struct pattern_set_el
;
187 struct pattern_reserv
;
193 struct state_ainsn_table
;
195 /* The following typedefs are for brevity. */
196 typedef struct unit_decl
*unit_decl_t
;
197 typedef struct decl
*decl_t
;
198 typedef struct regexp
*regexp_t
;
199 typedef struct unit_set_el
*unit_set_el_t
;
200 typedef struct pattern_set_el
*pattern_set_el_t
;
201 typedef struct pattern_reserv
*pattern_reserv_t
;
202 typedef struct alt_state
*alt_state_t
;
203 typedef struct state
*state_t
;
204 typedef struct arc
*arc_t
;
205 typedef struct ainsn
*ainsn_t
;
206 typedef struct automaton
*automaton_t
;
207 typedef struct automata_list_el
*automata_list_el_t
;
208 typedef struct state_ainsn_table
*state_ainsn_table_t
;
211 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
212 gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
213 gen_absence_set, gen_final_absence_set, gen_automaton,
214 gen_automata_option, gen_reserv, gen_insn_reserv,
215 initiate_automaton_gen, expand_automata, write_automata are
216 described on the file top because the functions are called from
219 static void *create_node (size_t);
220 static void *copy_node (const void *, size_t);
221 static char *check_name (char *, pos_t
);
222 static char *next_sep_el (char **, int, int);
223 static int n_sep_els (char *, int, int);
224 static char **get_str_vect (char *, int *, int, int);
225 static void gen_presence_absence_set (rtx
, int, int);
226 static regexp_t
gen_regexp_el (char *);
227 static regexp_t
gen_regexp_repeat (char *);
228 static regexp_t
gen_regexp_allof (char *);
229 static regexp_t
gen_regexp_oneof (char *);
230 static regexp_t
gen_regexp_sequence (char *);
231 static regexp_t
gen_regexp (char *);
233 static unsigned string_hash (const char *);
234 static unsigned automaton_decl_hash (const void *);
235 static int automaton_decl_eq_p (const void *,
237 static decl_t
insert_automaton_decl (decl_t
);
238 static decl_t
find_automaton_decl (char *);
239 static void initiate_automaton_decl_table (void);
240 static void finish_automaton_decl_table (void);
242 static hashval_t
insn_decl_hash (const void *);
243 static int insn_decl_eq_p (const void *,
245 static decl_t
insert_insn_decl (decl_t
);
246 static decl_t
find_insn_decl (char *);
247 static void initiate_insn_decl_table (void);
248 static void finish_insn_decl_table (void);
250 static hashval_t
decl_hash (const void *);
251 static int decl_eq_p (const void *,
253 static decl_t
insert_decl (decl_t
);
254 static decl_t
find_decl (char *);
255 static void initiate_decl_table (void);
256 static void finish_decl_table (void);
258 static unit_set_el_t
process_excls (char **, int, pos_t
);
259 static void add_excls (unit_set_el_t
, unit_set_el_t
,
261 static unit_set_el_t process_presence_absence_names
262 (char **, int, pos_t
,
264 static pattern_set_el_t process_presence_absence_patterns
265 (char ***, int, pos_t
,
267 static void add_presence_absence (unit_set_el_t
,
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,
281 static void evaluate_max_reserv_cycles (void);
282 static void check_all_description (void);
284 static ticker_t
create_ticker (void);
285 static void ticker_off (ticker_t
*);
286 static void ticker_on (ticker_t
*);
287 static int active_time (ticker_t
);
288 static void print_active_time (FILE *, ticker_t
);
290 static void add_advance_cycle_insn_decl (void);
292 static alt_state_t
get_free_alt_state (void);
293 static void free_alt_state (alt_state_t
);
294 static void free_alt_states (alt_state_t
);
295 static int alt_state_cmp (const void *alt_state_ptr_1
,
296 const void *alt_state_ptr_2
);
297 static alt_state_t
uniq_sort_alt_states (alt_state_t
);
298 static int alt_states_eq (alt_state_t
, alt_state_t
);
299 static void initiate_alt_states (void);
300 static void finish_alt_states (void);
302 static reserv_sets_t
alloc_empty_reserv_sets (void);
303 static unsigned reserv_sets_hash_value (reserv_sets_t
);
304 static int reserv_sets_cmp (reserv_sets_t
, reserv_sets_t
);
305 static int reserv_sets_eq (reserv_sets_t
, reserv_sets_t
);
306 static void set_unit_reserv (reserv_sets_t
, int, int);
307 static int test_unit_reserv (reserv_sets_t
, int, int);
308 static int it_is_empty_reserv_sets (reserv_sets_t
)
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
,
314 static void reserv_sets_and (reserv_sets_t
, reserv_sets_t
,
317 static void output_cycle_reservs (FILE *, reserv_sets_t
,
319 static void output_reserv_sets (FILE *, reserv_sets_t
);
320 static state_t
get_free_state (int, automaton_t
);
321 static void free_state (state_t
);
322 static hashval_t
state_hash (const void *);
323 static int state_eq_p (const void *, const void *);
324 static state_t
insert_state (state_t
);
325 static void set_state_reserv (state_t
, int, int);
326 static int intersected_state_reservs_p (state_t
, state_t
);
327 static state_t
states_union (state_t
, state_t
, reserv_sets_t
);
328 static state_t
state_shift (state_t
, reserv_sets_t
);
329 static void initiate_states (void);
330 static void finish_states (void);
332 static void free_arc (arc_t
);
333 static void remove_arc (state_t
, arc_t
);
334 static arc_t
find_arc (state_t
, state_t
, ainsn_t
);
335 static arc_t
add_arc (state_t
, state_t
, ainsn_t
, int);
336 static arc_t
first_out_arc (state_t
);
337 static arc_t
next_out_arc (arc_t
);
338 static void initiate_arcs (void);
339 static void finish_arcs (void);
341 static automata_list_el_t
get_free_automata_list_el (void);
342 static void free_automata_list_el (automata_list_el_t
);
343 static void free_automata_list (automata_list_el_t
);
344 static hashval_t
automata_list_hash (const void *);
345 static int automata_list_eq_p (const void *, const void *);
346 static void initiate_automata_lists (void);
347 static void automata_list_start (void);
348 static void automata_list_add (automaton_t
);
349 static automata_list_el_t
automata_list_finish (void);
350 static void finish_automata_lists (void);
352 static void initiate_excl_sets (void);
353 static reserv_sets_t
get_excl_set (reserv_sets_t
);
355 static pattern_reserv_t
form_reserv_sets_list (pattern_set_el_t
);
356 static void initiate_presence_absence_pattern_sets (void);
357 static int check_presence_pattern_sets (reserv_sets_t
,
359 static int check_absence_pattern_sets (reserv_sets_t
, reserv_sets_t
,
362 static regexp_t
copy_insn_regexp (regexp_t
);
363 static regexp_t
transform_1 (regexp_t
);
364 static regexp_t
transform_2 (regexp_t
);
365 static regexp_t
transform_3 (regexp_t
);
366 static regexp_t regexp_transform_func
367 (regexp_t
, regexp_t (*) (regexp_t
));
368 static regexp_t
transform_regexp (regexp_t
);
369 static void transform_insn_regexps (void);
371 static void store_alt_unit_usage (regexp_t
, regexp_t
, int, int);
372 static void check_regexp_units_distribution (const char *, regexp_t
);
373 static void check_unit_distributions_to_automata (void);
375 static int process_seq_for_forming_states (regexp_t
, automaton_t
,
377 static void finish_forming_alt_state (alt_state_t
,
379 static void process_alts_for_forming_states (regexp_t
,
381 static void create_alt_states (automaton_t
);
383 static void form_ainsn_with_same_reservs (automaton_t
);
385 static reserv_sets_t
form_reservs_matter (automaton_t
);
386 static void make_automaton (automaton_t
);
387 static void form_arcs_marked_by_insn (state_t
);
388 static int create_composed_state (state_t
, arc_t
, vla_ptr_t
*);
389 static void NDFA_to_DFA (automaton_t
);
390 static void pass_state_graph (state_t
, void (*) (state_t
));
391 static void pass_states (automaton_t
,
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,
404 static void evaluate_equiv_classes (automaton_t
, vla_ptr_t
*);
405 static void merge_states (automaton_t
, vla_ptr_t
*);
406 static void set_new_cycle_flags (state_t
);
407 static void minimize_DFA (automaton_t
);
408 static void incr_states_and_arcs_nums (state_t
);
409 static void count_states_and_arcs (automaton_t
, int *, int *);
410 static void build_automaton (automaton_t
);
412 static void set_order_state_num (state_t
);
413 static void enumerate_states (automaton_t
);
415 static ainsn_t
insert_ainsn_into_equiv_class (ainsn_t
, ainsn_t
);
416 static void delete_ainsn_from_equiv_class (ainsn_t
);
417 static void process_insn_equiv_class (ainsn_t
, arc_t
*);
418 static void process_state_for_insn_equiv_partition (state_t
);
419 static void set_insn_equiv_classes (automaton_t
);
421 static double estimate_one_automaton_bound (void);
422 static int compare_max_occ_cycle_nums (const void *,
424 static void units_to_automata_heuristic_distr (void);
425 static ainsn_t
create_ainsns (void);
426 static void units_to_automata_distr (void);
427 static void create_automata (void);
429 static void form_regexp (regexp_t
);
430 static const char *regexp_representation (regexp_t
);
431 static void finish_regexp_representation (void);
433 static void output_range_type (FILE *, long int, long int);
434 static int longest_path_length (state_t
);
435 static void process_state_longest_path_length (state_t
);
436 static void output_dfa_max_issue_rate (void);
437 static void output_vect (vect_el_t
*, int);
438 static void output_chip_member_name (FILE *, automaton_t
);
439 static void output_temp_chip_member_name (FILE *, automaton_t
);
440 static void output_translate_vect_name (FILE *, automaton_t
);
441 static void output_trans_full_vect_name (FILE *, automaton_t
);
442 static void output_trans_comb_vect_name (FILE *, automaton_t
);
443 static void output_trans_check_vect_name (FILE *, automaton_t
);
444 static void output_trans_base_vect_name (FILE *, automaton_t
);
445 static void output_state_alts_full_vect_name (FILE *, automaton_t
);
446 static void output_state_alts_comb_vect_name (FILE *, automaton_t
);
447 static void output_state_alts_check_vect_name (FILE *, automaton_t
);
448 static void output_state_alts_base_vect_name (FILE *, automaton_t
);
449 static void output_min_issue_delay_vect_name (FILE *, automaton_t
);
450 static void output_dead_lock_vect_name (FILE *, automaton_t
);
451 static void output_reserved_units_table_name (FILE *, automaton_t
);
452 static void output_state_member_type (FILE *, automaton_t
);
453 static void output_chip_definitions (void);
454 static void output_translate_vect (automaton_t
);
455 static int comb_vect_p (state_ainsn_table_t
);
456 static state_ainsn_table_t
create_state_ainsn_table (automaton_t
);
457 static void output_state_ainsn_table
458 (state_ainsn_table_t
, char *, void (*) (FILE *, automaton_t
),
459 void (*) (FILE *, automaton_t
), void (*) (FILE *, automaton_t
),
460 void (*) (FILE *, automaton_t
));
461 static void add_vect (state_ainsn_table_t
,
462 int, vect_el_t
*, int);
463 static int out_state_arcs_num (state_t
);
464 static int compare_transition_els_num (const void *, const void *);
465 static void add_vect_el (vla_hwint_t
*,
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 *,
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 *,
502 static void output_get_cpu_unit_code_func (void);
503 static void output_cpu_unit_reservation_p (void);
504 static void output_dfa_clean_insn_cache_func (void);
505 static void output_dfa_start_func (void);
506 static void output_dfa_finish_func (void);
508 static void output_regexp (regexp_t
);
509 static void output_unit_set_el_list (unit_set_el_t
);
510 static void output_pattern_set_el_list (pattern_set_el_t
);
511 static void output_description (void);
512 static void output_automaton_name (FILE *, automaton_t
);
513 static void output_automaton_units (automaton_t
);
514 static void add_state_reservs (state_t
);
515 static void output_state_arcs (state_t
);
516 static int state_reservs_cmp (const void *,
518 static void remove_state_duplicate_reservs (void);
519 static void output_state (state_t
);
520 static void output_automaton_descriptions (void);
521 static void output_statistics (FILE *);
522 static void output_time_statistics (FILE *);
523 static void generate (void);
525 static void make_insn_alts_attr (void);
526 static void make_internal_dfa_insn_code_attr (void);
527 static void make_default_insn_latency_attr (void);
528 static void make_bypass_attr (void);
529 static const char *file_name_suffix (const char *);
530 static const char *base_file_name (const char *);
531 static void check_automata_insn_issues (void);
532 static void add_automaton_state (state_t
);
533 static void form_important_insn_automata_lists (void);
535 /* Undefined position. */
536 static pos_t no_pos
= 0;
538 /* All IR is stored in the following obstack. */
539 static struct obstack irp
;
543 /* This page contains code for work with variable length array (vla)
544 of pointers. We could be use only varray. But we add new lay
545 because we add elements very frequently and this could stress OS
546 allocator when varray is used only. */
548 /* Start work with vla. */
549 #define VLA_PTR_CREATE(vla, allocated_length, name) \
552 vla_ptr_t *const _vla_ptr = &(vla); \
554 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
555 _vla_ptr->length = 0; \
559 /* Finish work with the vla. */
560 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
562 /* Return start address of the vla. */
563 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
565 /* Address of the last element of the vla. Do not use side effects in
566 the macro argument. */
567 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
569 /* Nullify the vla. */
570 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
572 /* Shorten the vla on given number bytes. */
573 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
575 /* Expand the vla on N elements. The values of new elements are
577 #define VLA_PTR_EXPAND(vla, n) \
579 vla_ptr_t *const _expand_vla_ptr = &(vla); \
580 const size_t _new_length = (n) + _expand_vla_ptr->length; \
582 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
583 VARRAY_GROW (_expand_vla_ptr->varray, \
584 (_new_length - _expand_vla_ptr->length < 128 \
585 ? _expand_vla_ptr->length + 128 : _new_length)); \
586 _expand_vla_ptr->length = _new_length; \
589 /* Add element to the end of the vla. */
590 #define VLA_PTR_ADD(vla, ptr) \
592 vla_ptr_t *const _vla_ptr = &(vla); \
594 VLA_PTR_EXPAND (*_vla_ptr, 1); \
595 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
598 /* Length of the vla in elements. */
599 #define VLA_PTR_LENGTH(vla) ((vla).length)
601 /* N-th element of the vla. */
602 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
605 /* The following macros are analogous to the previous ones but for
606 VLAs of HOST WIDE INTs. */
608 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
610 vla_hwint_t *const _vla_ptr = &(vla); \
612 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
613 _vla_ptr->length = 0; \
616 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
618 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
620 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
622 #define VLA_HWINT_EXPAND(vla, n) \
624 vla_hwint_t *const _expand_vla_ptr = &(vla); \
625 const size_t _new_length = (n) + _expand_vla_ptr->length; \
627 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
628 VARRAY_GROW (_expand_vla_ptr->varray, \
629 (_new_length - _expand_vla_ptr->length < 128 \
630 ? _expand_vla_ptr->length + 128 : _new_length)); \
631 _expand_vla_ptr->length = _new_length; \
634 #define VLA_HWINT_ADD(vla, ptr) \
636 vla_hwint_t *const _vla_ptr = &(vla); \
638 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
639 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
642 #define VLA_HWINT_LENGTH(vla) ((vla).length)
644 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
648 /* Options with the following names can be set up in automata_option
649 construction. Because the strings occur more one time we use the
652 #define NO_MINIMIZATION_OPTION "-no-minimization"
654 #define TIME_OPTION "-time"
656 #define V_OPTION "-v"
658 #define W_OPTION "-w"
660 #define NDFA_OPTION "-ndfa"
662 #define PROGRESS_OPTION "-progress"
664 /* The following flags are set up by function `initiate_automaton_gen'. */
666 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
667 static int ndfa_flag
;
669 /* Do not make minimization of DFA (`-no-minimization'). */
670 static int no_minimization_flag
;
672 /* Value of this variable is number of automata being generated. The
673 actual number of automata may be less this value if there is not
674 sufficient number of units. This value is defined by argument of
675 option `-split' or by constructions automaton if the value is zero
676 (it is default value of the argument). */
677 static int split_argument
;
679 /* Flag of output time statistics (`-time'). */
680 static int time_flag
;
682 /* Flag of creation of description file which contains description of
683 result automaton and statistics information (`-v'). */
686 /* Flag of output of a progress bar showing how many states were
687 generated so far for automaton being processed (`-progress'). */
688 static int progress_flag
;
690 /* Flag of generating warning instead of error for non-critical errors
695 /* Output file for pipeline hazard recognizer (PHR) being generated.
696 The value is NULL if the file is not defined. */
697 static FILE *output_file
;
699 /* Description file of PHR. The value is NULL if the file is not
701 static FILE *output_description_file
;
703 /* PHR description file name. */
704 static char *output_description_file_name
;
706 /* Value of the following variable is node representing description
707 being processed. This is start point of IR. */
708 static struct description
*description
;
712 /* This page contains description of IR structure (nodes). */
726 /* This describes define_cpu_unit and define_query_cpu_unit (see file
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. */
737 /* The following fields are defined by checker. */
739 /* The following field value is nonzero if the unit is used in an
743 /* The following field value is order number (0, 1, ...) of given
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
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. */
772 /* The following is the last cycle on which the unit was checked for
773 correct distributions of units to automata in a regexp. */
774 int last_distribution_check_cycle
;
776 /* The following fields are defined by automaton generator. */
778 /* The following field value is number of the automaton to which
779 given unit belongs. */
780 int corresponding_automaton_num
;
781 /* If the following value is not zero, the cpu unit is present in a
782 `exclusion_set' or in right part of a `presence_set',
783 `final_presence_set', `absence_set', and
784 `final_absence_set'define_query_cpu_unit. */
788 /* This describes define_bypass (see file rtl.def). */
794 char *bypass_guard_name
;
796 /* The following fields are defined by checker. */
798 /* output and input insns of given bypass. */
799 struct insn_reserv_decl
*out_insn_reserv
;
800 struct insn_reserv_decl
*in_insn_reserv
;
801 /* The next bypass for given output insn. */
802 struct bypass_decl
*next
;
805 /* This describes define_automaton (see file rtl.def). */
806 struct automaton_decl
810 /* The following fields are defined by automaton generator. */
812 /* The following field value is nonzero if the automaton is used in
813 an regexp definition. */
814 char automaton_is_used
;
816 /* The following fields are defined by checker. */
818 /* The following field value is the corresponding automaton. This
819 field is not NULL only if the automaton is present in unit
820 declarations and the automatic partition on automata is not
822 automaton_t corresponding_automaton
;
825 /* This describes exclusion relations: exclusion_set (see file
830 int first_list_length
;
834 /* This describes unit relations: [final_]presence_set or
835 [final_]absence_set (see file rtl.def). */
836 struct unit_pattern_rel_decl
845 /* This describes define_reservation (see file rtl.def). */
851 /* The following fields are defined by checker. */
853 /* The following field value is nonzero if the unit is used in an
856 /* The following field is used to check up cycle in expression
861 /* This describes define_insn_reservation (see file rtl.def). */
862 struct insn_reserv_decl
869 /* The following fields are defined by checker. */
871 /* The following field value is order number (0, 1, ...) of given
874 /* The following field value is list of bypasses in which given insn
876 struct bypass_decl
*bypass_list
;
878 /* The following fields are defined by automaton generator. */
880 /* The following field is the insn regexp transformed that
881 the regexp has not optional regexp, repetition regexp, and an
882 reservation name (i.e. reservation identifiers are changed by the
883 corresponding regexp) and all alternations are the topest level
884 of the regexp. The value can be NULL only if it is special
885 insn `cycle advancing'. */
886 regexp_t transformed_regexp
;
887 /* The following field value is list of arcs marked given
888 insn. The field is used in transformation NDFA -> DFA. */
889 arc_t arcs_marked_by_insn
;
890 /* The two following fields are used during minimization of a finite state
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). */
896 /* The field value is state_alts of arc leaving a state (fixed
897 during an automaton minimization) and marked by given insn
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. */
907 /* This contains a declaration mentioned above. */
910 /* What node in the union? */
915 struct unit_decl unit
;
916 struct bypass_decl bypass
;
917 struct automaton_decl automaton
;
918 struct excl_rel_decl excl
;
919 struct unit_pattern_rel_decl presence
;
920 struct unit_pattern_rel_decl absence
;
921 struct reserv_decl reserv
;
922 struct insn_reserv_decl insn_reserv
;
926 /* The following structures represent parsed reservation strings. */
938 /* Cpu unit in reservation. */
942 unit_decl_t unit_decl
;
945 /* Define_reservation in a reservation. */
949 struct reserv_decl
*reserv_decl
;
952 /* Absence of reservation (represented by string `nothing'). */
953 struct nothing_regexp
955 /* This used to be empty but ISO C doesn't allow that. */
959 /* Representation of reservations separated by ',' (see file
961 struct sequence_regexp
964 regexp_t regexps
[1];
967 /* Representation of construction `repeat' (see file rtl.def). */
974 /* Representation of reservations separated by '+' (see file
979 regexp_t regexps
[1];
982 /* Representation of reservations separated by '|' (see file
987 regexp_t regexps
[1];
990 /* Representation of a reservation string. */
993 /* What node in the union? */
994 enum regexp_mode mode
;
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
;
1008 /* Represents description of pipeline hazard description based on
1014 /* The following fields are defined by checker. */
1016 /* The following fields values are correspondingly number of all
1017 units, query units, and insns in the description. */
1019 int query_units_num
;
1021 /* The following field value is max length (in cycles) of
1022 reservations of insns. The field value is defined only for
1023 correct programs. */
1024 int max_insn_reserv_cycles
;
1026 /* The following fields are defined by automaton generator. */
1028 /* The following field value is the first automaton. */
1029 automaton_t first_automaton
;
1031 /* The following field is created by pipeline hazard parser and
1032 contains all declarations. We allocate additional entry for
1033 special insn "cycle advancing" which is added by the automaton
1039 /* The following nodes are created in automaton checker. */
1041 /* The following nodes represent exclusion set for cpu units. Each
1042 element is accessed through only one excl_list. */
1045 unit_decl_t unit_decl
;
1046 unit_set_el_t next_unit_set_el
;
1049 /* The following nodes represent presence or absence pattern for cpu
1050 units. Each element is accessed through only one presence_list or
1052 struct pattern_set_el
1054 /* The number of units in unit_decls. */
1056 /* The units forming the pattern. */
1057 struct unit_decl
**unit_decls
;
1058 pattern_set_el_t next_pattern_set_el
;
1062 /* The following nodes are created in automaton generator. */
1065 /* The following nodes represent presence or absence pattern for cpu
1066 units. Each element is accessed through only one element of
1067 unit_presence_set_table or unit_absence_set_table. */
1068 struct pattern_reserv
1070 reserv_sets_t reserv
;
1071 pattern_reserv_t next_pattern_reserv
;
1074 /* The following node type describes state automaton. The state may
1075 be deterministic or non-deterministic. Non-deterministic state has
1076 several component states which represent alternative cpu units
1077 reservations. The state also is used for describing a
1078 deterministic reservation of automaton insn. */
1081 /* The following member value is nonzero if there is a transition by
1084 /* The following field is list of processor unit reservations on
1086 reserv_sets_t reservs
;
1087 /* The following field is unique number of given state between other
1090 /* The following field value is automaton to which given state
1092 automaton_t automaton
;
1093 /* The following field value is the first arc output from given
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. */
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
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
1122 int order_state_num
;
1123 /* This member is used for passing states for searching minimal
1126 /* The following member is used to evaluate min issue delay of insn
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
1133 int longest_path_length
;
1136 /* The following macro is an initial value of member
1137 `longest_path_length' of a state. */
1138 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1140 /* Automaton arc. */
1143 /* The following field refers for the state into which given arc
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. */
1151 /* The following field value is the next arc output from the same
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. */
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. */
1168 /* The following field is a deterministic state which characterizes
1169 unit reservations of the instruction. */
1171 /* The following field refers to the next state which characterizes
1172 unit reservations of the instruction. */
1173 alt_state_t next_alt_state
;
1174 /* The following field refers to the next state in sorted list. */
1175 alt_state_t next_sorted_alt_state
;
1178 /* The following node type describes insn of automaton. They are
1179 labels of FA arcs. */
1182 /* The following field value is the corresponding insn declaration
1184 struct insn_reserv_decl
*insn_reserv_decl
;
1185 /* The following field value is the next insn declaration for an
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
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. */
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. */
1224 /* The following describes an automaton for PHR. */
1227 /* The following field value is the list of insn declarations for
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
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
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
1257 int minimal_DFA_arcs_num
;
1258 /* The following two members refer for two table state x ainsn ->
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. */
1265 /* Usually min issue delay is small and we can place several (2, 4,
1266 8) elements in one vector element. So the compression factor can
1267 be 1 (no compression), 2, 4, 8. */
1268 int min_issue_delay_table_compression_factor
;
1271 /* The following is the element of the list of automata. */
1272 struct automata_list_el
1274 /* The automaton itself. */
1275 automaton_t automaton
;
1276 /* The next automata set element. */
1277 automata_list_el_t next_automata_list_el
;
1280 /* The following structure describes a table state X ainsn -> int(>= 0). */
1281 struct state_ainsn_table
1283 /* Automaton to which given table belongs. */
1284 automaton_t automaton
;
1285 /* The following tree vectors for comb vector implementation of the
1287 vla_hwint_t comb_vect
;
1288 vla_hwint_t check_vect
;
1289 vla_hwint_t base_vect
;
1290 /* This is simple implementation of the table. */
1291 vla_hwint_t full_vect
;
1292 /* Minimal and maximal values of the previous vectors. */
1293 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1294 int min_base_vect_el_value
, max_base_vect_el_value
;
1297 /* Macros to access members of unions. Use only them for access to
1298 union members of declarations and regexps. */
1300 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1302 #define DECL_UNIT(d) __extension__ \
1303 (({ struct decl *const _decl = (d); \
1304 if (_decl->mode != dm_unit) \
1305 decl_mode_check_failed (_decl->mode, "dm_unit", \
1306 __FILE__, __LINE__, __FUNCTION__); \
1307 &(_decl)->decl.unit; }))
1309 #define DECL_BYPASS(d) __extension__ \
1310 (({ struct decl *const _decl = (d); \
1311 if (_decl->mode != dm_bypass) \
1312 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1313 __FILE__, __LINE__, __FUNCTION__); \
1314 &(_decl)->decl.bypass; }))
1316 #define DECL_AUTOMATON(d) __extension__ \
1317 (({ struct decl *const _decl = (d); \
1318 if (_decl->mode != dm_automaton) \
1319 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1320 __FILE__, __LINE__, __FUNCTION__); \
1321 &(_decl)->decl.automaton; }))
1323 #define DECL_EXCL(d) __extension__ \
1324 (({ struct decl *const _decl = (d); \
1325 if (_decl->mode != dm_excl) \
1326 decl_mode_check_failed (_decl->mode, "dm_excl", \
1327 __FILE__, __LINE__, __FUNCTION__); \
1328 &(_decl)->decl.excl; }))
1330 #define DECL_PRESENCE(d) __extension__ \
1331 (({ struct decl *const _decl = (d); \
1332 if (_decl->mode != dm_presence) \
1333 decl_mode_check_failed (_decl->mode, "dm_presence", \
1334 __FILE__, __LINE__, __FUNCTION__); \
1335 &(_decl)->decl.presence; }))
1337 #define DECL_ABSENCE(d) __extension__ \
1338 (({ struct decl *const _decl = (d); \
1339 if (_decl->mode != dm_absence) \
1340 decl_mode_check_failed (_decl->mode, "dm_absence", \
1341 __FILE__, __LINE__, __FUNCTION__); \
1342 &(_decl)->decl.absence; }))
1344 #define DECL_RESERV(d) __extension__ \
1345 (({ struct decl *const _decl = (d); \
1346 if (_decl->mode != dm_reserv) \
1347 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1348 __FILE__, __LINE__, __FUNCTION__); \
1349 &(_decl)->decl.reserv; }))
1351 #define DECL_INSN_RESERV(d) __extension__ \
1352 (({ struct decl *const _decl = (d); \
1353 if (_decl->mode != dm_insn_reserv) \
1354 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1355 __FILE__, __LINE__, __FUNCTION__); \
1356 &(_decl)->decl.insn_reserv; }))
1358 static const char *decl_name (enum decl_mode
);
1359 static void decl_mode_check_failed (enum decl_mode
, const char *,
1360 const char *, int, const char *)
1363 /* Return string representation of declaration mode MODE. */
1365 decl_name (enum decl_mode mode
)
1367 static char str
[100];
1369 if (mode
== dm_unit
)
1371 else if (mode
== dm_bypass
)
1373 else if (mode
== dm_automaton
)
1374 return "dm_automaton";
1375 else if (mode
== 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
)
1383 else if (mode
== dm_insn_reserv
)
1384 return "dm_insn_reserv";
1386 sprintf (str
, "unknown (%d)", (int) mode
);
1390 /* The function prints message about unexpected declaration and finish
1393 decl_mode_check_failed (enum decl_mode mode
, const char *expected_mode_str
,
1394 const char *file
, int line
, const char *func
)
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
));
1404 #define REGEXP_UNIT(r) __extension__ \
1405 (({ struct regexp *const _regexp = (r); \
1406 if (_regexp->mode != rm_unit) \
1407 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1408 __FILE__, __LINE__, __FUNCTION__); \
1409 &(_regexp)->regexp.unit; }))
1411 #define REGEXP_RESERV(r) __extension__ \
1412 (({ struct regexp *const _regexp = (r); \
1413 if (_regexp->mode != rm_reserv) \
1414 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1415 __FILE__, __LINE__, __FUNCTION__); \
1416 &(_regexp)->regexp.reserv; }))
1418 #define REGEXP_SEQUENCE(r) __extension__ \
1419 (({ struct regexp *const _regexp = (r); \
1420 if (_regexp->mode != rm_sequence) \
1421 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1422 __FILE__, __LINE__, __FUNCTION__); \
1423 &(_regexp)->regexp.sequence; }))
1425 #define REGEXP_REPEAT(r) __extension__ \
1426 (({ struct regexp *const _regexp = (r); \
1427 if (_regexp->mode != rm_repeat) \
1428 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1429 __FILE__, __LINE__, __FUNCTION__); \
1430 &(_regexp)->regexp.repeat; }))
1432 #define REGEXP_ALLOF(r) __extension__ \
1433 (({ struct regexp *const _regexp = (r); \
1434 if (_regexp->mode != rm_allof) \
1435 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1436 __FILE__, __LINE__, __FUNCTION__); \
1437 &(_regexp)->regexp.allof; }))
1439 #define REGEXP_ONEOF(r) __extension__ \
1440 (({ struct regexp *const _regexp = (r); \
1441 if (_regexp->mode != rm_oneof) \
1442 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1443 __FILE__, __LINE__, __FUNCTION__); \
1444 &(_regexp)->regexp.oneof; }))
1446 static const char *regexp_name (enum regexp_mode
);
1447 static void regexp_mode_check_failed (enum regexp_mode
, const char *,
1449 const char *) ATTRIBUTE_NORETURN
;
1452 /* Return string representation of regexp mode MODE. */
1454 regexp_name (enum regexp_mode mode
)
1463 return "rm_nothing";
1465 return "rm_sequence";
1477 /* The function prints message about unexpected regexp and finish the
1480 regexp_mode_check_failed (enum regexp_mode mode
,
1481 const char *expected_mode_str
,
1482 const char *file
, int line
, const char *func
)
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
));
1491 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1493 #define DECL_UNIT(d) (&(d)->decl.unit)
1494 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1495 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1496 #define DECL_EXCL(d) (&(d)->decl.excl)
1497 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1498 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1499 #define DECL_RESERV(d) (&(d)->decl.reserv)
1500 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1502 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1503 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1504 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1505 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1506 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1507 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1509 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1511 /* Create IR structure (node). */
1513 create_node (size_t size
)
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
);
1525 /* Copy IR structure (node). */
1527 copy_node (const void *from
, size_t size
)
1529 void *const result
= create_node (size
);
1530 memcpy (result
, from
, size
);
1534 /* The function checks that NAME does not contain quotes (`"'). */
1536 check_name (char * name
, pos_t pos ATTRIBUTE_UNUSED
)
1540 for (str
= name
; *str
!= '\0'; str
++)
1542 error ("Name `%s' contains quotes", name
);
1546 /* Pointers to all declarations during IR generation are stored in the
1548 static vla_ptr_t decls
;
1550 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1551 string containing the next separated element, taking parentheses
1552 into account if PAR_FLAG has nonzero value. Advance the pointer to
1553 after the string scanned, or the end-of-string. Return NULL if at
1556 next_sep_el (char **pstr
, int sep
, int par_flag
)
1563 /* Remove leading whitespaces. */
1564 while (ISSPACE ((int) **pstr
))
1571 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1573 if (par_flag
&& *p
== '(')
1575 else if (par_flag
&& *p
== ')')
1577 else if (pars_num
== 0 && *p
== sep
)
1579 if (pars_num
== 0 && ISSPACE ((int) *p
))
1583 for (; n_spaces
!= 0; n_spaces
--)
1584 obstack_1grow (&irp
, p
[-n_spaces
]);
1585 obstack_1grow (&irp
, *p
);
1588 obstack_1grow (&irp
, '\0');
1589 out_str
= obstack_base (&irp
);
1590 obstack_finish (&irp
);
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
1604 n_sep_els (char *s
, int sep
, int par_flag
)
1612 for (pars_num
= 0, n
= 1; *s
; s
++)
1613 if (par_flag
&& *s
== '(')
1615 else if (par_flag
&& *s
== ')')
1617 else if (pars_num
== 0 && *s
== sep
)
1620 return (pars_num
!= 0 ? -1 : n
);
1623 /* Given a string and a separator, return vector of strings which are
1624 elements in the string and number of elements through els_num.
1625 Take parentheses into account if PAREN_P has nonzero value. The
1626 function also inserts the end marker NULL at the end of vector.
1627 Return 0 for the null string, -1 if parentheses are not balanced. */
1629 get_str_vect (char *str
, int *els_num
, int sep
, int paren_p
)
1636 *els_num
= n_sep_els (str
, sep
, paren_p
);
1639 obstack_blank (&irp
, sizeof (char *) * (*els_num
+ 1));
1640 vect
= (char **) obstack_base (&irp
);
1641 obstack_finish (&irp
);
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
);
1651 /* Process a DEFINE_CPU_UNIT.
1653 This gives information about a unit contained in CPU. We fill a
1654 struct unit_decl with information used later by `expand_automata'. */
1656 gen_cpu_unit (rtx def
)
1659 char **str_cpu_units
;
1663 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',',
1665 if (str_cpu_units
== NULL
)
1666 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1667 for (i
= 0; i
< vect_length
; i
++)
1669 decl
= create_node (sizeof (struct decl
));
1670 decl
->mode
= dm_unit
;
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
);
1682 /* Process a DEFINE_QUERY_CPU_UNIT.
1684 This gives information about a unit contained in CPU. We fill a
1685 struct unit_decl with information used later by `expand_automata'. */
1687 gen_query_cpu_unit (rtx def
)
1690 char **str_cpu_units
;
1694 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',',
1696 if (str_cpu_units
== NULL
)
1697 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1698 for (i
= 0; i
< vect_length
; i
++)
1700 decl
= create_node (sizeof (struct decl
));
1701 decl
->mode
= dm_unit
;
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
);
1711 /* Process a DEFINE_BYPASS.
1713 This gives information about a unit contained in the CPU. We fill
1714 in a struct bypass_decl with information used later by
1715 `expand_automata'. */
1717 gen_bypass (rtx def
)
1726 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', FALSE
);
1727 if (out_insns
== NULL
)
1728 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1729 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', FALSE
);
1730 if (in_insns
== NULL
)
1731 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1732 for (i
= 0; i
< out_length
; i
++)
1733 for (j
= 0; j
< in_length
; j
++)
1735 decl
= create_node (sizeof (struct decl
));
1736 decl
->mode
= dm_bypass
;
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
);
1747 /* Process an EXCLUSION_SET.
1749 This gives information about a cpu unit conflicts. We fill a
1750 struct excl_rel_decl (excl) with information used later by
1751 `expand_automata'. */
1753 gen_excl_set (rtx def
)
1756 char **first_str_cpu_units
;
1757 char **second_str_cpu_units
;
1758 int first_vect_length
;
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
, ',',
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
;
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
];
1780 DECL_EXCL (decl
)->names
[i
]
1781 = second_str_cpu_units
[i
- first_vect_length
];
1782 VLA_PTR_ADD (decls
, decl
);
1786 /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1787 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1789 This gives information about a cpu unit reservation requirements.
1790 We fill a struct unit_pattern_rel_decl with information used later
1791 by `expand_automata'. */
1793 gen_presence_absence_set (rtx def
, int presence_p
, int final_p
)
1796 char **str_cpu_units
;
1797 char ***str_patterns
;
1798 int cpu_units_length
;
1800 int patterns_length
;
1803 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &cpu_units_length
, ',',
1805 if (str_cpu_units
== NULL
)
1808 ? "invalid first string `%s' in final_presence_set"
1809 : "invalid first string `%s' in presence_set")
1811 ? "invalid first string `%s' in final_absence_set"
1812 : "invalid first string `%s' in absence_set")),
1814 str_patterns
= (char ***) get_str_vect ((char *) XSTR (def
, 1),
1815 &patterns_length
, ',', FALSE
);
1816 if (str_patterns
== NULL
)
1819 ? "invalid second string `%s' in final_presence_set"
1820 : "invalid second string `%s' in presence_set")
1822 ? "invalid second string `%s' in final_absence_set"
1823 : "invalid second string `%s' in absence_set")), XSTR (def
, 1));
1824 for (i
= 0; i
< patterns_length
; i
++)
1826 str_patterns
[i
] = get_str_vect ((char *) str_patterns
[i
], &length
, ' ',
1828 gcc_assert (str_patterns
[i
]);
1830 decl
= create_node (sizeof (struct decl
));
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
;
1843 decl
->mode
= dm_absence
;
1844 DECL_ABSENCE (decl
)->names_num
= cpu_units_length
;
1845 DECL_ABSENCE (decl
)->names
= str_cpu_units
;
1846 DECL_ABSENCE (decl
)->patterns
= str_patterns
;
1847 DECL_ABSENCE (decl
)->patterns_num
= patterns_length
;
1848 DECL_ABSENCE (decl
)->final_p
= final_p
;
1850 VLA_PTR_ADD (decls
, decl
);
1854 /* Process a PRESENCE_SET.
1856 This gives information about a cpu unit reservation requirements.
1857 We fill a struct unit_pattern_rel_decl (presence) with information
1858 used later by `expand_automata'. */
1860 gen_presence_set (rtx def
)
1862 gen_presence_absence_set (def
, TRUE
, FALSE
);
1865 /* Process a FINAL_PRESENCE_SET.
1867 This gives information about a cpu unit reservation requirements.
1868 We fill a struct unit_pattern_rel_decl (presence) with information
1869 used later by `expand_automata'. */
1871 gen_final_presence_set (rtx def
)
1873 gen_presence_absence_set (def
, TRUE
, TRUE
);
1876 /* Process an ABSENCE_SET.
1878 This gives information about a cpu unit reservation requirements.
1879 We fill a struct unit_pattern_rel_decl (absence) with information
1880 used later by `expand_automata'. */
1882 gen_absence_set (rtx def
)
1884 gen_presence_absence_set (def
, FALSE
, FALSE
);
1887 /* Process a FINAL_ABSENCE_SET.
1889 This gives information about a cpu unit reservation requirements.
1890 We fill a struct unit_pattern_rel_decl (absence) with information
1891 used later by `expand_automata'. */
1893 gen_final_absence_set (rtx def
)
1895 gen_presence_absence_set (def
, FALSE
, TRUE
);
1898 /* Process a DEFINE_AUTOMATON.
1900 This gives information about a finite state automaton used for
1901 recognizing pipeline hazards. We fill a struct automaton_decl
1902 with information used later by `expand_automata'. */
1904 gen_automaton (rtx def
)
1907 char **str_automata
;
1911 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',',
1913 if (str_automata
== NULL
)
1914 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1915 for (i
= 0; i
< vect_length
; i
++)
1917 decl
= create_node (sizeof (struct decl
));
1918 decl
->mode
= dm_automaton
;
1920 DECL_AUTOMATON (decl
)->name
= check_name (str_automata
[i
], decl
->pos
);
1921 VLA_PTR_ADD (decls
, decl
);
1926 /* Process an AUTOMATA_OPTION.
1928 This gives information how to generate finite state automaton used
1929 for recognizing pipeline hazards. */
1931 gen_automata_option (rtx def
)
1933 if (strcmp (XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1934 no_minimization_flag
= 1;
1935 else if (strcmp (XSTR (def
, 0), TIME_OPTION
+ 1) == 0)
1937 else if (strcmp (XSTR (def
, 0), V_OPTION
+ 1) == 0)
1939 else if (strcmp (XSTR (def
, 0), W_OPTION
+ 1) == 0)
1941 else if (strcmp (XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1943 else if (strcmp (XSTR (def
, 0), PROGRESS_OPTION
+ 1) == 0)
1946 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1949 /* Name in reservation to denote absence reservation. */
1950 #define NOTHING_NAME "nothing"
1952 /* The following string contains original reservation string being
1954 static char *reserv_str
;
1956 /* Parse an element in STR. */
1958 gen_regexp_el (char *str
)
1966 if (str
[len
- 1] != ')')
1967 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1968 str
[len
- 1] = '\0';
1969 regexp
= gen_regexp_sequence (str
+ 1);
1971 else if (strcmp (str
, NOTHING_NAME
) == 0)
1973 regexp
= create_node (sizeof (struct decl
));
1974 regexp
->mode
= rm_nothing
;
1978 regexp
= create_node (sizeof (struct decl
));
1979 regexp
->mode
= rm_unit
;
1980 REGEXP_UNIT (regexp
)->name
= str
;
1985 /* Parse construction `repeat' in STR. */
1987 gen_regexp_repeat (char *str
)
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
);
2000 regexp
= gen_regexp_el (repeat_vect
[0]);
2001 for (i
= 1; i
< els_num
; i
++)
2003 repeat
= create_node (sizeof (struct regexp
));
2004 repeat
->mode
= rm_repeat
;
2005 REGEXP_REPEAT (repeat
)->regexp
= regexp
;
2006 REGEXP_REPEAT (repeat
)->repeat_num
= atoi (repeat_vect
[i
]);
2007 if (REGEXP_REPEAT (repeat
)->repeat_num
<= 1)
2008 fatal ("repetition `%s' <= 1 in reservation `%s'",
2015 return gen_regexp_el (str
);
2018 /* Parse reservation STR which possibly contains separator '+'. */
2020 gen_regexp_allof (char *str
)
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
);
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
]);
2041 return gen_regexp_repeat (str
);
2044 /* Parse reservation STR which possibly contains separator '|'. */
2046 gen_regexp_oneof (char *str
)
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
);
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
]);
2067 return gen_regexp_allof (str
);
2070 /* Parse reservation STR which possibly contains separator ','. */
2072 gen_regexp_sequence (char *str
)
2075 char **sequence_vect
;
2079 sequence_vect
= get_str_vect (str
, &els_num
, ',', TRUE
);
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
]);
2092 return gen_regexp_oneof (str
);
2095 /* Parse construction reservation STR. */
2097 gen_regexp (char *str
)
2100 return gen_regexp_sequence (str
);;
2103 /* Process a DEFINE_RESERVATION.
2105 This gives information about a reservation of cpu units. We fill
2106 in a struct reserv_decl with information used later by
2107 `expand_automata'. */
2109 gen_reserv (rtx def
)
2113 decl
= create_node (sizeof (struct decl
));
2114 decl
->mode
= dm_reserv
;
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
);
2122 /* Process a DEFINE_INSN_RESERVATION.
2124 This gives information about the reservation of cpu units by an
2125 insn. We fill a struct insn_reserv_decl with information used
2126 later by `expand_automata'. */
2128 gen_insn_reserv (rtx def
)
2132 decl
= create_node (sizeof (struct decl
));
2133 decl
->mode
= dm_insn_reserv
;
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
);
2146 /* The function evaluates hash value (0..UINT_MAX) of string. */
2148 string_hash (const char *string
)
2152 for (result
= i
= 0;*string
++ != '\0'; i
++)
2153 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
2159 /* This page contains abstract data `table of automaton declarations'.
2160 Elements of the table is nodes representing automaton declarations.
2161 Key of the table elements is name of given automaton. Remember
2162 that automaton names have own space. */
2164 /* The function evaluates hash value of an automaton declaration. The
2165 function is used by abstract data `hashtab'. The function returns
2166 hash value (0..UINT_MAX) of given automaton declaration. */
2168 automaton_decl_hash (const void *automaton_decl
)
2170 const decl_t decl
= (decl_t
) automaton_decl
;
2172 gcc_assert (decl
->mode
!= dm_automaton
2173 || DECL_AUTOMATON (decl
)->name
);
2174 return string_hash (DECL_AUTOMATON (decl
)->name
);
2177 /* The function tests automaton declarations on equality of their
2178 keys. The function is used by abstract data `hashtab'. The
2179 function returns 1 if the declarations have the same key, 0
2182 automaton_decl_eq_p (const void* automaton_decl_1
,
2183 const void* automaton_decl_2
)
2185 const decl_t decl1
= (decl_t
) automaton_decl_1
;
2186 const decl_t decl2
= (decl_t
) automaton_decl_2
;
2188 gcc_assert (decl1
->mode
== dm_automaton
2189 && DECL_AUTOMATON (decl1
)->name
2190 && decl2
->mode
== dm_automaton
2191 && DECL_AUTOMATON (decl2
)->name
);
2192 return strcmp (DECL_AUTOMATON (decl1
)->name
,
2193 DECL_AUTOMATON (decl2
)->name
) == 0;
2196 /* The automaton declaration table itself is represented by the
2197 following variable. */
2198 static htab_t automaton_decl_table
;
2200 /* The function inserts automaton declaration into the table. The
2201 function does nothing if an automaton declaration with the same key
2202 exists already in the table. The function returns automaton
2203 declaration node in the table with the same key as given automaton
2204 declaration node. */
2206 insert_automaton_decl (decl_t automaton_decl
)
2210 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
2211 if (*entry_ptr
== NULL
)
2212 *entry_ptr
= (void *) automaton_decl
;
2213 return (decl_t
) *entry_ptr
;
2216 /* The following variable value is node representing automaton
2217 declaration. The node used for searching automaton declaration
2219 static struct decl work_automaton_decl
;
2221 /* The function searches for automaton declaration in the table with
2222 the same key as node representing name of the automaton
2223 declaration. The function returns node found in the table, NULL if
2224 such node does not exist in the table. */
2226 find_automaton_decl (char *name
)
2230 work_automaton_decl
.mode
= dm_automaton
;
2231 DECL_AUTOMATON (&work_automaton_decl
)->name
= name
;
2232 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
2233 return (decl_t
) entry
;
2236 /* The function creates empty automaton declaration table and node
2237 representing automaton declaration and used for searching automaton
2238 declaration with given name. The function must be called only once
2239 before any work with the automaton declaration table. */
2241 initiate_automaton_decl_table (void)
2243 work_automaton_decl
.mode
= dm_automaton
;
2244 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
2245 automaton_decl_eq_p
, (htab_del
) 0);
2248 /* The function deletes the automaton declaration table. Only call of
2249 function `initiate_automaton_decl_table' is possible immediately
2250 after this function call. */
2252 finish_automaton_decl_table (void)
2254 htab_delete (automaton_decl_table
);
2259 /* This page contains abstract data `table of insn declarations'.
2260 Elements of the table is nodes representing insn declarations. Key
2261 of the table elements is name of given insn (in corresponding
2262 define_insn_reservation). Remember that insn names have own
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. */
2269 insn_decl_hash (const void *insn_decl
)
2271 const decl_t decl
= (decl_t
) insn_decl
;
2273 gcc_assert (decl
->mode
== dm_insn_reserv
2274 && DECL_INSN_RESERV (decl
)->name
);
2275 return string_hash (DECL_INSN_RESERV (decl
)->name
);
2278 /* The function tests insn declarations on equality of their keys.
2279 The function is used by abstract data `hashtab'. The function
2280 returns 1 if declarations have the same key, 0 otherwise. */
2282 insn_decl_eq_p (const void *insn_decl_1
, const void *insn_decl_2
)
2284 const decl_t decl1
= (decl_t
) insn_decl_1
;
2285 const decl_t decl2
= (decl_t
) insn_decl_2
;
2287 gcc_assert (decl1
->mode
== dm_insn_reserv
2288 && DECL_INSN_RESERV (decl1
)->name
2289 && decl2
->mode
== dm_insn_reserv
2290 && DECL_INSN_RESERV (decl2
)->name
);
2291 return strcmp (DECL_INSN_RESERV (decl1
)->name
,
2292 DECL_INSN_RESERV (decl2
)->name
) == 0;
2295 /* The insn declaration table itself is represented by the following
2296 variable. The table does not contain insn reservation
2298 static htab_t insn_decl_table
;
2300 /* The function inserts insn declaration into the table. The function
2301 does nothing if an insn declaration with the same key exists
2302 already in the table. The function returns insn declaration node
2303 in the table with the same key as given insn declaration node. */
2305 insert_insn_decl (decl_t insn_decl
)
2309 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2310 if (*entry_ptr
== NULL
)
2311 *entry_ptr
= (void *) insn_decl
;
2312 return (decl_t
) *entry_ptr
;
2315 /* The following variable value is node representing insn reservation
2316 declaration. The node used for searching insn reservation
2317 declaration with given name. */
2318 static struct decl work_insn_decl
;
2320 /* The function searches for insn reservation declaration in the table
2321 with the same key as node representing name of the insn reservation
2322 declaration. The function returns node found in the table, NULL if
2323 such node does not exist in the table. */
2325 find_insn_decl (char *name
)
2329 work_insn_decl
.mode
= dm_insn_reserv
;
2330 DECL_INSN_RESERV (&work_insn_decl
)->name
= name
;
2331 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2332 return (decl_t
) entry
;
2335 /* The function creates empty insn declaration table and node
2336 representing insn declaration and used for searching insn
2337 declaration with given name. The function must be called only once
2338 before any work with the insn declaration table. */
2340 initiate_insn_decl_table (void)
2342 work_insn_decl
.mode
= dm_insn_reserv
;
2343 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
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. */
2351 finish_insn_decl_table (void)
2353 htab_delete (insn_decl_table
);
2358 /* This page contains abstract data `table of declarations'. Elements
2359 of the table is nodes representing declarations (of units and
2360 reservations). Key of the table elements is names of given
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. */
2367 decl_hash (const void *decl
)
2369 const decl_t d
= (const decl_t
) decl
;
2371 gcc_assert ((d
->mode
== dm_unit
&& DECL_UNIT (d
)->name
)
2372 || (d
->mode
== dm_reserv
&& DECL_RESERV (d
)->name
));
2373 return string_hash (d
->mode
== dm_unit
2374 ? DECL_UNIT (d
)->name
: DECL_RESERV (d
)->name
);
2377 /* The function tests declarations on equality of their keys. The
2378 function is used by abstract data 'hashtab'. The function
2379 returns 1 if the declarations have the same key, 0 otherwise. */
2381 decl_eq_p (const void *decl_1
, const void *decl_2
)
2383 const decl_t d1
= (const decl_t
) decl_1
;
2384 const decl_t d2
= (const decl_t
) decl_2
;
2386 gcc_assert ((d1
->mode
== dm_unit
&& DECL_UNIT (d1
)->name
)
2387 || (d1
->mode
== dm_reserv
&& DECL_RESERV (d1
)->name
));
2388 gcc_assert ((d2
->mode
== dm_unit
&& DECL_UNIT (d2
)->name
)
2389 || (d2
->mode
== dm_reserv
&& DECL_RESERV (d2
)->name
));
2390 return strcmp ((d1
->mode
== dm_unit
2391 ? DECL_UNIT (d1
)->name
: DECL_RESERV (d1
)->name
),
2392 (d2
->mode
== dm_unit
2393 ? DECL_UNIT (d2
)->name
: DECL_RESERV (d2
)->name
)) == 0;
2396 /* The declaration table itself is represented by the following
2398 static htab_t decl_table
;
2400 /* The function inserts declaration into the table. The function does
2401 nothing if a declaration with the same key exists already in the
2402 table. The function returns declaration node in the table with the
2403 same key as given declaration node. */
2406 insert_decl (decl_t decl
)
2410 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2411 if (*entry_ptr
== NULL
)
2412 *entry_ptr
= (void *) decl
;
2413 return (decl_t
) *entry_ptr
;
2416 /* The following variable value is node representing declaration. The
2417 node used for searching declaration with given name. */
2418 static struct decl work_decl
;
2420 /* The function searches for declaration in the table with the same
2421 key as node representing name of the declaration. The function
2422 returns node found in the table, NULL if such node does not exist
2425 find_decl (char *name
)
2429 work_decl
.mode
= dm_unit
;
2430 DECL_UNIT (&work_decl
)->name
= name
;
2431 entry
= htab_find (decl_table
, &work_decl
);
2432 return (decl_t
) entry
;
2435 /* The function creates empty declaration table and node representing
2436 declaration and used for searching declaration with given name.
2437 The function must be called only once before any work with the
2438 declaration table. */
2440 initiate_decl_table (void)
2442 work_decl
.mode
= dm_unit
;
2443 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2446 /* The function deletes the declaration table. Only call of function
2447 `initiate_declaration_table' is possible immediately after this
2450 finish_decl_table (void)
2452 htab_delete (decl_table
);
2457 /* This page contains checker of pipeline hazard description. */
2459 /* Checking NAMES in an exclusion clause vector and returning formed
2460 unit_set_el_list. */
2461 static unit_set_el_t
2462 process_excls (char **names
, int num
, pos_t excl_pos ATTRIBUTE_UNUSED
)
2464 unit_set_el_t el_list
;
2465 unit_set_el_t last_el
;
2466 unit_set_el_t new_el
;
2467 decl_t decl_in_table
;
2472 for (i
= 0; i
< num
; i
++)
2474 decl_in_table
= find_decl (names
[i
]);
2475 if (decl_in_table
== NULL
)
2476 error ("unit `%s' in exclusion is not declared", names
[i
]);
2477 else if (decl_in_table
->mode
!= dm_unit
)
2478 error ("`%s' in exclusion is not unit", names
[i
]);
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
;
2488 last_el
->next_unit_set_el
= new_el
;
2489 last_el
= last_el
->next_unit_set_el
;
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". */
2500 add_excls (unit_set_el_t dest_list
, unit_set_el_t source_list
,
2501 pos_t excl_pos ATTRIBUTE_UNUSED
)
2505 unit_set_el_t curr_el
;
2506 unit_set_el_t prev_el
;
2509 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2510 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2512 if (dst
->unit_decl
== src
->unit_decl
)
2514 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2517 if (dst
->unit_decl
->automaton_name
!= NULL
2518 && src
->unit_decl
->automaton_name
!= NULL
2519 && strcmp (dst
->unit_decl
->automaton_name
,
2520 src
->unit_decl
->automaton_name
) != 0)
2522 error ("units `%s' and `%s' in exclusion set belong to different automata",
2523 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2526 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2528 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2529 if (curr_el
->unit_decl
== src
->unit_decl
)
2531 if (curr_el
== NULL
)
2533 /* Element not found - insert. */
2534 copy
= copy_node (src
, sizeof (*src
));
2535 copy
->next_unit_set_el
= NULL
;
2536 if (prev_el
== NULL
)
2537 dst
->unit_decl
->excl_list
= copy
;
2539 prev_el
->next_unit_set_el
= copy
;
2544 /* Checking NAMES in presence/absence clause and returning the
2545 formed unit_set_el_list. The function is called only after
2546 processing all exclusion sets. */
2547 static unit_set_el_t
2548 process_presence_absence_names (char **names
, int num
,
2549 pos_t req_pos ATTRIBUTE_UNUSED
,
2550 int presence_p
, int final_p
)
2552 unit_set_el_t el_list
;
2553 unit_set_el_t last_el
;
2554 unit_set_el_t new_el
;
2555 decl_t decl_in_table
;
2560 for (i
= 0; i
< num
; i
++)
2562 decl_in_table
= find_decl (names
[i
]);
2563 if (decl_in_table
== NULL
)
2566 ? "unit `%s' in final presence set is not declared"
2567 : "unit `%s' in presence set is not declared")
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
)
2574 ? "`%s' in final presence set is not unit"
2575 : "`%s' in presence set is not unit")
2577 ? "`%s' in final absence set is not unit"
2578 : "`%s' in absence set is not unit")), names
[i
]);
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
;
2588 last_el
->next_unit_set_el
= new_el
;
2589 last_el
= last_el
->next_unit_set_el
;
2596 /* Checking NAMES in patterns of a presence/absence clause and
2597 returning the formed pattern_set_el_list. The function is called
2598 only after processing all exclusion sets. */
2599 static pattern_set_el_t
2600 process_presence_absence_patterns (char ***patterns
, int num
,
2601 pos_t req_pos ATTRIBUTE_UNUSED
,
2602 int presence_p
, int final_p
)
2604 pattern_set_el_t el_list
;
2605 pattern_set_el_t last_el
;
2606 pattern_set_el_t new_el
;
2607 decl_t decl_in_table
;
2612 for (i
= 0; i
< num
; i
++)
2614 for (j
= 0; patterns
[i
] [j
] != NULL
; j
++)
2616 new_el
= create_node (sizeof (struct pattern_set_el
)
2617 + sizeof (struct unit_decl
*) * j
);
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
;
2626 last_el
->next_pattern_set_el
= new_el
;
2627 last_el
= last_el
->next_pattern_set_el
;
2629 new_el
->units_num
= 0;
2630 for (j
= 0; patterns
[i
] [j
] != NULL
; j
++)
2632 decl_in_table
= find_decl (patterns
[i
] [j
]);
2633 if (decl_in_table
== NULL
)
2636 ? "unit `%s' in final presence set is not declared"
2637 : "unit `%s' in presence set is not declared")
2639 ? "unit `%s' in final absence set is not declared"
2640 : "unit `%s' in absence set is not declared")),
2642 else if (decl_in_table
->mode
!= dm_unit
)
2645 ? "`%s' in final presence set is not unit"
2646 : "`%s' in presence set is not unit")
2648 ? "`%s' in final absence set is not unit"
2649 : "`%s' in absence set is not unit")),
2653 new_el
->unit_decls
[new_el
->units_num
]
2654 = DECL_UNIT (decl_in_table
);
2655 new_el
->units_num
++;
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
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
)
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
;
2686 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2687 for (pat
= pattern_list
; pat
!= NULL
; pat
= pat
->next_pattern_set_el
)
2689 for (i
= 0; i
< pat
->units_num
; i
++)
2691 unit
= pat
->unit_decls
[i
];
2692 if (dst
->unit_decl
== unit
&& pat
->units_num
== 1 && !presence_p
)
2694 error ("unit `%s' requires own absence", unit
->name
);
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)
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")
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
);
2714 for (curr_excl_el
= dst
->unit_decl
->excl_list
;
2715 curr_excl_el
!= NULL
;
2716 curr_excl_el
= curr_excl_el
->next_unit_set_el
)
2718 if (unit
== curr_excl_el
->unit_decl
&& pat
->units_num
== 1)
2722 error ("unit `%s' excludes and requires presence of `%s'",
2723 dst
->unit_decl
->name
, unit
->name
);
2728 (0, "unit `%s' excludes and requires presence of `%s'",
2729 dst
->unit_decl
->name
, unit
->name
);
2732 else if (pat
->units_num
== 1)
2733 for (curr_pat_el
= dst
->unit_decl
->presence_list
;
2734 curr_pat_el
!= NULL
;
2735 curr_pat_el
= curr_pat_el
->next_pattern_set_el
)
2736 if (curr_pat_el
->units_num
== 1
2737 && unit
== curr_pat_el
->unit_decls
[0])
2742 ("unit `%s' requires absence and presence of `%s'",
2743 dst
->unit_decl
->name
, unit
->name
);
2748 (0, "unit `%s' requires absence and presence of `%s'",
2749 dst
->unit_decl
->name
, unit
->name
);
2753 for (prev_el
= (presence_p
2755 ? dst
->unit_decl
->final_presence_list
2756 : dst
->unit_decl
->final_presence_list
)
2758 ? dst
->unit_decl
->final_absence_list
2759 : dst
->unit_decl
->absence_list
));
2760 prev_el
!= NULL
&& prev_el
->next_pattern_set_el
!= NULL
;
2761 prev_el
= prev_el
->next_pattern_set_el
)
2763 copy
= copy_node (pat
, sizeof (*pat
));
2764 copy
->next_pattern_set_el
= NULL
;
2765 if (prev_el
== NULL
)
2770 dst
->unit_decl
->final_presence_list
= copy
;
2772 dst
->unit_decl
->presence_list
= copy
;
2775 dst
->unit_decl
->final_absence_list
= copy
;
2777 dst
->unit_decl
->absence_list
= copy
;
2780 prev_el
->next_pattern_set_el
= copy
;
2787 /* The function searches for bypass with given IN_INSN_RESERV in given
2789 static struct bypass_decl
*
2790 find_bypass (struct bypass_decl
*bypass_list
,
2791 struct insn_reserv_decl
*in_insn_reserv
)
2793 struct bypass_decl
*bypass
;
2795 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2796 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2801 /* The function processes pipeline description declarations, checks
2802 their correctness, and forms exclusion/presence/absence sets. */
2804 process_decls (void)
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
;
2815 /* Checking repeated automata declarations. */
2816 automaton_presence
= 0;
2817 for (i
= 0; i
< description
->decls_num
; i
++)
2819 decl
= description
->decls
[i
];
2820 if (decl
->mode
== dm_automaton
)
2822 automaton_presence
= 1;
2823 decl_in_table
= insert_automaton_decl (decl
);
2824 if (decl_in_table
!= decl
)
2827 error ("repeated declaration of automaton `%s'",
2828 DECL_AUTOMATON (decl
)->name
);
2830 warning (0, "repeated declaration of automaton `%s'",
2831 DECL_AUTOMATON (decl
)->name
);
2835 /* Checking undeclared automata, repeated declarations (except for
2836 automata) and correctness of their attributes (insn latency times
2838 for (i
= 0; i
< description
->decls_num
; i
++)
2840 decl
= description
->decls
[i
];
2841 if (decl
->mode
== dm_insn_reserv
)
2843 DECL_INSN_RESERV (decl
)->condexp
2844 = check_attr_test (DECL_INSN_RESERV (decl
)->condexp
, 0, 0);
2845 if (DECL_INSN_RESERV (decl
)->default_latency
< 0)
2846 error ("define_insn_reservation `%s' has negative latency time",
2847 DECL_INSN_RESERV (decl
)->name
);
2848 DECL_INSN_RESERV (decl
)->insn_num
= description
->insns_num
;
2849 description
->insns_num
++;
2850 decl_in_table
= insert_insn_decl (decl
);
2851 if (decl_in_table
!= decl
)
2852 error ("`%s' is already used as insn reservation name",
2853 DECL_INSN_RESERV (decl
)->name
);
2855 else if (decl
->mode
== dm_bypass
)
2857 if (DECL_BYPASS (decl
)->latency
< 0)
2858 error ("define_bypass `%s - %s' has negative latency time",
2859 DECL_BYPASS (decl
)->out_insn_name
,
2860 DECL_BYPASS (decl
)->in_insn_name
);
2862 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2864 if (decl
->mode
== dm_unit
)
2866 DECL_UNIT (decl
)->automaton_decl
= NULL
;
2867 if (DECL_UNIT (decl
)->automaton_name
!= NULL
)
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
);
2876 DECL_AUTOMATON (automaton_decl
)->automaton_is_used
= 1;
2877 DECL_UNIT (decl
)->automaton_decl
2878 = DECL_AUTOMATON (automaton_decl
);
2881 else if (automaton_presence
)
2882 error ("define_unit `%s' without automaton when one defined",
2883 DECL_UNIT (decl
)->name
);
2884 DECL_UNIT (decl
)->unit_num
= description
->units_num
;
2885 description
->units_num
++;
2886 if (strcmp (DECL_UNIT (decl
)->name
, NOTHING_NAME
) == 0)
2888 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2891 decl_in_table
= find_decl (DECL_UNIT (decl
)->name
);
2895 if (strcmp (DECL_RESERV (decl
)->name
, NOTHING_NAME
) == 0)
2897 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2900 decl_in_table
= find_decl (DECL_RESERV (decl
)->name
);
2902 if (decl_in_table
== NULL
)
2903 decl_in_table
= insert_decl (decl
);
2906 if (decl
->mode
== dm_unit
)
2907 error ("repeated declaration of unit `%s'",
2908 DECL_UNIT (decl
)->name
);
2910 error ("repeated declaration of reservation `%s'",
2911 DECL_RESERV (decl
)->name
);
2915 /* Check bypasses and form list of bypasses for each (output)
2917 for (i
= 0; i
< description
->decls_num
; i
++)
2919 decl
= description
->decls
[i
];
2920 if (decl
->mode
== dm_bypass
)
2922 out_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->out_insn_name
);
2923 in_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->in_insn_name
);
2924 if (out_insn_reserv
== NULL
)
2925 error ("there is no insn reservation `%s'",
2926 DECL_BYPASS (decl
)->out_insn_name
);
2927 else if (in_insn_reserv
== NULL
)
2928 error ("there is no insn reservation `%s'",
2929 DECL_BYPASS (decl
)->in_insn_name
);
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
);
2937 = find_bypass (DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
,
2938 DECL_BYPASS (decl
)->in_insn_reserv
);
2941 if (DECL_BYPASS (decl
)->latency
== bypass
->latency
)
2945 ("the same bypass `%s - %s' is already defined",
2946 DECL_BYPASS (decl
)->out_insn_name
,
2947 DECL_BYPASS (decl
)->in_insn_name
);
2950 (0, "the same bypass `%s - %s' is already defined",
2951 DECL_BYPASS (decl
)->out_insn_name
,
2952 DECL_BYPASS (decl
)->in_insn_name
);
2955 error ("bypass `%s - %s' is already defined",
2956 DECL_BYPASS (decl
)->out_insn_name
,
2957 DECL_BYPASS (decl
)->in_insn_name
);
2961 DECL_BYPASS (decl
)->next
2962 = DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
;
2963 DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
2964 = DECL_BYPASS (decl
);
2970 /* Check exclusion set declarations and form exclusion sets. */
2971 for (i
= 0; i
< description
->decls_num
; i
++)
2973 decl
= description
->decls
[i
];
2974 if (decl
->mode
== dm_excl
)
2976 unit_set_el_t unit_set_el_list
;
2977 unit_set_el_t unit_set_el_list_2
;
2980 = process_excls (DECL_EXCL (decl
)->names
,
2981 DECL_EXCL (decl
)->first_list_length
, decl
->pos
);
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
,
2988 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2989 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2993 /* Check presence set declarations and form presence sets. */
2994 for (i
= 0; i
< description
->decls_num
; i
++)
2996 decl
= description
->decls
[i
];
2997 if (decl
->mode
== dm_presence
)
2999 unit_set_el_t unit_set_el_list
;
3000 pattern_set_el_t pattern_set_el_list
;
3003 = process_presence_absence_names
3004 (DECL_PRESENCE (decl
)->names
, DECL_PRESENCE (decl
)->names_num
,
3005 decl
->pos
, TRUE
, DECL_PRESENCE (decl
)->final_p
);
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
,
3013 DECL_PRESENCE (decl
)->final_p
);
3017 /* Check absence set declarations and form absence sets. */
3018 for (i
= 0; i
< description
->decls_num
; i
++)
3020 decl
= description
->decls
[i
];
3021 if (decl
->mode
== dm_absence
)
3023 unit_set_el_t unit_set_el_list
;
3024 pattern_set_el_t pattern_set_el_list
;
3027 = process_presence_absence_names
3028 (DECL_ABSENCE (decl
)->names
, DECL_ABSENCE (decl
)->names_num
,
3029 decl
->pos
, FALSE
, DECL_ABSENCE (decl
)->final_p
);
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
,
3037 DECL_ABSENCE (decl
)->final_p
);
3042 /* The following function checks that declared automaton is used. If
3043 the automaton is not used, the function fixes error/warning. The
3044 following function must be called only after `process_decls'. */
3046 check_automaton_usage (void)
3051 for (i
= 0; i
< description
->decls_num
; i
++)
3053 decl
= description
->decls
[i
];
3054 if (decl
->mode
== dm_automaton
3055 && !DECL_AUTOMATON (decl
)->automaton_is_used
)
3058 error ("automaton `%s' is not used", DECL_AUTOMATON (decl
)->name
);
3060 warning (0, "automaton `%s' is not used",
3061 DECL_AUTOMATON (decl
)->name
);
3066 /* The following recursive function processes all regexp in order to
3067 fix usage of units or reservations and to fix errors of undeclared
3068 name. The function may change unit_regexp onto reserv_regexp.
3069 Remember that reserv_regexp does not exist before the function
3072 process_regexp (regexp_t regexp
)
3074 decl_t decl_in_table
;
3075 regexp_t new_regexp
;
3078 switch (regexp
->mode
)
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
);
3086 switch (decl_in_table
->mode
)
3089 DECL_UNIT (decl_in_table
)->unit_is_used
= 1;
3090 REGEXP_UNIT (regexp
)->unit_decl
= DECL_UNIT (decl_in_table
);
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
;
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
]);
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
]);
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
]);
3124 REGEXP_REPEAT (regexp
)->regexp
3125 = process_regexp (REGEXP_REPEAT (regexp
)->regexp
);
3135 /* The following function processes regexp of define_reservation and
3136 define_insn_reservation with the aid of function
3137 `process_regexp'. */
3139 process_regexp_decls (void)
3144 for (i
= 0; i
< description
->decls_num
; i
++)
3146 decl
= description
->decls
[i
];
3147 if (decl
->mode
== dm_reserv
)
3148 DECL_RESERV (decl
)->regexp
3149 = process_regexp (DECL_RESERV (decl
)->regexp
);
3150 else if (decl
->mode
== dm_insn_reserv
)
3151 DECL_INSN_RESERV (decl
)->regexp
3152 = process_regexp (DECL_INSN_RESERV (decl
)->regexp
);
3156 /* The following function checks that declared unit is used. If the
3157 unit is not used, the function fixes errors/warnings. The
3158 following function must be called only after `process_decls',
3159 `process_regexp_decls'. */
3166 for (i
= 0; i
< description
->decls_num
; i
++)
3168 decl
= description
->decls
[i
];
3169 if (decl
->mode
== dm_unit
&& !DECL_UNIT (decl
)->unit_is_used
)
3172 error ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3174 warning (0, "unit `%s' is not used", DECL_UNIT (decl
)->name
);
3176 else if (decl
->mode
== dm_reserv
&& !DECL_RESERV (decl
)->reserv_is_used
)
3179 error ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3181 warning (0, "reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3186 /* The following variable value is number of reservation being
3187 processed on loop recognition. */
3188 static int curr_loop_pass_num
;
3190 /* The following recursive function returns nonzero value if REGEXP
3191 contains given decl or reservations in given regexp refers for
3194 loop_in_regexp (regexp_t regexp
, decl_t start_decl
)
3200 switch (regexp
->mode
)
3206 if (start_decl
->mode
== dm_reserv
3207 && REGEXP_RESERV (regexp
)->reserv_decl
== DECL_RESERV (start_decl
))
3209 else if (REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3210 == curr_loop_pass_num
)
3211 /* declaration has been processed. */
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
,
3222 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3223 if (loop_in_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
], start_decl
))
3228 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3229 if (loop_in_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
], start_decl
))
3234 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3235 if (loop_in_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
], start_decl
))
3240 return loop_in_regexp (REGEXP_REPEAT (regexp
)->regexp
, start_decl
);
3250 /* The following function fixes errors "cycle in definition ...". The
3251 function uses function `loop_in_regexp' for that. */
3253 check_loops_in_regexps (void)
3258 for (i
= 0; i
< description
->decls_num
; i
++)
3260 decl
= description
->decls
[i
];
3261 if (decl
->mode
== dm_reserv
)
3262 DECL_RESERV (decl
)->loop_pass_num
= 0;
3264 for (i
= 0; i
< description
->decls_num
; i
++)
3266 decl
= description
->decls
[i
];
3267 curr_loop_pass_num
= i
;
3269 if (decl
->mode
== dm_reserv
)
3271 DECL_RESERV (decl
)->loop_pass_num
= curr_loop_pass_num
;
3272 if (loop_in_regexp (DECL_RESERV (decl
)->regexp
, decl
))
3274 gcc_assert (DECL_RESERV (decl
)->regexp
);
3275 error ("cycle in definition of reservation `%s'",
3276 DECL_RESERV (decl
)->name
);
3282 /* The function recursively processes IR of reservation and defines
3283 max and min cycle for reservation of unit. */
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
)
3291 switch (regexp
->mode
)
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
;
3304 process_regexp_cycles (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3305 max_start_cycle
, min_start_cycle
,
3306 max_finish_cycle
, min_finish_cycle
);
3310 for (i
= 0; i
< REGEXP_REPEAT (regexp
)->repeat_num
; i
++)
3312 process_regexp_cycles (REGEXP_REPEAT (regexp
)->regexp
,
3313 max_start_cycle
, min_start_cycle
,
3314 max_finish_cycle
, min_finish_cycle
);
3315 max_start_cycle
= *max_finish_cycle
+ 1;
3316 min_start_cycle
= *min_finish_cycle
+ 1;
3321 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3323 process_regexp_cycles (REGEXP_SEQUENCE (regexp
)->regexps
[i
],
3324 max_start_cycle
, min_start_cycle
,
3325 max_finish_cycle
, min_finish_cycle
);
3326 max_start_cycle
= *max_finish_cycle
+ 1;
3327 min_start_cycle
= *min_finish_cycle
+ 1;
3336 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3338 process_regexp_cycles (REGEXP_ALLOF (regexp
)->regexps
[i
],
3339 max_start_cycle
, min_start_cycle
,
3340 max_finish_cycle
, min_finish_cycle
);
3341 if (max_cycle
< *max_finish_cycle
)
3342 max_cycle
= *max_finish_cycle
;
3343 if (i
== 0 || min_cycle
> *min_finish_cycle
)
3344 min_cycle
= *min_finish_cycle
;
3346 *max_finish_cycle
= max_cycle
;
3347 *min_finish_cycle
= min_cycle
;
3356 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3358 process_regexp_cycles (REGEXP_ONEOF (regexp
)->regexps
[i
],
3359 max_start_cycle
, min_start_cycle
,
3360 max_finish_cycle
, min_finish_cycle
);
3361 if (max_cycle
< *max_finish_cycle
)
3362 max_cycle
= *max_finish_cycle
;
3363 if (i
== 0 || min_cycle
> *min_finish_cycle
)
3364 min_cycle
= *min_finish_cycle
;
3366 *max_finish_cycle
= max_cycle
;
3367 *min_finish_cycle
= min_cycle
;
3372 *max_finish_cycle
= max_start_cycle
;
3373 *min_finish_cycle
= min_start_cycle
;
3381 /* The following function is called only for correct program. The
3382 function defines max reservation of insns in cycles. */
3384 evaluate_max_reserv_cycles (void)
3386 int max_insn_cycles_num
;
3387 int min_insn_cycles_num
;
3391 description
->max_insn_reserv_cycles
= 0;
3392 for (i
= 0; i
< description
->decls_num
; i
++)
3394 decl
= description
->decls
[i
];
3395 if (decl
->mode
== dm_insn_reserv
)
3397 process_regexp_cycles (DECL_INSN_RESERV (decl
)->regexp
, 0, 0,
3398 &max_insn_cycles_num
, &min_insn_cycles_num
);
3399 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3400 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3403 description
->max_insn_reserv_cycles
++;
3406 /* The following function calls functions for checking all
3409 check_all_description (void)
3412 check_automaton_usage ();
3413 process_regexp_decls ();
3415 check_loops_in_regexps ();
3417 evaluate_max_reserv_cycles ();
3422 /* The page contains abstract data `ticker'. This data is used to
3423 report time of different phases of building automata. It is
3424 possibly to write a description for which automata will be built
3425 during several minutes even on fast machine. */
3427 /* The following function creates ticker and makes it active. */
3429 create_ticker (void)
3433 ticker
.modified_creation_time
= get_run_time ();
3434 ticker
.incremented_off_time
= 0;
3438 /* The following function switches off given ticker. */
3440 ticker_off (ticker_t
*ticker
)
3442 if (ticker
->incremented_off_time
== 0)
3443 ticker
->incremented_off_time
= get_run_time () + 1;
3446 /* The following function switches on given ticker. */
3448 ticker_on (ticker_t
*ticker
)
3450 if (ticker
->incremented_off_time
!= 0)
3452 ticker
->modified_creation_time
3453 += get_run_time () - ticker
->incremented_off_time
+ 1;
3454 ticker
->incremented_off_time
= 0;
3458 /* The following function returns current time in milliseconds since
3459 the moment when given ticker was created. */
3461 active_time (ticker_t ticker
)
3463 if (ticker
.incremented_off_time
!= 0)
3464 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3466 return get_run_time () - ticker
.modified_creation_time
;
3469 /* The following function returns string representation of active time
3470 of given ticker. The result is string representation of seconds
3471 with accuracy of 1/100 second. Only result of the last call of the
3472 function exists. Therefore the following code is not correct
3474 printf ("parser time: %s\ngeneration time: %s\n",
3475 active_time_string (parser_ticker),
3476 active_time_string (generation_ticker));
3478 Correct code has to be the following
3480 printf ("parser time: %s\n", active_time_string (parser_ticker));
3481 printf ("generation time: %s\n",
3482 active_time_string (generation_ticker));
3486 print_active_time (FILE *f
, ticker_t ticker
)
3490 msecs
= active_time (ticker
);
3491 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3496 /* The following variable value is number of automaton which are
3497 really being created. This value is defined on the base of
3498 argument of option `-split'. If the variable has zero value the
3499 number of automata is defined by the constructions `%automaton'.
3500 This case occurs when option `-split' is absent or has zero
3501 argument. If constructions `define_automaton' is absent only one
3502 automaton is created. */
3503 static int automata_num
;
3505 /* The following variable values are times of
3506 o transformation of regular expressions
3507 o building NDFA (DFA if !ndfa_flag)
3508 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3510 o building insn equivalence classes
3513 static ticker_t transform_time
;
3514 static ticker_t NDFA_time
;
3515 static ticker_t NDFA_to_DFA_time
;
3516 static ticker_t minimize_time
;
3517 static ticker_t equiv_time
;
3518 static ticker_t automaton_generation_time
;
3519 static ticker_t output_time
;
3521 /* The following variable values are times of
3524 all pipeline hazard translator work */
3525 static ticker_t check_time
;
3526 static ticker_t generation_time
;
3527 static ticker_t all_time
;
3531 /* Pseudo insn decl which denotes advancing cycle. */
3532 static decl_t advance_cycle_insn_decl
;
3534 add_advance_cycle_insn_decl (void)
3536 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3537 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3538 advance_cycle_insn_decl
->pos
= no_pos
;
3539 DECL_INSN_RESERV (advance_cycle_insn_decl
)->regexp
= NULL
;
3540 DECL_INSN_RESERV (advance_cycle_insn_decl
)->name
= (char *) "$advance_cycle";
3541 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
3542 = description
->insns_num
;
3543 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3544 description
->decls_num
++;
3545 description
->insns_num
++;
3550 /* Abstract data `alternative states' which represents
3551 nondeterministic nature of the description (see comments for
3552 structures alt_state and state). */
3554 /* List of free states. */
3555 static alt_state_t first_free_alt_state
;
3558 /* The following variables is maximal number of allocated nodes
3560 static int allocated_alt_states_num
= 0;
3563 /* The following function returns free node alt_state. It may be new
3564 allocated node or node freed earlier. */
3566 get_free_alt_state (void)
3570 if (first_free_alt_state
!= NULL
)
3572 result
= first_free_alt_state
;
3573 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3578 allocated_alt_states_num
++;
3580 result
= create_node (sizeof (struct alt_state
));
3582 result
->state
= NULL
;
3583 result
->next_alt_state
= NULL
;
3584 result
->next_sorted_alt_state
= NULL
;
3588 /* The function frees node ALT_STATE. */
3590 free_alt_state (alt_state_t alt_state
)
3592 if (alt_state
== NULL
)
3594 alt_state
->next_alt_state
= first_free_alt_state
;
3595 first_free_alt_state
= alt_state
;
3598 /* The function frees list started with node ALT_STATE_LIST. */
3600 free_alt_states (alt_state_t alt_states_list
)
3602 alt_state_t curr_alt_state
;
3603 alt_state_t next_alt_state
;
3605 for (curr_alt_state
= alt_states_list
;
3606 curr_alt_state
!= NULL
;
3607 curr_alt_state
= next_alt_state
)
3609 next_alt_state
= curr_alt_state
->next_alt_state
;
3610 free_alt_state (curr_alt_state
);
3614 /* The function compares unique numbers of alt states. */
3616 alt_state_cmp (const void *alt_state_ptr_1
, const void *alt_state_ptr_2
)
3618 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3619 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3621 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3622 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3628 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3629 states from the list. The comparison key is alt state unique
3632 uniq_sort_alt_states (alt_state_t alt_states_list
)
3634 alt_state_t curr_alt_state
;
3635 vla_ptr_t alt_states
;
3637 size_t prev_unique_state_ind
;
3639 alt_state_t
*result_ptr
;
3641 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3642 for (curr_alt_state
= alt_states_list
;
3643 curr_alt_state
!= NULL
;
3644 curr_alt_state
= curr_alt_state
->next_alt_state
)
3645 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3646 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3647 sizeof (alt_state_t
), alt_state_cmp
);
3648 if (VLA_PTR_LENGTH (alt_states
) == 0)
3652 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3653 prev_unique_state_ind
= 0;
3654 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3655 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3657 prev_unique_state_ind
++;
3658 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3661 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3662 free_alt_state (result_ptr
[i
]);
3664 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3665 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3666 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3667 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3668 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3669 result
= *result_ptr
;
3671 VLA_PTR_DELETE (alt_states
);
3675 /* The function checks equality of alt state lists. Remember that the
3676 lists must be already sorted by the previous function. */
3678 alt_states_eq (alt_state_t alt_states_1
, alt_state_t alt_states_2
)
3680 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3681 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3683 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3684 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3686 return alt_states_1
== alt_states_2
;
3689 /* Initialization of the abstract data. */
3691 initiate_alt_states (void)
3693 first_free_alt_state
= NULL
;
3696 /* Finishing work with the abstract data. */
3698 finish_alt_states (void)
3704 /* The page contains macros for work with bits strings. We could use
3705 standard gcc bitmap or sbitmap but it would result in difficulties
3706 of building canadian cross. */
3708 /* Set bit number bitno in the bit string. The macro is not side
3710 #define SET_BIT(bitstring, bitno) \
3711 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3713 #define CLEAR_BIT(bitstring, bitno) \
3714 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3716 /* Test if bit number bitno in the bitstring is set. The macro is not
3717 side effect proof. */
3718 #define TEST_BIT(bitstring, bitno) \
3719 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3723 /* This page contains abstract data `state'. */
3725 /* Maximal length of reservations in cycles (>= 1). */
3726 static int max_cycles_num
;
3728 /* Number of set elements (see type set_el_t) needed for
3729 representation of one cycle reservation. It is depended on units
3731 static int els_in_cycle_reserv
;
3733 /* Number of set elements (see type set_el_t) needed for
3734 representation of maximal length reservation. Deterministic
3735 reservation is stored as set (bit string) of length equal to the
3736 variable value * number of bits in set_el_t. */
3737 static int els_in_reservs
;
3739 /* VLA for representation of array of pointers to unit
3741 static vla_ptr_t units_container
;
3743 /* The start address of the array. */
3744 static unit_decl_t
*units_array
;
3746 /* Temporary reservation of maximal length. */
3747 static reserv_sets_t temp_reserv
;
3749 /* The state table itself is represented by the following variable. */
3750 static htab_t state_table
;
3752 /* VLA for representation of array of pointers to free nodes
3754 static vla_ptr_t free_states
;
3756 static int curr_unique_state_num
;
3759 /* The following variables is maximal number of allocated nodes
3761 static int allocated_states_num
= 0;
3764 /* Allocate new reservation set. */
3765 static reserv_sets_t
3766 alloc_empty_reserv_sets (void)
3768 reserv_sets_t result
;
3770 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3771 result
= (reserv_sets_t
) obstack_base (&irp
);
3772 obstack_finish (&irp
);
3773 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3777 /* Hash value of reservation set. */
3779 reserv_sets_hash_value (reserv_sets_t reservs
)
3781 set_el_t hash_value
;
3784 set_el_t
*reserv_ptr
;
3787 reservs_num
= els_in_reservs
;
3788 reserv_ptr
= reservs
;
3790 while (reservs_num
!= 0)
3793 hash_value
+= ((*reserv_ptr
>> i
)
3794 | (*reserv_ptr
<< (sizeof (set_el_t
) * CHAR_BIT
- i
)));
3796 if (i
== sizeof (set_el_t
) * CHAR_BIT
)
3800 if (sizeof (set_el_t
) <= sizeof (unsigned))
3803 for (i
= sizeof (set_el_t
); i
> 0; i
-= sizeof (unsigned) - 1)
3805 result
+= (unsigned) hash_value
;
3806 hash_value
>>= (sizeof (unsigned) - 1) * CHAR_BIT
;
3811 /* Comparison of given reservation sets. */
3813 reserv_sets_cmp (reserv_sets_t reservs_1
, reserv_sets_t reservs_2
)
3816 set_el_t
*reserv_ptr_1
;
3817 set_el_t
*reserv_ptr_2
;
3819 gcc_assert (reservs_1
&& reservs_2
);
3820 reservs_num
= els_in_reservs
;
3821 reserv_ptr_1
= reservs_1
;
3822 reserv_ptr_2
= reservs_2
;
3823 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3829 if (reservs_num
== 0)
3831 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3837 /* The function checks equality of the reservation sets. */
3839 reserv_sets_eq (reserv_sets_t reservs_1
, reserv_sets_t reservs_2
)
3841 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3844 /* Set up in the reservation set that unit with UNIT_NUM is used on
3847 set_unit_reserv (reserv_sets_t reservs
, int cycle_num
, int unit_num
)
3849 gcc_assert (cycle_num
< max_cycles_num
);
3850 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3851 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3854 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3855 used on CYCLE_NUM. */
3857 test_unit_reserv (reserv_sets_t reservs
, int cycle_num
, int unit_num
)
3859 gcc_assert (cycle_num
< max_cycles_num
);
3860 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3861 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3864 /* The function checks that the reservation set represents no one unit
3867 it_is_empty_reserv_sets (reserv_sets_t operand
)
3869 set_el_t
*reserv_ptr
;
3872 gcc_assert (operand
);
3873 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3875 reserv_ptr
++, reservs_num
--)
3876 if (*reserv_ptr
!= 0)
3881 /* The function checks that the reservation sets are intersected,
3882 i.e. there is a unit reservation on a cycle in both reservation
3885 reserv_sets_are_intersected (reserv_sets_t operand_1
,
3886 reserv_sets_t operand_2
)
3890 set_el_t
*cycle_ptr_1
;
3891 set_el_t
*cycle_ptr_2
;
3893 gcc_assert (operand_1
&& operand_2
);
3894 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3895 el_ptr_1
< operand_1
+ els_in_reservs
;
3896 el_ptr_1
++, el_ptr_2
++)
3897 if (*el_ptr_1
& *el_ptr_2
)
3899 reserv_sets_or (temp_reserv
, operand_1
, operand_2
);
3900 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3901 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3902 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3904 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3905 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3906 el_ptr_1
++, el_ptr_2
++)
3907 if (*el_ptr_1
& *el_ptr_2
)
3909 if (!check_presence_pattern_sets (cycle_ptr_1
, cycle_ptr_2
, FALSE
))
3911 if (!check_presence_pattern_sets (temp_reserv
+ (cycle_ptr_2
3915 if (!check_absence_pattern_sets (cycle_ptr_1
, cycle_ptr_2
, FALSE
))
3917 if (!check_absence_pattern_sets (temp_reserv
+ (cycle_ptr_2
- operand_2
),
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. */
3928 reserv_sets_shift (reserv_sets_t result
, reserv_sets_t operand
)
3932 gcc_assert (result
&& operand
&& result
!= operand
);
3933 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3934 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3937 /* OR of the reservation sets. */
3939 reserv_sets_or (reserv_sets_t result
, reserv_sets_t operand_1
,
3940 reserv_sets_t operand_2
)
3944 set_el_t
*result_set_el_ptr
;
3946 gcc_assert (result
&& operand_1
&& operand_2
);
3947 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3948 el_ptr_1
< operand_1
+ els_in_reservs
;
3949 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3950 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3953 /* AND of the reservation sets. */
3955 reserv_sets_and (reserv_sets_t result
, reserv_sets_t operand_1
,
3956 reserv_sets_t operand_2
)
3960 set_el_t
*result_set_el_ptr
;
3962 gcc_assert (result
&& operand_1
&& operand_2
);
3963 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3964 el_ptr_1
< operand_1
+ els_in_reservs
;
3965 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3966 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3969 /* The function outputs string representation of units reservation on
3970 cycle START_CYCLE in the reservation set. The function uses repeat
3971 construction if REPETITION_NUM > 1. */
3973 output_cycle_reservs (FILE *f
, reserv_sets_t reservs
, int start_cycle
,
3977 int reserved_units_num
;
3979 reserved_units_num
= 0;
3980 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3981 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3982 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3983 reserved_units_num
++;
3984 gcc_assert (repetition_num
> 0);
3985 if (repetition_num
!= 1 && reserved_units_num
> 1)
3987 reserved_units_num
= 0;
3989 unit_num
< description
->units_num
;
3991 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3992 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3994 if (reserved_units_num
!= 0)
3996 reserved_units_num
++;
3997 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3999 if (reserved_units_num
== 0)
4000 fprintf (f
, NOTHING_NAME
);
4001 gcc_assert (repetition_num
> 0);
4002 if (repetition_num
!= 1 && reserved_units_num
> 1)
4004 if (repetition_num
!= 1)
4005 fprintf (f
, "*%d", repetition_num
);
4008 /* The function outputs string representation of units reservation in
4009 the reservation set. */
4011 output_reserv_sets (FILE *f
, reserv_sets_t reservs
)
4013 int start_cycle
= 0;
4018 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
4019 if (repetition_num
== 0)
4022 start_cycle
= cycle
;
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)
4033 if (start_cycle
!= 0)
4035 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
4037 start_cycle
= cycle
;
4039 if (start_cycle
< max_cycles_num
)
4041 if (start_cycle
!= 0)
4043 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
4047 /* The following function returns free node state for AUTOMATON. It
4048 may be new allocated node or node freed earlier. The function also
4049 allocates reservation set if WITH_RESERVS has nonzero value. */
4051 get_free_state (int with_reservs
, automaton_t automaton
)
4055 gcc_assert (max_cycles_num
> 0 && automaton
);
4056 if (VLA_PTR_LENGTH (free_states
) != 0)
4058 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
4059 VLA_PTR_SHORTEN (free_states
, 1);
4060 result
->automaton
= automaton
;
4061 result
->first_out_arc
= NULL
;
4062 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
4063 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
4064 result
->component_states
= NULL
;
4065 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
4070 allocated_states_num
++;
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
++;
4081 if (result
->reservs
== NULL
)
4082 result
->reservs
= alloc_empty_reserv_sets ();
4084 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
4089 /* The function frees node STATE. */
4091 free_state (state_t state
)
4093 free_alt_states (state
->component_states
);
4094 VLA_PTR_ADD (free_states
, state
);
4097 /* Hash value of STATE. If STATE represents deterministic state it is
4098 simply hash value of the corresponding reservation set. Otherwise
4099 it is formed from hash values of the component deterministic
4100 states. One more key is order number of state automaton. */
4102 state_hash (const void *state
)
4104 unsigned int hash_value
;
4105 alt_state_t alt_state
;
4107 if (((state_t
) state
)->component_states
== NULL
)
4108 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
4112 for (alt_state
= ((state_t
) state
)->component_states
;
4114 alt_state
= alt_state
->next_sorted_alt_state
)
4115 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4116 | (hash_value
<< CHAR_BIT
))
4117 + alt_state
->state
->unique_num
);
4119 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4120 | (hash_value
<< CHAR_BIT
))
4121 + ((state_t
) state
)->automaton
->automaton_order_num
);
4125 /* Return nonzero value if the states are the same. */
4127 state_eq_p (const void *state_1
, const void *state_2
)
4129 alt_state_t alt_state_1
;
4130 alt_state_t alt_state_2
;
4132 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
4134 else if (((state_t
) state_1
)->component_states
== NULL
4135 && ((state_t
) state_2
)->component_states
== NULL
)
4136 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
4137 ((state_t
) state_2
)->reservs
);
4138 else if (((state_t
) state_1
)->component_states
!= NULL
4139 && ((state_t
) state_2
)->component_states
!= NULL
)
4141 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
4142 alt_state_2
= ((state_t
) state_2
)->component_states
;
4143 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
4144 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
4145 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
4146 /* All state in the list must be already in the hash table.
4147 Also the lists must be sorted. */
4148 if (alt_state_1
->state
!= alt_state_2
->state
)
4150 return alt_state_1
== alt_state_2
;
4156 /* Insert STATE into the state table. */
4158 insert_state (state_t state
)
4162 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
4163 if (*entry_ptr
== NULL
)
4164 *entry_ptr
= (void *) state
;
4165 return (state_t
) *entry_ptr
;
4168 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4169 deterministic STATE. */
4171 set_state_reserv (state_t state
, int cycle_num
, int unit_num
)
4173 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
4176 /* Return nonzero value if the deterministic states contains a
4177 reservation of the same cpu unit on the same cpu cycle. */
4179 intersected_state_reservs_p (state_t state1
, state_t state2
)
4181 gcc_assert (state1
->automaton
== state2
->automaton
);
4182 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
4185 /* Return deterministic state (inserted into the table) which
4186 representing the automaton state which is union of reservations of
4187 the deterministic states masked by RESERVS. */
4189 states_union (state_t state1
, state_t state2
, reserv_sets_t reservs
)
4192 state_t state_in_table
;
4194 gcc_assert (state1
->automaton
== state2
->automaton
);
4195 result
= get_free_state (1, state1
->automaton
);
4196 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
4197 reserv_sets_and (result
->reservs
, result
->reservs
, reservs
);
4198 state_in_table
= insert_state (result
);
4199 if (result
!= state_in_table
)
4201 free_state (result
);
4202 result
= state_in_table
;
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. */
4211 state_shift (state_t state
, reserv_sets_t reservs
)
4214 state_t state_in_table
;
4216 result
= get_free_state (1, state
->automaton
);
4217 reserv_sets_shift (result
->reservs
, state
->reservs
);
4218 reserv_sets_and (result
->reservs
, result
->reservs
, reservs
);
4219 state_in_table
= insert_state (result
);
4220 if (result
!= state_in_table
)
4222 free_state (result
);
4223 result
= state_in_table
;
4228 /* Initialization of the abstract data. */
4230 initiate_states (void)
4235 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
4237 = (description
->decls_num
&& description
->units_num
4238 ? VLA_PTR_BEGIN (units_container
) : NULL
);
4239 for (i
= 0; i
< description
->decls_num
; i
++)
4241 decl
= description
->decls
[i
];
4242 if (decl
->mode
== dm_unit
)
4243 units_array
[DECL_UNIT (decl
)->unit_num
] = DECL_UNIT (decl
);
4245 max_cycles_num
= description
->max_insn_reserv_cycles
;
4247 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
4248 / (sizeof (set_el_t
) * CHAR_BIT
));
4249 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
4250 curr_unique_state_num
= 0;
4251 initiate_alt_states ();
4252 VLA_PTR_CREATE (free_states
, 1500, "free states");
4253 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
4254 temp_reserv
= alloc_empty_reserv_sets ();
4257 /* Finishing work with the abstract data. */
4259 finish_states (void)
4261 VLA_PTR_DELETE (units_container
);
4262 htab_delete (state_table
);
4263 VLA_PTR_DELETE (free_states
);
4264 finish_alt_states ();
4269 /* Abstract data `arcs'. */
4271 /* List of free arcs. */
4272 static arc_t first_free_arc
;
4275 /* The following variables is maximal number of allocated nodes
4277 static int allocated_arcs_num
= 0;
4280 /* The function frees node ARC. */
4282 free_arc (arc_t arc
)
4284 arc
->next_out_arc
= first_free_arc
;
4285 first_free_arc
= arc
;
4288 /* The function removes and frees ARC staring from FROM_STATE. */
4290 remove_arc (state_t from_state
, arc_t arc
)
4296 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
4298 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
4299 if (curr_arc
== arc
)
4301 gcc_assert (curr_arc
);
4302 if (prev_arc
== NULL
)
4303 from_state
->first_out_arc
= arc
->next_out_arc
;
4305 prev_arc
->next_out_arc
= arc
->next_out_arc
;
4309 /* The functions returns arc with given characteristics (or NULL if
4310 the arc does not exist). */
4312 find_arc (state_t from_state
, state_t to_state
, ainsn_t insn
)
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
)
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). */
4326 add_arc (state_t from_state
, state_t to_state
, ainsn_t ainsn
,
4331 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4332 if (new_arc
!= NULL
)
4334 if (first_free_arc
== NULL
)
4337 allocated_arcs_num
++;
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
;
4346 new_arc
= first_free_arc
;
4347 first_free_arc
= first_free_arc
->next_out_arc
;
4349 new_arc
->to_state
= to_state
;
4350 new_arc
->insn
= ainsn
;
4351 ainsn
->arc_exists_p
= 1;
4352 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4353 from_state
->first_out_arc
= new_arc
;
4354 new_arc
->next_arc_marked_by_insn
= NULL
;
4355 new_arc
->state_alts
= state_alts
;
4359 /* The function returns the first arc starting from STATE. */
4361 first_out_arc (state_t state
)
4363 return state
->first_out_arc
;
4366 /* The function returns next out arc after ARC. */
4368 next_out_arc (arc_t arc
)
4370 return arc
->next_out_arc
;
4373 /* Initialization of the abstract data. */
4375 initiate_arcs (void)
4377 first_free_arc
= NULL
;
4380 /* Finishing work with the abstract data. */
4388 /* Abstract data `automata lists'. */
4390 /* List of free states. */
4391 static automata_list_el_t first_free_automata_list_el
;
4393 /* The list being formed. */
4394 static automata_list_el_t current_automata_list
;
4396 /* Hash table of automata lists. */
4397 static htab_t automata_list_table
;
4399 /* The following function returns free automata list el. It may be
4400 new allocated node or node freed earlier. */
4401 static automata_list_el_t
4402 get_free_automata_list_el (void)
4404 automata_list_el_t result
;
4406 if (first_free_automata_list_el
!= NULL
)
4408 result
= first_free_automata_list_el
;
4409 first_free_automata_list_el
4410 = first_free_automata_list_el
->next_automata_list_el
;
4413 result
= create_node (sizeof (struct automata_list_el
));
4414 result
->automaton
= NULL
;
4415 result
->next_automata_list_el
= NULL
;
4419 /* The function frees node AUTOMATA_LIST_EL. */
4421 free_automata_list_el (automata_list_el_t automata_list_el
)
4423 if (automata_list_el
== NULL
)
4425 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4426 first_free_automata_list_el
= automata_list_el
;
4429 /* The function frees list AUTOMATA_LIST. */
4431 free_automata_list (automata_list_el_t automata_list
)
4433 automata_list_el_t curr_automata_list_el
;
4434 automata_list_el_t next_automata_list_el
;
4436 for (curr_automata_list_el
= automata_list
;
4437 curr_automata_list_el
!= NULL
;
4438 curr_automata_list_el
= next_automata_list_el
)
4440 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4441 free_automata_list_el (curr_automata_list_el
);
4445 /* Hash value of AUTOMATA_LIST. */
4447 automata_list_hash (const void *automata_list
)
4449 unsigned int hash_value
;
4450 automata_list_el_t curr_automata_list_el
;
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
);
4462 /* Return nonzero value if the automata_lists are the same. */
4464 automata_list_eq_p (const void *automata_list_1
, const void *automata_list_2
)
4466 automata_list_el_t automata_list_el_1
;
4467 automata_list_el_t automata_list_el_2
;
4469 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4470 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4471 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4472 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4473 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4474 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4476 return automata_list_el_1
== automata_list_el_2
;
4479 /* Initialization of the abstract data. */
4481 initiate_automata_lists (void)
4483 first_free_automata_list_el
= NULL
;
4484 automata_list_table
= htab_create (1500, automata_list_hash
,
4485 automata_list_eq_p
, (htab_del
) 0);
4488 /* The following function starts new automata list and makes it the
4491 automata_list_start (void)
4493 current_automata_list
= NULL
;
4496 /* The following function adds AUTOMATON to the current list. */
4498 automata_list_add (automaton_t automaton
)
4500 automata_list_el_t el
;
4502 el
= get_free_automata_list_el ();
4503 el
->automaton
= automaton
;
4504 el
->next_automata_list_el
= current_automata_list
;
4505 current_automata_list
= el
;
4508 /* The following function finishes forming the current list, inserts
4509 it into the table and returns it. */
4510 static automata_list_el_t
4511 automata_list_finish (void)
4515 if (current_automata_list
== 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
;
4522 free_automata_list (current_automata_list
);
4523 current_automata_list
= NULL
;
4524 return (automata_list_el_t
) *entry_ptr
;
4527 /* Finishing work with the abstract data. */
4529 finish_automata_lists (void)
4531 htab_delete (automata_list_table
);
4536 /* The page contains abstract data for work with exclusion sets (see
4537 exclusion_set in file rtl.def). */
4539 /* The following variable refers to an exclusion set returned by
4540 get_excl_set. This is bit string of length equal to cpu units
4541 number. If exclusion set for given unit contains 1 for a unit,
4542 then simultaneous reservation of the units is prohibited. */
4543 static reserv_sets_t excl_set
;
4545 /* The array contains exclusion sets for each unit. */
4546 static reserv_sets_t
*unit_excl_set_table
;
4548 /* The following function forms the array containing exclusion sets
4551 initiate_excl_sets (void)
4554 reserv_sets_t unit_excl_set
;
4558 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4559 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4560 obstack_finish (&irp
);
4561 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4562 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4563 obstack_finish (&irp
);
4564 /* Evaluate unit exclusion sets. */
4565 for (i
= 0; i
< description
->decls_num
; i
++)
4567 decl
= description
->decls
[i
];
4568 if (decl
->mode
== dm_unit
)
4570 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4571 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4572 obstack_finish (&irp
);
4573 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4574 for (el
= DECL_UNIT (decl
)->excl_list
;
4576 el
= el
->next_unit_set_el
)
4578 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4579 el
->unit_decl
->in_set_p
= TRUE
;
4581 unit_excl_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_excl_set
;
4586 /* The function sets up and return EXCL_SET which is union of
4587 exclusion sets for each unit in IN_SET. */
4588 static reserv_sets_t
4589 get_excl_set (reserv_sets_t in_set
)
4597 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4598 memset (excl_set
, 0, chars_num
);
4599 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4600 if (((unsigned char *) in_set
) [excl_char_num
])
4601 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4602 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4604 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4605 if (start_unit_num
>= description
->units_num
)
4607 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4610 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4618 /* The page contains abstract data for work with presence/absence
4619 pattern sets (see presence_set/absence_set in file rtl.def). */
4621 /* The following arrays contain correspondingly presence, final
4622 presence, absence, and final absence patterns for each unit. */
4623 static pattern_reserv_t
*unit_presence_set_table
;
4624 static pattern_reserv_t
*unit_final_presence_set_table
;
4625 static pattern_reserv_t
*unit_absence_set_table
;
4626 static pattern_reserv_t
*unit_final_absence_set_table
;
4628 /* The following function forms list of reservation sets for given
4630 static pattern_reserv_t
4631 form_reserv_sets_list (pattern_set_el_t pattern_list
)
4633 pattern_set_el_t el
;
4634 pattern_reserv_t first
, curr
, prev
;
4637 prev
= first
= NULL
;
4638 for (el
= pattern_list
; el
!= NULL
; el
= el
->next_pattern_set_el
)
4640 curr
= create_node (sizeof (struct pattern_reserv
));
4641 curr
->reserv
= alloc_empty_reserv_sets ();
4642 curr
->next_pattern_reserv
= NULL
;
4643 for (i
= 0; i
< el
->units_num
; i
++)
4645 SET_BIT (curr
->reserv
, el
->unit_decls
[i
]->unit_num
);
4646 el
->unit_decls
[i
]->in_set_p
= TRUE
;
4649 prev
->next_pattern_reserv
= curr
;
4657 /* The following function forms the array containing presence and
4658 absence pattern sets for each unit. */
4660 initiate_presence_absence_pattern_sets (void)
4665 obstack_blank (&irp
, description
->units_num
* sizeof (pattern_reserv_t
));
4666 unit_presence_set_table
= (pattern_reserv_t
*) obstack_base (&irp
);
4667 obstack_finish (&irp
);
4668 obstack_blank (&irp
, description
->units_num
* sizeof (pattern_reserv_t
));
4669 unit_final_presence_set_table
= (pattern_reserv_t
*) obstack_base (&irp
);
4670 obstack_finish (&irp
);
4671 obstack_blank (&irp
, description
->units_num
* sizeof (pattern_reserv_t
));
4672 unit_absence_set_table
= (pattern_reserv_t
*) obstack_base (&irp
);
4673 obstack_finish (&irp
);
4674 obstack_blank (&irp
, description
->units_num
* sizeof (pattern_reserv_t
));
4675 unit_final_absence_set_table
= (pattern_reserv_t
*) obstack_base (&irp
);
4676 obstack_finish (&irp
);
4677 /* Evaluate unit presence/absence sets. */
4678 for (i
= 0; i
< description
->decls_num
; i
++)
4680 decl
= description
->decls
[i
];
4681 if (decl
->mode
== dm_unit
)
4683 unit_presence_set_table
[DECL_UNIT (decl
)->unit_num
]
4684 = form_reserv_sets_list (DECL_UNIT (decl
)->presence_list
);
4685 unit_final_presence_set_table
[DECL_UNIT (decl
)->unit_num
]
4686 = form_reserv_sets_list (DECL_UNIT (decl
)->final_presence_list
);
4687 unit_absence_set_table
[DECL_UNIT (decl
)->unit_num
]
4688 = form_reserv_sets_list (DECL_UNIT (decl
)->absence_list
);
4689 unit_final_absence_set_table
[DECL_UNIT (decl
)->unit_num
]
4690 = form_reserv_sets_list (DECL_UNIT (decl
)->final_absence_list
);
4695 /* The function checks that CHECKED_SET satisfies all presence pattern
4696 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4699 check_presence_pattern_sets (reserv_sets_t checked_set
,
4700 reserv_sets_t origional_set
,
4709 pattern_reserv_t pat_reserv
;
4711 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4712 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4713 if (((unsigned char *) origional_set
) [char_num
])
4714 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4715 if ((((unsigned char *) origional_set
) [char_num
] >> i
) & 1)
4717 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4718 if (start_unit_num
>= description
->units_num
)
4721 && unit_final_presence_set_table
[start_unit_num
] == NULL
)
4723 && unit_presence_set_table
[start_unit_num
] == NULL
))
4726 for (pat_reserv
= (final_p
4727 ? unit_final_presence_set_table
[start_unit_num
]
4728 : unit_presence_set_table
[start_unit_num
]);
4730 pat_reserv
= pat_reserv
->next_pattern_reserv
)
4732 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4733 if ((checked_set
[unit_num
] & pat_reserv
->reserv
[unit_num
])
4734 != pat_reserv
->reserv
[unit_num
])
4736 presence_p
= presence_p
|| unit_num
>= els_in_cycle_reserv
;
4744 /* The function checks that CHECKED_SET satisfies all absence pattern
4745 sets for units in ORIGIONAL_SET. The function returns TRUE if it
4748 check_absence_pattern_sets (reserv_sets_t checked_set
,
4749 reserv_sets_t origional_set
,
4757 pattern_reserv_t pat_reserv
;
4759 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4760 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4761 if (((unsigned char *) origional_set
) [char_num
])
4762 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4763 if ((((unsigned char *) origional_set
) [char_num
] >> i
) & 1)
4765 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4766 if (start_unit_num
>= description
->units_num
)
4768 for (pat_reserv
= (final_p
4769 ? unit_final_absence_set_table
[start_unit_num
]
4770 : unit_absence_set_table
[start_unit_num
]);
4772 pat_reserv
= pat_reserv
->next_pattern_reserv
)
4774 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4775 if ((checked_set
[unit_num
] & pat_reserv
->reserv
[unit_num
])
4776 != pat_reserv
->reserv
[unit_num
]
4777 && pat_reserv
->reserv
[unit_num
])
4779 if (unit_num
>= els_in_cycle_reserv
)
4788 /* This page contains code for transformation of original reservations
4789 described in .md file. The main goal of transformations is
4790 simplifying reservation and lifting up all `|' on the top of IR
4791 reservation representation. */
4794 /* The following function makes copy of IR representation of
4795 reservation. The function also substitutes all reservations
4796 defined by define_reservation by corresponding value during making
4799 copy_insn_regexp (regexp_t regexp
)
4804 switch (regexp
->mode
)
4807 result
= copy_insn_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
);
4811 result
= copy_node (regexp
, sizeof (struct regexp
));
4815 result
= copy_node (regexp
, sizeof (struct regexp
));
4816 REGEXP_REPEAT (result
)->regexp
4817 = copy_insn_regexp (REGEXP_REPEAT (regexp
)->regexp
);
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
]);
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
]);
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
]);
4848 result
= copy_node (regexp
, sizeof (struct regexp
));
4857 /* The following variable is set up 1 if a transformation has been
4859 static int regexp_transformed_p
;
4861 /* The function makes transformation
4864 transform_1 (regexp_t regexp
)
4871 if (regexp
->mode
== rm_repeat
)
4873 repeat_num
= REGEXP_REPEAT (regexp
)->repeat_num
;
4874 gcc_assert (repeat_num
> 1);
4875 operand
= REGEXP_REPEAT (regexp
)->regexp
;
4877 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4878 * (repeat_num
- 1));
4879 regexp
->mode
= rm_sequence
;
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;
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|... */
4894 transform_2 (regexp_t regexp
)
4896 if (regexp
->mode
== rm_sequence
)
4898 regexp_t sequence
= NULL
;
4900 int sequence_index
= 0;
4903 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4904 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4907 sequence
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4910 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4912 gcc_assert (REGEXP_SEQUENCE (sequence
)->regexps_num
> 1
4913 && REGEXP_SEQUENCE (regexp
)->regexps_num
> 1);
4914 result
= create_node (sizeof (struct regexp
)
4916 * (REGEXP_SEQUENCE (regexp
)->regexps_num
4917 + REGEXP_SEQUENCE (sequence
)->regexps_num
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
]);
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;
4940 else if (regexp
->mode
== rm_allof
)
4942 regexp_t allof
= NULL
;
4944 int allof_index
= 0;
4947 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4948 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_allof
)
4951 allof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4954 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4956 gcc_assert (REGEXP_ALLOF (allof
)->regexps_num
> 1
4957 && REGEXP_ALLOF (regexp
)->regexps_num
> 1);
4958 result
= create_node (sizeof (struct regexp
)
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
]);
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;
4983 else if (regexp
->mode
== rm_oneof
)
4985 regexp_t oneof
= NULL
;
4987 int oneof_index
= 0;
4990 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4991 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4994 oneof
= REGEXP_ONEOF (regexp
)->regexps
[i
];
4997 if (i
< REGEXP_ONEOF (regexp
)->regexps_num
)
4999 gcc_assert (REGEXP_ONEOF (oneof
)->regexps_num
> 1
5000 && REGEXP_ONEOF (regexp
)->regexps_num
> 1);
5001 result
= create_node (sizeof (struct regexp
)
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
]);
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;
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),... */
5035 transform_3 (regexp_t regexp
)
5037 if (regexp
->mode
== rm_sequence
)
5039 regexp_t oneof
= NULL
;
5040 int oneof_index
= 0;
5045 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5046 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_oneof
)
5049 oneof
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
5052 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
5054 gcc_assert (REGEXP_ONEOF (oneof
)->regexps_num
> 1
5055 && REGEXP_SEQUENCE (regexp
)->regexps_num
> 1);
5056 result
= create_node (sizeof (struct regexp
)
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
++)
5066 = create_node (sizeof (struct regexp
)
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
]);
5079 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
5080 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
5082 regexp_transformed_p
= 1;
5086 else if (regexp
->mode
== rm_allof
)
5088 regexp_t oneof
= NULL
;
5090 int oneof_index
= 0;
5091 int max_seq_length
, allof_length
;
5093 regexp_t allof
= NULL
;
5094 regexp_t allof_op
= NULL
;
5097 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5098 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
5101 oneof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
5104 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
5106 gcc_assert (REGEXP_ONEOF (oneof
)->regexps_num
> 1
5107 && REGEXP_ALLOF (regexp
)->regexps_num
> 1);
5108 result
= create_node (sizeof (struct regexp
)
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
++)
5118 = create_node (sizeof (struct regexp
)
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
]);
5131 REGEXP_ALLOF (allof
)->regexps
[j
]
5132 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
5134 regexp_transformed_p
= 1;
5138 if (regexp
->mode
== rm_allof
)
5139 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5141 switch (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
)
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
;
5159 if (max_seq_length
!= 0)
5161 gcc_assert (max_seq_length
!= 1
5162 && REGEXP_ALLOF (regexp
)->regexps_num
> 1);
5163 result
= create_node (sizeof (struct regexp
)
5164 + sizeof (regexp_t
) * (max_seq_length
- 1));
5165 result
->mode
= rm_sequence
;
5166 result
->pos
= regexp
->pos
;
5167 REGEXP_SEQUENCE (result
)->regexps_num
= max_seq_length
;
5168 for (i
= 0; i
< max_seq_length
; i
++)
5171 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5172 switch (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
)
5175 if (i
< (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5176 ->regexps
[j
])->regexps_num
))
5179 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5189 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5197 if (allof_length
== 1)
5198 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof_op
;
5201 allof
= create_node (sizeof (struct regexp
)
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
;
5209 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5210 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5212 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5213 ->regexps
[j
])->regexps_num
)))
5215 allof_op
= (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5218 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5223 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5225 || (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5228 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5229 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5235 regexp_transformed_p
= 1;
5242 /* The function traverses IR of reservation and applies transformations
5243 implemented by FUNC. */
5245 regexp_transform_func (regexp_t regexp
, regexp_t (*func
) (regexp_t regexp
))
5249 switch (regexp
->mode
)
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
],
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
);
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
);
5271 REGEXP_REPEAT (regexp
)->regexp
5272 = regexp_transform_func (REGEXP_REPEAT (regexp
)->regexp
, func
);
5282 return (*func
) (regexp
);
5285 /* The function applies all transformations for IR representation of
5286 reservation REGEXP. */
5288 transform_regexp (regexp_t regexp
)
5290 regexp
= regexp_transform_func (regexp
, transform_1
);
5293 regexp_transformed_p
= 0;
5294 regexp
= regexp_transform_func (regexp
, transform_2
);
5295 regexp
= regexp_transform_func (regexp
, transform_3
);
5297 while (regexp_transformed_p
);
5301 /* The function applies all transformations for reservations of all
5302 insn declarations. */
5304 transform_insn_regexps (void)
5309 transform_time
= create_ticker ();
5310 add_advance_cycle_insn_decl ();
5312 fprintf (stderr
, "Reservation transformation...");
5313 for (i
= 0; i
< description
->decls_num
; i
++)
5315 decl
= description
->decls
[i
];
5316 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
5317 DECL_INSN_RESERV (decl
)->transformed_regexp
5318 = transform_regexp (copy_insn_regexp
5319 (DECL_INSN_RESERV (decl
)->regexp
));
5322 fprintf (stderr
, "done\n");
5323 ticker_off (&transform_time
);
5328 /* The following variable value is TRUE if the first annotated message
5329 about units to automata distribution has been output. */
5330 static int annotation_message_reported_p
;
5332 /* The following structure describes usage of a unit in a reservation. */
5335 unit_decl_t unit_decl
;
5336 /* The following forms a list of units used on the same cycle in the
5337 same alternative. */
5338 struct unit_usage
*next
;
5341 /* Obstack for unit_usage structures. */
5342 static struct obstack unit_usages
;
5344 /* VLA for representation of array of pointers to unit usage
5345 structures. There is an element for each combination of
5346 (alternative number, cycle). Unit usages on given cycle in
5347 alternative with given number are referred through element with
5348 index equals to the cycle * number of all alternatives in the regexp
5349 + the alternative number. */
5350 static vla_ptr_t cycle_alt_unit_usages
;
5352 /* The following function creates the structure unit_usage for UNIT on
5353 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5354 accessed through cycle_alt_unit_usages. */
5356 store_alt_unit_usage (regexp_t regexp
, regexp_t unit
, int cycle
,
5359 size_t i
, length
, old_length
;
5360 unit_decl_t unit_decl
;
5361 struct unit_usage
*unit_usage_ptr
;
5364 gcc_assert (regexp
&& regexp
->mode
== rm_oneof
5365 && alt_num
< REGEXP_ONEOF (regexp
)->regexps_num
);
5366 unit_decl
= REGEXP_UNIT (unit
)->unit_decl
;
5367 old_length
= VLA_PTR_LENGTH (cycle_alt_unit_usages
);
5368 length
= (cycle
+ 1) * REGEXP_ONEOF (regexp
)->regexps_num
;
5369 if (old_length
< length
)
5371 VLA_PTR_EXPAND (cycle_alt_unit_usages
, length
- old_length
);
5372 for (i
= old_length
; i
< length
; i
++)
5373 VLA_PTR (cycle_alt_unit_usages
, i
) = NULL
;
5375 obstack_blank (&unit_usages
, sizeof (struct unit_usage
));
5376 unit_usage_ptr
= (struct unit_usage
*) obstack_base (&unit_usages
);
5377 obstack_finish (&unit_usages
);
5378 unit_usage_ptr
->unit_decl
= unit_decl
;
5379 index
= cycle
* REGEXP_ONEOF (regexp
)->regexps_num
+ alt_num
;
5380 unit_usage_ptr
->next
= VLA_PTR (cycle_alt_unit_usages
, index
);
5381 VLA_PTR (cycle_alt_unit_usages
, index
) = unit_usage_ptr
;
5382 unit_decl
->last_distribution_check_cycle
= -1; /* undefined */
5385 /* The function processes given REGEXP to find units with the wrong
5388 check_regexp_units_distribution (const char *insn_reserv_name
,
5392 regexp_t seq
, allof
, unit
;
5393 struct unit_usage
*unit_usage_ptr
, *other_unit_usage_ptr
;
5395 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5397 /* Store all unit usages in the regexp: */
5398 obstack_init (&unit_usages
);
5399 VLA_PTR_CREATE (cycle_alt_unit_usages
, 100, "unit usages on cycles");
5400 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5402 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5406 for (j
= 0; j
< REGEXP_SEQUENCE (seq
)->regexps_num
; j
++)
5408 allof
= REGEXP_SEQUENCE (seq
)->regexps
[j
];
5409 switch (allof
->mode
)
5412 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5414 unit
= REGEXP_ALLOF (allof
)->regexps
[k
];
5415 if (unit
->mode
== rm_unit
)
5416 store_alt_unit_usage (regexp
, unit
, j
, i
);
5418 gcc_assert (unit
->mode
== rm_nothing
);
5423 store_alt_unit_usage (regexp
, allof
, j
, i
);
5436 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5438 unit
= REGEXP_ALLOF (seq
)->regexps
[k
];
5442 store_alt_unit_usage (regexp
, unit
, 0, i
);
5455 store_alt_unit_usage (regexp
, seq
, 0, i
);
5465 /* Check distribution: */
5466 for (i
= 0; i
< (int) VLA_PTR_LENGTH (cycle_alt_unit_usages
); i
++)
5468 cycle
= i
/ REGEXP_ONEOF (regexp
)->regexps_num
;
5469 for (unit_usage_ptr
= VLA_PTR (cycle_alt_unit_usages
, i
);
5470 unit_usage_ptr
!= NULL
;
5471 unit_usage_ptr
= unit_usage_ptr
->next
)
5472 if (cycle
!= unit_usage_ptr
->unit_decl
->last_distribution_check_cycle
)
5474 unit_usage_ptr
->unit_decl
->last_distribution_check_cycle
= cycle
;
5475 for (k
= cycle
* REGEXP_ONEOF (regexp
)->regexps_num
;
5476 k
< (int) VLA_PTR_LENGTH (cycle_alt_unit_usages
)
5477 && k
== cycle
* REGEXP_ONEOF (regexp
)->regexps_num
;
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
)
5486 if (other_unit_usage_ptr
== NULL
5487 && VLA_PTR (cycle_alt_unit_usages
, k
) != NULL
)
5490 if (k
< (int) VLA_PTR_LENGTH (cycle_alt_unit_usages
)
5491 && k
== cycle
* REGEXP_ONEOF (regexp
)->regexps_num
)
5493 if (!annotation_message_reported_p
)
5495 fprintf (stderr
, "\n");
5496 error ("The following units do not satisfy units-automata distribution rule");
5497 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5498 annotation_message_reported_p
= TRUE
;
5500 error ("Unit %s, reserv. %s, cycle %d",
5501 unit_usage_ptr
->unit_decl
->name
, insn_reserv_name
,
5506 VLA_PTR_DELETE (cycle_alt_unit_usages
);
5507 obstack_free (&unit_usages
, NULL
);
5510 /* The function finds units which violates units to automata
5511 distribution rule. If the units exist, report about them. */
5513 check_unit_distributions_to_automata (void)
5519 fprintf (stderr
, "Check unit distributions to automata...");
5520 annotation_message_reported_p
= FALSE
;
5521 for (i
= 0; i
< description
->decls_num
; i
++)
5523 decl
= description
->decls
[i
];
5524 if (decl
->mode
== dm_insn_reserv
)
5525 check_regexp_units_distribution
5526 (DECL_INSN_RESERV (decl
)->name
,
5527 DECL_INSN_RESERV (decl
)->transformed_regexp
);
5530 fprintf (stderr
, "done\n");
5535 /* The page contains code for building alt_states (see comments for
5536 IR) describing all possible insns reservations of an automaton. */
5538 /* Current state being formed for which the current alt_state
5540 static state_t state_being_formed
;
5542 /* Current alt_state being formed. */
5543 static alt_state_t alt_state_being_formed
;
5545 /* This recursive function processes `,' and units in reservation
5546 REGEXP for forming alt_states of AUTOMATON. It is believed that
5547 CURR_CYCLE is start cycle of all reservation REGEXP. */
5549 process_seq_for_forming_states (regexp_t regexp
, automaton_t automaton
,
5557 switch (regexp
->mode
)
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
);
5567 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5569 = process_seq_for_forming_states
5570 (REGEXP_SEQUENCE (regexp
)->regexps
[i
], automaton
, curr_cycle
) + 1;
5575 int finish_cycle
= 0;
5578 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5580 cycle
= process_seq_for_forming_states (REGEXP_ALLOF (regexp
)
5582 automaton
, curr_cycle
);
5583 if (finish_cycle
< cycle
)
5584 finish_cycle
= cycle
;
5586 return finish_cycle
;
5597 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5598 inserts alt_state into the table. */
5600 finish_forming_alt_state (alt_state_t alt_state
,
5601 automaton_t automaton ATTRIBUTE_UNUSED
)
5603 state_t state_in_table
;
5604 state_t corresponding_state
;
5606 corresponding_state
= alt_state
->state
;
5607 state_in_table
= insert_state (corresponding_state
);
5608 if (state_in_table
!= corresponding_state
)
5610 free_state (corresponding_state
);
5611 alt_state
->state
= state_in_table
;
5615 /* The following variable value is current automaton insn for whose
5616 reservation the alt states are created. */
5617 static ainsn_t curr_ainsn
;
5619 /* This recursive function processes `|' in reservation REGEXP for
5620 forming alt_states of AUTOMATON. List of the alt states should
5621 have the same order as in the description. */
5623 process_alts_for_forming_states (regexp_t regexp
, automaton_t automaton
,
5628 if (regexp
->mode
!= rm_oneof
)
5630 alt_state_being_formed
= get_free_alt_state ();
5631 state_being_formed
= get_free_state (1, automaton
);
5632 alt_state_being_formed
->state
= state_being_formed
;
5633 /* We inserts in reverse order but we process alternatives also
5634 in reverse order. So we have the same order of alternative
5635 as in the description. */
5636 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5637 curr_ainsn
->alt_states
= alt_state_being_formed
;
5638 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5639 finish_forming_alt_state (alt_state_being_formed
, automaton
);
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
5647 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5648 process_alts_for_forming_states (REGEXP_ONEOF (regexp
)->regexps
[i
],
5653 /* Create nodes alt_state for all AUTOMATON insns. */
5655 create_alt_states (automaton_t automaton
)
5657 struct insn_reserv_decl
*reserv_decl
;
5659 for (curr_ainsn
= automaton
->ainsn_list
;
5661 curr_ainsn
= curr_ainsn
->next_ainsn
)
5663 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5664 if (reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5666 curr_ainsn
->alt_states
= NULL
;
5667 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5669 curr_ainsn
->sorted_alt_states
5670 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5677 /* The page contains major code for building DFA(s) for fast pipeline
5678 hazards recognition. */
5680 /* The function forms list of ainsns of AUTOMATON with the same
5683 form_ainsn_with_same_reservs (automaton_t automaton
)
5687 vla_ptr_t first_insns
;
5688 vla_ptr_t last_insns
;
5690 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5691 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5692 for (curr_ainsn
= automaton
->ainsn_list
;
5694 curr_ainsn
= curr_ainsn
->next_ainsn
)
5695 if (curr_ainsn
->insn_reserv_decl
5696 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
5698 curr_ainsn
->next_same_reservs_insn
= NULL
;
5699 curr_ainsn
->first_insn_with_same_reservs
= 1;
5703 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5705 (curr_ainsn
->sorted_alt_states
,
5706 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5708 curr_ainsn
->next_same_reservs_insn
= NULL
;
5709 if (i
< VLA_PTR_LENGTH (first_insns
))
5711 curr_ainsn
->first_insn_with_same_reservs
= 0;
5712 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5714 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5718 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5719 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5720 curr_ainsn
->first_insn_with_same_reservs
= 1;
5723 VLA_PTR_DELETE (first_insns
);
5724 VLA_PTR_DELETE (last_insns
);
5727 /* Forming unit reservations which can affect creating the automaton
5728 states achieved from a given state. It permits to build smaller
5729 automata in many cases. We would have the same automata after
5730 the minimization without such optimization, but the automaton
5731 right after the building could be huge. So in other words, usage
5732 of reservs_matter means some minimization during building the
5734 static reserv_sets_t
5735 form_reservs_matter (automaton_t automaton
)
5738 reserv_sets_t reservs_matter
= alloc_empty_reserv_sets();
5740 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
5741 for (unit
= 0; unit
< description
->units_num
; unit
++)
5742 if (units_array
[unit
]->automaton_decl
5743 == automaton
->corresponding_automaton_decl
5744 && (cycle
>= units_array
[unit
]->min_occ_cycle_num
5745 /* We can not remove queried unit from reservations. */
5746 || units_array
[unit
]->query_p
5747 /* We can not remove units which are used
5748 `exclusion_set', `presence_set',
5749 `final_presence_set', `absence_set', and
5750 `final_absence_set'. */
5751 || units_array
[unit
]->in_set_p
))
5752 set_unit_reserv (reservs_matter
, cycle
, unit
);
5753 return reservs_matter
;
5756 /* The following function creates all states of nondeterministic (if
5757 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5759 make_automaton (automaton_t automaton
)
5762 struct insn_reserv_decl
*insn_reserv_decl
;
5763 alt_state_t alt_state
;
5765 state_t start_state
;
5767 ainsn_t advance_cycle_ainsn
;
5769 vla_ptr_t state_stack
;
5771 reserv_sets_t reservs_matter
= form_reservs_matter (automaton
);
5773 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5774 /* Create the start state (empty state). */
5775 start_state
= insert_state (get_free_state (1, automaton
));
5776 automaton
->start_state
= start_state
;
5777 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5778 VLA_PTR_ADD (state_stack
, start_state
);
5780 while (VLA_PTR_LENGTH (state_stack
) != 0)
5782 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5783 VLA_PTR_SHORTEN (state_stack
, 1);
5784 advance_cycle_ainsn
= NULL
;
5785 for (ainsn
= automaton
->ainsn_list
;
5787 ainsn
= ainsn
->next_ainsn
)
5788 if (ainsn
->first_insn_with_same_reservs
)
5790 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5791 if (insn_reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5793 /* We process alt_states in the same order as they are
5794 present in the description. */
5796 for (alt_state
= ainsn
->alt_states
;
5798 alt_state
= alt_state
->next_alt_state
)
5800 state2
= alt_state
->state
;
5801 if (!intersected_state_reservs_p (state
, state2
))
5803 state2
= states_union (state
, state2
, reservs_matter
);
5804 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5806 state2
->it_was_placed_in_stack_for_NDFA_forming
5808 VLA_PTR_ADD (state_stack
, state2
);
5810 if (progress_flag
&& states_n
% 100 == 0)
5811 fprintf (stderr
, ".");
5813 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5818 if (!ndfa_flag
&& added_arc
!= NULL
)
5820 added_arc
->state_alts
= 0;
5821 for (alt_state
= ainsn
->alt_states
;
5823 alt_state
= alt_state
->next_alt_state
)
5825 state2
= alt_state
->state
;
5826 if (!intersected_state_reservs_p (state
, state2
))
5827 added_arc
->state_alts
++;
5832 advance_cycle_ainsn
= ainsn
;
5834 /* Add transition to advance cycle. */
5835 state2
= state_shift (state
, reservs_matter
);
5836 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5838 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5839 VLA_PTR_ADD (state_stack
, state2
);
5841 if (progress_flag
&& states_n
% 100 == 0)
5842 fprintf (stderr
, ".");
5844 gcc_assert (advance_cycle_ainsn
);
5845 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5847 VLA_PTR_DELETE (state_stack
);
5850 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5852 form_arcs_marked_by_insn (state_t state
)
5858 for (i
= 0; i
< description
->decls_num
; i
++)
5860 decl
= description
->decls
[i
];
5861 if (decl
->mode
== dm_insn_reserv
)
5862 DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
= NULL
;
5864 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5866 gcc_assert (arc
->insn
);
5867 arc
->next_arc_marked_by_insn
5868 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5869 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5873 /* The function creates composed state (see comments for IR) from
5874 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5875 same insn. If the composed state is not in STATE_STACK yet, it is
5876 pushed into STATE_STACK. */
5878 create_composed_state (state_t original_state
, arc_t arcs_marked_by_insn
,
5879 vla_ptr_t
*state_stack
)
5882 alt_state_t alt_state
, curr_alt_state
;
5883 alt_state_t new_alt_state
;
5886 state_t state_in_table
;
5888 alt_state_t canonical_alt_states_list
;
5890 int new_state_p
= 0;
5892 if (arcs_marked_by_insn
== NULL
)
5894 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5895 state
= arcs_marked_by_insn
->to_state
;
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
;
5904 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5905 if (curr_arc
->to_state
->component_states
== NULL
)
5907 new_alt_state
= get_free_alt_state ();
5908 new_alt_state
->next_alt_state
= curr_alt_state
;
5909 new_alt_state
->state
= curr_arc
->to_state
;
5910 curr_alt_state
= new_alt_state
;
5913 for (alt_state
= curr_arc
->to_state
->component_states
;
5915 alt_state
= alt_state
->next_sorted_alt_state
)
5917 new_alt_state
= get_free_alt_state ();
5918 new_alt_state
->next_alt_state
= curr_alt_state
;
5919 new_alt_state
->state
= alt_state
->state
;
5920 gcc_assert (!alt_state
->state
->component_states
);
5921 curr_alt_state
= new_alt_state
;
5923 /* There are not identical sets in the alt state list. */
5924 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5925 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5928 state
= canonical_alt_states_list
->state
;
5929 free_state (temp_state
);
5933 state
->component_states
= canonical_alt_states_list
;
5934 state_in_table
= insert_state (state
);
5935 if (state_in_table
!= state
)
5938 (state_in_table
->it_was_placed_in_stack_for_DFA_forming
);
5940 state
= state_in_table
;
5944 gcc_assert (!state
->it_was_placed_in_stack_for_DFA_forming
);
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
);
5951 curr_arc
= next_out_arc (curr_arc
))
5952 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5954 arcs_marked_by_insn
->to_state
= state
;
5955 for (alts_number
= 0,
5956 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5958 curr_arc
= next_arc
)
5960 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5961 remove_arc (original_state
, curr_arc
);
5964 arcs_marked_by_insn
->state_alts
= alts_number
;
5967 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5969 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5970 VLA_PTR_ADD (*state_stack
, state
);
5975 /* The function transforms nondeterministic AUTOMATON into
5978 NDFA_to_DFA (automaton_t automaton
)
5980 state_t start_state
;
5983 vla_ptr_t state_stack
;
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
);
5993 while (VLA_PTR_LENGTH (state_stack
) != 0)
5995 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5996 VLA_PTR_SHORTEN (state_stack
, 1);
5997 form_arcs_marked_by_insn (state
);
5998 for (i
= 0; i
< description
->decls_num
; i
++)
6000 decl
= description
->decls
[i
];
6001 if (decl
->mode
== dm_insn_reserv
6002 && create_composed_state
6003 (state
, DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
,
6007 if (progress_flag
&& states_n
% 100 == 0)
6008 fprintf (stderr
, ".");
6012 VLA_PTR_DELETE (state_stack
);
6015 /* The following variable value is current number (1, 2, ...) of passing
6017 static int curr_state_graph_pass_num
;
6019 /* This recursive function passes all states achieved from START_STATE
6020 and applies APPLIED_FUNC to them. */
6022 pass_state_graph (state_t start_state
, void (*applied_func
) (state_t state
))
6026 if (start_state
->pass_num
== curr_state_graph_pass_num
)
6028 start_state
->pass_num
= curr_state_graph_pass_num
;
6029 (*applied_func
) (start_state
);
6030 for (arc
= first_out_arc (start_state
);
6032 arc
= next_out_arc (arc
))
6033 pass_state_graph (arc
->to_state
, applied_func
);
6036 /* This recursive function passes all states of AUTOMATON and applies
6037 APPLIED_FUNC to them. */
6039 pass_states (automaton_t automaton
, void (*applied_func
) (state_t state
))
6041 curr_state_graph_pass_num
++;
6042 pass_state_graph (automaton
->start_state
, applied_func
);
6045 /* The function initializes code for passing of all states. */
6047 initiate_pass_states (void)
6049 curr_state_graph_pass_num
= 0;
6052 /* The following vla is used for storing pointers to all achieved
6054 static vla_ptr_t all_achieved_states
;
6056 /* This function is called by function pass_states to add an achieved
6059 add_achieved_state (state_t state
)
6061 VLA_PTR_ADD (all_achieved_states
, state
);
6064 /* The function sets up equivalence numbers of insns which mark all
6065 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6066 nonzero value) or by equiv_class_num_2 of the destination state.
6067 The function returns number of out arcs of STATE. */
6069 set_out_arc_insns_equiv_num (state_t state
, int odd_iteration_flag
)
6071 int state_out_arcs_num
;
6074 state_out_arcs_num
= 0;
6075 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6077 gcc_assert (!arc
->insn
->insn_reserv_decl
->equiv_class_num
6078 && !arc
->insn
->insn_reserv_decl
->state_alts
);
6079 state_out_arcs_num
++;
6080 arc
->insn
->insn_reserv_decl
->equiv_class_num
6081 = (odd_iteration_flag
6082 ? arc
->to_state
->equiv_class_num_1
6083 : arc
->to_state
->equiv_class_num_2
);
6084 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
6085 gcc_assert (arc
->insn
->insn_reserv_decl
->equiv_class_num
6086 && arc
->insn
->insn_reserv_decl
->state_alts
> 0);
6088 return state_out_arcs_num
;
6091 /* The function clears equivalence numbers and alt_states in all insns
6092 which mark all out arcs of STATE. */
6094 clear_arc_insns_equiv_num (state_t state
)
6098 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6100 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
6101 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
6105 /* The function copies pointers to equivalent states from vla FROM
6108 copy_equiv_class (vla_ptr_t
*to
, const vla_ptr_t
*from
)
6112 VLA_PTR_NULLIFY (*to
);
6113 for (class_ptr
= VLA_PTR_BEGIN (*from
);
6114 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
6116 VLA_PTR_ADD (*to
, *class_ptr
);
6119 /* The following function returns TRUE if STATE reserves the unit with
6120 UNIT_NUM on the first cycle. */
6122 first_cycle_unit_presence (state_t state
, int unit_num
)
6124 alt_state_t alt_state
;
6126 if (state
->component_states
== NULL
)
6127 return test_unit_reserv (state
->reservs
, 0, unit_num
);
6130 for (alt_state
= state
->component_states
;
6132 alt_state
= alt_state
->next_sorted_alt_state
)
6133 if (test_unit_reserv (alt_state
->state
->reservs
, 0, unit_num
))
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. */
6145 state_is_differed (state_t state
, state_t another_state
,
6146 int another_state_out_arcs_num
, int odd_iteration_flag
)
6149 int state_out_arcs_num
;
6150 int i
, presence1_p
, presence2_p
;
6152 state_out_arcs_num
= 0;
6153 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6155 state_out_arcs_num
++;
6156 if ((odd_iteration_flag
6157 ? arc
->to_state
->equiv_class_num_1
6158 : arc
->to_state
->equiv_class_num_2
)
6159 != arc
->insn
->insn_reserv_decl
->equiv_class_num
6160 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
6163 if (state_out_arcs_num
!= another_state_out_arcs_num
)
6165 /* Now we are looking at the states with the point of view of query
6167 for (i
= 0; i
< description
->units_num
; i
++)
6168 if (units_array
[i
]->query_p
)
6170 presence1_p
= first_cycle_unit_presence (state
, i
);
6171 presence2_p
= first_cycle_unit_presence (another_state
, i
);
6172 if ((presence1_p
&& !presence2_p
) || (!presence1_p
&& presence2_p
))
6178 /* The function makes initial partition of STATES on equivalent
6181 init_equiv_class (state_t
*states
, int states_num
)
6184 state_t result_equiv_class
;
6186 result_equiv_class
= NULL
;
6187 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
6189 (*state_ptr
)->equiv_class_num_1
= 1;
6190 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
6191 result_equiv_class
= *state_ptr
;
6193 return result_equiv_class
;
6196 /* The function processes equivalence class given by its pointer
6197 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6198 are not equivalent states, the function partitions the class
6199 removing nonequivalent states and placing them in
6200 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6201 assigns it to the state equivalence number. If the class has been
6202 partitioned, the function returns nonzero value. */
6204 partition_equiv_class (state_t
*equiv_class_ptr
, int odd_iteration_flag
,
6205 vla_ptr_t
*next_iteration_classes
,
6206 int *new_equiv_class_num_ptr
)
6208 state_t new_equiv_class
;
6210 state_t first_state
;
6217 gcc_assert (*equiv_class_ptr
);
6218 for (first_state
= *equiv_class_ptr
;
6219 first_state
!= NULL
;
6220 first_state
= new_equiv_class
)
6222 new_equiv_class
= NULL
;
6223 if (first_state
->next_equiv_class_state
!= NULL
)
6225 /* There are more one states in the class equivalence. */
6226 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
6227 odd_iteration_flag
);
6228 for (prev_state
= first_state
,
6229 curr_state
= first_state
->next_equiv_class_state
;
6231 curr_state
= next_state
)
6233 next_state
= curr_state
->next_equiv_class_state
;
6234 if (state_is_differed (curr_state
, first_state
, out_arcs_num
,
6235 odd_iteration_flag
))
6237 /* Remove curr state from the class equivalence. */
6238 prev_state
->next_equiv_class_state
= next_state
;
6239 /* Add curr state to the new class equivalence. */
6240 curr_state
->next_equiv_class_state
= new_equiv_class
;
6241 if (new_equiv_class
== NULL
)
6242 (*new_equiv_class_num_ptr
)++;
6243 if (odd_iteration_flag
)
6244 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
6246 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
6247 new_equiv_class
= curr_state
;
6251 prev_state
= curr_state
;
6253 clear_arc_insns_equiv_num (first_state
);
6255 if (new_equiv_class
!= NULL
)
6256 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
6261 /* The function finds equivalent states of AUTOMATON. */
6263 evaluate_equiv_classes (automaton_t automaton
, vla_ptr_t
*equiv_classes
)
6265 state_t new_equiv_class
;
6266 int new_equiv_class_num
;
6267 int odd_iteration_flag
;
6269 vla_ptr_t next_iteration_classes
;
6270 state_t
*equiv_class_ptr
;
6273 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
6274 pass_states (automaton
, add_achieved_state
);
6275 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
6276 VLA_PTR_LENGTH (all_achieved_states
));
6277 odd_iteration_flag
= 0;
6278 new_equiv_class_num
= 1;
6279 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
6280 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
6283 odd_iteration_flag
= !odd_iteration_flag
;
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
);
6290 if (odd_iteration_flag
)
6291 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
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
);
6297 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
6298 &next_iteration_classes
,
6299 &new_equiv_class_num
))
6302 while (!finish_flag
);
6303 VLA_PTR_DELETE (next_iteration_classes
);
6304 VLA_PTR_DELETE (all_achieved_states
);
6307 /* The function merges equivalent states of AUTOMATON. */
6309 merge_states (automaton_t automaton
, vla_ptr_t
*equiv_classes
)
6311 state_t
*equiv_class_ptr
;
6314 state_t first_class_state
;
6315 alt_state_t alt_states
;
6316 alt_state_t alt_state
, new_alt_state
;
6320 /* Create states corresponding to equivalence classes containing two
6322 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6323 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6325 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6327 /* There are more one states in the class equivalence. */
6328 /* Create new compound state. */
6329 new_state
= get_free_state (0, automaton
);
6331 first_class_state
= *equiv_class_ptr
;
6332 for (curr_state
= first_class_state
;
6334 curr_state
= curr_state
->next_equiv_class_state
)
6336 curr_state
->equiv_class_state
= new_state
;
6337 if (curr_state
->component_states
== NULL
)
6339 new_alt_state
= get_free_alt_state ();
6340 new_alt_state
->state
= curr_state
;
6341 new_alt_state
->next_alt_state
= alt_states
;
6342 alt_states
= new_alt_state
;
6345 for (alt_state
= curr_state
->component_states
;
6347 alt_state
= alt_state
->next_sorted_alt_state
)
6349 new_alt_state
= get_free_alt_state ();
6350 new_alt_state
->state
= alt_state
->state
;
6351 new_alt_state
->next_alt_state
= alt_states
;
6352 alt_states
= new_alt_state
;
6355 /* Its is important that alt states were sorted before and
6356 after merging to have the same querying results. */
6357 new_state
->component_states
= uniq_sort_alt_states (alt_states
);
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
);
6364 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6366 first_class_state
= *equiv_class_ptr
;
6367 /* Create new arcs output from the state corresponding to
6369 for (curr_arc
= first_out_arc (first_class_state
);
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
;
6378 curr_state
= curr_state
->next_equiv_class_state
)
6380 if (automaton
->start_state
== curr_state
)
6381 automaton
->start_state
= curr_state
->equiv_class_state
;
6382 /* Delete the state and its output arcs. */
6383 for (curr_arc
= first_out_arc (curr_state
);
6385 curr_arc
= next_arc
)
6387 next_arc
= next_out_arc (curr_arc
);
6388 free_arc (curr_arc
);
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
);
6398 curr_arc
= next_out_arc (curr_arc
))
6399 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
6403 /* The function sets up new_cycle_p for states if there is arc to the
6404 state marked by advance_cycle_insn_decl. */
6406 set_new_cycle_flags (state_t state
)
6410 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6411 if (arc
->insn
->insn_reserv_decl
6412 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
6413 arc
->to_state
->new_cycle_p
= 1;
6416 /* The top level function for minimization of deterministic
6419 minimize_DFA (automaton_t automaton
)
6421 vla_ptr_t equiv_classes
;
6423 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
6424 evaluate_equiv_classes (automaton
, &equiv_classes
);
6425 merge_states (automaton
, &equiv_classes
);
6426 pass_states (automaton
, set_new_cycle_flags
);
6427 VLA_PTR_DELETE (equiv_classes
);
6430 /* Values of two variables are counted number of states and arcs in an
6432 static int curr_counted_states_num
;
6433 static int curr_counted_arcs_num
;
6435 /* The function is called by function `pass_states' to count states
6436 and arcs of an automaton. */
6438 incr_states_and_arcs_nums (state_t state
)
6442 curr_counted_states_num
++;
6443 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6444 curr_counted_arcs_num
++;
6447 /* The function counts states and arcs of AUTOMATON. */
6449 count_states_and_arcs (automaton_t automaton
, int *states_num
,
6452 curr_counted_states_num
= 0;
6453 curr_counted_arcs_num
= 0;
6454 pass_states (automaton
, incr_states_and_arcs_nums
);
6455 *states_num
= curr_counted_states_num
;
6456 *arcs_num
= curr_counted_arcs_num
;
6459 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6460 recognition after checking and simplifying IR of the
6463 build_automaton (automaton_t automaton
)
6468 ticker_on (&NDFA_time
);
6471 if (automaton
->corresponding_automaton_decl
== NULL
)
6472 fprintf (stderr
, "Create anonymous automaton");
6474 fprintf (stderr
, "Create automaton `%s'",
6475 automaton
->corresponding_automaton_decl
->name
);
6476 fprintf (stderr
, " (1 dot is 100 new states):");
6478 make_automaton (automaton
);
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
);
6488 if (automaton
->corresponding_automaton_decl
== NULL
)
6489 fprintf (stderr
, "Make anonymous DFA");
6491 fprintf (stderr
, "Make DFA `%s'",
6492 automaton
->corresponding_automaton_decl
->name
);
6493 fprintf (stderr
, " (1 dot is 100 new states):");
6495 NDFA_to_DFA (automaton
);
6497 fprintf (stderr
, " done\n");
6498 ticker_off (&NDFA_to_DFA_time
);
6499 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6500 automaton
->DFA_states_num
= states_num
;
6501 automaton
->DFA_arcs_num
= arcs_num
;
6502 if (!no_minimization_flag
)
6504 ticker_on (&minimize_time
);
6507 if (automaton
->corresponding_automaton_decl
== NULL
)
6508 fprintf (stderr
, "Minimize anonymous DFA...");
6510 fprintf (stderr
, "Minimize DFA `%s'...",
6511 automaton
->corresponding_automaton_decl
->name
);
6513 minimize_DFA (automaton
);
6515 fprintf (stderr
, "done\n");
6516 ticker_off (&minimize_time
);
6517 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6518 automaton
->minimal_DFA_states_num
= states_num
;
6519 automaton
->minimal_DFA_arcs_num
= arcs_num
;
6525 /* The page contains code for enumeration of all states of an automaton. */
6527 /* Variable used for enumeration of all states of an automaton. Its
6528 value is current number of automaton states. */
6529 static int curr_state_order_num
;
6531 /* The function is called by function `pass_states' for enumerating
6534 set_order_state_num (state_t state
)
6536 state
->order_state_num
= curr_state_order_num
;
6537 curr_state_order_num
++;
6540 /* The function enumerates all states of AUTOMATON. */
6542 enumerate_states (automaton_t automaton
)
6544 curr_state_order_num
= 0;
6545 pass_states (automaton
, set_order_state_num
);
6546 automaton
->achieved_states_num
= curr_state_order_num
;
6551 /* The page contains code for finding equivalent automaton insns
6554 /* The function inserts AINSN into cyclic list
6555 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6557 insert_ainsn_into_equiv_class (ainsn_t ainsn
,
6558 ainsn_t cyclic_equiv_class_insn_list
)
6560 if (cyclic_equiv_class_insn_list
== NULL
)
6561 ainsn
->next_equiv_class_insn
= ainsn
;
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
;
6571 /* The function deletes equiv_class_insn into cyclic list of
6572 equivalent ainsns. */
6574 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn
)
6576 ainsn_t curr_equiv_class_insn
;
6577 ainsn_t prev_equiv_class_insn
;
6579 prev_equiv_class_insn
= equiv_class_insn
;
6580 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
6581 curr_equiv_class_insn
!= equiv_class_insn
;
6582 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
6583 prev_equiv_class_insn
= curr_equiv_class_insn
;
6584 if (prev_equiv_class_insn
!= equiv_class_insn
)
6585 prev_equiv_class_insn
->next_equiv_class_insn
6586 = equiv_class_insn
->next_equiv_class_insn
;
6589 /* The function processes AINSN of a state in order to find equivalent
6590 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6593 process_insn_equiv_class (ainsn_t ainsn
, arc_t
*insn_arcs_array
)
6597 ainsn_t cyclic_insn_list
;
6600 gcc_assert (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]);
6602 /* New class of ainsns which are not equivalent to given ainsn. */
6603 cyclic_insn_list
= NULL
;
6606 next_insn
= curr_insn
->next_equiv_class_insn
;
6607 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6609 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6612 delete_ainsn_from_equiv_class (curr_insn
);
6613 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6616 curr_insn
= next_insn
;
6618 while (curr_insn
!= ainsn
);
6621 /* The function processes STATE in order to find equivalent ainsns. */
6623 process_state_for_insn_equiv_partition (state_t state
)
6626 arc_t
*insn_arcs_array
;
6628 vla_ptr_t insn_arcs_vect
;
6630 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6631 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6632 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6633 /* Process insns of the arcs. */
6634 for (i
= 0; i
< description
->insns_num
; i
++)
6635 insn_arcs_array
[i
] = NULL
;
6636 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6637 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6638 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6639 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6640 VLA_PTR_DELETE (insn_arcs_vect
);
6643 /* The function searches for equivalent ainsns of AUTOMATON. */
6645 set_insn_equiv_classes (automaton_t automaton
)
6650 ainsn_t cyclic_insn_list
;
6651 ainsn_t insn_with_same_reservs
;
6652 int equiv_classes_num
;
6654 /* All insns are included in one equivalence class. */
6655 cyclic_insn_list
= NULL
;
6656 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6657 if (ainsn
->first_insn_with_same_reservs
)
6658 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
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)
6671 gcc_assert (first_insn
->first_insn_with_same_reservs
);
6672 first_insn
->first_ainsn_with_given_equivalence_num
= 1;
6673 curr_insn
= first_insn
;
6676 for (insn_with_same_reservs
= curr_insn
;
6677 insn_with_same_reservs
!= NULL
;
6678 insn_with_same_reservs
6679 = insn_with_same_reservs
->next_same_reservs_insn
)
6680 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6681 curr_insn
= curr_insn
->next_equiv_class_insn
;
6683 while (curr_insn
!= first_insn
);
6684 equiv_classes_num
++;
6686 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6691 /* This page contains code for creating DFA(s) and calls functions
6695 /* The following value is used to prevent floating point overflow for
6696 estimating an automaton bound. The value should be less DBL_MAX on
6697 the host machine. We use here approximate minimum of maximal
6698 double floating point value required by ANSI C standard. It
6699 will work for non ANSI sun compiler too. */
6701 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6703 /* The function estimate size of the single DFA used by PHR (pipeline
6704 hazards recognizer). */
6706 estimate_one_automaton_bound (void)
6709 double one_automaton_estimation_bound
;
6713 one_automaton_estimation_bound
= 1.0;
6714 for (i
= 0; i
< description
->decls_num
; i
++)
6716 decl
= description
->decls
[i
];
6717 if (decl
->mode
== dm_unit
)
6719 root_value
= exp (log (DECL_UNIT (decl
)->max_occ_cycle_num
6720 - DECL_UNIT (decl
)->min_occ_cycle_num
+ 1.0)
6722 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6723 > one_automaton_estimation_bound
)
6724 one_automaton_estimation_bound
*= root_value
;
6727 return one_automaton_estimation_bound
;
6730 /* The function compares unit declarations according to their maximal
6731 cycle in reservations. */
6733 compare_max_occ_cycle_nums (const void *unit_decl_1
,
6734 const void *unit_decl_2
)
6736 if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6737 < (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
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
))
6746 /* The function makes heuristic assigning automata to units. Actually
6747 efficacy of the algorithm has been checked yet??? */
6749 units_to_automata_heuristic_distr (void)
6751 double estimation_bound
;
6753 decl_t
*unit_decl_ptr
;
6757 vla_ptr_t unit_decls
;
6760 if (description
->units_num
== 0)
6762 estimation_bound
= estimate_one_automaton_bound ();
6763 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6764 for (i
= 0; i
< description
->decls_num
; i
++)
6766 decl
= description
->decls
[i
];
6767 if (decl
->mode
== dm_unit
)
6768 VLA_PTR_ADD (unit_decls
, decl
);
6770 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6771 sizeof (decl_t
), compare_max_occ_cycle_nums
);
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
);
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
)
6787 / (DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
)))))
6789 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6793 bound_value
*= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6794 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6796 gcc_assert (automaton_num
== automata_num
- 1);
6797 VLA_PTR_DELETE (unit_decls
);
6800 /* The functions creates automaton insns for each automata. Automaton
6801 insn is simply insn for given automaton which makes reservation
6802 only of units of the automaton. */
6804 create_ainsns (void)
6807 ainsn_t first_ainsn
;
6814 for (i
= 0; i
< description
->decls_num
; i
++)
6816 decl
= description
->decls
[i
];
6817 if (decl
->mode
== dm_insn_reserv
)
6819 curr_ainsn
= create_node (sizeof (struct ainsn
));
6820 curr_ainsn
->insn_reserv_decl
= DECL_INSN_RESERV (decl
);
6821 curr_ainsn
->important_p
= FALSE
;
6822 curr_ainsn
->next_ainsn
= NULL
;
6823 if (prev_ainsn
== NULL
)
6824 first_ainsn
= curr_ainsn
;
6826 prev_ainsn
->next_ainsn
= curr_ainsn
;
6827 prev_ainsn
= curr_ainsn
;
6833 /* The function assigns automata to units according to constructions
6834 `define_automaton' in the description. */
6836 units_to_automata_distr (void)
6841 for (i
= 0; i
< description
->decls_num
; i
++)
6843 decl
= description
->decls
[i
];
6844 if (decl
->mode
== dm_unit
)
6846 if (DECL_UNIT (decl
)->automaton_decl
== NULL
6847 || (DECL_UNIT (decl
)->automaton_decl
->corresponding_automaton
6849 /* Distribute to the first automaton. */
6850 DECL_UNIT (decl
)->corresponding_automaton_num
= 0;
6852 DECL_UNIT (decl
)->corresponding_automaton_num
6853 = (DECL_UNIT (decl
)->automaton_decl
6854 ->corresponding_automaton
->automaton_order_num
);
6859 /* The function creates DFA(s) for fast pipeline hazards recognition
6860 after checking and simplifying IR of the description. */
6862 create_automata (void)
6864 automaton_t curr_automaton
;
6865 automaton_t prev_automaton
;
6867 int curr_automaton_num
;
6870 if (automata_num
!= 0)
6872 units_to_automata_heuristic_distr ();
6873 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6874 curr_automaton_num
< automata_num
;
6875 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6877 curr_automaton
= create_node (sizeof (struct automaton
));
6878 curr_automaton
->ainsn_list
= create_ainsns ();
6879 curr_automaton
->corresponding_automaton_decl
= NULL
;
6880 curr_automaton
->next_automaton
= NULL
;
6881 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6882 if (prev_automaton
== NULL
)
6883 description
->first_automaton
= curr_automaton
;
6885 prev_automaton
->next_automaton
= curr_automaton
;
6890 curr_automaton_num
= 0;
6891 prev_automaton
= NULL
;
6892 for (i
= 0; i
< description
->decls_num
; i
++)
6894 decl
= description
->decls
[i
];
6895 if (decl
->mode
== dm_automaton
6896 && DECL_AUTOMATON (decl
)->automaton_is_used
)
6898 curr_automaton
= create_node (sizeof (struct automaton
));
6899 curr_automaton
->ainsn_list
= create_ainsns ();
6900 curr_automaton
->corresponding_automaton_decl
6901 = DECL_AUTOMATON (decl
);
6902 curr_automaton
->next_automaton
= NULL
;
6903 DECL_AUTOMATON (decl
)->corresponding_automaton
= curr_automaton
;
6904 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6905 if (prev_automaton
== NULL
)
6906 description
->first_automaton
= curr_automaton
;
6908 prev_automaton
->next_automaton
= curr_automaton
;
6909 curr_automaton_num
++;
6910 prev_automaton
= curr_automaton
;
6913 if (curr_automaton_num
== 0)
6915 curr_automaton
= create_node (sizeof (struct automaton
));
6916 curr_automaton
->ainsn_list
= create_ainsns ();
6917 curr_automaton
->corresponding_automaton_decl
= NULL
;
6918 curr_automaton
->next_automaton
= NULL
;
6919 description
->first_automaton
= curr_automaton
;
6921 units_to_automata_distr ();
6923 NDFA_time
= create_ticker ();
6924 ticker_off (&NDFA_time
);
6925 NDFA_to_DFA_time
= create_ticker ();
6926 ticker_off (&NDFA_to_DFA_time
);
6927 minimize_time
= create_ticker ();
6928 ticker_off (&minimize_time
);
6929 equiv_time
= create_ticker ();
6930 ticker_off (&equiv_time
);
6931 for (curr_automaton
= description
->first_automaton
;
6932 curr_automaton
!= NULL
;
6933 curr_automaton
= curr_automaton
->next_automaton
)
6937 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6938 fprintf (stderr
, "Prepare anonymous automaton creation ... ");
6940 fprintf (stderr
, "Prepare automaton `%s' creation...",
6941 curr_automaton
->corresponding_automaton_decl
->name
);
6943 create_alt_states (curr_automaton
);
6944 form_ainsn_with_same_reservs (curr_automaton
);
6946 fprintf (stderr
, "done\n");
6947 build_automaton (curr_automaton
);
6948 enumerate_states (curr_automaton
);
6949 ticker_on (&equiv_time
);
6950 set_insn_equiv_classes (curr_automaton
);
6951 ticker_off (&equiv_time
);
6957 /* This page contains code for forming string representation of
6958 regexp. The representation is formed on IR obstack. So you should
6959 not work with IR obstack between regexp_representation and
6960 finish_regexp_representation calls. */
6962 /* This recursive function forms string representation of regexp
6963 (without tailing '\0'). */
6965 form_regexp (regexp_t regexp
)
6969 switch (regexp
->mode
)
6971 case rm_unit
: case rm_reserv
:
6973 const char *name
= (regexp
->mode
== rm_unit
6974 ? REGEXP_UNIT (regexp
)->name
6975 : REGEXP_RESERV (regexp
)->name
);
6977 obstack_grow (&irp
, name
, strlen (name
));
6982 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
6985 obstack_1grow (&irp
, ',');
6986 form_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
6991 obstack_1grow (&irp
, '(');
6992 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
6995 obstack_1grow (&irp
, '+');
6996 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6997 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6998 obstack_1grow (&irp
, '(');
6999 form_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
7000 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
7001 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
7002 obstack_1grow (&irp
, ')');
7004 obstack_1grow (&irp
, ')');
7008 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
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
, ')');
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
));
7039 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
7047 /* The function returns string representation of REGEXP on IR
7050 regexp_representation (regexp_t regexp
)
7052 form_regexp (regexp
);
7053 obstack_1grow (&irp
, '\0');
7054 return obstack_base (&irp
);
7057 /* The function frees memory allocated for last formed string
7058 representation of regexp. */
7060 finish_regexp_representation (void)
7062 int length
= obstack_object_size (&irp
);
7064 obstack_blank_fast (&irp
, -length
);
7069 /* This page contains code for output PHR (pipeline hazards recognizer). */
7071 /* The function outputs minimal C type which is sufficient for
7072 representation numbers in range min_range_value and
7073 max_range_value. Because host machine and build machine may be
7074 different, we use here minimal values required by ANSI C standard
7075 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7079 output_range_type (FILE *f
, long int min_range_value
,
7080 long int max_range_value
)
7082 if (min_range_value
>= 0 && max_range_value
<= 255)
7083 fprintf (f
, "unsigned char");
7084 else if (min_range_value
>= -127 && max_range_value
<= 127)
7085 fprintf (f
, "signed char");
7086 else if (min_range_value
>= 0 && max_range_value
<= 65535)
7087 fprintf (f
, "unsigned short");
7088 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
7089 fprintf (f
, "short");
7094 /* The following macro value is used as value of member
7095 `longest_path_length' of state when we are processing path and the
7096 state on the path. */
7098 #define ON_THE_PATH -2
7100 /* The following recursive function searches for the length of the
7101 longest path starting from STATE which does not contain cycles and
7102 `cycle advance' arcs. */
7105 longest_path_length (state_t state
)
7110 if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
7112 /* We don't expect the path cycle here. Our graph may contain
7113 only cycles with one state on the path not containing `cycle
7114 advance' arcs -- see comment below. */
7115 gcc_assert (state
->longest_path_length
!= ON_THE_PATH
);
7117 /* We already visited the state. */
7118 return state
->longest_path_length
;
7122 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7123 /* Ignore cycles containing one state and `cycle advance' arcs. */
7124 if (arc
->to_state
!= state
7125 && (arc
->insn
->insn_reserv_decl
7126 != DECL_INSN_RESERV (advance_cycle_insn_decl
)))
7128 length
= longest_path_length (arc
->to_state
);
7129 if (length
> result
)
7132 state
->longest_path_length
= result
+ 1;
7136 /* The following variable value is value of the corresponding global
7137 variable in the automaton based pipeline interface. */
7139 static int max_dfa_issue_rate
;
7141 /* The following function processes the longest path length staring
7142 from STATE to find MAX_DFA_ISSUE_RATE. */
7145 process_state_longest_path_length (state_t state
)
7149 value
= longest_path_length (state
);
7150 if (value
> max_dfa_issue_rate
)
7151 max_dfa_issue_rate
= value
;
7154 /* The following macro value is name of the corresponding global
7155 variable in the automaton based pipeline interface. */
7157 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7159 /* The following function calculates value of the corresponding
7160 global variable and outputs its declaration. */
7163 output_dfa_max_issue_rate (void)
7165 automaton_t automaton
;
7167 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH
!= ON_THE_PATH
&& ON_THE_PATH
< 0);
7168 max_dfa_issue_rate
= 0;
7169 for (automaton
= description
->first_automaton
;
7171 automaton
= automaton
->next_automaton
)
7172 pass_states (automaton
, process_state_longest_path_length
);
7173 fprintf (output_file
, "\nint %s = %d;\n",
7174 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
7177 /* The function outputs all initialization values of VECT with length
7180 output_vect (vect_el_t
*vect
, int vect_length
)
7185 if (vect_length
== 0)
7186 fprintf (output_file
,
7187 "0 /* This is dummy el because the vect is empty */");
7192 fprintf (output_file
, "%5ld", (long) *vect
);
7194 if (els_on_line
== 10)
7197 fprintf (output_file
, ",\n");
7199 else if (vect_length
!= 0)
7200 fprintf (output_file
, ", ");
7204 while (vect_length
!= 0);
7208 /* The following is name of the structure which represents DFA(s) for
7210 #define CHIP_NAME "DFA_chip"
7212 /* The following is name of member which represents state of a DFA for
7215 output_chip_member_name (FILE *f
, automaton_t automaton
)
7217 if (automaton
->corresponding_automaton_decl
== NULL
)
7218 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
7220 fprintf (f
, "%s_automaton_state",
7221 automaton
->corresponding_automaton_decl
->name
);
7224 /* The following is name of temporary variable which stores state of a
7227 output_temp_chip_member_name (FILE *f
, automaton_t automaton
)
7230 output_chip_member_name (f
, automaton
);
7233 /* This is name of macro value which is code of pseudo_insn
7234 representing advancing cpu cycle. Its value is used as internal
7235 code unknown insn. */
7236 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7238 /* Output name of translate vector for given automaton. */
7240 output_translate_vect_name (FILE *f
, automaton_t automaton
)
7242 if (automaton
->corresponding_automaton_decl
== NULL
)
7243 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
7245 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
7248 /* Output name for simple transition table representation. */
7250 output_trans_full_vect_name (FILE *f
, automaton_t automaton
)
7252 if (automaton
->corresponding_automaton_decl
== NULL
)
7253 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
7255 fprintf (f
, "%s_transitions",
7256 automaton
->corresponding_automaton_decl
->name
);
7259 /* Output name of comb vector of the transition table for given
7262 output_trans_comb_vect_name (FILE *f
, automaton_t automaton
)
7264 if (automaton
->corresponding_automaton_decl
== NULL
)
7265 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
7267 fprintf (f
, "%s_transitions",
7268 automaton
->corresponding_automaton_decl
->name
);
7271 /* Output name of check vector of the transition table for given
7274 output_trans_check_vect_name (FILE *f
, automaton_t automaton
)
7276 if (automaton
->corresponding_automaton_decl
== NULL
)
7277 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
7279 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
7282 /* Output name of base vector of the transition table for given
7285 output_trans_base_vect_name (FILE *f
, automaton_t automaton
)
7287 if (automaton
->corresponding_automaton_decl
== NULL
)
7288 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
7290 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
7293 /* Output name for simple alternatives number representation. */
7295 output_state_alts_full_vect_name (FILE *f
, automaton_t automaton
)
7297 if (automaton
->corresponding_automaton_decl
== NULL
)
7298 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7300 fprintf (f
, "%s_state_alts",
7301 automaton
->corresponding_automaton_decl
->name
);
7304 /* Output name of comb vector of the alternatives number table for given
7307 output_state_alts_comb_vect_name (FILE *f
, automaton_t automaton
)
7309 if (automaton
->corresponding_automaton_decl
== NULL
)
7310 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7312 fprintf (f
, "%s_state_alts",
7313 automaton
->corresponding_automaton_decl
->name
);
7316 /* Output name of check vector of the alternatives number table for given
7319 output_state_alts_check_vect_name (FILE *f
, automaton_t automaton
)
7321 if (automaton
->corresponding_automaton_decl
== NULL
)
7322 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
7324 fprintf (f
, "%s_check_state_alts",
7325 automaton
->corresponding_automaton_decl
->name
);
7328 /* Output name of base vector of the alternatives number table for given
7331 output_state_alts_base_vect_name (FILE *f
, automaton_t automaton
)
7333 if (automaton
->corresponding_automaton_decl
== NULL
)
7334 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
7336 fprintf (f
, "%s_base_state_alts",
7337 automaton
->corresponding_automaton_decl
->name
);
7340 /* Output name of simple min issue delay table representation. */
7342 output_min_issue_delay_vect_name (FILE *f
, automaton_t automaton
)
7344 if (automaton
->corresponding_automaton_decl
== NULL
)
7345 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
7347 fprintf (f
, "%s_min_issue_delay",
7348 automaton
->corresponding_automaton_decl
->name
);
7351 /* Output name of deadlock vector for given automaton. */
7353 output_dead_lock_vect_name (FILE *f
, automaton_t automaton
)
7355 if (automaton
->corresponding_automaton_decl
== NULL
)
7356 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
7358 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
7361 /* Output name of reserved units table for AUTOMATON into file F. */
7363 output_reserved_units_table_name (FILE *f
, automaton_t automaton
)
7365 if (automaton
->corresponding_automaton_decl
== NULL
)
7366 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
7368 fprintf (f
, "%s_reserved_units",
7369 automaton
->corresponding_automaton_decl
->name
);
7372 /* Name of the PHR interface macro. */
7373 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7375 /* Name of the PHR interface macro. */
7376 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7378 /* Names of an internal functions: */
7379 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7381 /* This is external type of DFA(s) state. */
7382 #define STATE_TYPE_NAME "state_t"
7384 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7386 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7388 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7390 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7392 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7394 /* Name of cache of insn dfa codes. */
7395 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7397 /* Name of length of cache of insn dfa codes. */
7398 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7400 /* Names of the PHR interface functions: */
7401 #define SIZE_FUNC_NAME "state_size"
7403 #define TRANSITION_FUNC_NAME "state_transition"
7405 #define STATE_ALTS_FUNC_NAME "state_alts"
7407 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7409 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7411 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7413 #define RESET_FUNC_NAME "state_reset"
7415 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7417 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7419 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7421 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7423 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7425 #define DFA_START_FUNC_NAME "dfa_start"
7427 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7429 /* Names of parameters of the PHR interface functions. */
7430 #define STATE_NAME "state"
7432 #define INSN_PARAMETER_NAME "insn"
7434 #define INSN2_PARAMETER_NAME "insn2"
7436 #define CHIP_PARAMETER_NAME "chip"
7438 #define FILE_PARAMETER_NAME "f"
7440 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7442 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7444 /* Names of the variables whose values are internal insn code of rtx
7446 #define INTERNAL_INSN_CODE_NAME "insn_code"
7448 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7450 /* Names of temporary variables in some functions. */
7451 #define TEMPORARY_VARIABLE_NAME "temp"
7453 #define I_VARIABLE_NAME "i"
7455 /* Name of result variable in some functions. */
7456 #define RESULT_VARIABLE_NAME "res"
7458 /* Name of function (attribute) to translate insn into internal insn
7460 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7462 /* Name of function (attribute) to translate insn into internal insn
7463 code with caching. */
7464 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7466 /* Name of function (attribute) to translate insn into internal insn
7468 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7470 /* Name of function (attribute) to translate insn into internal insn
7472 #define BYPASS_P_FUNC_NAME "bypass_p"
7474 /* Output C type which is used for representation of codes of states
7477 output_state_member_type (FILE *f
, automaton_t automaton
)
7479 output_range_type (f
, 0, automaton
->achieved_states_num
);
7482 /* Output definition of the structure representing current DFA(s)
7485 output_chip_definitions (void)
7487 automaton_t automaton
;
7489 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
7490 for (automaton
= description
->first_automaton
;
7492 automaton
= automaton
->next_automaton
)
7494 fprintf (output_file
, " ");
7495 output_state_member_type (output_file
, automaton
);
7496 fprintf (output_file
, " ");
7497 output_chip_member_name (output_file
, automaton
);
7498 fprintf (output_file
, ";\n");
7500 fprintf (output_file
, "};\n\n");
7502 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
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). */
7511 output_translate_vect (automaton_t automaton
)
7515 vla_hwint_t translate_vect
;
7517 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
7518 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
7519 for (insn_value
= 0; insn_value
< description
->insns_num
; insn_value
++)
7520 /* Undefined value */
7521 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
7522 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7523 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
7524 = ainsn
->insn_equiv_class_num
;
7525 fprintf (output_file
,
7526 "/* Vector translating external insn codes to internal ones.*/\n");
7527 fprintf (output_file
, "static const ");
7528 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
7529 fprintf (output_file
, " ");
7530 output_translate_vect_name (output_file
, automaton
);
7531 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7532 output_vect (VLA_HWINT_BEGIN (translate_vect
),
7533 VLA_HWINT_LENGTH (translate_vect
));
7534 fprintf (output_file
, "};\n\n");
7535 VLA_HWINT_DELETE (translate_vect
);
7538 /* The value in a table state x ainsn -> something which represents
7540 static int undefined_vect_el_value
;
7542 /* The following function returns nonzero value if the best
7543 representation of the table is comb vector. */
7545 comb_vect_p (state_ainsn_table_t tab
)
7547 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
7548 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
7551 /* The following function creates new table for AUTOMATON. */
7552 static state_ainsn_table_t
7553 create_state_ainsn_table (automaton_t automaton
)
7555 state_ainsn_table_t tab
;
7556 int full_vect_length
;
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;
7578 /* The following function outputs the best C representation of the
7579 table TAB of given TABLE_NAME. */
7581 output_state_ainsn_table (state_ainsn_table_t tab
, char *table_name
,
7582 void (*output_full_vect_name_func
) (FILE *, automaton_t
),
7583 void (*output_comb_vect_name_func
) (FILE *, automaton_t
),
7584 void (*output_check_vect_name_func
) (FILE *, automaton_t
),
7585 void (*output_base_vect_name_func
) (FILE *, automaton_t
))
7587 if (!comb_vect_p (tab
))
7589 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7590 fprintf (output_file
, "static const ");
7591 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7592 tab
->max_comb_vect_el_value
);
7593 fprintf (output_file
, " ");
7594 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7595 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7596 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7597 VLA_HWINT_LENGTH (tab
->full_vect
));
7598 fprintf (output_file
, "};\n\n");
7602 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7603 fprintf (output_file
, "static const ");
7604 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7605 tab
->max_comb_vect_el_value
);
7606 fprintf (output_file
, " ");
7607 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7608 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7609 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7610 VLA_HWINT_LENGTH (tab
->comb_vect
));
7611 fprintf (output_file
, "};\n\n");
7612 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7613 fprintf (output_file
, "static const ");
7614 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7615 fprintf (output_file
, " ");
7616 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7617 fprintf (output_file
, "[] = {\n");
7618 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7619 VLA_HWINT_LENGTH (tab
->check_vect
));
7620 fprintf (output_file
, "};\n\n");
7621 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7622 fprintf (output_file
, "static const ");
7623 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7624 tab
->max_base_vect_el_value
);
7625 fprintf (output_file
, " ");
7626 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7627 fprintf (output_file
, "[] = {\n");
7628 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7629 VLA_HWINT_LENGTH (tab
->base_vect
));
7630 fprintf (output_file
, "};\n\n");
7634 /* The following function adds vector with length VECT_LENGTH and
7635 elements pointed to by VECT to table TAB as its line with number
7638 add_vect (state_ainsn_table_t tab
, int vect_num
, vect_el_t
*vect
,
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
;
7647 int first_unempty_vect_index
;
7648 int additional_els_num
;
7652 unsigned long vect_mask
, comb_vect_mask
;
7654 gcc_assert (vect_length
);
7655 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7656 gcc_assert (vect
[vect_length
- 1] != undefined_vect_el_value
);
7657 /* Form full vector in the table: */
7658 for (i
= 0; i
< vect_length
; i
++)
7659 VLA_HWINT (tab
->full_vect
,
7660 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
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
)
7673 /* Search for the place in comb vect for the inserted vect. */
7676 if (vect_length
- first_unempty_vect_index
>= SIZEOF_LONG
* CHAR_BIT
)
7678 for (comb_vect_index
= 0;
7679 comb_vect_index
< comb_vect_els_num
;
7682 for (vect_index
= first_unempty_vect_index
;
7683 vect_index
< vect_length
7684 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7686 if (vect
[vect_index
] != undefined_vect_el_value
7687 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7688 != undefined_vect_el_value
))
7690 if (vect_index
>= vect_length
7691 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7699 for (vect_index
= first_unempty_vect_index
;
7700 vect_index
< vect_length
;
7703 vect_mask
= vect_mask
<< 1;
7704 if (vect
[vect_index
] != undefined_vect_el_value
)
7708 /* Search for the place in comb vect for the inserted vect. */
7709 comb_vect_index
= 0;
7710 if (comb_vect_els_num
== 0)
7714 for (vect_index
= first_unempty_vect_index
;
7715 vect_index
< vect_length
&& vect_index
< comb_vect_els_num
;
7718 comb_vect_mask
<<= 1;
7719 if (vect_index
+ comb_vect_index
< comb_vect_els_num
7720 && comb_vect_start
[vect_index
+ comb_vect_index
]
7721 != undefined_vect_el_value
)
7722 comb_vect_mask
|= 1;
7724 if ((vect_mask
& comb_vect_mask
) == 0)
7727 for (comb_vect_index
= 1, i
= vect_length
; i
< comb_vect_els_num
;
7728 comb_vect_index
++, i
++)
7730 comb_vect_mask
= (comb_vect_mask
<< 1) | 1;
7731 comb_vect_mask
^= comb_vect_start
[i
] == undefined_vect_el_value
;
7732 if ((vect_mask
& comb_vect_mask
) == 0)
7735 for ( ; comb_vect_index
< comb_vect_els_num
; comb_vect_index
++)
7737 comb_vect_mask
<<= 1;
7738 if ((vect_mask
& comb_vect_mask
) == 0)
7743 /* Slot was found. */
7744 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7745 if (additional_els_num
< 0)
7746 additional_els_num
= 0;
7747 /* Expand comb and check vectors. */
7748 vect_el
= undefined_vect_el_value
;
7749 no_state_value
= tab
->automaton
->achieved_states_num
;
7750 while (additional_els_num
> 0)
7752 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7753 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7754 additional_els_num
--;
7756 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7757 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7758 gcc_assert (VLA_HWINT_LENGTH (tab
->comb_vect
)
7759 >= (size_t) (comb_vect_index
+ real_vect_length
));
7760 /* Fill comb and check vectors. */
7761 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7762 if (vect
[vect_index
] != undefined_vect_el_value
)
7764 gcc_assert (comb_vect_start
[comb_vect_index
+ vect_index
]
7765 == undefined_vect_el_value
);
7766 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7767 gcc_assert (vect
[vect_index
] >= 0);
7768 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7769 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7770 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7771 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7772 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7774 if (tab
->max_comb_vect_el_value
< undefined_vect_el_value
)
7775 tab
->max_comb_vect_el_value
= undefined_vect_el_value
;
7776 if (tab
->min_comb_vect_el_value
> undefined_vect_el_value
)
7777 tab
->min_comb_vect_el_value
= undefined_vect_el_value
;
7778 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7779 tab
->max_base_vect_el_value
= comb_vect_index
;
7780 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7781 tab
->min_base_vect_el_value
= comb_vect_index
;
7782 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7785 /* Return number of out arcs of STATE. */
7787 out_state_arcs_num (state_t state
)
7793 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7795 gcc_assert (arc
->insn
);
7796 if (arc
->insn
->first_ainsn_with_given_equivalence_num
)
7802 /* Compare number of possible transitions from the states. */
7804 compare_transition_els_num (const void *state_ptr_1
,
7805 const void *state_ptr_2
)
7807 int transition_els_num_1
;
7808 int transition_els_num_2
;
7810 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7811 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7812 if (transition_els_num_1
< transition_els_num_2
)
7814 else if (transition_els_num_1
== transition_els_num_2
)
7820 /* The function adds element EL_VALUE to vector VECT for a table state
7823 add_vect_el (vla_hwint_t
*vect
, ainsn_t ainsn
, int el_value
)
7825 int equiv_class_num
;
7829 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7830 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7831 vect_index
<= equiv_class_num
;
7833 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7834 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7837 /* This is for forming vector of states of an automaton. */
7838 static vla_ptr_t output_states_vect
;
7840 /* The function is called by function pass_states. The function adds
7841 STATE to `output_states_vect'. */
7843 add_states_vect_el (state_t state
)
7845 VLA_PTR_ADD (output_states_vect
, state
);
7848 /* Form and output vectors (comb, check, base or full vector)
7849 representing transition table of AUTOMATON. */
7851 output_trans_table (automaton_t automaton
)
7855 vla_hwint_t transition_vect
;
7857 undefined_vect_el_value
= automaton
->achieved_states_num
;
7858 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7859 /* Create vect of pointers to states ordered by num of transitions
7860 from the state (state with the maximum num is the first). */
7861 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7862 pass_states (automaton
, add_states_vect_el
);
7863 qsort (VLA_PTR_BEGIN (output_states_vect
),
7864 VLA_PTR_LENGTH (output_states_vect
),
7865 sizeof (state_t
), compare_transition_els_num
);
7866 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7867 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7868 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7871 VLA_HWINT_NULLIFY (transition_vect
);
7872 for (arc
= first_out_arc (*state_ptr
);
7874 arc
= next_out_arc (arc
))
7876 gcc_assert (arc
->insn
);
7877 if (arc
->insn
->first_ainsn_with_given_equivalence_num
)
7878 add_vect_el (&transition_vect
, arc
->insn
,
7879 arc
->to_state
->order_state_num
);
7881 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7882 VLA_HWINT_BEGIN (transition_vect
),
7883 VLA_HWINT_LENGTH (transition_vect
));
7885 output_state_ainsn_table
7886 (automaton
->trans_table
, (char *) "state transitions",
7887 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7888 output_trans_check_vect_name
, output_trans_base_vect_name
);
7889 VLA_PTR_DELETE (output_states_vect
);
7890 VLA_HWINT_DELETE (transition_vect
);
7893 /* Form and output vectors (comb, check, base or simple vect)
7894 representing alts number table of AUTOMATON. The table is state x
7895 ainsn -> number of possible alternative reservations by the
7898 output_state_alts_table (automaton_t automaton
)
7902 vla_hwint_t state_alts_vect
;
7904 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7905 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7906 /* Create vect of pointers to states ordered by num of transitions
7907 from the state (state with the maximum num is the first). */
7908 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7909 pass_states (automaton
, add_states_vect_el
);
7910 qsort (VLA_PTR_BEGIN (output_states_vect
),
7911 VLA_PTR_LENGTH (output_states_vect
),
7912 sizeof (state_t
), compare_transition_els_num
);
7913 /* Create base, comb, and check vectors. */
7914 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7915 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7916 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7919 VLA_HWINT_NULLIFY (state_alts_vect
);
7920 for (arc
= first_out_arc (*state_ptr
);
7922 arc
= next_out_arc (arc
))
7924 gcc_assert (arc
->insn
);
7925 if (arc
->insn
->first_ainsn_with_given_equivalence_num
)
7926 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7928 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7929 VLA_HWINT_BEGIN (state_alts_vect
),
7930 VLA_HWINT_LENGTH (state_alts_vect
));
7932 output_state_ainsn_table
7933 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7934 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7935 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7936 VLA_PTR_DELETE (output_states_vect
);
7937 VLA_HWINT_DELETE (state_alts_vect
);
7940 /* The current number of passing states to find minimal issue delay
7941 value for an ainsn and state. */
7942 static int curr_state_pass_num
;
7944 /* This recursive function passes states to find minimal issue delay
7945 value for AINSN. The state being visited is STATE. The function
7946 returns minimal issue delay value for AINSN in STATE or -1 if we
7947 enter into a loop. */
7949 min_issue_delay_pass_states (state_t state
, ainsn_t ainsn
)
7952 int min_insn_issue_delay
, insn_issue_delay
;
7954 if (state
->state_pass_num
== curr_state_pass_num
7955 || state
->min_insn_issue_delay
!= -1)
7956 /* We've entered into a loop or already have the correct value for
7957 given state and ainsn. */
7958 return state
->min_insn_issue_delay
;
7959 state
->state_pass_num
= curr_state_pass_num
;
7960 min_insn_issue_delay
= -1;
7961 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7962 if (arc
->insn
== ainsn
)
7964 min_insn_issue_delay
= 0;
7969 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7970 if (insn_issue_delay
!= -1)
7972 if (arc
->insn
->insn_reserv_decl
7973 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
7975 if (min_insn_issue_delay
== -1
7976 || min_insn_issue_delay
> insn_issue_delay
)
7978 min_insn_issue_delay
= insn_issue_delay
;
7979 if (insn_issue_delay
== 0)
7984 return min_insn_issue_delay
;
7987 /* The function searches minimal issue delay value for AINSN in STATE.
7988 The function can return negative value if we can not issue AINSN. We
7989 will report about it later. */
7991 min_issue_delay (state_t state
, ainsn_t ainsn
)
7993 curr_state_pass_num
++;
7994 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7995 return state
->min_insn_issue_delay
;
7998 /* The function initiates code for finding minimal issue delay values.
7999 It should be called only once. */
8001 initiate_min_issue_delay_pass_states (void)
8003 curr_state_pass_num
= 0;
8006 /* Form and output vectors representing minimal issue delay table of
8007 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8010 output_min_issue_delay_table (automaton_t automaton
)
8012 vla_hwint_t min_issue_delay_vect
;
8013 vla_hwint_t compressed_min_issue_delay_vect
;
8014 vect_el_t min_delay
;
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
);
8028 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
8029 * automaton
->insn_equiv_classes_num
);
8031 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
8032 automaton
->max_min_delay
= 0;
8033 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
8034 if (ainsn
->first_ainsn_with_given_equivalence_num
)
8036 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
8037 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
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
);
8044 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
8045 if (automaton
->max_min_delay
< min_delay
)
8046 automaton
->max_min_delay
= min_delay
;
8047 VLA_HWINT (min_issue_delay_vect
,
8048 (*state_ptr
)->order_state_num
8049 * automaton
->insn_equiv_classes_num
8050 + ainsn
->insn_equiv_class_num
) = min_delay
;
8053 fprintf (output_file
, "/* Vector of min issue delay of insns. */\n");
8054 fprintf (output_file
, "static const ");
8055 output_range_type (output_file
, 0, automaton
->max_min_delay
);
8056 fprintf (output_file
, " ");
8057 output_min_issue_delay_vect_name (output_file
, automaton
);
8058 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
8059 /* Compress the vector. */
8060 if (automaton
->max_min_delay
< 2)
8061 automaton
->min_issue_delay_table_compression_factor
= 8;
8062 else if (automaton
->max_min_delay
< 4)
8063 automaton
->min_issue_delay_table_compression_factor
= 4;
8064 else if (automaton
->max_min_delay
< 16)
8065 automaton
->min_issue_delay_table_compression_factor
= 2;
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
8074 / automaton
->min_issue_delay_table_compression_factor
);
8076 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
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
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
);
8095 /* Number of states which contains transition only by advancing cpu
8097 static int locked_states_num
;
8100 /* Form and output vector representing the locked states of
8103 output_dead_lock_vect (automaton_t automaton
)
8107 vla_hwint_t dead_lock_vect
;
8109 /* Create vect of pointers to states ordered by num of
8110 transitions from the state (state with the maximum num is the
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
);
8120 arc
= first_out_arc (*state_ptr
);
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);
8127 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
8128 locked_states_num
++;
8131 fprintf (output_file
, "/* Vector for locked state flags. */\n");
8132 fprintf (output_file
, "static const ");
8133 output_range_type (output_file
, 0, 1);
8134 fprintf (output_file
, " ");
8135 output_dead_lock_vect_name (output_file
, automaton
);
8136 fprintf (output_file
, "[] = {\n");
8137 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
8138 VLA_HWINT_LENGTH (dead_lock_vect
));
8139 fprintf (output_file
, "};\n\n");
8140 VLA_HWINT_DELETE (dead_lock_vect
);
8141 VLA_PTR_DELETE (output_states_vect
);
8144 /* Form and output vector representing reserved units of the states of
8147 output_reserved_units_table (automaton_t automaton
)
8149 state_t
*curr_state_ptr
;
8150 vla_hwint_t reserved_units_table
;
8151 size_t state_byte_size
;
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
);
8163 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
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
);
8170 for (i
= 0; i
< description
->units_num
; i
++)
8171 if (units_array
[i
]->query_p
8172 && first_cycle_unit_presence (*curr_state_ptr
, i
))
8173 VLA_HWINT (reserved_units_table
,
8174 (*curr_state_ptr
)->order_state_num
* state_byte_size
8175 + units_array
[i
]->query_num
/ 8)
8176 += (1 << (units_array
[i
]->query_num
% 8));
8178 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
8179 fprintf (output_file
, "static const ");
8180 output_range_type (output_file
, 0, 255);
8181 fprintf (output_file
, " ");
8182 output_reserved_units_table_name (output_file
, automaton
);
8183 fprintf (output_file
, "[] = {\n");
8184 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
8185 VLA_HWINT_LENGTH (reserved_units_table
));
8186 fprintf (output_file
, "};\n\n");
8187 VLA_HWINT_DELETE (reserved_units_table
);
8188 VLA_PTR_DELETE (output_states_vect
);
8191 /* The function outputs all tables representing DFA(s) used for fast
8192 pipeline hazards recognition. */
8194 output_tables (void)
8196 automaton_t automaton
;
8199 locked_states_num
= 0;
8201 initiate_min_issue_delay_pass_states ();
8202 for (automaton
= description
->first_automaton
;
8204 automaton
= automaton
->next_automaton
)
8206 output_translate_vect (automaton
);
8207 output_trans_table (automaton
);
8208 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
8209 output_state_alts_table (automaton
);
8210 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
8211 AUTOMATON_STATE_ALTS_MACRO_NAME
);
8212 output_min_issue_delay_table (automaton
);
8213 output_dead_lock_vect (automaton
);
8214 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
8215 output_reserved_units_table (automaton
);
8216 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
8217 CPU_UNITS_QUERY_MACRO_NAME
);
8219 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
8220 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
8223 /* The function outputs definition and value of PHR interface variable
8224 `max_insn_queue_index'. Its value is not less than maximal queue
8225 length needed for the insn scheduler. */
8227 output_max_insn_queue_index_def (void)
8229 int i
, max
, latency
;
8232 max
= description
->max_insn_reserv_cycles
;
8233 for (i
= 0; i
< description
->decls_num
; i
++)
8235 decl
= description
->decls
[i
];
8236 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8238 latency
= DECL_INSN_RESERV (decl
)->default_latency
;
8242 else if (decl
->mode
== dm_bypass
)
8244 latency
= DECL_BYPASS (decl
)->latency
;
8249 for (i
= 0; (1 << i
) <= max
; i
++)
8251 gcc_assert (i
>= 0);
8252 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
8256 /* The function outputs switch cases for insn reservations using
8257 function *output_automata_list_code. */
8259 output_insn_code_cases (void (*output_automata_list_code
)
8260 (automata_list_el_t
))
8265 for (i
= 0; i
< description
->decls_num
; i
++)
8267 decl
= description
->decls
[i
];
8268 if (decl
->mode
== dm_insn_reserv
)
8269 DECL_INSN_RESERV (decl
)->processed_p
= FALSE
;
8271 for (i
= 0; i
< description
->decls_num
; i
++)
8273 decl
= description
->decls
[i
];
8274 if (decl
->mode
== dm_insn_reserv
8275 && !DECL_INSN_RESERV (decl
)->processed_p
)
8277 for (j
= i
; j
< description
->decls_num
; j
++)
8279 decl2
= description
->decls
[j
];
8280 if (decl2
->mode
== dm_insn_reserv
8281 && (DECL_INSN_RESERV (decl2
)->important_automata_list
8282 == DECL_INSN_RESERV (decl
)->important_automata_list
))
8284 DECL_INSN_RESERV (decl2
)->processed_p
= TRUE
;
8285 fprintf (output_file
, " case %d: /* %s */\n",
8286 DECL_INSN_RESERV (decl2
)->insn_num
,
8287 DECL_INSN_RESERV (decl2
)->name
);
8290 (*output_automata_list_code
)
8291 (DECL_INSN_RESERV (decl
)->important_automata_list
);
8297 /* The function outputs a code for evaluation of a minimal delay of
8298 issue of insns which have reservations in given AUTOMATA_LIST. */
8300 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list
)
8302 automata_list_el_t el
;
8303 automaton_t automaton
;
8305 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8307 automaton
= el
->automaton
;
8308 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8309 output_min_issue_delay_vect_name (output_file
, automaton
);
8310 fprintf (output_file
,
8311 (automaton
->min_issue_delay_table_compression_factor
!= 1
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");
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
);
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
))
8335 if (el
== automata_list
)
8336 fprintf (output_file
, " %s = %s;\n",
8337 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8340 fprintf (output_file
, " if (%s > %s)\n",
8341 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8342 fprintf (output_file
, " %s = %s;\n",
8343 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8346 fprintf (output_file
, " break;\n\n");
8349 /* Output function `internal_min_issue_delay'. */
8351 output_internal_min_issue_delay_func (void)
8353 fprintf (output_file
,
8354 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8355 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8356 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8357 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8358 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8359 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8360 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
8361 fprintf (output_file
,
8362 "\n default:\n %s = -1;\n break;\n }\n",
8363 RESULT_VARIABLE_NAME
);
8364 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8365 fprintf (output_file
, "}\n\n");
8368 /* The function outputs a code changing state after issue of insns
8369 which have reservations in given AUTOMATA_LIST. */
8371 output_automata_list_transition_code (automata_list_el_t automata_list
)
8373 automata_list_el_t el
, next_el
;
8375 fprintf (output_file
, " {\n");
8376 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8377 for (el
= automata_list
;; el
= next_el
)
8379 next_el
= el
->next_automata_list_el
;
8380 if (next_el
== NULL
)
8382 fprintf (output_file
, " ");
8383 output_state_member_type (output_file
, el
->automaton
);
8384 fprintf (output_file
, " ");
8385 output_temp_chip_member_name (output_file
, el
->automaton
);
8386 fprintf (output_file
, ";\n");
8388 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8389 if (comb_vect_p (el
->automaton
->trans_table
))
8391 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8392 output_trans_base_vect_name (output_file
, el
->automaton
);
8393 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8394 output_chip_member_name (output_file
, el
->automaton
);
8395 fprintf (output_file
, "] + ");
8396 output_translate_vect_name (output_file
, el
->automaton
);
8397 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8398 fprintf (output_file
, " if (");
8399 output_trans_check_vect_name (output_file
, el
->automaton
);
8400 fprintf (output_file
, " [%s] != %s->",
8401 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8402 output_chip_member_name (output_file
, el
->automaton
);
8403 fprintf (output_file
, ")\n");
8404 fprintf (output_file
, " return %s (%s, %s);\n",
8405 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8406 CHIP_PARAMETER_NAME
);
8407 fprintf (output_file
, " else\n");
8408 fprintf (output_file
, " ");
8409 if (el
->next_automata_list_el
!= NULL
)
8410 output_temp_chip_member_name (output_file
, el
->automaton
);
8413 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8414 output_chip_member_name (output_file
, el
->automaton
);
8416 fprintf (output_file
, " = ");
8417 output_trans_comb_vect_name (output_file
, el
->automaton
);
8418 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
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
);
8441 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8442 output_chip_member_name (output_file
, el
->automaton
);
8444 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
8446 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8447 for (el
= automata_list
;; el
= next_el
)
8449 next_el
= el
->next_automata_list_el
;
8450 if (next_el
== NULL
)
8452 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
8453 output_chip_member_name (output_file
, el
->automaton
);
8454 fprintf (output_file
, " = ");
8455 output_temp_chip_member_name (output_file
, el
->automaton
);
8456 fprintf (output_file
, ";\n");
8458 fprintf (output_file
, " return -1;\n");
8459 fprintf (output_file
, " }\n");
8462 /* Output function `internal_state_transition'. */
8464 output_internal_trans_func (void)
8466 fprintf (output_file
,
8467 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8468 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8469 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8470 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME
);
8471 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8472 output_insn_code_cases (output_automata_list_transition_code
);
8473 fprintf (output_file
, "\n default:\n return -1;\n }\n");
8474 fprintf (output_file
, "}\n\n");
8481 insn_code = dfa_insn_code (insn);
8482 if (insn_code > DFA__ADVANCE_CYCLE)
8486 insn_code = DFA__ADVANCE_CYCLE;
8488 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8489 code denotes CODE. */
8491 output_internal_insn_code_evaluation (const char *insn_name
,
8492 const char *insn_code_name
,
8495 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
8496 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
8497 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
8498 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
8499 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
8500 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
8501 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
8505 /* This function outputs `dfa_insn_code' and its helper function
8506 `dfa_insn_code_enlarge'. */
8508 output_dfa_insn_code_func (void)
8510 /* Emacs c-mode gets really confused if there's a { or } in column 0
8511 inside a string, so don't do that. */
8512 fprintf (output_file
, "\
8514 dfa_insn_code_enlarge (int 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\
8531 int uid = INSN_UID (%s);\n\
8533 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
,
8534 INSN_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
);
8536 fprintf (output_file
,
8537 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8538 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8539 fprintf (output_file
, " %s = %s[uid];\n",
8540 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8541 fprintf (output_file
, "\
8547 INTERNAL_INSN_CODE_NAME
,
8548 INTERNAL_INSN_CODE_NAME
,
8549 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
,
8550 DFA_INSN_CODES_VARIABLE_NAME
, INTERNAL_INSN_CODE_NAME
);
8551 fprintf (output_file
, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME
);
8554 /* The function outputs PHR interface function `state_transition'. */
8556 output_trans_func (void)
8558 fprintf (output_file
, "int\n%s (%s %s, rtx %s)\n",
8559 TRANSITION_FUNC_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8560 INSN_PARAMETER_NAME
);
8561 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8562 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8563 INTERNAL_INSN_CODE_NAME
, -1);
8564 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8565 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8568 /* The function outputs a code for evaluation of alternative states
8569 number for insns which have reservations in given AUTOMATA_LIST. */
8571 output_automata_list_state_alts_code (automata_list_el_t automata_list
)
8573 automata_list_el_t el
;
8574 automaton_t automaton
;
8576 fprintf (output_file
, " {\n");
8577 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8578 if (comb_vect_p (el
->automaton
->state_alts_table
))
8580 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
8583 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8585 automaton
= el
->automaton
;
8586 if (comb_vect_p (automaton
->state_alts_table
))
8588 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8589 output_state_alts_base_vect_name (output_file
, automaton
);
8590 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8591 output_chip_member_name (output_file
, automaton
);
8592 fprintf (output_file
, "] + ");
8593 output_translate_vect_name (output_file
, automaton
);
8594 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8595 fprintf (output_file
, " if (");
8596 output_state_alts_check_vect_name (output_file
, automaton
);
8597 fprintf (output_file
, " [%s] != %s->",
8598 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8599 output_chip_member_name (output_file
, automaton
);
8600 fprintf (output_file
, ")\n");
8601 fprintf (output_file
, " return 0;\n");
8602 fprintf (output_file
, " else\n");
8603 fprintf (output_file
,
8604 (el
== automata_list
8605 ? " %s = " : " %s += "),
8606 RESULT_VARIABLE_NAME
);
8607 output_state_alts_comb_vect_name (output_file
, automaton
);
8608 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8612 fprintf (output_file
,
8613 (el
== automata_list
8614 ? "\n %s = " : " %s += "),
8615 RESULT_VARIABLE_NAME
);
8616 output_state_alts_full_vect_name (output_file
, automaton
);
8617 fprintf (output_file
, " [");
8618 output_translate_vect_name (output_file
, automaton
);
8619 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8620 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8621 output_chip_member_name (output_file
, automaton
);
8622 fprintf (output_file
, " * %d];\n",
8623 automaton
->insn_equiv_classes_num
);
8626 fprintf (output_file
, " break;\n }\n\n");
8629 /* Output function `internal_state_alts'. */
8631 output_internal_state_alts_func (void)
8633 fprintf (output_file
,
8634 "static int\n%s (int %s, struct %s *%s)\n",
8635 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8636 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8637 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8638 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8639 output_insn_code_cases (output_automata_list_state_alts_code
);
8640 fprintf (output_file
,
8641 "\n default:\n %s = 0;\n break;\n }\n",
8642 RESULT_VARIABLE_NAME
);
8643 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8644 fprintf (output_file
, "}\n\n");
8647 /* The function outputs PHR interface function `state_alts'. */
8649 output_state_alts_func (void)
8651 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8652 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8653 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8654 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8655 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8656 INTERNAL_INSN_CODE_NAME
, 0);
8657 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8658 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8661 /* Output function `min_issue_delay'. */
8663 output_min_issue_delay_func (void)
8665 fprintf (output_file
, "int\n%s (%s %s, rtx %s)\n",
8666 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8667 INSN_PARAMETER_NAME
);
8668 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8669 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8670 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8671 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8672 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8673 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8674 fprintf (output_file
, " }\n else\n %s = %s;\n",
8675 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8676 fprintf (output_file
, "\n return %s (%s, %s);\n",
8677 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8679 fprintf (output_file
, "}\n\n");
8682 /* Output function `internal_dead_lock'. */
8684 output_internal_dead_lock_func (void)
8686 automaton_t automaton
;
8688 fprintf (output_file
, "static int\n%s (struct %s *%s)\n",
8689 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
, CHIP_PARAMETER_NAME
);
8690 fprintf (output_file
, "{\n");
8691 for (automaton
= description
->first_automaton
;
8693 automaton
= automaton
->next_automaton
)
8695 fprintf (output_file
, " if (");
8696 output_dead_lock_vect_name (output_file
, automaton
);
8697 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8698 output_chip_member_name (output_file
, automaton
);
8699 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8701 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8704 /* The function outputs PHR interface function `state_dead_lock_p'. */
8706 output_dead_lock_func (void)
8708 fprintf (output_file
, "int\n%s (%s %s)\n",
8709 DEAD_LOCK_FUNC_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8710 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8711 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8714 /* Output function `internal_reset'. */
8716 output_internal_reset_func (void)
8718 fprintf (output_file
, "static inline void\n%s (struct %s *%s)\n",
8719 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
, CHIP_PARAMETER_NAME
);
8720 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8721 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8724 /* The function outputs PHR interface function `state_size'. */
8726 output_size_func (void)
8728 fprintf (output_file
, "int\n%s (void)\n", SIZE_FUNC_NAME
);
8729 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8732 /* The function outputs PHR interface function `state_reset'. */
8734 output_reset_func (void)
8736 fprintf (output_file
, "void\n%s (%s %s)\n",
8737 RESET_FUNC_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8738 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8742 /* Output function `min_insn_conflict_delay'. */
8744 output_min_insn_conflict_delay_func (void)
8746 fprintf (output_file
,
8747 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8748 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
, STATE_TYPE_NAME
,
8749 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8750 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s, transition;\n",
8751 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8752 INTERNAL_INSN2_CODE_NAME
);
8753 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8754 INTERNAL_INSN_CODE_NAME
, 0);
8755 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8756 INTERNAL_INSN2_CODE_NAME
, 0);
8757 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8758 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8759 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8760 fprintf (output_file
, " transition = %s (%s, &%s);\n",
8761 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8762 fprintf (output_file
, " gcc_assert (transition <= 0);\n");
8763 fprintf (output_file
, " return %s (%s, &%s);\n",
8764 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8766 fprintf (output_file
, "}\n\n");
8769 /* Output function `internal_insn_latency'. */
8771 output_internal_insn_latency_func (void)
8774 struct bypass_decl
*bypass
;
8776 const char *tabletype
= "unsigned char";
8778 /* Find the smallest integer type that can hold all the default
8780 for (i
= 0; i
< description
->decls_num
; i
++)
8781 if (description
->decls
[i
]->mode
== dm_insn_reserv
)
8783 decl
= description
->decls
[i
];
8784 if (DECL_INSN_RESERV (decl
)->default_latency
> UCHAR_MAX
8785 && tabletype
[0] != 'i') /* Don't shrink it. */
8786 tabletype
= "unsigned short";
8787 if (DECL_INSN_RESERV (decl
)->default_latency
> USHRT_MAX
)
8791 fprintf (output_file
, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8792 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8793 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8794 INSN2_PARAMETER_NAME
);
8795 fprintf (output_file
, "{\n");
8797 if (DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
== 0)
8799 fputs (" return 0;\n}\n\n", output_file
);
8803 fprintf (output_file
, " static const %s default_latencies[] =\n {",
8806 for (i
= 0, j
= 0, col
= 7; i
< description
->decls_num
; i
++)
8807 if (description
->decls
[i
]->mode
== dm_insn_reserv
8808 && description
->decls
[i
] != advance_cycle_insn_decl
)
8810 if ((col
= (col
+1) % 8) == 0)
8811 fputs ("\n ", output_file
);
8812 decl
= description
->decls
[i
];
8813 gcc_assert (j
++ == DECL_INSN_RESERV (decl
)->insn_num
);
8814 fprintf (output_file
, "% 4d,",
8815 DECL_INSN_RESERV (decl
)->default_latency
);
8817 gcc_assert (j
== DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
8818 fputs ("\n };\n", output_file
);
8820 fprintf (output_file
, " if (%s >= %s || %s >= %s)\n return 0;\n",
8821 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8822 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8824 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8825 for (i
= 0; i
< description
->decls_num
; i
++)
8826 if (description
->decls
[i
]->mode
== dm_insn_reserv
8827 && DECL_INSN_RESERV (description
->decls
[i
])->bypass_list
)
8829 decl
= description
->decls
[i
];
8830 fprintf (output_file
,
8831 " case %d:\n switch (%s)\n {\n",
8832 DECL_INSN_RESERV (decl
)->insn_num
,
8833 INTERNAL_INSN2_CODE_NAME
);
8834 for (bypass
= DECL_INSN_RESERV (decl
)->bypass_list
;
8836 bypass
= bypass
->next
)
8838 gcc_assert (bypass
->in_insn_reserv
->insn_num
8839 != (DECL_INSN_RESERV
8840 (advance_cycle_insn_decl
)->insn_num
));
8841 fprintf (output_file
, " case %d:\n",
8842 bypass
->in_insn_reserv
->insn_num
);
8843 if (bypass
->bypass_guard_name
== NULL
)
8844 fprintf (output_file
, " return %d;\n",
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",
8857 fputs (" }\n break;\n", output_file
);
8860 fprintf (output_file
, " }\n return default_latencies[%s];\n}\n\n",
8861 INTERNAL_INSN_CODE_NAME
);
8864 /* The function outputs PHR interface function `insn_latency'. */
8866 output_insn_latency_func (void)
8868 fprintf (output_file
, "int\n%s (rtx %s, rtx %s)\n",
8869 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8870 fprintf (output_file
, "{\n int %s, %s;\n",
8871 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8872 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8873 INTERNAL_INSN_CODE_NAME
, 0);
8874 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8875 INTERNAL_INSN2_CODE_NAME
, 0);
8876 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8877 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8878 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8879 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8882 /* The function outputs PHR interface function `print_reservation'. */
8884 output_print_reservation_func (void)
8889 fprintf (output_file
,
8890 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8891 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8892 INSN_PARAMETER_NAME
);
8894 if (DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
== 0)
8896 fprintf (output_file
, " fputs (\"%s\", %s);\n}\n\n",
8897 NOTHING_NAME
, FILE_PARAMETER_NAME
);
8902 fputs (" static const char *const reservation_names[] =\n {",
8905 for (i
= 0, j
= 0; i
< description
->decls_num
; i
++)
8907 decl
= description
->decls
[i
];
8908 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8910 gcc_assert (j
== DECL_INSN_RESERV (decl
)->insn_num
);
8913 fprintf (output_file
, "\n \"%s\",",
8914 regexp_representation (DECL_INSN_RESERV (decl
)->regexp
));
8915 finish_regexp_representation ();
8918 gcc_assert (j
== DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
8920 fprintf (output_file
, "\n \"%s\"\n };\n int %s;\n\n",
8921 NOTHING_NAME
, INTERNAL_INSN_CODE_NAME
);
8923 fprintf (output_file
, " if (%s == 0)\n %s = %s;\n",
8924 INSN_PARAMETER_NAME
,
8925 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8926 fprintf (output_file
, " else\n\
8932 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8933 INSN_PARAMETER_NAME
,
8934 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8935 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8937 fprintf (output_file
, " fputs (reservation_names[%s], %s);\n}\n\n",
8938 INTERNAL_INSN_CODE_NAME
, FILE_PARAMETER_NAME
);
8941 /* The following function is used to sort unit declaration by their
8944 units_cmp (const void *unit1
, const void *unit2
)
8946 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8947 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8949 return strcmp (u1
->name
, u2
->name
);
8952 /* The following macro value is name of struct containing unit name
8954 #define NAME_CODE_STRUCT_NAME "name_code"
8956 /* The following macro value is name of table of struct name_code. */
8957 #define NAME_CODE_TABLE_NAME "name_code_table"
8959 /* The following macro values are member names for struct name_code. */
8960 #define NAME_MEMBER_NAME "name"
8961 #define CODE_MEMBER_NAME "code"
8963 /* The following macro values are local variable names for function
8964 `get_cpu_unit_code'. */
8965 #define CMP_VARIABLE_NAME "cmp"
8966 #define LOW_VARIABLE_NAME "l"
8967 #define MIDDLE_VARIABLE_NAME "m"
8968 #define HIGH_VARIABLE_NAME "h"
8970 /* The following function outputs function to obtain internal cpu unit
8971 code by the cpu unit name. */
8973 output_get_cpu_unit_code_func (void)
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");
9018 /* The following function outputs function to check reservation of cpu
9019 unit (its internal code will be passed as the function argument) in
9022 output_cpu_unit_reservation_p (void)
9024 automaton_t automaton
;
9026 fprintf (output_file
, "int\n%s (%s %s, int %s)\n",
9027 CPU_UNIT_RESERVATION_P_FUNC_NAME
,
9028 STATE_TYPE_NAME
, STATE_NAME
,
9029 CPU_CODE_PARAMETER_NAME
);
9030 fprintf (output_file
, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
9031 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
9032 description
->query_units_num
);
9033 for (automaton
= description
->first_automaton
;
9035 automaton
= automaton
->next_automaton
)
9037 fprintf (output_file
, " if ((");
9038 output_reserved_units_table_name (output_file
, automaton
);
9039 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
9040 output_chip_member_name (output_file
, automaton
);
9041 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9042 (description
->query_units_num
+ 7) / 8,
9043 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
9044 fprintf (output_file
, " return 1;\n");
9046 fprintf (output_file
, " return 0;\n}\n\n");
9049 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9051 output_dfa_clean_insn_cache_func (void)
9053 fprintf (output_file
,
9054 "void\n%s (void)\n{\n int %s;\n\n",
9055 DFA_CLEAN_INSN_CACHE_FUNC_NAME
, I_VARIABLE_NAME
);
9056 fprintf (output_file
,
9057 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9058 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
9059 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
9060 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
9063 /* The function outputs PHR interface function `dfa_start'. */
9065 output_dfa_start_func (void)
9067 fprintf (output_file
,
9068 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
9069 DFA_START_FUNC_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9070 fprintf (output_file
, " %s = xmalloc (%s * sizeof (int));\n",
9071 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9072 fprintf (output_file
, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME
);
9075 /* The function outputs PHR interface function `dfa_finish'. */
9077 output_dfa_finish_func (void)
9079 fprintf (output_file
, "void\n%s (void)\n{\n free (%s);\n}\n\n",
9080 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
9085 /* The page contains code for output description file (readable
9086 representation of original description and generated DFA(s). */
9088 /* The function outputs string representation of IR reservation. */
9090 output_regexp (regexp_t regexp
)
9092 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
9093 finish_regexp_representation ();
9096 /* Output names of units in LIST separated by comma. */
9098 output_unit_set_el_list (unit_set_el_t list
)
9102 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
9105 fprintf (output_description_file
, ", ");
9106 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
9110 /* Output patterns in LIST separated by comma. */
9112 output_pattern_set_el_list (pattern_set_el_t list
)
9114 pattern_set_el_t el
;
9117 for (el
= list
; el
!= NULL
; el
= el
->next_pattern_set_el
)
9120 fprintf (output_description_file
, ", ");
9121 for (i
= 0; i
< el
->units_num
; i
++)
9122 fprintf (output_description_file
, (i
== 0 ? "%s" : " %s"),
9123 el
->unit_decls
[i
]->name
);
9127 /* The function outputs string representation of IR define_reservation
9128 and define_insn_reservation. */
9130 output_description (void)
9135 for (i
= 0; i
< description
->decls_num
; i
++)
9137 decl
= description
->decls
[i
];
9138 if (decl
->mode
== dm_unit
)
9140 if (DECL_UNIT (decl
)->excl_list
!= NULL
)
9142 fprintf (output_description_file
, "unit %s exlusion_set: ",
9143 DECL_UNIT (decl
)->name
);
9144 output_unit_set_el_list (DECL_UNIT (decl
)->excl_list
);
9145 fprintf (output_description_file
, "\n");
9147 if (DECL_UNIT (decl
)->presence_list
!= NULL
)
9149 fprintf (output_description_file
, "unit %s presence_set: ",
9150 DECL_UNIT (decl
)->name
);
9151 output_pattern_set_el_list (DECL_UNIT (decl
)->presence_list
);
9152 fprintf (output_description_file
, "\n");
9154 if (DECL_UNIT (decl
)->final_presence_list
!= NULL
)
9156 fprintf (output_description_file
, "unit %s final_presence_set: ",
9157 DECL_UNIT (decl
)->name
);
9158 output_pattern_set_el_list
9159 (DECL_UNIT (decl
)->final_presence_list
);
9160 fprintf (output_description_file
, "\n");
9162 if (DECL_UNIT (decl
)->absence_list
!= NULL
)
9164 fprintf (output_description_file
, "unit %s absence_set: ",
9165 DECL_UNIT (decl
)->name
);
9166 output_pattern_set_el_list (DECL_UNIT (decl
)->absence_list
);
9167 fprintf (output_description_file
, "\n");
9169 if (DECL_UNIT (decl
)->final_absence_list
!= NULL
)
9171 fprintf (output_description_file
, "unit %s final_absence_set: ",
9172 DECL_UNIT (decl
)->name
);
9173 output_pattern_set_el_list
9174 (DECL_UNIT (decl
)->final_absence_list
);
9175 fprintf (output_description_file
, "\n");
9179 fprintf (output_description_file
, "\n");
9180 for (i
= 0; i
< description
->decls_num
; i
++)
9182 decl
= description
->decls
[i
];
9183 if (decl
->mode
== dm_reserv
)
9185 fprintf (output_description_file
, "reservation %s: ",
9186 DECL_RESERV (decl
)->name
);
9187 output_regexp (DECL_RESERV (decl
)->regexp
);
9188 fprintf (output_description_file
, "\n");
9190 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9192 fprintf (output_description_file
, "insn reservation %s ",
9193 DECL_INSN_RESERV (decl
)->name
);
9194 print_rtl (output_description_file
,
9195 DECL_INSN_RESERV (decl
)->condexp
);
9196 fprintf (output_description_file
, ": ");
9197 output_regexp (DECL_INSN_RESERV (decl
)->regexp
);
9198 fprintf (output_description_file
, "\n");
9200 else if (decl
->mode
== dm_bypass
)
9201 fprintf (output_description_file
, "bypass %d %s %s\n",
9202 DECL_BYPASS (decl
)->latency
,
9203 DECL_BYPASS (decl
)->out_insn_name
,
9204 DECL_BYPASS (decl
)->in_insn_name
);
9206 fprintf (output_description_file
, "\n\f\n");
9209 /* The function outputs name of AUTOMATON. */
9211 output_automaton_name (FILE *f
, automaton_t automaton
)
9213 if (automaton
->corresponding_automaton_decl
== NULL
)
9214 fprintf (f
, "#%d", automaton
->automaton_order_num
);
9216 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
9219 /* Maximal length of line for pretty printing into description
9221 #define MAX_LINE_LENGTH 70
9223 /* The function outputs units name belonging to AUTOMATON. */
9225 output_automaton_units (automaton_t automaton
)
9229 int curr_line_length
;
9230 int there_is_an_automaton_unit
;
9233 fprintf (output_description_file
, "\n Corresponding units:\n");
9234 fprintf (output_description_file
, " ");
9235 curr_line_length
= 4;
9236 there_is_an_automaton_unit
= 0;
9237 for (i
= 0; i
< description
->decls_num
; i
++)
9239 decl
= description
->decls
[i
];
9240 if (decl
->mode
== dm_unit
9241 && (DECL_UNIT (decl
)->corresponding_automaton_num
9242 == automaton
->automaton_order_num
))
9244 there_is_an_automaton_unit
= 1;
9245 name
= DECL_UNIT (decl
)->name
;
9246 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
9248 curr_line_length
= strlen (name
) + 4;
9249 fprintf (output_description_file
, "\n ");
9253 curr_line_length
+= strlen (name
) + 1;
9254 fprintf (output_description_file
, " ");
9256 fprintf (output_description_file
, "%s", name
);
9259 if (!there_is_an_automaton_unit
)
9260 fprintf (output_description_file
, "<None>");
9261 fprintf (output_description_file
, "\n\n");
9264 /* The following variable is used for forming array of all possible cpu unit
9265 reservations described by the current DFA state. */
9266 static vla_ptr_t state_reservs
;
9268 /* The function forms `state_reservs' for STATE. */
9270 add_state_reservs (state_t state
)
9272 alt_state_t curr_alt_state
;
9273 reserv_sets_t reservs
;
9275 if (state
->component_states
!= NULL
)
9276 for (curr_alt_state
= state
->component_states
;
9277 curr_alt_state
!= NULL
;
9278 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
9279 add_state_reservs (curr_alt_state
->state
);
9282 reservs
= state
->reservs
;
9283 VLA_PTR_ADD (state_reservs
, reservs
);
9287 /* The function outputs readable representation of all out arcs of
9290 output_state_arcs (state_t state
)
9295 int curr_line_length
;
9297 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
9300 gcc_assert (ainsn
->first_insn_with_same_reservs
);
9301 fprintf (output_description_file
, " ");
9302 curr_line_length
= 7;
9303 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
9306 insn_name
= ainsn
->insn_reserv_decl
->name
;
9307 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
9309 if (ainsn
!= arc
->insn
)
9311 fprintf (output_description_file
, ",\n ");
9312 curr_line_length
= strlen (insn_name
) + 6;
9315 curr_line_length
+= strlen (insn_name
);
9319 curr_line_length
+= strlen (insn_name
);
9320 if (ainsn
!= arc
->insn
)
9322 curr_line_length
+= 2;
9323 fprintf (output_description_file
, ", ");
9326 fprintf (output_description_file
, "%s", insn_name
);
9327 ainsn
= ainsn
->next_same_reservs_insn
;
9329 while (ainsn
!= NULL
);
9330 fprintf (output_description_file
, " %d (%d)\n",
9331 arc
->to_state
->order_state_num
, arc
->state_alts
);
9333 fprintf (output_description_file
, "\n");
9336 /* The following function is used for sorting possible cpu unit
9337 reservation of a DFA state. */
9339 state_reservs_cmp (const void *reservs_ptr_1
, const void *reservs_ptr_2
)
9341 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
9342 *(reserv_sets_t
*) reservs_ptr_2
);
9345 /* The following function is used for sorting possible cpu unit
9346 reservation of a DFA state. */
9348 remove_state_duplicate_reservs (void)
9350 reserv_sets_t
*reservs_ptr
;
9351 reserv_sets_t
*last_formed_reservs_ptr
;
9353 last_formed_reservs_ptr
= NULL
;
9354 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9355 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9357 if (last_formed_reservs_ptr
== NULL
)
9358 last_formed_reservs_ptr
= reservs_ptr
;
9359 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
9361 ++last_formed_reservs_ptr
;
9362 *last_formed_reservs_ptr
= *reservs_ptr
;
9364 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
9367 /* The following function output readable representation of DFA(s)
9368 state used for fast recognition of pipeline hazards. State is
9369 described by possible (current and scheduled) cpu unit
9372 output_state (state_t state
)
9374 reserv_sets_t
*reservs_ptr
;
9376 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
9377 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
9378 fprintf (output_description_file
,
9379 state
->new_cycle_p
? " (new cycle)\n" : "\n");
9380 add_state_reservs (state
);
9381 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
9382 sizeof (reserv_sets_t
), state_reservs_cmp
);
9383 remove_state_duplicate_reservs ();
9384 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9385 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9388 fprintf (output_description_file
, " ");
9389 output_reserv_sets (output_description_file
, *reservs_ptr
);
9390 fprintf (output_description_file
, "\n");
9392 fprintf (output_description_file
, "\n");
9393 output_state_arcs (state
);
9394 VLA_PTR_DELETE (state_reservs
);
9397 /* The following function output readable representation of
9398 DFAs used for fast recognition of pipeline hazards. */
9400 output_automaton_descriptions (void)
9402 automaton_t automaton
;
9404 for (automaton
= description
->first_automaton
;
9406 automaton
= automaton
->next_automaton
)
9408 fprintf (output_description_file
, "\nAutomaton ");
9409 output_automaton_name (output_description_file
, automaton
);
9410 fprintf (output_description_file
, "\n");
9411 output_automaton_units (automaton
);
9412 pass_states (automaton
, output_state
);
9418 /* The page contains top level function for generation DFA(s) used for
9421 /* The function outputs statistics about work of different phases of
9424 output_statistics (FILE *f
)
9426 automaton_t automaton
;
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;
9436 for (automaton
= description
->first_automaton
;
9438 automaton
= automaton
->next_automaton
)
9440 fprintf (f
, "\nAutomaton ");
9441 output_automaton_name (f
, automaton
);
9442 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
9443 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
9444 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
9445 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
9446 states_num
= automaton
->DFA_states_num
;
9447 if (!no_minimization_flag
)
9449 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9450 automaton
->minimal_DFA_states_num
,
9451 automaton
->minimal_DFA_arcs_num
);
9452 states_num
= automaton
->minimal_DFA_states_num
;
9454 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
9455 description
->insns_num
, automaton
->insn_equiv_classes_num
);
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"));
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"));
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
;
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
);
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
);
9500 /* The function output times of work of different phases of DFA
9503 output_time_statistics (FILE *f
)
9505 fprintf (f
, "\n transformation: ");
9506 print_active_time (f
, transform_time
);
9507 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
9508 print_active_time (f
, NDFA_time
);
9511 fprintf (f
, ", NDFA -> DFA: ");
9512 print_active_time (f
, NDFA_to_DFA_time
);
9514 fprintf (f
, "\n DFA minimization: ");
9515 print_active_time (f
, minimize_time
);
9516 fprintf (f
, ", making insn equivalence: ");
9517 print_active_time (f
, equiv_time
);
9518 fprintf (f
, "\n all automaton generation: ");
9519 print_active_time (f
, automaton_generation_time
);
9520 fprintf (f
, ", output: ");
9521 print_active_time (f
, output_time
);
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. */
9531 automata_num
= split_argument
;
9532 if (description
->units_num
< automata_num
)
9533 automata_num
= description
->units_num
;
9536 initiate_automata_lists ();
9537 initiate_pass_states ();
9538 initiate_excl_sets ();
9539 initiate_presence_absence_pattern_sets ();
9540 automaton_generation_time
= create_ticker ();
9542 ticker_off (&automaton_generation_time
);
9547 /* The following function creates insn attribute whose values are
9548 number alternatives in insn reservations. */
9550 make_insn_alts_attr (void)
9556 condexp
= rtx_alloc (COND
);
9557 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9558 XEXP (condexp
, 1) = make_numeric_value (0);
9559 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9561 decl
= description
->decls
[i
];
9562 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9564 XVECEXP (condexp
, 0, 2 * insn_num
)
9565 = DECL_INSN_RESERV (decl
)->condexp
;
9566 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9567 = make_numeric_value
9568 (DECL_INSN_RESERV (decl
)->transformed_regexp
->mode
!= rm_oneof
9569 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl
)
9570 ->transformed_regexp
)->regexps_num
);
9574 gcc_assert (description
->insns_num
== insn_num
+ 1);
9575 make_internal_attr (attr_printf (sizeof ("*")
9576 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
9577 "*%s", INSN_ALTS_FUNC_NAME
),
9578 condexp
, ATTR_NONE
);
9583 /* The following function creates attribute which is order number of
9584 insn in pipeline hazard description translator. */
9586 make_internal_dfa_insn_code_attr (void)
9592 condexp
= rtx_alloc (COND
);
9593 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9595 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl
)
9597 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9599 decl
= description
->decls
[i
];
9600 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9602 XVECEXP (condexp
, 0, 2 * insn_num
)
9603 = DECL_INSN_RESERV (decl
)->condexp
;
9604 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9605 = make_numeric_value (DECL_INSN_RESERV (decl
)->insn_num
);
9609 gcc_assert (description
->insns_num
== insn_num
+ 1);
9611 (attr_printf (sizeof ("*")
9612 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
9613 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
9614 condexp
, ATTR_STATIC
);
9619 /* The following function creates attribute which order number of insn
9620 in pipeline hazard description translator. */
9622 make_default_insn_latency_attr (void)
9628 condexp
= rtx_alloc (COND
);
9629 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9630 XEXP (condexp
, 1) = make_numeric_value (0);
9631 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9633 decl
= description
->decls
[i
];
9634 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9636 XVECEXP (condexp
, 0, 2 * insn_num
)
9637 = DECL_INSN_RESERV (decl
)->condexp
;
9638 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9639 = make_numeric_value (DECL_INSN_RESERV (decl
)->default_latency
);
9643 gcc_assert (description
->insns_num
== insn_num
+ 1);
9644 make_internal_attr (attr_printf (sizeof ("*")
9645 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
9646 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
9647 condexp
, ATTR_NONE
);
9652 /* The following function creates attribute which returns 1 if given
9653 output insn has bypassing and 0 otherwise. */
9655 make_bypass_attr (void)
9658 int bypass_insns_num
= 0;
9662 for (i
= 0; i
< description
->decls_num
; i
++)
9664 decl
= description
->decls
[i
];
9665 if (decl
->mode
== dm_insn_reserv
9666 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9667 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9670 if (bypass_insns_num
== 0)
9671 result_rtx
= make_numeric_value (0);
9674 result_rtx
= rtx_alloc (COND
);
9675 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
9676 XEXP (result_rtx
, 1) = make_numeric_value (0);
9678 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
9680 decl
= description
->decls
[i
];
9681 if (decl
->mode
== dm_insn_reserv
9682 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9683 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9685 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9686 = DECL_INSN_RESERV (decl
)->condexp
;
9687 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9688 = make_numeric_value (1);
9693 make_internal_attr (attr_printf (sizeof ("*")
9694 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9695 "*%s", BYPASS_P_FUNC_NAME
),
9696 result_rtx
, ATTR_NONE
);
9701 /* This page mainly contains top level functions of pipeline hazards
9702 description translator. */
9704 /* The following macro value is suffix of name of description file of
9705 pipeline hazards description translator. */
9706 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9708 /* The function returns suffix of given file name. The returned
9709 string can not be changed. */
9711 file_name_suffix (const char *file_name
)
9713 const char *last_period
;
9715 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9716 if (*file_name
== '.')
9717 last_period
= file_name
;
9718 return (last_period
== NULL
? file_name
: last_period
);
9721 /* The function returns base name of given file name, i.e. pointer to
9722 first char after last `/' (or `\' for WIN32) in given file name,
9723 given file name itself if the directory name is absent. The
9724 returned string can not be changed. */
9726 base_file_name (const char *file_name
)
9728 int directory_name_length
;
9730 directory_name_length
= strlen (file_name
);
9732 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9733 && file_name
[directory_name_length
] != '\\')
9735 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9737 directory_name_length
--;
9738 return file_name
+ directory_name_length
+ 1;
9741 /* The following is top level function to initialize the work of
9742 pipeline hazards description translator. */
9744 initiate_automaton_gen (int argc
, char **argv
)
9746 const char *base_name
;
9750 split_argument
= 0; /* default value */
9751 no_minimization_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)
9761 else if (strcmp (argv
[i
], V_OPTION
) == 0)
9763 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9765 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9767 else if (strcmp (argv
[i
], PROGRESS_OPTION
) == 0)
9769 else if (strcmp (argv
[i
], "-split") == 0)
9772 fatal ("-split has no argument.");
9773 fatal ("option `-split' has not been implemented yet\n");
9774 /* split_argument = atoi (argument_vect [i + 1]); */
9776 VLA_PTR_CREATE (decls
, 150, "decls");
9777 /* Initialize IR storage. */
9778 obstack_init (&irp
);
9779 initiate_automaton_decl_table ();
9780 initiate_insn_decl_table ();
9781 initiate_decl_table ();
9782 output_file
= stdout
;
9783 output_description_file
= NULL
;
9784 base_name
= base_file_name (argv
[1]);
9785 obstack_grow (&irp
, base_name
,
9786 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9787 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9788 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9789 obstack_1grow (&irp
, '\0');
9790 output_description_file_name
= obstack_base (&irp
);
9791 obstack_finish (&irp
);
9794 /* The following function checks existence at least one arc marked by
9797 check_automata_insn_issues (void)
9799 automaton_t automaton
;
9800 ainsn_t ainsn
, reserv_ainsn
;
9802 for (automaton
= description
->first_automaton
;
9804 automaton
= automaton
->next_automaton
)
9806 for (ainsn
= automaton
->ainsn_list
;
9808 ainsn
= ainsn
->next_ainsn
)
9809 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9811 for (reserv_ainsn
= ainsn
;
9812 reserv_ainsn
!= NULL
;
9813 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9814 if (automaton
->corresponding_automaton_decl
!= NULL
)
9817 error ("Automaton `%s': Insn `%s' will never be issued",
9818 automaton
->corresponding_automaton_decl
->name
,
9819 reserv_ainsn
->insn_reserv_decl
->name
);
9822 (0, "Automaton `%s': Insn `%s' will never be issued",
9823 automaton
->corresponding_automaton_decl
->name
,
9824 reserv_ainsn
->insn_reserv_decl
->name
);
9829 error ("Insn `%s' will never be issued",
9830 reserv_ainsn
->insn_reserv_decl
->name
);
9832 warning (0, "Insn `%s' will never be issued",
9833 reserv_ainsn
->insn_reserv_decl
->name
);
9839 /* The following vla is used for storing pointers to all achieved
9841 static vla_ptr_t automaton_states
;
9843 /* This function is called by function pass_states to add an achieved
9846 add_automaton_state (state_t state
)
9848 VLA_PTR_ADD (automaton_states
, state
);
9851 /* The following function forms list of important automata (whose
9852 states may be changed after the insn issue) for each insn. */
9854 form_important_insn_automata_lists (void)
9856 automaton_t automaton
;
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
;
9868 automaton
= automaton
->next_automaton
)
9870 VLA_PTR_NULLIFY (automaton_states
);
9871 pass_states (automaton
, add_automaton_state
);
9872 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9873 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9876 for (arc
= first_out_arc (*state_ptr
);
9878 arc
= next_out_arc (arc
))
9879 if (arc
->to_state
!= *state_ptr
)
9881 gcc_assert (arc
->insn
->first_insn_with_same_reservs
);
9882 for (ainsn
= arc
->insn
;
9884 ainsn
= ainsn
->next_same_reservs_insn
)
9885 ainsn
->important_p
= TRUE
;
9889 VLA_PTR_DELETE (automaton_states
);
9890 /* Create automata sets for the insns. */
9891 for (i
= 0; i
< description
->decls_num
; i
++)
9893 decl
= description
->decls
[i
];
9894 if (decl
->mode
== dm_insn_reserv
)
9896 automata_list_start ();
9897 for (automaton
= description
->first_automaton
;
9899 automaton
= automaton
->next_automaton
)
9900 for (ainsn
= automaton
->ainsn_list
;
9902 ainsn
= ainsn
->next_ainsn
)
9903 if (ainsn
->important_p
9904 && ainsn
->insn_reserv_decl
== DECL_INSN_RESERV (decl
))
9906 automata_list_add (automaton
);
9909 DECL_INSN_RESERV (decl
)->important_automata_list
9910 = automata_list_finish ();
9916 /* The following is top level function to generate automat(a,on) for
9917 fast recognition of pipeline hazards. */
9919 expand_automata (void)
9923 description
= create_node (sizeof (struct description
)
9924 /* One entry for cycle advancing insn. */
9925 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9926 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9927 description
->query_units_num
= 0;
9928 for (i
= 0; i
< description
->decls_num
; i
++)
9930 description
->decls
[i
] = VLA_PTR (decls
, i
);
9931 if (description
->decls
[i
]->mode
== dm_unit
9932 && DECL_UNIT (description
->decls
[i
])->query_p
)
9933 DECL_UNIT (description
->decls
[i
])->query_num
9934 = description
->query_units_num
++;
9936 all_time
= create_ticker ();
9937 check_time
= create_ticker ();
9939 fprintf (stderr
, "Check description...");
9940 check_all_description ();
9942 fprintf (stderr
, "done\n");
9943 ticker_off (&check_time
);
9944 generation_time
= create_ticker ();
9947 transform_insn_regexps ();
9948 check_unit_distributions_to_automata ();
9953 check_automata_insn_issues ();
9957 form_important_insn_automata_lists ();
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 ();
9965 fprintf (stderr
, "done\n");
9967 ticker_off (&generation_time
);
9968 ticker_off (&all_time
);
9970 fprintf (stderr
, "All other genattrtab stuff...");
9973 /* The following is top level function to output PHR and to finish
9974 work with pipeline description translator. */
9976 write_automata (void)
9979 fprintf (stderr
, "done\n");
9981 fatal ("Errors in DFA description");
9982 ticker_on (&all_time
);
9983 output_time
= create_ticker ();
9985 fprintf (stderr
, "Forming and outputting automata tables...");
9986 output_dfa_max_issue_rate ();
9990 fprintf (stderr
, "done\n");
9991 fprintf (stderr
, "Output functions to work with automata...");
9993 output_chip_definitions ();
9994 output_max_insn_queue_index_def ();
9995 output_internal_min_issue_delay_func ();
9996 output_internal_trans_func ();
9997 /* Cache of insn dfa codes: */
9998 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9999 fprintf (output_file
, "\nstatic int %s;\n\n",
10000 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
10001 output_dfa_insn_code_func ();
10002 output_trans_func ();
10003 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
10004 output_internal_state_alts_func ();
10005 output_state_alts_func ();
10006 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
10007 AUTOMATON_STATE_ALTS_MACRO_NAME
);
10008 output_min_issue_delay_func ();
10009 output_internal_dead_lock_func ();
10010 output_dead_lock_func ();
10011 output_size_func ();
10012 output_internal_reset_func ();
10013 output_reset_func ();
10014 output_min_insn_conflict_delay_func ();
10015 output_internal_insn_latency_func ();
10016 output_insn_latency_func ();
10017 output_print_reservation_func ();
10018 /* Output function get_cpu_unit_code. */
10019 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
10020 output_get_cpu_unit_code_func ();
10021 output_cpu_unit_reservation_p ();
10022 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
10023 CPU_UNITS_QUERY_MACRO_NAME
);
10024 output_dfa_clean_insn_cache_func ();
10025 output_dfa_start_func ();
10026 output_dfa_finish_func ();
10028 fprintf (stderr
, "done\n");
10031 output_description_file
= fopen (output_description_file_name
, "w");
10032 if (output_description_file
== NULL
)
10034 perror (output_description_file_name
);
10035 exit (FATAL_EXIT_CODE
);
10038 fprintf (stderr
, "Output automata description...");
10039 output_description ();
10040 output_automaton_descriptions ();
10042 fprintf (stderr
, "done\n");
10043 output_statistics (output_description_file
);
10045 output_statistics (stderr
);
10046 ticker_off (&output_time
);
10047 output_time_statistics (stderr
);
10050 finish_automata_lists ();
10053 fprintf (stderr
, "Summary:\n");
10054 fprintf (stderr
, " check time ");
10055 print_active_time (stderr
, check_time
);
10056 fprintf (stderr
, ", generation time ");
10057 print_active_time (stderr
, generation_time
);
10058 fprintf (stderr
, ", all time ");
10059 print_active_time (stderr
, all_time
);
10060 fprintf (stderr
, "\n");
10062 /* Finish all work. */
10063 if (output_description_file
!= NULL
)
10065 fflush (output_description_file
);
10066 if (ferror (stdout
) != 0)
10067 fatal ("Error in writing DFA description file %s",
10068 output_description_file_name
);
10069 fclose (output_description_file
);
10071 finish_automaton_decl_table ();
10072 finish_insn_decl_table ();
10073 finish_decl_table ();
10074 obstack_free (&irp
, NULL
);
10075 if (have_error
&& output_description_file
!= NULL
)
10076 remove (output_description_file_name
);