1 /* Pipeline hazard description translator.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 Written by Vladimir Makarov <vmakarov@redhat.com>
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 GNU CC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 1. Detecting pipeline structural hazards quickly. T. Proebsting,
26 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
27 Principles of Programming Languages, pages 280--286, 1994.
29 This article is a good start point to understand usage of finite
30 state automata for pipeline hazard recognizers. But I'd
31 recommend the 2nd article for more deep understanding.
33 2. Efficient Instruction Scheduling Using Finite State Automata:
34 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
35 article about usage of finite state automata for pipeline hazard
38 The current implementation is different from the 2nd article in the
41 1. New operator `|' (alternative) is permitted in functional unit
42 reservation which can be treated deterministicly and
45 2. Possibility of usage of nondeterministic automata too.
47 3. Possibility to query functional unit reservations for given
50 4. Several constructions to describe impossible reservations
51 (`exclusion_set', `presence_set', and `absence_set').
53 5. No reverse automata are generated. Trace instruction scheduling
54 requires this. It can be easily added in the future if we
57 6. Union of automaton states are not generated yet. It is planned
58 to be implemented. Such feature is needed to make more accurate
59 interlock insn scheduling to get state describing functional
60 unit reservation in a joint CFG point.
63 /* This file code processes constructions of machine description file
64 which describes automaton used for recognition of processor pipeline
65 hazards by insn scheduler and can be used for other tasks (such as
68 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
69 `gen_bypass', `gen_excl_set', `gen_presence_set',
70 `gen_absence_set', `gen_automaton', `gen_automata_option',
71 `gen_reserv', `gen_insn_reserv' are called from file
72 `genattrtab.c'. They transform RTL constructions describing
73 automata in .md file into internal representation convenient for
76 The translator major function `expand_automata' processes the
77 description internal representation into finite state automaton.
80 o checking correctness of the automaton pipeline description
81 (major function is `check_all_description').
83 o generating automaton (automata) from the description (major
84 function is `make_automaton').
86 o optional transformation of nondeterministic finite state
87 automata into deterministic ones if the alternative operator
88 `|' is treated nondeterministicly in the description (major
89 function is NDFA_to_DFA).
91 o optional minimization of the finite state automata by merging
92 equivalent automaton states (major function is `minimize_DFA').
94 o forming tables (some as comb vectors) and attributes
95 representing the automata (functions output_..._table).
97 Function `write_automata' outputs the created finite state
98 automaton as different tables and functions which works with the
99 automata to inquire automaton state and to change its state. These
100 function are used by gcc instruction scheduler and may be some
117 #include "genattrtab.h"
119 /* Positions in machine description file. Now they are not used. But
120 they could be used in the future for better diagnostic messages. */
123 /* The following is element of vector of current (and planned in the
124 future) functional unit reservations. */
125 typedef unsigned HOST_WIDE_INT set_el_t
;
127 /* Reservations of function units are represented by value of the following
129 typedef set_el_t
*reserv_sets_t
;
131 /* The following structure represents variable length array (vla) of
132 pointers and HOST WIDE INTs. We could be use only varray. But we
133 add new lay because we add elements very frequently and this could
134 stress OS allocator when varray is used only. */
136 size_t length
; /* current size of vla. */
137 varray_type varray
; /* container for vla. */
140 typedef vla_ptr_t vla_hwint_t
;
142 /* The following structure describes a ticker. */
145 /* The following member value is time of the ticker creation with
146 taking into account time when the ticker is off. Active time of
147 the ticker is current time minus the value. */
148 int modified_creation_time
;
149 /* The following member value is time (incremented by one) when the
150 ticker was off. Zero value means that now the ticker is on. */
151 int incremented_off_time
;
154 /* The ticker is represented by the following type. */
155 typedef struct ticker ticker_t
;
157 /* The following type describes elements of output vectors. */
158 typedef HOST_WIDE_INT vect_el_t
;
160 /* Forward declaration of structures of internal representation of
161 pipeline description based on NDFA. */
166 struct automaton_decl
;
167 struct unit_rel_decl
;
169 struct insn_reserv_decl
;
172 struct result_regexp
;
173 struct reserv_regexp
;
174 struct nothing_regexp
;
175 struct sequence_regexp
;
176 struct repeat_regexp
;
187 struct state_ainsn_table
;
189 /* The following typedefs are for brevity. */
190 typedef struct unit_decl
*unit_decl_t
;
191 typedef struct decl
*decl_t
;
192 typedef struct regexp
*regexp_t
;
193 typedef struct unit_set_el
*unit_set_el_t
;
194 typedef struct alt_state
*alt_state_t
;
195 typedef struct state
*state_t
;
196 typedef struct arc
*arc_t
;
197 typedef struct ainsn
*ainsn_t
;
198 typedef struct automaton
*automaton_t
;
199 typedef struct automata_list_el
*automata_list_el_t
;
200 typedef struct state_ainsn_table
*state_ainsn_table_t
;
203 /* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
204 gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
205 gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
206 initiate_automaton_gen, expand_automata, write_automata are
207 described on the file top because the functions are called from
210 static void *create_node
PARAMS ((size_t));
211 static void *copy_node
PARAMS ((const void *, size_t));
212 static char *check_name
PARAMS ((char *, pos_t
));
213 static char *next_sep_el
PARAMS ((char **, int, int));
214 static int n_sep_els
PARAMS ((char *, int, int));
215 static char **get_str_vect
PARAMS ((char *, int *, int, int));
216 static regexp_t gen_regexp_el
PARAMS ((char *));
217 static regexp_t gen_regexp_repeat
PARAMS ((char *));
218 static regexp_t gen_regexp_allof
PARAMS ((char *));
219 static regexp_t gen_regexp_oneof
PARAMS ((char *));
220 static regexp_t gen_regexp_sequence
PARAMS ((char *));
221 static regexp_t gen_regexp
PARAMS ((char *));
223 static unsigned string_hash
PARAMS ((const char *));
224 static unsigned automaton_decl_hash
PARAMS ((const void *));
225 static int automaton_decl_eq_p
PARAMS ((const void *,
227 static decl_t insert_automaton_decl
PARAMS ((decl_t
));
228 static decl_t find_automaton_decl
PARAMS ((char *));
229 static void initiate_automaton_decl_table
PARAMS ((void));
230 static void finish_automaton_decl_table
PARAMS ((void));
232 static unsigned insn_decl_hash
PARAMS ((const void *));
233 static int insn_decl_eq_p
PARAMS ((const void *,
235 static decl_t insert_insn_decl
PARAMS ((decl_t
));
236 static decl_t find_insn_decl
PARAMS ((char *));
237 static void initiate_insn_decl_table
PARAMS ((void));
238 static void finish_insn_decl_table
PARAMS ((void));
240 static unsigned decl_hash
PARAMS ((const void *));
241 static int decl_eq_p
PARAMS ((const void *,
243 static decl_t insert_decl
PARAMS ((decl_t
));
244 static decl_t find_decl
PARAMS ((char *));
245 static void initiate_decl_table
PARAMS ((void));
246 static void finish_decl_table
PARAMS ((void));
248 static unit_set_el_t process_excls
PARAMS ((char **, int, pos_t
));
249 static void add_excls
PARAMS ((unit_set_el_t
, unit_set_el_t
,
251 static unit_set_el_t process_presence_absence
252 PARAMS ((char **, int, pos_t
, int));
253 static void add_presence_absence
PARAMS ((unit_set_el_t
, unit_set_el_t
,
255 static void process_decls
PARAMS ((void));
256 static struct bypass_decl
*find_bypass
PARAMS ((struct bypass_decl
*,
257 struct insn_reserv_decl
*));
258 static void check_automaton_usage
PARAMS ((void));
259 static regexp_t process_regexp
PARAMS ((regexp_t
));
260 static void process_regexp_decls
PARAMS ((void));
261 static void check_usage
PARAMS ((void));
262 static int loop_in_regexp
PARAMS ((regexp_t
, decl_t
));
263 static void check_loops_in_regexps
PARAMS ((void));
264 static int process_regexp_cycles
PARAMS ((regexp_t
, int));
265 static void evaluate_max_reserv_cycles
PARAMS ((void));
266 static void check_all_description
PARAMS ((void));
268 static ticker_t create_ticker
PARAMS ((void));
269 static void ticker_off
PARAMS ((ticker_t
*));
270 static void ticker_on
PARAMS ((ticker_t
*));
271 static int active_time
PARAMS ((ticker_t
));
272 static void print_active_time
PARAMS ((FILE *, ticker_t
));
274 static void add_advance_cycle_insn_decl
PARAMS ((void));
276 static alt_state_t get_free_alt_state
PARAMS ((void));
277 static void free_alt_state
PARAMS ((alt_state_t
));
278 static void free_alt_states
PARAMS ((alt_state_t
));
279 static int alt_state_cmp
PARAMS ((const void *alt_state_ptr_1
,
280 const void *alt_state_ptr_2
));
281 static alt_state_t uniq_sort_alt_states
PARAMS ((alt_state_t
));
282 static int alt_states_eq
PARAMS ((alt_state_t
, alt_state_t
));
283 static void initiate_alt_states
PARAMS ((void));
284 static void finish_alt_states
PARAMS ((void));
286 static reserv_sets_t alloc_empty_reserv_sets
PARAMS ((void));
287 static unsigned reserv_sets_hash_value
PARAMS ((reserv_sets_t
));
288 static int reserv_sets_cmp
PARAMS ((reserv_sets_t
, reserv_sets_t
));
289 static int reserv_sets_eq
PARAMS ((reserv_sets_t
, reserv_sets_t
));
290 static void set_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
291 static int test_unit_reserv
PARAMS ((reserv_sets_t
, int, int));
292 static int it_is_empty_reserv_sets
PARAMS ((reserv_sets_t
))
294 static int reserv_sets_are_intersected
PARAMS ((reserv_sets_t
, reserv_sets_t
));
295 static void reserv_sets_shift
PARAMS ((reserv_sets_t
, reserv_sets_t
));
296 static void reserv_sets_or
PARAMS ((reserv_sets_t
, reserv_sets_t
,
298 static void reserv_sets_and
PARAMS ((reserv_sets_t
, reserv_sets_t
,
301 static void output_cycle_reservs
PARAMS ((FILE *, reserv_sets_t
,
303 static void output_reserv_sets
PARAMS ((FILE *, reserv_sets_t
));
304 static state_t get_free_state
PARAMS ((int, automaton_t
));
305 static void free_state
PARAMS ((state_t
));
306 static unsigned state_hash
PARAMS ((const void *));
307 static int state_eq_p
PARAMS ((const void *, const void *));
308 static state_t insert_state
PARAMS ((state_t
));
309 static void set_state_reserv
PARAMS ((state_t
, int, int));
310 static int intersected_state_reservs_p
PARAMS ((state_t
, state_t
));
311 static state_t states_union
PARAMS ((state_t
, state_t
));
312 static state_t state_shift
PARAMS ((state_t
));
313 static void initiate_states
PARAMS ((void));
314 static void finish_states
PARAMS ((void));
316 static void free_arc
PARAMS ((arc_t
));
317 static void remove_arc
PARAMS ((state_t
, arc_t
));
318 static arc_t find_arc
PARAMS ((state_t
, state_t
, ainsn_t
));
319 static arc_t add_arc
PARAMS ((state_t
, state_t
, ainsn_t
, int));
320 static arc_t first_out_arc
PARAMS ((state_t
));
321 static arc_t next_out_arc
PARAMS ((arc_t
));
322 static void initiate_arcs
PARAMS ((void));
323 static void finish_arcs
PARAMS ((void));
325 static automata_list_el_t get_free_automata_list_el
PARAMS ((void));
326 static void free_automata_list_el
PARAMS ((automata_list_el_t
));
327 static void free_automata_list
PARAMS ((automata_list_el_t
));
328 static unsigned automata_list_hash
PARAMS ((const void *));
329 static int automata_list_eq_p
PARAMS ((const void *, const void *));
330 static void initiate_automata_lists
PARAMS ((void));
331 static void automata_list_start
PARAMS ((void));
332 static void automata_list_add
PARAMS ((automaton_t
));
333 static automata_list_el_t automata_list_finish
PARAMS ((void));
334 static void finish_automata_lists
PARAMS ((void));
336 static void initiate_excl_sets
PARAMS ((void));
337 static reserv_sets_t get_excl_set
PARAMS ((reserv_sets_t
));
339 static void initiate_presence_absence_sets
PARAMS ((void));
340 static reserv_sets_t get_presence_absence_set
PARAMS ((reserv_sets_t
, int));
342 static regexp_t copy_insn_regexp
PARAMS ((regexp_t
));
343 static regexp_t transform_1
PARAMS ((regexp_t
));
344 static regexp_t transform_2
PARAMS ((regexp_t
));
345 static regexp_t transform_3
PARAMS ((regexp_t
));
346 static regexp_t regexp_transform_func
347 PARAMS ((regexp_t
, regexp_t (*) (regexp_t
)));
348 static regexp_t transform_regexp
PARAMS ((regexp_t
));
349 static void transform_insn_regexps
PARAMS ((void));
351 static void process_unit_to_form_the_same_automaton_unit_lists
352 PARAMS ((regexp_t
, regexp_t
, int));
353 static void form_the_same_automaton_unit_lists_from_regexp
PARAMS ((regexp_t
));
354 static void form_the_same_automaton_unit_lists
PARAMS ((void));
355 static void check_unit_distributions_to_automata
PARAMS ((void));
357 static int process_seq_for_forming_states
PARAMS ((regexp_t
, automaton_t
,
359 static void finish_forming_alt_state
PARAMS ((alt_state_t
,
361 static void process_alts_for_forming_states
PARAMS ((regexp_t
,
363 static void create_alt_states
PARAMS ((automaton_t
));
365 static void form_ainsn_with_same_reservs
PARAMS ((automaton_t
));
367 static void make_automaton
PARAMS ((automaton_t
));
368 static void form_arcs_marked_by_insn
PARAMS ((state_t
));
369 static void create_composed_state
PARAMS ((state_t
, arc_t
, vla_ptr_t
*));
370 static void NDFA_to_DFA
PARAMS ((automaton_t
));
371 static void pass_state_graph
PARAMS ((state_t
, void (*) (state_t
)));
372 static void pass_states
PARAMS ((automaton_t
,
373 void (*) (state_t
)));
374 static void initiate_pass_states
PARAMS ((void));
375 static void add_achieved_state
PARAMS ((state_t
));
376 static int set_out_arc_insns_equiv_num
PARAMS ((state_t
, int));
377 static void clear_arc_insns_equiv_num
PARAMS ((state_t
));
378 static void copy_equiv_class
PARAMS ((vla_ptr_t
*to
,
379 const vla_ptr_t
*from
));
380 static int state_is_differed
PARAMS ((state_t
, int, int));
381 static state_t init_equiv_class
PARAMS ((state_t
*states
, int));
382 static int partition_equiv_class
PARAMS ((state_t
*, int,
383 vla_ptr_t
*, int *));
384 static void evaluate_equiv_classes
PARAMS ((automaton_t
, vla_ptr_t
*));
385 static void merge_states
PARAMS ((automaton_t
, vla_ptr_t
*));
386 static void set_new_cycle_flags
PARAMS ((state_t
));
387 static void minimize_DFA
PARAMS ((automaton_t
));
388 static void incr_states_and_arcs_nums
PARAMS ((state_t
));
389 static void count_states_and_arcs
PARAMS ((automaton_t
, int *, int *));
390 static void build_automaton
PARAMS ((automaton_t
));
392 static void set_order_state_num
PARAMS ((state_t
));
393 static void enumerate_states
PARAMS ((automaton_t
));
395 static ainsn_t insert_ainsn_into_equiv_class
PARAMS ((ainsn_t
, ainsn_t
));
396 static void delete_ainsn_from_equiv_class
PARAMS ((ainsn_t
));
397 static void process_insn_equiv_class
PARAMS ((ainsn_t
, arc_t
*));
398 static void process_state_for_insn_equiv_partition
PARAMS ((state_t
));
399 static void set_insn_equiv_classes
PARAMS ((automaton_t
));
401 static double estimate_one_automaton_bound
PARAMS ((void));
402 static int compare_max_occ_cycle_nums
PARAMS ((const void *,
404 static void units_to_automata_heuristic_distr
PARAMS ((void));
405 static ainsn_t create_ainsns
PARAMS ((void));
406 static void units_to_automata_distr
PARAMS ((void));
407 static void create_automata
PARAMS ((void));
409 static void form_regexp
PARAMS ((regexp_t
));
410 static const char *regexp_representation
PARAMS ((regexp_t
));
411 static void finish_regexp_representation
PARAMS ((void));
413 static void output_range_type
PARAMS ((FILE *, long int, long int));
414 static int longest_path_length
PARAMS ((state_t
));
415 static void process_state_longest_path_length
PARAMS ((state_t
));
416 static void output_dfa_max_issue_rate
PARAMS ((void));
417 static void output_vect
PARAMS ((vect_el_t
*, int));
418 static void output_chip_member_name
PARAMS ((FILE *, automaton_t
));
419 static void output_temp_chip_member_name
PARAMS ((FILE *, automaton_t
));
420 static void output_translate_vect_name
PARAMS ((FILE *, automaton_t
));
421 static void output_trans_full_vect_name
PARAMS ((FILE *, automaton_t
));
422 static void output_trans_comb_vect_name
PARAMS ((FILE *, automaton_t
));
423 static void output_trans_check_vect_name
PARAMS ((FILE *, automaton_t
));
424 static void output_trans_base_vect_name
PARAMS ((FILE *, automaton_t
));
425 static void output_state_alts_full_vect_name
PARAMS ((FILE *, automaton_t
));
426 static void output_state_alts_comb_vect_name
PARAMS ((FILE *, automaton_t
));
427 static void output_state_alts_check_vect_name
PARAMS ((FILE *, automaton_t
));
428 static void output_state_alts_base_vect_name
PARAMS ((FILE *, automaton_t
));
429 static void output_min_issue_delay_vect_name
PARAMS ((FILE *, automaton_t
));
430 static void output_dead_lock_vect_name
PARAMS ((FILE *, automaton_t
));
431 static void output_reserved_units_table_name
PARAMS ((FILE *, automaton_t
));
432 static void output_state_member_type
PARAMS ((FILE *, automaton_t
));
433 static void output_chip_definitions
PARAMS ((void));
434 static void output_translate_vect
PARAMS ((automaton_t
));
435 static int comb_vect_p
PARAMS ((state_ainsn_table_t
));
436 static state_ainsn_table_t create_state_ainsn_table
PARAMS ((automaton_t
));
437 static void output_state_ainsn_table
438 PARAMS ((state_ainsn_table_t
, char *, void (*) (FILE *, automaton_t
),
439 void (*) (FILE *, automaton_t
), void (*) (FILE *, automaton_t
),
440 void (*) (FILE *, automaton_t
)));
441 static void add_vect
PARAMS ((state_ainsn_table_t
,
442 int, vect_el_t
*, int));
443 static int out_state_arcs_num
PARAMS ((state_t
));
444 static int compare_transition_els_num
PARAMS ((const void *, const void *));
445 static void add_vect_el
PARAMS ((vla_hwint_t
*,
447 static void add_states_vect_el
PARAMS ((state_t
));
448 static void output_trans_table
PARAMS ((automaton_t
));
449 static void output_state_alts_table
PARAMS ((automaton_t
));
450 static int min_issue_delay_pass_states
PARAMS ((state_t
, ainsn_t
));
451 static int min_issue_delay
PARAMS ((state_t
, ainsn_t
));
452 static void initiate_min_issue_delay_pass_states
PARAMS ((void));
453 static void output_min_issue_delay_table
PARAMS ((automaton_t
));
454 static void output_dead_lock_vect
PARAMS ((automaton_t
));
455 static void output_reserved_units_table
PARAMS ((automaton_t
));
456 static void output_tables
PARAMS ((void));
457 static void output_max_insn_queue_index_def
PARAMS ((void));
458 static void output_insn_code_cases
PARAMS ((void (*) (automata_list_el_t
)));
459 static void output_automata_list_min_issue_delay_code
PARAMS ((automata_list_el_t
));
460 static void output_internal_min_issue_delay_func
PARAMS ((void));
461 static void output_automata_list_transition_code
PARAMS ((automata_list_el_t
));
462 static void output_internal_trans_func
PARAMS ((void));
463 static void output_internal_insn_code_evaluation
PARAMS ((const char *,
465 static void output_dfa_insn_code_func
PARAMS ((void));
466 static void output_trans_func
PARAMS ((void));
467 static void output_automata_list_state_alts_code
PARAMS ((automata_list_el_t
));
468 static void output_internal_state_alts_func
PARAMS ((void));
469 static void output_state_alts_func
PARAMS ((void));
470 static void output_min_issue_delay_func
PARAMS ((void));
471 static void output_internal_dead_lock_func
PARAMS ((void));
472 static void output_dead_lock_func
PARAMS ((void));
473 static void output_internal_reset_func
PARAMS ((void));
474 static void output_size_func
PARAMS ((void));
475 static void output_reset_func
PARAMS ((void));
476 static void output_min_insn_conflict_delay_func
PARAMS ((void));
477 static void output_internal_insn_latency_func
PARAMS ((void));
478 static void output_insn_latency_func
PARAMS ((void));
479 static void output_print_reservation_func
PARAMS ((void));
480 static int units_cmp
PARAMS ((const void *,
482 static void output_get_cpu_unit_code_func
PARAMS ((void));
483 static void output_cpu_unit_reservation_p
PARAMS ((void));
484 static void output_dfa_start_func
PARAMS ((void));
485 static void output_dfa_finish_func
PARAMS ((void));
487 static void output_regexp
PARAMS ((regexp_t
));
488 static void output_unit_set_el_list
PARAMS ((unit_set_el_t
));
489 static void output_description
PARAMS ((void));
490 static void output_automaton_name
PARAMS ((FILE *, automaton_t
));
491 static void output_automaton_units
PARAMS ((automaton_t
));
492 static void add_state_reservs
PARAMS ((state_t
));
493 static void output_state_arcs
PARAMS ((state_t
));
494 static int state_reservs_cmp
PARAMS ((const void *,
496 static void remove_state_duplicate_reservs
PARAMS ((void));
497 static void output_state
PARAMS ((state_t
));
498 static void output_automaton_descriptions
PARAMS ((void));
499 static void output_statistics
PARAMS ((FILE *));
500 static void output_time_statistics
PARAMS ((FILE *));
501 static void generate
PARAMS ((void));
503 static void make_insn_alts_attr
PARAMS ((void));
504 static void make_internal_dfa_insn_code_attr
PARAMS ((void));
505 static void make_default_insn_latency_attr
PARAMS ((void));
506 static void make_bypass_attr
PARAMS ((void));
507 static const char *file_name_suffix
PARAMS ((const char *));
508 static const char *base_file_name
PARAMS ((const char *));
509 static void check_automata_insn_issues
PARAMS ((void));
510 static void add_automaton_state
PARAMS ((state_t
));
511 static void form_important_insn_automata_lists
PARAMS ((void));
513 /* Undefined position. */
514 static pos_t no_pos
= 0;
516 /* All IR is stored in the following obstack. */
517 static struct obstack irp
;
521 /* This page contains code for work with variable length array (vla)
522 of pointers. We could be use only varray. But we add new lay
523 because we add elements very frequently and this could stress OS
524 allocator when varray is used only. */
526 /* Start work with vla. */
527 #define VLA_PTR_CREATE(vla, allocated_length, name) \
530 vla_ptr_t *const vla_ptr = &(vla); \
532 VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
533 vla_ptr->length = 0; \
537 /* Finish work with the vla. */
538 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
540 /* Return start address of the vla. */
541 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
543 /* Address of the last element of the vla. Do not use side effects in
544 the macro argument. */
545 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
547 /* Nullify the vla. */
548 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
550 /* Shorten the vla on given number bytes. */
551 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
553 /* Expand the vla on N elements. The values of new elements are
555 #define VLA_PTR_EXPAND(vla, n) \
557 vla_ptr_t *const expand_vla_ptr = &(vla); \
558 const size_t new_length = (n) + expand_vla_ptr->length; \
560 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
561 VARRAY_GROW (expand_vla_ptr->varray, \
562 (new_length - expand_vla_ptr->length < 128 \
563 ? expand_vla_ptr->length + 128 : new_length)); \
564 expand_vla_ptr->length = new_length; \
567 /* Add element to the end of the vla. */
568 #define VLA_PTR_ADD(vla, ptr) \
570 vla_ptr_t *const vla_ptr = &(vla); \
572 VLA_PTR_EXPAND (*vla_ptr, 1); \
573 VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
576 /* Length of the vla in elements. */
577 #define VLA_PTR_LENGTH(vla) ((vla).length)
579 /* N-th element of the vla. */
580 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
583 /* The following macros are analogous to the previous ones but for
584 VLAs of HOST WIDE INTs. */
586 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
588 vla_hwint_t *const vla_ptr = &(vla); \
590 VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
591 vla_ptr->length = 0; \
594 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
596 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
598 /* Do not use side effects in the macro argument. */
599 #define VLA_HWINT_LAST(vla) (&VARRAY_WIDE_INT ((vla).varray, \
602 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
604 #define VLA_HWINT_SHORTEN(vla, n) ((vla).length -= (n))
606 #define VLA_HWINT_EXPAND(vla, n) \
608 vla_hwint_t *const expand_vla_ptr = &(vla); \
609 const size_t new_length = (n) + expand_vla_ptr->length; \
611 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
612 VARRAY_GROW (expand_vla_ptr->varray, \
613 (new_length - expand_vla_ptr->length < 128 \
614 ? expand_vla_ptr->length + 128 : new_length)); \
615 expand_vla_ptr->length = new_length; \
618 #define VLA_HWINT_ADD(vla, ptr) \
620 vla_hwint_t *const vla_ptr = &(vla); \
622 VLA_HWINT_EXPAND (*vla_ptr, 1); \
623 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
626 #define VLA_HWINT_LENGTH(vla) ((vla).length)
628 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
632 /* Options with the following names can be set up in automata_option
633 construction. Because the strings occur more one time we use the
636 #define NO_MINIMIZATION_OPTION "-no-minimization"
638 #define TIME_OPTION "-time"
640 #define V_OPTION "-v"
642 #define W_OPTION "-w"
644 #define NDFA_OPTION "-ndfa"
646 /* The following flags are set up by function `initiate_automaton_gen'. */
648 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
649 static int ndfa_flag
;
651 /* Do not make minimization of DFA (`-no-minimization'). */
652 static int no_minimization_flag
;
654 /* Value of this variable is number of automata being generated. The
655 actual number of automata may be less this value if there is not
656 sufficient number of units. This value is defined by argument of
657 option `-split' or by constructions automaton if the value is zero
658 (it is default value of the argument). */
659 static int split_argument
;
661 /* Flag of output time statistics (`-time'). */
662 static int time_flag
;
664 /* Flag of creation of description file which contains description of
665 result automaton and statistics information (`-v'). */
668 /* Flag of generating warning instead of error for non-critical errors
673 /* Output file for pipeline hazard recognizer (PHR) being generated.
674 The value is NULL if the file is not defined. */
675 static FILE *output_file
;
677 /* Description file of PHR. The value is NULL if the file is not
679 static FILE *output_description_file
;
681 /* PHR description file name. */
682 static char *output_description_file_name
;
684 /* Value of the following variable is node representing description
685 being processed. This is start point of IR. */
686 static struct description
*description
;
690 /* This page contains description of IR structure (nodes). */
704 /* This describes define_cpu_unit and define_query_cpu_unit (see file
709 /* NULL if the automaton name is absent. */
710 char *automaton_name
;
711 /* If the following value is not zero, the cpu unit reservation is
712 described in define_query_cpu_unit. */
715 /* The following fields are defined by checker. */
717 /* The following field value is nonzero if the unit is used in an
721 /* The following field value is used to form cyclic lists of units
722 which should be in the same automaton because the unit is
723 reserved not on all alternatives of a regexp on a cycle. */
724 unit_decl_t the_same_automaton_unit
;
725 /* The following field is TRUE if we already reported that the unit
726 is not in the same automaton. */
727 int the_same_automaton_message_reported_p
;
729 /* The following field value is order number (0, 1, ...) of given
732 /* The following field value is corresponding declaration of
733 automaton which was given in description. If the field value is
734 NULL then automaton in the unit declaration was absent. */
735 struct automaton_decl
*automaton_decl
;
736 /* The following field value is maximal cycle number (1, ...) on
737 which given unit occurs in insns. Zero value means that given
738 unit is not used in insns. */
739 int max_occ_cycle_num
;
740 /* The following list contains units which conflict with given
742 unit_set_el_t excl_list
;
743 /* The following list contains units which are required to
744 reservation of given unit. */
745 unit_set_el_t presence_list
;
746 /* The following list contains units which should be not present in
747 reservation for given unit. */
748 unit_set_el_t absence_list
;
749 /* The following is used only when `query_p' has nonzero value.
750 This is query number for the unit. */
753 /* The following fields are defined by automaton generator. */
755 /* The following field value is number of the automaton to which
756 given unit belongs. */
757 int corresponding_automaton_num
;
760 /* This describes define_bypass (see file rtl.def). */
766 char *bypass_guard_name
;
768 /* The following fields are defined by checker. */
770 /* output and input insns of given bypass. */
771 struct insn_reserv_decl
*out_insn_reserv
;
772 struct insn_reserv_decl
*in_insn_reserv
;
773 /* The next bypass for given output insn. */
774 struct bypass_decl
*next
;
777 /* This describes define_automaton (see file rtl.def). */
778 struct automaton_decl
782 /* The following fields are defined by automaton generator. */
784 /* The following field value is nonzero if the automaton is used in
785 an regexp definition. */
786 char automaton_is_used
;
788 /* The following fields are defined by checker. */
790 /* The following field value is the corresponding automaton. This
791 field is not NULL only if the automaton is present in unit
792 declarations and the automatic partition on automata is not
794 automaton_t corresponding_automaton
;
797 /* This describes unit relations: exclusion_set, presence_set, or
798 absence_set (see file rtl.def). */
802 int first_list_length
;
806 /* This describes define_reservation (see file rtl.def). */
812 /* The following fields are defined by checker. */
814 /* The following field value is nonzero if the unit is used in an
817 /* The following field is used to check up cycle in expression
822 /* This describes define_insn_reservartion (see file rtl.def). */
823 struct insn_reserv_decl
830 /* The following fields are defined by checker. */
832 /* The following field value is order number (0, 1, ...) of given
835 /* The following field value is list of bypasses in which given insn
837 struct bypass_decl
*bypass_list
;
839 /* The following fields are defined by automaton generator. */
841 /* The following field is the insn regexp transformed that
842 the regexp has not optional regexp, repetition regexp, and an
843 reservation name (i.e. reservation identifiers are changed by the
844 corresponding regexp) and all alternations are the topest level
845 of the regexp. The value can be NULL only if it is special
846 insn `cycle advancing'. */
847 regexp_t transformed_regexp
;
848 /* The following field value is list of arcs marked given
849 insn. The field is used in transfromation NDFA -> DFA. */
850 arc_t arcs_marked_by_insn
;
851 /* The two following fields are used during minimization of a finite state
853 /* The field value is number of equivalence class of state into
854 which arc marked by given insn enters from a state (fixed during
855 an automaton minimization). */
857 /* The field value is state_alts of arc leaving a state (fixed
858 during an automaton minimization) and marked by given insn
861 /* The following member value is the list to automata which can be
862 changed by the insn issue. */
863 automata_list_el_t important_automata_list
;
864 /* The following member is used to process insn once for output. */
868 /* This contains a declaration mentioned above. */
871 /* What node in the union? */
876 struct unit_decl unit
;
877 struct bypass_decl bypass
;
878 struct automaton_decl automaton
;
879 struct unit_rel_decl excl
;
880 struct unit_rel_decl presence
;
881 struct unit_rel_decl absence
;
882 struct reserv_decl reserv
;
883 struct insn_reserv_decl insn_reserv
;
887 /* The following structures represent parsed reservation strings. */
899 /* Cpu unit in reservation. */
903 unit_decl_t unit_decl
;
906 /* Define_reservation in a reservation. */
910 struct reserv_decl
*reserv_decl
;
913 /* Absence of reservation (represented by string `nothing'). */
914 struct nothing_regexp
916 /* This used to be empty but ISO C doesn't allow that. */
920 /* Representation of reservations separated by ',' (see file
922 struct sequence_regexp
925 regexp_t regexps
[1];
928 /* Representation of construction `repeat' (see file rtl.def). */
935 /* Representation of reservations separated by '+' (see file
940 regexp_t regexps
[1];
943 /* Representation of reservations separated by '|' (see file
948 regexp_t regexps
[1];
951 /* Representation of a reservation string. */
954 /* What node in the union? */
955 enum regexp_mode mode
;
959 struct unit_regexp unit
;
960 struct reserv_regexp reserv
;
961 struct nothing_regexp nothing
;
962 struct sequence_regexp sequence
;
963 struct repeat_regexp repeat
;
964 struct allof_regexp allof
;
965 struct oneof_regexp oneof
;
969 /* Reperesents description of pipeline hazard description based on
975 /* The following fields are defined by checker. */
977 /* The following fields values are correspondingly number of all
978 units, query units, and insns in the description. */
982 /* The following field value is max length (in cycles) of
983 reservations of insns. The field value is defined only for
985 int max_insn_reserv_cycles
;
987 /* The following fields are defined by automaton generator. */
989 /* The following field value is the first automaton. */
990 automaton_t first_automaton
;
992 /* The following field is created by pipeline hazard parser and
993 contains all declarations. We allocate additional entry for
994 special insn "cycle advancing" which is added by the automaton
1001 /* The following nodes are created in automaton checker. */
1003 /* The following nodes represent exclusion, presence, absence set for
1004 cpu units. Each element are accessed through only one excl_list,
1005 presence_list, absence_list. */
1008 unit_decl_t unit_decl
;
1009 unit_set_el_t next_unit_set_el
;
1014 /* The following nodes are created in automaton generator. */
1016 /* The following node type describes state automaton. The state may
1017 be deterministic or non-deterministic. Non-deterministic state has
1018 several component states which represent alternative cpu units
1019 reservations. The state also is used for describing a
1020 deterministic reservation of automaton insn. */
1023 /* The following member value is nonzero if there is a transition by
1026 /* The following field is list of processor unit reservations on
1028 reserv_sets_t reservs
;
1029 /* The following field is unique number of given state between other
1032 /* The following field value is automaton to which given state
1034 automaton_t automaton
;
1035 /* The following field value is the first arc output from given
1037 arc_t first_out_arc
;
1038 /* The following field is used to form NDFA. */
1039 char it_was_placed_in_stack_for_NDFA_forming
;
1040 /* The following field is used to form DFA. */
1041 char it_was_placed_in_stack_for_DFA_forming
;
1042 /* The following field is used to transform NDFA to DFA. The field
1043 value is not NULL if the state is a compound state. In this case
1044 the value of field `unit_sets_list' is NULL. All states in the
1045 list are in the hash table. The list is formed through field
1046 `next_sorted_alt_state'. */
1047 alt_state_t component_states
;
1048 /* The following field is used for passing graph of states. */
1050 /* The list of states belonging to one equivalence class is formed
1051 with the aid of the following field. */
1052 state_t next_equiv_class_state
;
1053 /* The two following fields are used during minimization of a finite
1055 int equiv_class_num_1
, equiv_class_num_2
;
1056 /* The following field is used during minimization of a finite state
1057 automaton. The field value is state corresponding to equivalence
1058 class to which given state belongs. */
1059 state_t equiv_class_state
;
1060 /* The following field value is the order number of given state.
1061 The states in final DFA is enumerated with the aid of the
1063 int order_state_num
;
1064 /* This member is used for passing states for searching minimal
1067 /* The following member is used to evaluate min issue delay of insn
1069 int min_insn_issue_delay
;
1070 /* The following member is used to evaluate max issue rate of the
1071 processor. The value of the member is maximal length of the path
1072 from given state no containing arcs marked by special insn `cycle
1074 int longest_path_length
;
1077 /* The following macro is an initial value of member
1078 `longest_path_length' of a state. */
1079 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1081 /* Automaton arc. */
1084 /* The following field refers for the state into which given arc
1087 /* The following field describes that the insn issue (with cycle
1088 advancing for special insn `cycle advancing' and without cycle
1089 advancing for others) makes transition from given state to
1090 another given state. */
1092 /* The following field value is the next arc output from the same
1095 /* List of arcs marked given insn is formed with the following
1096 field. The field is used in transfromation NDFA -> DFA. */
1097 arc_t next_arc_marked_by_insn
;
1098 /* The following field is defined if NDFA_FLAG is zero. The member
1099 value is number of alternative reservations which can be used for
1100 transition for given state by given insn. */
1104 /* The following node type describes a deterministic alternative in
1105 non-deterministic state which characterizes cpu unit reservations
1106 of automaton insn or which is part of NDFA. */
1109 /* The following field is a determinist state which characterizes
1110 unit reservations of the instruction. */
1112 /* The following field refers to the next state which characterizes
1113 unit reservations of the instruction. */
1114 alt_state_t next_alt_state
;
1115 /* The following field refers to the next state in sorted list. */
1116 alt_state_t next_sorted_alt_state
;
1119 /* The following node type describes insn of automaton. They are
1120 labels of FA arcs. */
1123 /* The following field value is the corresponding insn declaration
1125 struct insn_reserv_decl
*insn_reserv_decl
;
1126 /* The following field value is the next insn declaration for an
1129 /* The following field is states which characterize automaton unit
1130 reservations of the instruction. The value can be NULL only if it
1131 is special insn `cycle advancing'. */
1132 alt_state_t alt_states
;
1133 /* The following field is sorted list of states which characterize
1134 automaton unit reservations of the instruction. The value can be
1135 NULL only if it is special insn `cycle advancing'. */
1136 alt_state_t sorted_alt_states
;
1137 /* The following field refers the next automaton insn with
1138 the same reservations. */
1139 ainsn_t next_same_reservs_insn
;
1140 /* The following field is flag of the first automaton insn with the
1141 same reservations in the declaration list. Only arcs marked such
1142 insn is present in the automaton. This significantly decreases
1143 memory requirements especially when several automata are
1145 char first_insn_with_same_reservs
;
1146 /* The following member has nonzero value if there is arc from state of
1147 the automaton marked by the ainsn. */
1149 /* Cyclic list of insns of an equivalence class is formed with the
1150 aid of the following field. */
1151 ainsn_t next_equiv_class_insn
;
1152 /* The following field value is nonzero if the insn declaration is
1153 the first insn declaration with given equivalence number. */
1154 char first_ainsn_with_given_equialence_num
;
1155 /* The following field is number of class of equivalence of insns.
1156 It is necessary because many insns may be equivalent with the
1157 point of view of pipeline hazards. */
1158 int insn_equiv_class_num
;
1159 /* The following member value is TRUE if there is an arc in the
1160 automaton marked by the insn into another state. In other
1161 words, the insn can change the state of the automaton. */
1165 /* The folowing describes an automaton for PHR. */
1168 /* The following field value is the list of insn declarations for
1171 /* The following field value is the corresponding automaton
1172 declaration. This field is not NULL only if the automatic
1173 partition on automata is not used. */
1174 struct automaton_decl
*corresponding_automaton_decl
;
1175 /* The following field value is the next automaton. */
1176 automaton_t next_automaton
;
1177 /* The following field is start state of FA. There are not unit
1178 reservations in the state. */
1179 state_t start_state
;
1180 /* The following field value is number of equivalence classes of
1181 insns (see field `insn_equiv_class_num' in
1182 `insn_reserv_decl'). */
1183 int insn_equiv_classes_num
;
1184 /* The following field value is number of states of final DFA. */
1185 int achieved_states_num
;
1186 /* The following field value is the order number (0, 1, ...) of
1188 int automaton_order_num
;
1189 /* The following fields contain statistics information about
1190 building automaton. */
1191 int NDFA_states_num
, DFA_states_num
;
1192 /* The following field value is defined only if minimization of DFA
1194 int minimal_DFA_states_num
;
1195 int NDFA_arcs_num
, DFA_arcs_num
;
1196 /* The following field value is defined only if minimization of DFA
1198 int minimal_DFA_arcs_num
;
1199 /* The following two members refer for two table state x ainsn ->
1201 state_ainsn_table_t trans_table
;
1202 state_ainsn_table_t state_alts_table
;
1203 /* The following member value is maximal value of min issue delay
1204 for insns of the automaton. */
1206 /* Usually min issue delay is small and we can place several (2, 4,
1207 8) elements in one vector element. So the compression factor can
1208 be 1 (no compression), 2, 4, 8. */
1209 int min_issue_delay_table_compression_factor
;
1212 /* The following is the element of the list of automata. */
1213 struct automata_list_el
1215 /* The automaton itself. */
1216 automaton_t automaton
;
1217 /* The next automata set element. */
1218 automata_list_el_t next_automata_list_el
;
1221 /* The following structure describes a table state X ainsn -> int(>= 0). */
1222 struct state_ainsn_table
1224 /* Automaton to which given table belongs. */
1225 automaton_t automaton
;
1226 /* The following tree vectors for comb vector implementation of the
1228 vla_hwint_t comb_vect
;
1229 vla_hwint_t check_vect
;
1230 vla_hwint_t base_vect
;
1231 /* This is simple implementation of the table. */
1232 vla_hwint_t full_vect
;
1233 /* Minimal and maximal values of the previous vectors. */
1234 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1235 int min_base_vect_el_value
, max_base_vect_el_value
;
1238 /* Macros to access members of unions. Use only them for access to
1239 union members of declarations and regexps. */
1241 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1243 #define DECL_UNIT(d) __extension__ \
1244 (({ struct decl *const _decl = (d); \
1245 if (_decl->mode != dm_unit) \
1246 decl_mode_check_failed (_decl->mode, "dm_unit", \
1247 __FILE__, __LINE__, __FUNCTION__); \
1248 &(_decl)->decl.unit; }))
1250 #define DECL_BYPASS(d) __extension__ \
1251 (({ struct decl *const _decl = (d); \
1252 if (_decl->mode != dm_bypass) \
1253 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1254 __FILE__, __LINE__, __FUNCTION__); \
1255 &(_decl)->decl.bypass; }))
1257 #define DECL_AUTOMATON(d) __extension__ \
1258 (({ struct decl *const _decl = (d); \
1259 if (_decl->mode != dm_automaton) \
1260 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1261 __FILE__, __LINE__, __FUNCTION__); \
1262 &(_decl)->decl.automaton; }))
1264 #define DECL_EXCL(d) __extension__ \
1265 (({ struct decl *const _decl = (d); \
1266 if (_decl->mode != dm_excl) \
1267 decl_mode_check_failed (_decl->mode, "dm_excl", \
1268 __FILE__, __LINE__, __FUNCTION__); \
1269 &(_decl)->decl.excl; }))
1271 #define DECL_PRESENCE(d) __extension__ \
1272 (({ struct decl *const _decl = (d); \
1273 if (_decl->mode != dm_presence) \
1274 decl_mode_check_failed (_decl->mode, "dm_presence", \
1275 __FILE__, __LINE__, __FUNCTION__); \
1276 &(_decl)->decl.presence; }))
1278 #define DECL_ABSENCE(d) __extension__ \
1279 (({ struct decl *const _decl = (d); \
1280 if (_decl->mode != dm_absence) \
1281 decl_mode_check_failed (_decl->mode, "dm_absence", \
1282 __FILE__, __LINE__, __FUNCTION__); \
1283 &(_decl)->decl.absence; }))
1285 #define DECL_RESERV(d) __extension__ \
1286 (({ struct decl *const _decl = (d); \
1287 if (_decl->mode != dm_reserv) \
1288 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1289 __FILE__, __LINE__, __FUNCTION__); \
1290 &(_decl)->decl.reserv; }))
1292 #define DECL_INSN_RESERV(d) __extension__ \
1293 (({ struct decl *const _decl = (d); \
1294 if (_decl->mode != dm_insn_reserv) \
1295 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1296 __FILE__, __LINE__, __FUNCTION__); \
1297 &(_decl)->decl.insn_reserv; }))
1299 static const char *decl_name
PARAMS ((enum decl_mode
));
1300 static void decl_mode_check_failed
PARAMS ((enum decl_mode
, const char *,
1301 const char *, int, const char *));
1303 /* Return string representation of declaration mode MODE. */
1306 enum decl_mode mode
;
1308 static char str
[100];
1310 if (mode
== dm_unit
)
1312 else if (mode
== dm_bypass
)
1314 else if (mode
== dm_automaton
)
1315 return "dm_automaton";
1316 else if (mode
== dm_excl
)
1318 else if (mode
== dm_presence
)
1319 return "dm_presence";
1320 else if (mode
== dm_absence
)
1321 return "dm_absence";
1322 else if (mode
== dm_reserv
)
1324 else if (mode
== dm_insn_reserv
)
1325 return "dm_insn_reserv";
1327 sprintf (str
, "unknown (%d)", (int) mode
);
1331 /* The function prints message about unexpected declaration and finish
1334 decl_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1335 enum decl_mode mode
;
1336 const char *expected_mode_str
;
1343 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1344 file
, line
, func
, expected_mode_str
, decl_name (mode
));
1349 #define REGEXP_UNIT(r) __extension__ \
1350 (({ struct regexp *const _regexp = (r); \
1351 if (_regexp->mode != rm_unit) \
1352 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1353 __FILE__, __LINE__, __FUNCTION__); \
1354 &(_regexp)->regexp.unit; }))
1356 #define REGEXP_RESERV(r) __extension__ \
1357 (({ struct regexp *const _regexp = (r); \
1358 if (_regexp->mode != rm_reserv) \
1359 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1360 __FILE__, __LINE__, __FUNCTION__); \
1361 &(_regexp)->regexp.reserv; }))
1363 #define REGEXP_SEQUENCE(r) __extension__ \
1364 (({ struct regexp *const _regexp = (r); \
1365 if (_regexp->mode != rm_sequence) \
1366 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1367 __FILE__, __LINE__, __FUNCTION__); \
1368 &(_regexp)->regexp.sequence; }))
1370 #define REGEXP_REPEAT(r) __extension__ \
1371 (({ struct regexp *const _regexp = (r); \
1372 if (_regexp->mode != rm_repeat) \
1373 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1374 __FILE__, __LINE__, __FUNCTION__); \
1375 &(_regexp)->regexp.repeat; }))
1377 #define REGEXP_ALLOF(r) __extension__ \
1378 (({ struct regexp *const _regexp = (r); \
1379 if (_regexp->mode != rm_allof) \
1380 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1381 __FILE__, __LINE__, __FUNCTION__); \
1382 &(_regexp)->regexp.allof; }))
1384 #define REGEXP_ONEOF(r) __extension__ \
1385 (({ struct regexp *const _regexp = (r); \
1386 if (_regexp->mode != rm_oneof) \
1387 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1388 __FILE__, __LINE__, __FUNCTION__); \
1389 &(_regexp)->regexp.oneof; }))
1391 static const char *regexp_name
PARAMS ((enum regexp_mode
));
1392 static void regexp_mode_check_failed
PARAMS ((enum regexp_mode
, const char *,
1397 /* Return string representation of regexp mode MODE. */
1400 enum regexp_mode mode
;
1402 static char str
[100];
1404 if (mode
== rm_unit
)
1406 else if (mode
== rm_reserv
)
1408 else if (mode
== rm_nothing
)
1409 return "rm_nothing";
1410 else if (mode
== rm_sequence
)
1411 return "rm_sequence";
1412 else if (mode
== rm_repeat
)
1414 else if (mode
== rm_allof
)
1416 else if (mode
== rm_oneof
)
1419 sprintf (str
, "unknown (%d)", (int) mode
);
1423 /* The function prints message about unexpected regexp and finish the
1426 regexp_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1427 enum regexp_mode mode
;
1428 const char *expected_mode_str
;
1435 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1436 file
, line
, func
, expected_mode_str
, regexp_name (mode
));
1440 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1442 #define DECL_UNIT(d) (&(d)->decl.unit)
1443 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1444 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1445 #define DECL_EXCL(d) (&(d)->decl.excl)
1446 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1447 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1448 #define DECL_RESERV(d) (&(d)->decl.reserv)
1449 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1451 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1452 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1453 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1454 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1455 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1456 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1458 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1460 /* Create IR structure (node). */
1467 obstack_blank (&irp
, size
);
1468 result
= obstack_base (&irp
);
1469 obstack_finish (&irp
);
1470 /* Default values of members are NULL and zero. */
1471 memset (result
, 0, size
);
1475 /* Copy IR structure (node). */
1477 copy_node (from
, size
)
1481 void *const result
= create_node (size
);
1482 memcpy (result
, from
, size
);
1486 /* The function checks that NAME does not contain quotes (`"'). */
1488 check_name (name
, pos
)
1490 pos_t pos ATTRIBUTE_UNUSED
;
1494 for (str
= name
; *str
!= '\0'; str
++)
1496 error ("Name `%s' contains quotes", name
);
1500 /* Pointers top all declartions during IR generation are stored in the
1502 static vla_ptr_t decls
;
1504 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1505 string containing the next separated element, taking parentheses
1506 into account if PAR_FLAG has nonzero value. Advance the pointer to
1507 after the string scanned, or the end-of-string. Return NULL if at
1510 next_sep_el (pstr
, sep
, par_flag
)
1520 /* Remove leading whitespaces. */
1521 while (ISSPACE ((int) **pstr
))
1528 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1530 if (par_flag
&& *p
== '(')
1532 else if (par_flag
&& *p
== ')')
1534 else if (pars_num
== 0 && *p
== sep
)
1536 if (pars_num
== 0 && ISSPACE ((int) *p
))
1540 for (; n_spaces
!= 0; n_spaces
--)
1541 obstack_1grow (&irp
, p
[-n_spaces
]);
1542 obstack_1grow (&irp
, *p
);
1545 obstack_1grow (&irp
, '\0');
1546 out_str
= obstack_base (&irp
);
1547 obstack_finish (&irp
);
1556 /* Given a string and a separator, return the number of separated
1557 elements in it, taking parentheses into account if PAR_FLAG has
1558 nonzero value. Return 0 for the null string, -1 if parantheses is
1561 n_sep_els (s
, sep
, par_flag
)
1572 for (pars_num
= 0, n
= 1; *s
; s
++)
1573 if (par_flag
&& *s
== '(')
1575 else if (par_flag
&& *s
== ')')
1577 else if (pars_num
== 0 && *s
== sep
)
1580 return (pars_num
!= 0 ? -1 : n
);
1583 /* Given a string and a separator, return vector of strings which are
1584 elements in the string and number of elements through els_num.
1585 Take parentheses into account if PAR_FLAG has nonzero value.
1586 Return 0 for the null string, -1 if parantheses are not balanced. */
1588 get_str_vect (str
, els_num
, sep
, par_flag
)
1598 *els_num
= n_sep_els (str
, sep
, par_flag
);
1601 obstack_blank (&irp
, sizeof (char *) * (*els_num
));
1602 vect
= (char **) obstack_base (&irp
);
1603 obstack_finish (&irp
);
1605 for (i
= 0; i
< *els_num
; i
++)
1606 vect
[i
] = next_sep_el (pstr
, sep
, par_flag
);
1607 if (next_sep_el (pstr
, sep
, par_flag
) != NULL
)
1612 /* Process a DEFINE_CPU_UNIT.
1614 This gives information about a unit contained in CPU. We fill a
1615 struct unit_decl with information used later by `expand_automata'. */
1621 char **str_cpu_units
;
1625 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1626 if (str_cpu_units
== NULL
)
1627 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1628 for (i
= 0; i
< vect_length
; i
++)
1630 decl
= create_node (sizeof (struct decl
));
1631 decl
->mode
= dm_unit
;
1633 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1634 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1635 DECL_UNIT (decl
)->query_p
= 0;
1636 VLA_PTR_ADD (decls
, decl
);
1641 /* Process a DEFINE_QUERY_CPU_UNIT.
1643 This gives information about a unit contained in CPU. We fill a
1644 struct unit_decl with information used later by `expand_automata'. */
1646 gen_query_cpu_unit (def
)
1650 char **str_cpu_units
;
1654 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1655 if (str_cpu_units
== NULL
)
1656 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1657 for (i
= 0; i
< vect_length
; i
++)
1659 decl
= create_node (sizeof (struct decl
));
1660 decl
->mode
= dm_unit
;
1662 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1663 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1664 DECL_UNIT (decl
)->query_p
= 1;
1665 VLA_PTR_ADD (decls
, decl
);
1670 /* Process a DEFINE_BYPASS.
1672 This gives information about a unit contained in the CPU. We fill
1673 in a struct bypass_decl with information used later by
1674 `expand_automata'. */
1686 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', 0);
1687 if (out_insns
== NULL
)
1688 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1689 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', 0);
1690 if (in_insns
== NULL
)
1691 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1692 for (i
= 0; i
< out_length
; i
++)
1693 for (j
= 0; j
< in_length
; j
++)
1695 decl
= create_node (sizeof (struct decl
));
1696 decl
->mode
= dm_bypass
;
1698 DECL_BYPASS (decl
)->latency
= XINT (def
, 0);
1699 DECL_BYPASS (decl
)->out_insn_name
= out_insns
[i
];
1700 DECL_BYPASS (decl
)->in_insn_name
= in_insns
[j
];
1701 DECL_BYPASS (decl
)->bypass_guard_name
= (char *) XSTR (def
, 3);
1702 VLA_PTR_ADD (decls
, decl
);
1707 /* Process an EXCLUSION_SET.
1709 This gives information about a cpu unit conflicts. We fill a
1710 struct unit_rel_decl (excl) with information used later by
1711 `expand_automata'. */
1717 char **first_str_cpu_units
;
1718 char **second_str_cpu_units
;
1719 int first_vect_length
;
1724 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1725 if (first_str_cpu_units
== NULL
)
1726 fatal ("invalid first string `%s' in exclusion_set", XSTR (def
, 0));
1727 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1729 if (second_str_cpu_units
== NULL
)
1730 fatal ("invalid second string `%s' in exclusion_set", XSTR (def
, 1));
1731 length
+= first_vect_length
;
1732 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1733 decl
->mode
= dm_excl
;
1735 DECL_EXCL (decl
)->names_num
= length
;
1736 DECL_EXCL (decl
)->first_list_length
= first_vect_length
;
1737 for (i
= 0; i
< length
; i
++)
1738 if (i
< first_vect_length
)
1739 DECL_EXCL (decl
)->names
[i
] = first_str_cpu_units
[i
];
1741 DECL_EXCL (decl
)->names
[i
]
1742 = second_str_cpu_units
[i
- first_vect_length
];
1743 VLA_PTR_ADD (decls
, decl
);
1747 /* Process a PRESENCE_SET.
1749 This gives information about a cpu unit reservation requirements.
1750 We fill a struct unit_rel_decl (presence) with information used
1751 later by `expand_automata'. */
1753 gen_presence_set (def
)
1757 char **first_str_cpu_units
;
1758 char **second_str_cpu_units
;
1759 int first_vect_length
;
1764 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1765 if (first_str_cpu_units
== NULL
)
1766 fatal ("invalid first string `%s' in presence_set", XSTR (def
, 0));
1767 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1769 if (second_str_cpu_units
== NULL
)
1770 fatal ("invalid second string `%s' in presence_set", XSTR (def
, 1));
1771 length
+= first_vect_length
;
1772 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1773 decl
->mode
= dm_presence
;
1775 DECL_PRESENCE (decl
)->names_num
= length
;
1776 DECL_PRESENCE (decl
)->first_list_length
= first_vect_length
;
1777 for (i
= 0; i
< length
; i
++)
1778 if (i
< first_vect_length
)
1779 DECL_PRESENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1781 DECL_PRESENCE (decl
)->names
[i
]
1782 = second_str_cpu_units
[i
- first_vect_length
];
1783 VLA_PTR_ADD (decls
, decl
);
1787 /* Process an ABSENCE_SET.
1789 This gives information about a cpu unit reservation requirements.
1790 We fill a struct unit_rel_decl (absence) with information used
1791 later by `expand_automata'. */
1793 gen_absence_set (def
)
1797 char **first_str_cpu_units
;
1798 char **second_str_cpu_units
;
1799 int first_vect_length
;
1804 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1805 if (first_str_cpu_units
== NULL
)
1806 fatal ("invalid first string `%s' in absence_set", XSTR (def
, 0));
1807 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1809 if (second_str_cpu_units
== NULL
)
1810 fatal ("invalid second string `%s' in absence_set", XSTR (def
, 1));
1811 length
+= first_vect_length
;
1812 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1813 decl
->mode
= dm_absence
;
1815 DECL_ABSENCE (decl
)->names_num
= length
;
1816 DECL_ABSENCE (decl
)->first_list_length
= first_vect_length
;
1817 for (i
= 0; i
< length
; i
++)
1818 if (i
< first_vect_length
)
1819 DECL_ABSENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1821 DECL_ABSENCE (decl
)->names
[i
]
1822 = second_str_cpu_units
[i
- first_vect_length
];
1823 VLA_PTR_ADD (decls
, decl
);
1827 /* Process a DEFINE_AUTOMATON.
1829 This gives information about a finite state automaton used for
1830 recognizing pipeline hazards. We fill a struct automaton_decl
1831 with information used later by `expand_automata'. */
1837 char **str_automata
;
1841 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1842 if (str_automata
== NULL
)
1843 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1844 for (i
= 0; i
< vect_length
; i
++)
1846 decl
= create_node (sizeof (struct decl
));
1847 decl
->mode
= dm_automaton
;
1849 DECL_AUTOMATON (decl
)->name
= check_name (str_automata
[i
], decl
->pos
);
1850 VLA_PTR_ADD (decls
, decl
);
1855 /* Process an AUTOMATA_OPTION.
1857 This gives information how to generate finite state automaton used
1858 for recognizing pipeline hazards. */
1860 gen_automata_option (def
)
1863 if (strcmp ((char *) XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1864 no_minimization_flag
= 1;
1865 else if (strcmp ((char *) XSTR (def
, 0), TIME_OPTION
+ 1) == 0)
1867 else if (strcmp ((char *) XSTR (def
, 0), V_OPTION
+ 1) == 0)
1869 else if (strcmp ((char *) XSTR (def
, 0), W_OPTION
+ 1) == 0)
1871 else if (strcmp ((char *) XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1874 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1877 /* Name in reservation to denote absence reservation. */
1878 #define NOTHING_NAME "nothing"
1880 /* The following string contains original reservation string being
1882 static char *reserv_str
;
1884 /* Parse an element in STR. */
1895 if (str
[len
- 1] != ')')
1896 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1897 str
[len
- 1] = '\0';
1898 regexp
= gen_regexp_sequence (str
+ 1);
1900 else if (strcmp (str
, NOTHING_NAME
) == 0)
1902 regexp
= create_node (sizeof (struct decl
));
1903 regexp
->mode
= rm_nothing
;
1907 regexp
= create_node (sizeof (struct decl
));
1908 regexp
->mode
= rm_unit
;
1909 REGEXP_UNIT (regexp
)->name
= str
;
1914 /* Parse construction `repeat' in STR. */
1916 gen_regexp_repeat (str
)
1925 repeat_vect
= get_str_vect (str
, &els_num
, '*', 1);
1926 if (repeat_vect
== NULL
)
1927 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1930 regexp
= gen_regexp_el (repeat_vect
[0]);
1931 for (i
= 1; i
< els_num
; i
++)
1933 repeat
= create_node (sizeof (struct regexp
));
1934 repeat
->mode
= rm_repeat
;
1935 REGEXP_REPEAT (repeat
)->regexp
= regexp
;
1936 REGEXP_REPEAT (repeat
)->repeat_num
= atoi (repeat_vect
[i
]);
1937 if (REGEXP_REPEAT (repeat
)->repeat_num
<= 1)
1938 fatal ("repetition `%s' <= 1 in reservation `%s'",
1945 return gen_regexp_el (str
);
1948 /* Parse reservation STR which possibly contains separator '+'. */
1950 gen_regexp_allof (str
)
1958 allof_vect
= get_str_vect (str
, &els_num
, '+', 1);
1959 if (allof_vect
== NULL
)
1960 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1963 allof
= create_node (sizeof (struct regexp
)
1964 + sizeof (regexp_t
) * (els_num
- 1));
1965 allof
->mode
= rm_allof
;
1966 REGEXP_ALLOF (allof
)->regexps_num
= els_num
;
1967 for (i
= 0; i
< els_num
; i
++)
1968 REGEXP_ALLOF (allof
)->regexps
[i
] = gen_regexp_repeat (allof_vect
[i
]);
1972 return gen_regexp_repeat (str
);
1975 /* Parse reservation STR which possibly contains separator '|'. */
1977 gen_regexp_oneof (str
)
1985 oneof_vect
= get_str_vect (str
, &els_num
, '|', 1);
1986 if (oneof_vect
== NULL
)
1987 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1990 oneof
= create_node (sizeof (struct regexp
)
1991 + sizeof (regexp_t
) * (els_num
- 1));
1992 oneof
->mode
= rm_oneof
;
1993 REGEXP_ONEOF (oneof
)->regexps_num
= els_num
;
1994 for (i
= 0; i
< els_num
; i
++)
1995 REGEXP_ONEOF (oneof
)->regexps
[i
] = gen_regexp_allof (oneof_vect
[i
]);
1999 return gen_regexp_allof (str
);
2002 /* Parse reservation STR which possibly contains separator ','. */
2004 gen_regexp_sequence (str
)
2008 char **sequence_vect
;
2012 sequence_vect
= get_str_vect (str
, &els_num
, ',', 1);
2015 sequence
= create_node (sizeof (struct regexp
)
2016 + sizeof (regexp_t
) * (els_num
- 1));
2017 sequence
->mode
= rm_sequence
;
2018 REGEXP_SEQUENCE (sequence
)->regexps_num
= els_num
;
2019 for (i
= 0; i
< els_num
; i
++)
2020 REGEXP_SEQUENCE (sequence
)->regexps
[i
]
2021 = gen_regexp_oneof (sequence_vect
[i
]);
2025 return gen_regexp_oneof (str
);
2028 /* Parse construction reservation STR. */
2034 return gen_regexp_sequence (str
);;
2037 /* Process a DEFINE_RESERVATION.
2039 This gives information about a reservation of cpu units. We fill
2040 in a struct reserv_decl with information used later by
2041 `expand_automata'. */
2048 decl
= create_node (sizeof (struct decl
));
2049 decl
->mode
= dm_reserv
;
2051 DECL_RESERV (decl
)->name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
2052 DECL_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 1));
2053 VLA_PTR_ADD (decls
, decl
);
2057 /* Process a DEFINE_INSN_RESERVATION.
2059 This gives information about the reservation of cpu units by an
2060 insn. We fill a struct insn_reserv_decl with information used
2061 later by `expand_automata'. */
2063 gen_insn_reserv (def
)
2068 decl
= create_node (sizeof (struct decl
));
2069 decl
->mode
= dm_insn_reserv
;
2071 DECL_INSN_RESERV (decl
)->name
2072 = check_name ((char *) XSTR (def
, 0), decl
->pos
);
2073 DECL_INSN_RESERV (decl
)->default_latency
= XINT (def
, 1);
2074 DECL_INSN_RESERV (decl
)->condexp
= XEXP (def
, 2);
2075 DECL_INSN_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 3));
2076 VLA_PTR_ADD (decls
, decl
);
2082 /* The function evaluates hash value (0..UINT_MAX) of string. */
2084 string_hash (string
)
2089 for (result
= i
= 0;*string
++ != '\0'; i
++)
2090 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
2096 /* This page contains abstract data `table of automaton declarations'.
2097 Elements of the table is nodes representing automaton declarations.
2098 Key of the table elements is name of given automaton. Rememeber
2099 that automaton names have own space. */
2101 /* The function evaluates hash value of an automaton declaration. The
2102 function is used by abstract data `hashtab'. The function returns
2103 hash value (0..UINT_MAX) of given automaton declaration. */
2105 automaton_decl_hash (automaton_decl
)
2106 const void *automaton_decl
;
2108 const decl_t decl
= (decl_t
) automaton_decl
;
2110 if (decl
->mode
== dm_automaton
&& DECL_AUTOMATON (decl
)->name
== NULL
)
2112 return string_hash (DECL_AUTOMATON (decl
)->name
);
2115 /* The function tests automaton declarations on equality of their
2116 keys. The function is used by abstract data `hashtab'. The
2117 function returns 1 if the declarations have the same key, 0
2120 automaton_decl_eq_p (automaton_decl_1
, automaton_decl_2
)
2121 const void* automaton_decl_1
;
2122 const void* automaton_decl_2
;
2124 const decl_t decl1
= (decl_t
) automaton_decl_1
;
2125 const decl_t decl2
= (decl_t
) automaton_decl_2
;
2127 if (decl1
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl1
)->name
== NULL
2128 || decl2
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl2
)->name
== NULL
)
2130 return strcmp (DECL_AUTOMATON (decl1
)->name
,
2131 DECL_AUTOMATON (decl2
)->name
) == 0;
2134 /* The automaton declaration table itself is represented by the
2135 following variable. */
2136 static htab_t automaton_decl_table
;
2138 /* The function inserts automaton declaration into the table. The
2139 function does nothing if an automaton declaration with the same key
2140 exists already in the table. The function returns automaton
2141 declaration node in the table with the same key as given automaton
2142 declaration node. */
2144 insert_automaton_decl (automaton_decl
)
2145 decl_t automaton_decl
;
2149 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
2150 if (*entry_ptr
== NULL
)
2151 *entry_ptr
= (void *) automaton_decl
;
2152 return (decl_t
) *entry_ptr
;
2155 /* The following variable value is node representing automaton
2156 declaration. The node used for searching automaton declaration
2158 static struct decl work_automaton_decl
;
2160 /* The function searches for automaton declaration in the table with
2161 the same key as node representing name of the automaton
2162 declaration. The function returns node found in the table, NULL if
2163 such node does not exist in the table. */
2165 find_automaton_decl (name
)
2170 work_automaton_decl
.mode
= dm_automaton
;
2171 DECL_AUTOMATON (&work_automaton_decl
)->name
= name
;
2172 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
2173 return (decl_t
) entry
;
2176 /* The function creates empty automaton declaration table and node
2177 representing automaton declaration and used for searching automaton
2178 declaration with given name. The function must be called only once
2179 before any work with the automaton declaration table. */
2181 initiate_automaton_decl_table ()
2183 work_automaton_decl
.mode
= dm_automaton
;
2184 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
2185 automaton_decl_eq_p
, (htab_del
) 0);
2188 /* The function deletes the automaton declaration table. Only call of
2189 function `initiate_automaton_decl_table' is possible immediately
2190 after this function call. */
2192 finish_automaton_decl_table ()
2194 htab_delete (automaton_decl_table
);
2199 /* This page contains abstract data `table of insn declarations'.
2200 Elements of the table is nodes representing insn declarations. Key
2201 of the table elements is name of given insn (in corresponding
2202 define_insn_reservation). Rememeber that insn names have own
2205 /* The function evaluates hash value of an insn declaration. The
2206 function is used by abstract data `hashtab'. The function returns
2207 hash value (0..UINT_MAX) of given insn declaration. */
2209 insn_decl_hash (insn_decl
)
2210 const void *insn_decl
;
2212 const decl_t decl
= (decl_t
) insn_decl
;
2214 if (decl
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl
)->name
== NULL
)
2216 return string_hash (DECL_INSN_RESERV (decl
)->name
);
2219 /* The function tests insn declarations on equality of their keys.
2220 The function is used by abstract data `hashtab'. The function
2221 returns 1 if declarations have the same key, 0 otherwise. */
2223 insn_decl_eq_p (insn_decl_1
, insn_decl_2
)
2224 const void *insn_decl_1
;
2225 const void *insn_decl_2
;
2227 const decl_t decl1
= (decl_t
) insn_decl_1
;
2228 const decl_t decl2
= (decl_t
) insn_decl_2
;
2230 if (decl1
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl1
)->name
== NULL
2231 || decl2
->mode
!= dm_insn_reserv
2232 || DECL_INSN_RESERV (decl2
)->name
== NULL
)
2234 return strcmp (DECL_INSN_RESERV (decl1
)->name
,
2235 DECL_INSN_RESERV (decl2
)->name
) == 0;
2238 /* The insn declaration table itself is represented by the following
2239 variable. The table does not contain insn reservation
2241 static htab_t insn_decl_table
;
2243 /* The function inserts insn declaration into the table. The function
2244 does nothing if an insn declaration with the same key exists
2245 already in the table. The function returns insn declaration node
2246 in the table with the same key as given insn declaration node. */
2248 insert_insn_decl (insn_decl
)
2253 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2254 if (*entry_ptr
== NULL
)
2255 *entry_ptr
= (void *) insn_decl
;
2256 return (decl_t
) *entry_ptr
;
2259 /* The following variable value is node representing insn reservation
2260 declaration. The node used for searching insn reservation
2261 declaration with given name. */
2262 static struct decl work_insn_decl
;
2264 /* The function searches for insn reservation declaration in the table
2265 with the same key as node representing name of the insn reservation
2266 declaration. The function returns node found in the table, NULL if
2267 such node does not exist in the table. */
2269 find_insn_decl (name
)
2274 work_insn_decl
.mode
= dm_insn_reserv
;
2275 DECL_INSN_RESERV (&work_insn_decl
)->name
= name
;
2276 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2277 return (decl_t
) entry
;
2280 /* The function creates empty insn declaration table and node
2281 representing insn declaration and used for searching insn
2282 declaration with given name. The function must be called only once
2283 before any work with the insn declaration table. */
2285 initiate_insn_decl_table ()
2287 work_insn_decl
.mode
= dm_insn_reserv
;
2288 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
2292 /* The function deletes the insn declaration table. Only call of
2293 function `initiate_insn_decl_table' is possible immediately after
2294 this function call. */
2296 finish_insn_decl_table ()
2298 htab_delete (insn_decl_table
);
2303 /* This page contains abstract data `table of declarations'. Elements
2304 of the table is nodes representing declarations (of units and
2305 reservations). Key of the table elements is names of given
2308 /* The function evaluates hash value of a declaration. The function
2309 is used by abstract data `hashtab'. The function returns hash
2310 value (0..UINT_MAX) of given declaration. */
2315 const decl_t d
= (const decl_t
) decl
;
2317 if ((d
->mode
!= dm_unit
|| DECL_UNIT (d
)->name
== NULL
)
2318 && (d
->mode
!= dm_reserv
|| DECL_RESERV (d
)->name
== NULL
))
2320 return string_hash (d
->mode
== dm_unit
2321 ? DECL_UNIT (d
)->name
: DECL_RESERV (d
)->name
);
2324 /* The function tests declarations on equality of their keys. The
2325 function is used by abstract data `hashtab'. The function
2326 returns 1 if the declarations have the same key, 0 otherwise. */
2328 decl_eq_p (decl_1
, decl_2
)
2332 const decl_t d1
= (const decl_t
) decl_1
;
2333 const decl_t d2
= (const decl_t
) decl_2
;
2335 if (((d1
->mode
!= dm_unit
|| DECL_UNIT (d1
)->name
== NULL
)
2336 && (d1
->mode
!= dm_reserv
|| DECL_RESERV (d1
)->name
== NULL
))
2337 || ((d2
->mode
!= dm_unit
|| DECL_UNIT (d2
)->name
== NULL
)
2338 && (d2
->mode
!= dm_reserv
|| DECL_RESERV (d2
)->name
== NULL
)))
2340 return strcmp ((d1
->mode
== dm_unit
2341 ? DECL_UNIT (d1
)->name
: DECL_RESERV (d1
)->name
),
2342 (d2
->mode
== dm_unit
2343 ? DECL_UNIT (d2
)->name
: DECL_RESERV (d2
)->name
)) == 0;
2346 /* The declaration table itself is represented by the following
2348 static htab_t decl_table
;
2350 /* The function inserts declaration into the table. The function does
2351 nothing if a declaration with the same key exists already in the
2352 table. The function returns declaration node in the table with the
2353 same key as given declaration node. */
2361 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2362 if (*entry_ptr
== NULL
)
2363 *entry_ptr
= (void *) decl
;
2364 return (decl_t
) *entry_ptr
;
2367 /* The following variable value is node representing declaration. The
2368 node used for searching declaration with given name. */
2369 static struct decl work_decl
;
2371 /* The function searches for declaration in the table with the same
2372 key as node representing name of the declaration. The function
2373 returns node found in the table, NULL if such node does not exist
2381 work_decl
.mode
= dm_unit
;
2382 DECL_UNIT (&work_decl
)->name
= name
;
2383 entry
= htab_find (decl_table
, &work_decl
);
2384 return (decl_t
) entry
;
2387 /* The function creates empty declaration table and node representing
2388 declaration and used for searching declaration with given name.
2389 The function must be called only once before any work with the
2390 declaration table. */
2392 initiate_decl_table ()
2394 work_decl
.mode
= dm_unit
;
2395 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2398 /* The function deletes the declaration table. Only call of function
2399 `initiate_declaration_table' is possible immediately after this
2402 finish_decl_table ()
2404 htab_delete (decl_table
);
2409 /* This page contains checker of pipeline hazard description. */
2411 /* Checking NAMES in an exclusion clause vector and returning formed
2412 unit_set_el_list. */
2413 static unit_set_el_t
2414 process_excls (names
, num
, excl_pos
)
2417 pos_t excl_pos ATTRIBUTE_UNUSED
;
2419 unit_set_el_t el_list
;
2420 unit_set_el_t last_el
;
2421 unit_set_el_t new_el
;
2422 decl_t decl_in_table
;
2427 for (i
= 0; i
< num
; i
++)
2429 decl_in_table
= find_decl (names
[i
]);
2430 if (decl_in_table
== NULL
)
2431 error ("unit `%s' in exclusion is not declared", names
[i
]);
2432 else if (decl_in_table
->mode
!= dm_unit
)
2433 error ("`%s' in exclusion is not unit", names
[i
]);
2436 new_el
= create_node (sizeof (struct unit_set_el
));
2437 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2438 new_el
->next_unit_set_el
= NULL
;
2439 if (last_el
== NULL
)
2440 el_list
= last_el
= new_el
;
2443 last_el
->next_unit_set_el
= new_el
;
2444 last_el
= last_el
->next_unit_set_el
;
2451 /* The function adds each element from SOURCE_LIST to the exclusion
2452 list of the each element from DEST_LIST. Checking situation "unit
2453 excludes itself". */
2455 add_excls (dest_list
, source_list
, excl_pos
)
2456 unit_set_el_t dest_list
;
2457 unit_set_el_t source_list
;
2458 pos_t excl_pos ATTRIBUTE_UNUSED
;
2462 unit_set_el_t curr_el
;
2463 unit_set_el_t prev_el
;
2466 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2467 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2469 if (dst
->unit_decl
== src
->unit_decl
)
2471 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2474 if (dst
->unit_decl
->automaton_name
!= NULL
2475 && src
->unit_decl
->automaton_name
!= NULL
2476 && strcmp (dst
->unit_decl
->automaton_name
,
2477 src
->unit_decl
->automaton_name
) != 0)
2479 error ("units `%s' and `%s' in exclusion set belong to different automata",
2480 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2483 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2485 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2486 if (curr_el
->unit_decl
== src
->unit_decl
)
2488 if (curr_el
== NULL
)
2490 /* Element not found - insert. */
2491 copy
= copy_node (src
, sizeof (*src
));
2492 copy
->next_unit_set_el
= NULL
;
2493 if (prev_el
== NULL
)
2494 dst
->unit_decl
->excl_list
= copy
;
2496 prev_el
->next_unit_set_el
= copy
;
2501 /* Checking NAMES in an presence clause vector and returning formed
2502 unit_set_el_list. The function is called only after processing all
2504 static unit_set_el_t
2505 process_presence_absence (names
, num
, req_pos
, presence_p
)
2508 pos_t req_pos ATTRIBUTE_UNUSED
;
2511 unit_set_el_t el_list
;
2512 unit_set_el_t last_el
;
2513 unit_set_el_t new_el
;
2514 decl_t decl_in_table
;
2519 for (i
= 0; i
< num
; i
++)
2521 decl_in_table
= find_decl (names
[i
]);
2522 if (decl_in_table
== NULL
)
2524 ? "unit `%s' in presence set is not declared"
2525 : "unit `%s' in absence set is not declared"), names
[i
]);
2526 else if (decl_in_table
->mode
!= dm_unit
)
2528 ? "`%s' in presence set is not unit"
2529 : "`%s' in absence set is not unit"), names
[i
]);
2532 new_el
= create_node (sizeof (struct unit_set_el
));
2533 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2534 new_el
->next_unit_set_el
= NULL
;
2535 if (last_el
== NULL
)
2536 el_list
= last_el
= new_el
;
2539 last_el
->next_unit_set_el
= new_el
;
2540 last_el
= last_el
->next_unit_set_el
;
2547 /* The function adds each element from SOURCE_LIST to presence (if
2548 PRESENCE_P) or absence list of the each element from DEST_LIST.
2549 Checking situations "unit requires own presence", "unit requires
2550 own absence", and "unit excludes and requires presence of ...".
2551 Remember that we process absence sets only after all presence
2554 add_presence_absence (dest_list
, source_list
, req_pos
, presence_p
)
2555 unit_set_el_t dest_list
;
2556 unit_set_el_t source_list
;
2557 pos_t req_pos ATTRIBUTE_UNUSED
;
2562 unit_set_el_t curr_el
;
2563 unit_set_el_t prev_el
;
2566 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2567 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2569 if (dst
->unit_decl
== src
->unit_decl
)
2572 ? "unit `%s' requires own presence"
2573 : "unit `%s' requires own absence"), src
->unit_decl
->name
);
2576 if (dst
->unit_decl
->automaton_name
!= NULL
2577 && src
->unit_decl
->automaton_name
!= NULL
2578 && strcmp (dst
->unit_decl
->automaton_name
,
2579 src
->unit_decl
->automaton_name
) != 0)
2582 ? "units `%s' and `%s' in presence set belong to different automata"
2583 : "units `%s' and `%s' in absence set belong to different automata"),
2584 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2587 for (curr_el
= (presence_p
2588 ? dst
->unit_decl
->presence_list
2589 : dst
->unit_decl
->absence_list
), prev_el
= NULL
;
2591 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2592 if (curr_el
->unit_decl
== src
->unit_decl
)
2594 if (curr_el
== NULL
)
2596 /* Element not found - insert if there is no error. */
2597 int no_error_flag
= 1;
2600 for (curr_el
= dst
->unit_decl
->excl_list
;
2602 curr_el
= curr_el
->next_unit_set_el
)
2604 if (src
->unit_decl
== curr_el
->unit_decl
)
2609 ("unit `%s' excludes and requires presence of `%s'",
2610 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2615 ("unit `%s' excludes and requires presence of `%s'",
2616 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2620 for (curr_el
= dst
->unit_decl
->presence_list
;
2622 curr_el
= curr_el
->next_unit_set_el
)
2624 if (src
->unit_decl
== curr_el
->unit_decl
)
2629 ("unit `%s' requires absence and presence of `%s'",
2630 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2635 ("unit `%s' requires absence and presence of `%s'",
2636 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2641 copy
= copy_node (src
, sizeof (*src
));
2642 copy
->next_unit_set_el
= NULL
;
2643 if (prev_el
== NULL
)
2646 dst
->unit_decl
->presence_list
= copy
;
2648 dst
->unit_decl
->absence_list
= copy
;
2651 prev_el
->next_unit_set_el
= copy
;
2657 /* The function searches for bypass with given IN_INSN_RESERV in given
2659 static struct bypass_decl
*
2660 find_bypass (bypass_list
, in_insn_reserv
)
2661 struct bypass_decl
*bypass_list
;
2662 struct insn_reserv_decl
*in_insn_reserv
;
2664 struct bypass_decl
*bypass
;
2666 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2667 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2672 /* The function processes pipeline description declarations, checks
2673 their correctness, and forms exclusion/presence/absence sets. */
2678 decl_t automaton_decl
;
2679 decl_t decl_in_table
;
2680 decl_t out_insn_reserv
;
2681 decl_t in_insn_reserv
;
2682 struct bypass_decl
*bypass
;
2683 int automaton_presence
;
2686 /* Checking repeated automata declarations. */
2687 automaton_presence
= 0;
2688 for (i
= 0; i
< description
->decls_num
; i
++)
2690 decl
= description
->decls
[i
];
2691 if (decl
->mode
== dm_automaton
)
2693 automaton_presence
= 1;
2694 decl_in_table
= insert_automaton_decl (decl
);
2695 if (decl_in_table
!= decl
)
2698 error ("repeated declaration of automaton `%s'",
2699 DECL_AUTOMATON (decl
)->name
);
2701 warning ("repeated declaration of automaton `%s'",
2702 DECL_AUTOMATON (decl
)->name
);
2706 /* Checking undeclared automata, repeated declarations (except for
2707 automata) and correctness of their attributes (insn latency times
2709 for (i
= 0; i
< description
->decls_num
; i
++)
2711 decl
= description
->decls
[i
];
2712 if (decl
->mode
== dm_insn_reserv
)
2714 DECL_INSN_RESERV (decl
)->condexp
2715 = check_attr_test (DECL_INSN_RESERV (decl
)->condexp
, 0, 0);
2716 if (DECL_INSN_RESERV (decl
)->default_latency
< 0)
2717 error ("define_insn_reservation `%s' has negative latency time",
2718 DECL_INSN_RESERV (decl
)->name
);
2719 DECL_INSN_RESERV (decl
)->insn_num
= description
->insns_num
;
2720 description
->insns_num
++;
2721 decl_in_table
= insert_insn_decl (decl
);
2722 if (decl_in_table
!= decl
)
2723 error ("`%s' is already used as insn reservation name",
2724 DECL_INSN_RESERV (decl
)->name
);
2726 else if (decl
->mode
== dm_bypass
)
2728 if (DECL_BYPASS (decl
)->latency
< 0)
2729 error ("define_bypass `%s - %s' has negative latency time",
2730 DECL_BYPASS (decl
)->out_insn_name
,
2731 DECL_BYPASS (decl
)->in_insn_name
);
2733 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2735 if (decl
->mode
== dm_unit
)
2737 DECL_UNIT (decl
)->automaton_decl
= NULL
;
2738 if (DECL_UNIT (decl
)->automaton_name
!= NULL
)
2741 = find_automaton_decl (DECL_UNIT (decl
)->automaton_name
);
2742 if (automaton_decl
== NULL
)
2743 error ("automaton `%s' is not declared",
2744 DECL_UNIT (decl
)->automaton_name
);
2747 DECL_AUTOMATON (automaton_decl
)->automaton_is_used
= 1;
2748 DECL_UNIT (decl
)->automaton_decl
2749 = DECL_AUTOMATON (automaton_decl
);
2752 else if (automaton_presence
)
2753 error ("define_unit `%s' without automaton when one defined",
2754 DECL_UNIT (decl
)->name
);
2755 DECL_UNIT (decl
)->unit_num
= description
->units_num
;
2756 description
->units_num
++;
2757 if (strcmp (DECL_UNIT (decl
)->name
, NOTHING_NAME
) == 0)
2759 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2762 decl_in_table
= find_decl (DECL_UNIT (decl
)->name
);
2766 if (strcmp (DECL_RESERV (decl
)->name
, NOTHING_NAME
) == 0)
2768 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2771 decl_in_table
= find_decl (DECL_RESERV (decl
)->name
);
2773 if (decl_in_table
== NULL
)
2774 decl_in_table
= insert_decl (decl
);
2777 if (decl
->mode
== dm_unit
)
2778 error ("repeated declaration of unit `%s'",
2779 DECL_UNIT (decl
)->name
);
2781 error ("repeated declaration of reservation `%s'",
2782 DECL_RESERV (decl
)->name
);
2786 /* Check bypasses and form list of bypasses for each (output)
2788 for (i
= 0; i
< description
->decls_num
; i
++)
2790 decl
= description
->decls
[i
];
2791 if (decl
->mode
== dm_bypass
)
2793 out_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->out_insn_name
);
2794 in_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->in_insn_name
);
2795 if (out_insn_reserv
== NULL
)
2796 error ("there is no insn reservation `%s'",
2797 DECL_BYPASS (decl
)->out_insn_name
);
2798 else if (in_insn_reserv
== NULL
)
2799 error ("there is no insn reservation `%s'",
2800 DECL_BYPASS (decl
)->in_insn_name
);
2803 DECL_BYPASS (decl
)->out_insn_reserv
2804 = DECL_INSN_RESERV (out_insn_reserv
);
2805 DECL_BYPASS (decl
)->in_insn_reserv
2806 = DECL_INSN_RESERV (in_insn_reserv
);
2808 = find_bypass (DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
,
2809 DECL_BYPASS (decl
)->in_insn_reserv
);
2812 if (DECL_BYPASS (decl
)->latency
== bypass
->latency
)
2816 ("the same bypass `%s - %s' is already defined",
2817 DECL_BYPASS (decl
)->out_insn_name
,
2818 DECL_BYPASS (decl
)->in_insn_name
);
2821 ("the same bypass `%s - %s' is already defined",
2822 DECL_BYPASS (decl
)->out_insn_name
,
2823 DECL_BYPASS (decl
)->in_insn_name
);
2826 error ("bypass `%s - %s' is already defined",
2827 DECL_BYPASS (decl
)->out_insn_name
,
2828 DECL_BYPASS (decl
)->in_insn_name
);
2832 DECL_BYPASS (decl
)->next
2833 = DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
;
2834 DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
2835 = DECL_BYPASS (decl
);
2841 /* Check exclusion set declarations and form exclussion sets. */
2842 for (i
= 0; i
< description
->decls_num
; i
++)
2844 decl
= description
->decls
[i
];
2845 if (decl
->mode
== dm_excl
)
2847 unit_set_el_t unit_set_el_list
;
2848 unit_set_el_t unit_set_el_list_2
;
2851 = process_excls (DECL_EXCL (decl
)->names
,
2852 DECL_EXCL (decl
)->first_list_length
, decl
->pos
);
2854 = process_excls (&DECL_EXCL (decl
)->names
2855 [DECL_EXCL (decl
)->first_list_length
],
2856 DECL_EXCL (decl
)->names_num
2857 - DECL_EXCL (decl
)->first_list_length
,
2859 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2860 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2864 /* Check presence set declarations and form presence sets. */
2865 for (i
= 0; i
< description
->decls_num
; i
++)
2867 decl
= description
->decls
[i
];
2868 if (decl
->mode
== dm_presence
)
2870 unit_set_el_t unit_set_el_list
;
2871 unit_set_el_t unit_set_el_list_2
;
2874 = process_presence_absence
2875 (DECL_PRESENCE (decl
)->names
,
2876 DECL_PRESENCE (decl
)->first_list_length
, decl
->pos
, 1);
2878 = process_presence_absence
2879 (&DECL_PRESENCE (decl
)->names
2880 [DECL_PRESENCE (decl
)->first_list_length
],
2881 DECL_PRESENCE (decl
)->names_num
2882 - DECL_PRESENCE (decl
)->first_list_length
,
2884 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2889 /* Check absence set declarations and form absence sets. */
2890 for (i
= 0; i
< description
->decls_num
; i
++)
2892 decl
= description
->decls
[i
];
2893 if (decl
->mode
== dm_absence
)
2895 unit_set_el_t unit_set_el_list
;
2896 unit_set_el_t unit_set_el_list_2
;
2899 = process_presence_absence
2900 (DECL_ABSENCE (decl
)->names
,
2901 DECL_ABSENCE (decl
)->first_list_length
, decl
->pos
, 0);
2903 = process_presence_absence
2904 (&DECL_ABSENCE (decl
)->names
2905 [DECL_ABSENCE (decl
)->first_list_length
],
2906 DECL_ABSENCE (decl
)->names_num
2907 - DECL_ABSENCE (decl
)->first_list_length
,
2909 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2915 /* The following function checks that declared automaton is used. If
2916 the automaton is not used, the function fixes error/warning. The
2917 following function must be called only after `process_decls'. */
2919 check_automaton_usage ()
2924 for (i
= 0; i
< description
->decls_num
; i
++)
2926 decl
= description
->decls
[i
];
2927 if (decl
->mode
== dm_automaton
2928 && !DECL_AUTOMATON (decl
)->automaton_is_used
)
2931 error ("automaton `%s' is not used", DECL_AUTOMATON (decl
)->name
);
2933 warning ("automaton `%s' is not used",
2934 DECL_AUTOMATON (decl
)->name
);
2939 /* The following recursive function processes all regexp in order to
2940 fix usage of units or reservations and to fix errors of undeclared
2941 name. The function may change unit_regexp onto reserv_regexp.
2942 Remember that reserv_regexp does not exist before the function
2945 process_regexp (regexp
)
2948 decl_t decl_in_table
;
2949 regexp_t new_regexp
;
2952 if (regexp
->mode
== rm_unit
)
2954 decl_in_table
= find_decl (REGEXP_UNIT (regexp
)->name
);
2955 if (decl_in_table
== NULL
)
2956 error ("undeclared unit or reservation `%s'",
2957 REGEXP_UNIT (regexp
)->name
);
2958 else if (decl_in_table
->mode
== dm_unit
)
2960 DECL_UNIT (decl_in_table
)->unit_is_used
= 1;
2961 REGEXP_UNIT (regexp
)->unit_decl
= DECL_UNIT (decl_in_table
);
2963 else if (decl_in_table
->mode
== dm_reserv
)
2965 DECL_RESERV (decl_in_table
)->reserv_is_used
= 1;
2966 new_regexp
= create_node (sizeof (struct regexp
));
2967 new_regexp
->mode
= rm_reserv
;
2968 new_regexp
->pos
= regexp
->pos
;
2969 REGEXP_RESERV (new_regexp
)->name
= REGEXP_UNIT (regexp
)->name
;
2970 REGEXP_RESERV (new_regexp
)->reserv_decl
2971 = DECL_RESERV (decl_in_table
);
2972 regexp
= new_regexp
;
2977 else if (regexp
->mode
== rm_sequence
)
2978 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
2979 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
2980 = process_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
2981 else if (regexp
->mode
== rm_allof
)
2982 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
2983 REGEXP_ALLOF (regexp
)->regexps
[i
]
2984 = process_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
2985 else if (regexp
->mode
== rm_oneof
)
2986 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
2987 REGEXP_ONEOF (regexp
)->regexps
[i
]
2988 = process_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
2989 else if (regexp
->mode
== rm_repeat
)
2990 REGEXP_REPEAT (regexp
)->regexp
2991 = process_regexp (REGEXP_REPEAT (regexp
)->regexp
);
2992 else if (regexp
->mode
!= rm_nothing
)
2997 /* The following function processes regexp of define_reservation and
2998 define_insn_reservation with the aid of function
2999 `process_regexp'. */
3001 process_regexp_decls ()
3006 for (i
= 0; i
< description
->decls_num
; i
++)
3008 decl
= description
->decls
[i
];
3009 if (decl
->mode
== dm_reserv
)
3010 DECL_RESERV (decl
)->regexp
3011 = process_regexp (DECL_RESERV (decl
)->regexp
);
3012 else if (decl
->mode
== dm_insn_reserv
)
3013 DECL_INSN_RESERV (decl
)->regexp
3014 = process_regexp (DECL_INSN_RESERV (decl
)->regexp
);
3018 /* The following function checks that declared unit is used. If the
3019 unit is not used, the function fixes errors/warnings. The
3020 following function must be called only after `process_decls',
3021 `process_regexp_decls'. */
3028 for (i
= 0; i
< description
->decls_num
; i
++)
3030 decl
= description
->decls
[i
];
3031 if (decl
->mode
== dm_unit
&& !DECL_UNIT (decl
)->unit_is_used
)
3034 error ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3036 warning ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3038 else if (decl
->mode
== dm_reserv
&& !DECL_RESERV (decl
)->reserv_is_used
)
3041 error ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3043 warning ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3048 /* The following variable value is number of reservation being
3049 processed on loop recognition. */
3050 static int curr_loop_pass_num
;
3052 /* The following recursive function returns nonzero value if REGEXP
3053 contains given decl or reservations in given regexp refers for
3056 loop_in_regexp (regexp
, start_decl
)
3064 if (regexp
->mode
== rm_unit
)
3066 else if (regexp
->mode
== rm_reserv
)
3068 if (start_decl
->mode
== dm_reserv
3069 && REGEXP_RESERV (regexp
)->reserv_decl
== DECL_RESERV (start_decl
))
3071 else if (REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3072 == curr_loop_pass_num
)
3073 /* declaration has been processed. */
3077 REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3078 = curr_loop_pass_num
;
3079 return loop_in_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3083 else if (regexp
->mode
== rm_sequence
)
3085 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3086 if (loop_in_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
], start_decl
))
3090 else if (regexp
->mode
== rm_allof
)
3092 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3093 if (loop_in_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
], start_decl
))
3097 else if (regexp
->mode
== rm_oneof
)
3099 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3100 if (loop_in_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
], start_decl
))
3104 else if (regexp
->mode
== rm_repeat
)
3105 return loop_in_regexp (REGEXP_REPEAT (regexp
)->regexp
, start_decl
);
3108 if (regexp
->mode
!= rm_nothing
)
3114 /* The following function fixes errors "cycle in definition ...". The
3115 function uses function `loop_in_regexp' for that. */
3117 check_loops_in_regexps ()
3122 for (i
= 0; i
< description
->decls_num
; i
++)
3124 decl
= description
->decls
[i
];
3125 if (decl
->mode
== dm_reserv
)
3126 DECL_RESERV (decl
)->loop_pass_num
= 0;
3128 for (i
= 0; i
< description
->decls_num
; i
++)
3130 decl
= description
->decls
[i
];
3131 curr_loop_pass_num
= i
;
3133 if (decl
->mode
== dm_reserv
)
3135 DECL_RESERV (decl
)->loop_pass_num
= curr_loop_pass_num
;
3136 if (loop_in_regexp (DECL_RESERV (decl
)->regexp
, decl
))
3138 if (DECL_RESERV (decl
)->regexp
== NULL
)
3140 error ("cycle in definition of reservation `%s'",
3141 DECL_RESERV (decl
)->name
);
3147 /* The function recursively processes IR of reservation and defines
3148 max and min cycle for reservation of unit and for result in the
3151 process_regexp_cycles (regexp
, start_cycle
)
3157 if (regexp
->mode
== rm_unit
)
3159 if (REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
< start_cycle
)
3160 REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
= start_cycle
;
3163 else if (regexp
->mode
== rm_reserv
)
3164 return process_regexp_cycles (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3166 else if (regexp
->mode
== rm_repeat
)
3168 for (i
= 0; i
< REGEXP_REPEAT (regexp
)->repeat_num
; i
++)
3169 start_cycle
= process_regexp_cycles (REGEXP_REPEAT (regexp
)->regexp
,
3173 else if (regexp
->mode
== rm_sequence
)
3175 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3177 = process_regexp_cycles (REGEXP_SEQUENCE (regexp
)->regexps
[i
],
3181 else if (regexp
->mode
== rm_allof
)
3183 int finish_cycle
= 0;
3186 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3188 cycle
= process_regexp_cycles (REGEXP_ALLOF (regexp
)->regexps
[i
],
3190 if (finish_cycle
< cycle
)
3191 finish_cycle
= cycle
;
3193 return finish_cycle
;
3195 else if (regexp
->mode
== rm_oneof
)
3197 int finish_cycle
= 0;
3200 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3202 cycle
= process_regexp_cycles (REGEXP_ONEOF (regexp
)->regexps
[i
],
3204 if (finish_cycle
< cycle
)
3205 finish_cycle
= cycle
;
3207 return finish_cycle
;
3211 if (regexp
->mode
!= rm_nothing
)
3217 /* The following function is called only for correct program. The
3218 function defines max reservation of insns in cycles. */
3220 evaluate_max_reserv_cycles ()
3222 int max_insn_cycles_num
;
3226 description
->max_insn_reserv_cycles
= 0;
3227 for (i
= 0; i
< description
->decls_num
; i
++)
3229 decl
= description
->decls
[i
];
3230 if (decl
->mode
== dm_insn_reserv
)
3233 = process_regexp_cycles (DECL_INSN_RESERV (decl
)->regexp
, 0);
3234 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3235 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3238 description
->max_insn_reserv_cycles
++;
3241 /* The following function calls functions for checking all
3244 check_all_description ()
3247 check_automaton_usage ();
3248 process_regexp_decls ();
3250 check_loops_in_regexps ();
3252 evaluate_max_reserv_cycles ();
3257 /* The page contains abstract data `ticker'. This data is used to
3258 report time of different phases of building automata. It is
3259 possibly to write a description for which automata will be built
3260 during several minutes even on fast machine. */
3262 /* The following function creates ticker and makes it active. */
3268 ticker
.modified_creation_time
= get_run_time ();
3269 ticker
.incremented_off_time
= 0;
3273 /* The following function switches off given ticker. */
3278 if (ticker
->incremented_off_time
== 0)
3279 ticker
->incremented_off_time
= get_run_time () + 1;
3282 /* The following function switches on given ticker. */
3287 if (ticker
->incremented_off_time
!= 0)
3289 ticker
->modified_creation_time
3290 += get_run_time () - ticker
->incremented_off_time
+ 1;
3291 ticker
->incremented_off_time
= 0;
3295 /* The following function returns current time in milliseconds since
3296 the moment when given ticker was created. */
3298 active_time (ticker
)
3301 if (ticker
.incremented_off_time
!= 0)
3302 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3304 return get_run_time () - ticker
.modified_creation_time
;
3307 /* The following function returns string representation of active time
3308 of given ticker. The result is string representation of seconds
3309 with accuracy of 1/100 second. Only result of the last call of the
3310 function exists. Therefore the following code is not correct
3312 printf ("parser time: %s\ngeneration time: %s\n",
3313 active_time_string (parser_ticker),
3314 active_time_string (generation_ticker));
3316 Correct code has to be the following
3318 printf ("parser time: %s\n", active_time_string (parser_ticker));
3319 printf ("generation time: %s\n",
3320 active_time_string (generation_ticker));
3324 print_active_time (f
, ticker
)
3330 msecs
= active_time (ticker
);
3331 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3336 /* The following variable value is number of automaton which are
3337 really being created. This value is defined on the base of
3338 argument of option `-split'. If the variable has zero value the
3339 number of automata is defined by the constructions `%automaton'.
3340 This case occures when option `-split' is absent or has zero
3341 argument. If constructions `define_automaton' is absent only one
3342 automaton is created. */
3343 static int automata_num
;
3345 /* The following variable values are times of
3346 o transformation of regular expressions
3347 o building NDFA (DFA if !ndfa_flag)
3348 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3350 o building insn equivalence classes
3353 static ticker_t transform_time
;
3354 static ticker_t NDFA_time
;
3355 static ticker_t NDFA_to_DFA_time
;
3356 static ticker_t minimize_time
;
3357 static ticker_t equiv_time
;
3358 static ticker_t automaton_generation_time
;
3359 static ticker_t output_time
;
3361 /* The following variable values are times of
3364 all pipeline hazard translator work */
3365 static ticker_t check_time
;
3366 static ticker_t generation_time
;
3367 static ticker_t all_time
;
3371 /* Pseudo insn decl which denotes advancing cycle. */
3372 static decl_t advance_cycle_insn_decl
;
3374 add_advance_cycle_insn_decl ()
3376 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3377 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3378 advance_cycle_insn_decl
->pos
= no_pos
;
3379 DECL_INSN_RESERV (advance_cycle_insn_decl
)->regexp
= NULL
;
3380 DECL_INSN_RESERV (advance_cycle_insn_decl
)->name
= (char *) "$advance_cycle";
3381 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
3382 = description
->insns_num
;
3383 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3384 description
->decls_num
++;
3385 description
->insns_num
++;
3390 /* Abstract data `alternative states' which reperesents
3391 nondeterministic nature of the description (see comments for
3392 structures alt_state and state). */
3394 /* List of free states. */
3395 static alt_state_t first_free_alt_state
;
3398 /* The following variables is maximal number of allocated nodes
3400 static int allocated_alt_states_num
= 0;
3403 /* The following function returns free node alt_state. It may be new
3404 allocated node or node freed eralier. */
3406 get_free_alt_state ()
3410 if (first_free_alt_state
!= NULL
)
3412 result
= first_free_alt_state
;
3413 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3418 allocated_alt_states_num
++;
3420 result
= create_node (sizeof (struct alt_state
));
3422 result
->state
= NULL
;
3423 result
->next_alt_state
= NULL
;
3424 result
->next_sorted_alt_state
= NULL
;
3428 /* The function frees node ALT_STATE. */
3430 free_alt_state (alt_state
)
3431 alt_state_t alt_state
;
3433 if (alt_state
== NULL
)
3435 alt_state
->next_alt_state
= first_free_alt_state
;
3436 first_free_alt_state
= alt_state
;
3439 /* The function frees list started with node ALT_STATE_LIST. */
3441 free_alt_states (alt_states_list
)
3442 alt_state_t alt_states_list
;
3444 alt_state_t curr_alt_state
;
3445 alt_state_t next_alt_state
;
3447 for (curr_alt_state
= alt_states_list
;
3448 curr_alt_state
!= NULL
;
3449 curr_alt_state
= next_alt_state
)
3451 next_alt_state
= curr_alt_state
->next_alt_state
;
3452 free_alt_state (curr_alt_state
);
3456 /* The function compares unique numbers of alt states. */
3458 alt_state_cmp (alt_state_ptr_1
, alt_state_ptr_2
)
3459 const void *alt_state_ptr_1
;
3460 const void *alt_state_ptr_2
;
3462 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3463 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3465 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3466 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3472 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3473 states from the list. The comparison key is alt state unique
3476 uniq_sort_alt_states (alt_states_list
)
3477 alt_state_t alt_states_list
;
3479 alt_state_t curr_alt_state
;
3480 vla_ptr_t alt_states
;
3482 size_t prev_unique_state_ind
;
3484 alt_state_t
*result_ptr
;
3486 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3487 for (curr_alt_state
= alt_states_list
;
3488 curr_alt_state
!= NULL
;
3489 curr_alt_state
= curr_alt_state
->next_alt_state
)
3490 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3491 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3492 sizeof (alt_state_t
), alt_state_cmp
);
3493 if (VLA_PTR_LENGTH (alt_states
) == 0)
3497 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3498 prev_unique_state_ind
= 0;
3499 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3500 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3502 prev_unique_state_ind
++;
3503 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3506 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3507 free_alt_state (result_ptr
[i
]);
3509 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3510 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3511 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3512 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3513 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3514 result
= *result_ptr
;
3516 VLA_PTR_DELETE (alt_states
);
3520 /* The function checks equality of alt state lists. Remember that the
3521 lists must be already sorted by the previous function. */
3523 alt_states_eq (alt_states_1
, alt_states_2
)
3524 alt_state_t alt_states_1
;
3525 alt_state_t alt_states_2
;
3527 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3528 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3530 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3531 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3533 return alt_states_1
== alt_states_2
;
3536 /* Initialization of the abstract data. */
3538 initiate_alt_states ()
3540 first_free_alt_state
= NULL
;
3543 /* Finishing work with the abstract data. */
3545 finish_alt_states ()
3551 /* The page contains macros for work with bits strings. We could use
3552 standard gcc bitmap or sbitmap but it would result in difficulties
3553 of building canadian cross. */
3555 /* Set bit number bitno in the bit string. The macro is not side
3557 #define SET_BIT(bitstring, bitno) \
3558 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3560 /* Test if bit number bitno in the bitstring is set. The macro is not
3561 side effect proof. */
3562 #define TEST_BIT(bitstring, bitno) \
3563 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3567 /* This page contains abstract data `state'. */
3569 /* Maximal length of reservations in cycles (>= 1). */
3570 static int max_cycles_num
;
3572 /* Number of set elements (see type set_el_t) needed for
3573 representation of one cycle reservation. It is depended on units
3575 static int els_in_cycle_reserv
;
3577 /* Number of set elements (see type set_el_t) needed for
3578 representation of maximal length reservation. Deterministic
3579 reservation is stored as set (bit string) of length equal to the
3580 variable value * number of bits in set_el_t. */
3581 static int els_in_reservs
;
3583 /* VLA for representation of array of pointers to unit
3585 static vla_ptr_t units_container
;
3587 /* The start address of the array. */
3588 static unit_decl_t
*units_array
;
3590 /* Empty reservation of maximal length. */
3591 static reserv_sets_t empty_reserv
;
3593 /* The state table itself is represented by the following variable. */
3594 static htab_t state_table
;
3596 /* VLA for representation of array of pointers to free nodes
3598 static vla_ptr_t free_states
;
3600 static int curr_unique_state_num
;
3603 /* The following variables is maximal number of allocated nodes
3605 static int allocated_states_num
= 0;
3608 /* Allocate new reservation set. */
3609 static reserv_sets_t
3610 alloc_empty_reserv_sets ()
3612 reserv_sets_t result
;
3614 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3615 result
= (reserv_sets_t
) obstack_base (&irp
);
3616 obstack_finish (&irp
);
3617 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3621 /* Hash value of reservation set. */
3623 reserv_sets_hash_value (reservs
)
3624 reserv_sets_t reservs
;
3626 set_el_t hash_value
;
3629 set_el_t
*reserv_ptr
;
3632 reservs_num
= els_in_reservs
;
3633 reserv_ptr
= reservs
;
3635 while (reservs_num
!= 0)
3638 hash_value
+= ((*reserv_ptr
>> i
)
3639 | (*reserv_ptr
<< (sizeof (set_el_t
) * CHAR_BIT
- i
)));
3641 if (i
== sizeof (set_el_t
) * CHAR_BIT
)
3645 if (sizeof (set_el_t
) <= sizeof (unsigned))
3648 for (i
= sizeof (set_el_t
); i
> 0; i
-= sizeof (unsigned) - 1)
3650 result
+= (unsigned) hash_value
;
3651 hash_value
>>= (sizeof (unsigned) - 1) * CHAR_BIT
;
3656 /* Comparison of given reservation sets. */
3658 reserv_sets_cmp (reservs_1
, reservs_2
)
3659 reserv_sets_t reservs_1
;
3660 reserv_sets_t reservs_2
;
3663 set_el_t
*reserv_ptr_1
;
3664 set_el_t
*reserv_ptr_2
;
3666 if (reservs_1
== NULL
|| reservs_2
== NULL
)
3668 reservs_num
= els_in_reservs
;
3669 reserv_ptr_1
= reservs_1
;
3670 reserv_ptr_2
= reservs_2
;
3671 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3677 if (reservs_num
== 0)
3679 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3685 /* The function checks equality of the reservation sets. */
3687 reserv_sets_eq (reservs_1
, reservs_2
)
3688 reserv_sets_t reservs_1
;
3689 reserv_sets_t reservs_2
;
3691 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3694 /* Set up in the reservation set that unit with UNIT_NUM is used on
3697 set_unit_reserv (reservs
, cycle_num
, unit_num
)
3698 reserv_sets_t reservs
;
3702 if (cycle_num
>= max_cycles_num
)
3704 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3705 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3708 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3709 used on CYCLE_NUM. */
3711 test_unit_reserv (reservs
, cycle_num
, unit_num
)
3712 reserv_sets_t reservs
;
3716 if (cycle_num
>= max_cycles_num
)
3718 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3719 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3722 /* The function checks that the reservation set represents no one unit
3725 it_is_empty_reserv_sets (operand
)
3726 reserv_sets_t operand
;
3728 set_el_t
*reserv_ptr
;
3731 if (operand
== NULL
)
3733 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3735 reserv_ptr
++, reservs_num
--)
3736 if (*reserv_ptr
!= 0)
3741 /* The function checks that the reservation sets are intersected,
3742 i.e. there is a unit reservation on a cycle in both reservation
3745 reserv_sets_are_intersected (operand_1
, operand_2
)
3746 reserv_sets_t operand_1
;
3747 reserv_sets_t operand_2
;
3751 set_el_t
*cycle_ptr_1
;
3752 set_el_t
*cycle_ptr_2
;
3755 if (operand_1
== NULL
|| operand_2
== NULL
)
3757 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3758 el_ptr_1
< operand_1
+ els_in_reservs
;
3759 el_ptr_1
++, el_ptr_2
++)
3760 if (*el_ptr_1
& *el_ptr_2
)
3762 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3763 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3764 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3766 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3767 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3768 el_ptr_1
++, el_ptr_2
++)
3769 if (*el_ptr_1
& *el_ptr_2
)
3772 for (el_ptr_1
= cycle_ptr_1
,
3773 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 1);
3774 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3775 el_ptr_1
++, el_ptr_2
++)
3776 if (*el_ptr_1
& *el_ptr_2
)
3778 else if (*el_ptr_2
!= 0)
3780 if (nonzero_p
&& el_ptr_1
>= cycle_ptr_1
+ els_in_cycle_reserv
)
3782 for (el_ptr_1
= cycle_ptr_1
,
3783 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 0);
3784 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3785 el_ptr_1
++, el_ptr_2
++)
3786 /* It looks like code for exclusion but exclusion set is
3787 made as symmetric relation preliminary. */
3788 if (*el_ptr_1
& *el_ptr_2
)
3794 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3795 cpu cycle. The remaining bits of OPERAND (representing the last
3796 cycle unit reservations) are not chenged. */
3798 reserv_sets_shift (result
, operand
)
3799 reserv_sets_t result
;
3800 reserv_sets_t operand
;
3804 if (result
== NULL
|| operand
== NULL
|| result
== operand
)
3806 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3807 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3810 /* OR of the reservation sets. */
3812 reserv_sets_or (result
, operand_1
, operand_2
)
3813 reserv_sets_t result
;
3814 reserv_sets_t operand_1
;
3815 reserv_sets_t operand_2
;
3819 set_el_t
*result_set_el_ptr
;
3821 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3823 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3824 el_ptr_1
< operand_1
+ els_in_reservs
;
3825 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3826 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3829 /* AND of the reservation sets. */
3831 reserv_sets_and (result
, operand_1
, operand_2
)
3832 reserv_sets_t result
;
3833 reserv_sets_t operand_1
;
3834 reserv_sets_t operand_2
;
3838 set_el_t
*result_set_el_ptr
;
3840 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3842 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3843 el_ptr_1
< operand_1
+ els_in_reservs
;
3844 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3845 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3848 /* The function outputs string representation of units reservation on
3849 cycle START_CYCLE in the reservation set. The function uses repeat
3850 construction if REPETITION_NUM > 1. */
3852 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
)
3854 reserv_sets_t reservs
;
3859 int reserved_units_num
;
3861 reserved_units_num
= 0;
3862 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3863 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3864 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3865 reserved_units_num
++;
3866 if (repetition_num
<= 0)
3868 if (repetition_num
!= 1 && reserved_units_num
> 1)
3870 reserved_units_num
= 0;
3872 unit_num
< description
->units_num
;
3874 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3875 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3877 if (reserved_units_num
!= 0)
3879 reserved_units_num
++;
3880 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3882 if (reserved_units_num
== 0)
3883 fprintf (f
, NOTHING_NAME
);
3884 if (repetition_num
<= 0)
3886 if (reserved_units_num
> 1)
3888 if (repetition_num
!= 1)
3889 fprintf (f
, "*%d", repetition_num
);
3892 /* The function outputs string representation of units reservation in
3893 the reservation set. */
3895 output_reserv_sets (f
, reservs
)
3897 reserv_sets_t reservs
;
3899 int start_cycle
= 0;
3904 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
3905 if (repetition_num
== 0)
3908 start_cycle
= cycle
;
3911 ((char *) reservs
+ start_cycle
* els_in_cycle_reserv
3912 * sizeof (set_el_t
),
3913 (char *) reservs
+ cycle
* els_in_cycle_reserv
3914 * sizeof (set_el_t
),
3915 els_in_cycle_reserv
* sizeof (set_el_t
)) == 0)
3919 if (start_cycle
!= 0)
3921 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3923 start_cycle
= cycle
;
3925 if (start_cycle
< max_cycles_num
)
3927 if (start_cycle
!= 0)
3929 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3933 /* The following function returns free node state for AUTOMATON. It
3934 may be new allocated node or node freed eralier. The function also
3935 allocates reservation set if WITH_RESERVS has nonzero value. */
3937 get_free_state (with_reservs
, automaton
)
3939 automaton_t automaton
;
3943 if (max_cycles_num
<= 0 || automaton
== NULL
)
3945 if (VLA_PTR_LENGTH (free_states
) != 0)
3947 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
3948 VLA_PTR_SHORTEN (free_states
, 1);
3949 result
->automaton
= automaton
;
3950 result
->first_out_arc
= NULL
;
3951 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
3952 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
3953 result
->component_states
= NULL
;
3954 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3959 allocated_states_num
++;
3961 result
= create_node (sizeof (struct state
));
3962 result
->automaton
= automaton
;
3963 result
->first_out_arc
= NULL
;
3964 result
->unique_num
= curr_unique_state_num
;
3965 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3966 curr_unique_state_num
++;
3970 if (result
->reservs
== NULL
)
3971 result
->reservs
= alloc_empty_reserv_sets ();
3973 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
3978 /* The function frees node STATE. */
3983 free_alt_states (state
->component_states
);
3984 VLA_PTR_ADD (free_states
, state
);
3987 /* Hash value of STATE. If STATE represents deterministic state it is
3988 simply hash value of the corresponding reservation set. Otherwise
3989 it is formed from hash values of the component deterministic
3990 states. One more key is order number of state automaton. */
3995 unsigned int hash_value
;
3996 alt_state_t alt_state
;
3998 if (((state_t
) state
)->component_states
== NULL
)
3999 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
4003 for (alt_state
= ((state_t
) state
)->component_states
;
4005 alt_state
= alt_state
->next_sorted_alt_state
)
4006 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4007 | (hash_value
<< CHAR_BIT
))
4008 + alt_state
->state
->unique_num
);
4010 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4011 | (hash_value
<< CHAR_BIT
))
4012 + ((state_t
) state
)->automaton
->automaton_order_num
);
4016 /* Return nonzero value if the states are the same. */
4018 state_eq_p (state_1
, state_2
)
4019 const void *state_1
;
4020 const void *state_2
;
4022 alt_state_t alt_state_1
;
4023 alt_state_t alt_state_2
;
4025 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
4027 else if (((state_t
) state_1
)->component_states
== NULL
4028 && ((state_t
) state_2
)->component_states
== NULL
)
4029 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
4030 ((state_t
) state_2
)->reservs
);
4031 else if (((state_t
) state_1
)->component_states
!= NULL
4032 && ((state_t
) state_2
)->component_states
!= NULL
)
4034 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
4035 alt_state_2
= ((state_t
) state_2
)->component_states
;
4036 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
4037 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
4038 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
4039 /* All state in the list must be already in the hash table.
4040 Also the lists must be sorted. */
4041 if (alt_state_1
->state
!= alt_state_2
->state
)
4043 return alt_state_1
== alt_state_2
;
4049 /* Insert STATE into the state table. */
4051 insert_state (state
)
4056 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
4057 if (*entry_ptr
== NULL
)
4058 *entry_ptr
= (void *) state
;
4059 return (state_t
) *entry_ptr
;
4062 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4063 deterministic STATE. */
4065 set_state_reserv (state
, cycle_num
, unit_num
)
4070 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
4073 /* Return nonzero value if the deterministic states contains a
4074 reservation of the same cpu unit on the same cpu cycle. */
4076 intersected_state_reservs_p (state1
, state2
)
4080 if (state1
->automaton
!= state2
->automaton
)
4082 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
4085 /* Return deterministic state (inserted into the table) which
4086 representing the automaton state whic is union of reservations of
4087 deterministic states. */
4089 states_union (state1
, state2
)
4094 state_t state_in_table
;
4096 if (state1
->automaton
!= state2
->automaton
)
4098 result
= get_free_state (1, state1
->automaton
);
4099 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
4100 state_in_table
= insert_state (result
);
4101 if (result
!= state_in_table
)
4103 free_state (result
);
4104 result
= state_in_table
;
4109 /* Return deterministic state (inserted into the table) which
4110 represent the automaton state is obtained from deterministic STATE
4111 by advancing cpu cycle. */
4117 state_t state_in_table
;
4119 result
= get_free_state (1, state
->automaton
);
4120 reserv_sets_shift (result
->reservs
, state
->reservs
);
4121 state_in_table
= insert_state (result
);
4122 if (result
!= state_in_table
)
4124 free_state (result
);
4125 result
= state_in_table
;
4130 /* Initialization of the abstract data. */
4137 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
4139 = (description
->decls_num
&& description
->units_num
4140 ? VLA_PTR_BEGIN (units_container
) : NULL
);
4141 for (i
= 0; i
< description
->decls_num
; i
++)
4143 decl
= description
->decls
[i
];
4144 if (decl
->mode
== dm_unit
)
4145 units_array
[DECL_UNIT (decl
)->unit_num
] = DECL_UNIT (decl
);
4147 max_cycles_num
= description
->max_insn_reserv_cycles
;
4149 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
4150 / (sizeof (set_el_t
) * CHAR_BIT
));
4151 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
4152 curr_unique_state_num
= 0;
4153 initiate_alt_states ();
4154 VLA_PTR_CREATE (free_states
, 1500, "free states");
4155 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
4156 empty_reserv
= alloc_empty_reserv_sets ();
4159 /* Finisging work with the abstract data. */
4163 VLA_PTR_DELETE (units_container
);
4164 htab_delete (state_table
);
4165 VLA_PTR_DELETE (free_states
);
4166 finish_alt_states ();
4171 /* Abstract data `arcs'. */
4173 /* List of free arcs. */
4174 static arc_t first_free_arc
;
4177 /* The following variables is maximal number of allocated nodes
4179 static int allocated_arcs_num
= 0;
4182 /* The function frees node ARC. */
4187 arc
->next_out_arc
= first_free_arc
;
4188 first_free_arc
= arc
;
4191 /* The function removes and frees ARC staring from FROM_STATE. */
4193 remove_arc (from_state
, arc
)
4202 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
4204 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
4205 if (curr_arc
== arc
)
4207 if (curr_arc
== NULL
)
4209 if (prev_arc
== NULL
)
4210 from_state
->first_out_arc
= arc
->next_out_arc
;
4212 prev_arc
->next_out_arc
= arc
->next_out_arc
;
4216 /* The functions returns arc with given characteristics (or NULL if
4217 the arc does not exist). */
4219 find_arc (from_state
, to_state
, insn
)
4226 for (arc
= first_out_arc (from_state
); arc
!= NULL
; arc
= next_out_arc (arc
))
4227 if (arc
->to_state
== to_state
&& arc
->insn
== insn
)
4232 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4233 and with given STATE_ALTS. The function returns added arc (or
4234 already existing arc). */
4236 add_arc (from_state
, to_state
, ainsn
, state_alts
)
4244 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4245 if (new_arc
!= NULL
)
4247 if (first_free_arc
== NULL
)
4250 allocated_arcs_num
++;
4252 new_arc
= create_node (sizeof (struct arc
));
4253 new_arc
->to_state
= NULL
;
4254 new_arc
->insn
= NULL
;
4255 new_arc
->next_out_arc
= NULL
;
4259 new_arc
= first_free_arc
;
4260 first_free_arc
= first_free_arc
->next_out_arc
;
4262 new_arc
->to_state
= to_state
;
4263 new_arc
->insn
= ainsn
;
4264 ainsn
->arc_exists_p
= 1;
4265 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4266 from_state
->first_out_arc
= new_arc
;
4267 new_arc
->next_arc_marked_by_insn
= NULL
;
4268 new_arc
->state_alts
= state_alts
;
4272 /* The function returns the first arc starting from STATE. */
4274 first_out_arc (state
)
4277 return state
->first_out_arc
;
4280 /* The function returns next out arc after ARC. */
4285 return arc
->next_out_arc
;
4288 /* Initialization of the abstract data. */
4292 first_free_arc
= NULL
;
4295 /* Finishing work with the abstract data. */
4303 /* Abstract data `automata lists'. */
4305 /* List of free states. */
4306 static automata_list_el_t first_free_automata_list_el
;
4308 /* The list being formed. */
4309 static automata_list_el_t current_automata_list
;
4311 /* Hash table of automata lists. */
4312 static htab_t automata_list_table
;
4314 /* The following function returns free automata list el. It may be
4315 new allocated node or node freed earlier. */
4316 static automata_list_el_t
4317 get_free_automata_list_el ()
4319 automata_list_el_t result
;
4321 if (first_free_automata_list_el
!= NULL
)
4323 result
= first_free_automata_list_el
;
4324 first_free_automata_list_el
4325 = first_free_automata_list_el
->next_automata_list_el
;
4328 result
= create_node (sizeof (struct automata_list_el
));
4329 result
->automaton
= NULL
;
4330 result
->next_automata_list_el
= NULL
;
4334 /* The function frees node AUTOMATA_LIST_EL. */
4336 free_automata_list_el (automata_list_el
)
4337 automata_list_el_t automata_list_el
;
4339 if (automata_list_el
== NULL
)
4341 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4342 first_free_automata_list_el
= automata_list_el
;
4345 /* The function frees list AUTOMATA_LIST. */
4347 free_automata_list (automata_list
)
4348 automata_list_el_t automata_list
;
4350 automata_list_el_t curr_automata_list_el
;
4351 automata_list_el_t next_automata_list_el
;
4353 for (curr_automata_list_el
= automata_list
;
4354 curr_automata_list_el
!= NULL
;
4355 curr_automata_list_el
= next_automata_list_el
)
4357 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4358 free_automata_list_el (curr_automata_list_el
);
4362 /* Hash value of AUTOMATA_LIST. */
4364 automata_list_hash (automata_list
)
4365 const void *automata_list
;
4367 unsigned int hash_value
;
4368 automata_list_el_t curr_automata_list_el
;
4371 for (curr_automata_list_el
= (automata_list_el_t
) automata_list
;
4372 curr_automata_list_el
!= NULL
;
4373 curr_automata_list_el
= curr_automata_list_el
->next_automata_list_el
)
4374 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4375 | (hash_value
<< CHAR_BIT
))
4376 + curr_automata_list_el
->automaton
->automaton_order_num
);
4380 /* Return nonzero value if the automata_lists are the same. */
4382 automata_list_eq_p (automata_list_1
, automata_list_2
)
4383 const void *automata_list_1
;
4384 const void *automata_list_2
;
4386 automata_list_el_t automata_list_el_1
;
4387 automata_list_el_t automata_list_el_2
;
4389 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4390 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4391 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4392 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4393 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4394 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4396 return automata_list_el_1
== automata_list_el_2
;
4399 /* Initialization of the abstract data. */
4401 initiate_automata_lists ()
4403 first_free_automata_list_el
= NULL
;
4404 automata_list_table
= htab_create (1500, automata_list_hash
,
4405 automata_list_eq_p
, (htab_del
) 0);
4408 /* The following function starts new automata list and makes it the
4411 automata_list_start ()
4413 current_automata_list
= NULL
;
4416 /* The following function adds AUTOMATON to the current list. */
4418 automata_list_add (automaton
)
4419 automaton_t automaton
;
4421 automata_list_el_t el
;
4423 el
= get_free_automata_list_el ();
4424 el
->automaton
= automaton
;
4425 el
->next_automata_list_el
= current_automata_list
;
4426 current_automata_list
= el
;
4429 /* The following function finishes forming the current list, inserts
4430 it into the table and returns it. */
4431 static automata_list_el_t
4432 automata_list_finish ()
4436 if (current_automata_list
== NULL
)
4438 entry_ptr
= htab_find_slot (automata_list_table
,
4439 (void *) current_automata_list
, 1);
4440 if (*entry_ptr
== NULL
)
4441 *entry_ptr
= (void *) current_automata_list
;
4443 free_automata_list (current_automata_list
);
4444 current_automata_list
= NULL
;
4445 return (automata_list_el_t
) *entry_ptr
;
4448 /* Finishing work with the abstract data. */
4450 finish_automata_lists ()
4452 htab_delete (automata_list_table
);
4457 /* The page contains abstract data for work with exclusion sets (see
4458 exclusion_set in file rtl.def). */
4460 /* The following variable refers to an exclusion set returned by
4461 get_excl_set. This is bit string of length equal to cpu units
4462 number. If exclusion set for given unit contains 1 for a unit,
4463 then simultaneous reservation of the units is prohibited. */
4464 static reserv_sets_t excl_set
;
4466 /* The array contains exclusion sets for each unit. */
4467 static reserv_sets_t
*unit_excl_set_table
;
4469 /* The following function forms the array containing exclusion sets
4472 initiate_excl_sets ()
4475 reserv_sets_t unit_excl_set
;
4479 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4480 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4481 obstack_finish (&irp
);
4482 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4483 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4484 obstack_finish (&irp
);
4485 /* Evaluate unit exclusion sets. */
4486 for (i
= 0; i
< description
->decls_num
; i
++)
4488 decl
= description
->decls
[i
];
4489 if (decl
->mode
== dm_unit
)
4491 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4492 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4493 obstack_finish (&irp
);
4494 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4495 for (el
= DECL_UNIT (decl
)->excl_list
;
4497 el
= el
->next_unit_set_el
)
4498 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4499 unit_excl_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_excl_set
;
4504 /* The function sets up and return EXCL_SET which is union of
4505 exclusion sets for each unit in IN_SET. */
4506 static reserv_sets_t
4507 get_excl_set (in_set
)
4508 reserv_sets_t in_set
;
4516 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4517 memset (excl_set
, 0, chars_num
);
4518 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4519 if (((unsigned char *) in_set
) [excl_char_num
])
4520 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4521 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4523 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4524 if (start_unit_num
>= description
->units_num
)
4526 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4529 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4537 /* The page contains abstract data for work with presence/absence sets
4538 (see presence_set/absence_set in file rtl.def). */
4540 /* The following variables refer to correspondingly an presence and an
4541 absence set returned by get_presence_absence_set. This is bit
4542 string of length equal to cpu units number. */
4543 static reserv_sets_t presence_set
, absence_set
;
4545 /* The following arrays contain correspondingly presence and absence
4546 sets for each unit. */
4547 static reserv_sets_t
*unit_presence_set_table
, *unit_absence_set_table
;
4549 /* The following function forms the array containing presence and
4550 absence sets for each unit */
4552 initiate_presence_absence_sets ()
4555 reserv_sets_t unit_set
;
4559 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4560 presence_set
= (reserv_sets_t
) obstack_base (&irp
);
4561 obstack_finish (&irp
);
4562 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4563 unit_presence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4564 obstack_finish (&irp
);
4565 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4566 absence_set
= (reserv_sets_t
) obstack_base (&irp
);
4567 obstack_finish (&irp
);
4568 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4569 unit_absence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4570 obstack_finish (&irp
);
4571 /* Evaluate unit presence/absence sets. */
4572 for (i
= 0; i
< description
->decls_num
; i
++)
4574 decl
= description
->decls
[i
];
4575 if (decl
->mode
== dm_unit
)
4577 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4578 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4579 obstack_finish (&irp
);
4580 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4581 for (el
= DECL_UNIT (decl
)->presence_list
;
4583 el
= el
->next_unit_set_el
)
4584 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4585 unit_presence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4587 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4588 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4589 obstack_finish (&irp
);
4590 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4591 for (el
= DECL_UNIT (decl
)->absence_list
;
4593 el
= el
->next_unit_set_el
)
4594 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4595 unit_absence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4600 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4601 ABSENCE_SET which is union of corresponding sets for each unit in
4603 static reserv_sets_t
4604 get_presence_absence_set (in_set
, presence_p
)
4605 reserv_sets_t in_set
;
4614 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4616 memset (presence_set
, 0, chars_num
);
4618 memset (absence_set
, 0, chars_num
);
4619 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4620 if (((unsigned char *) in_set
) [char_num
])
4621 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4622 if ((((unsigned char *) in_set
) [char_num
] >> i
) & 1)
4624 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4625 if (start_unit_num
>= description
->units_num
)
4626 return (presence_p
? presence_set
: absence_set
);
4627 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4629 presence_set
[unit_num
]
4630 |= unit_presence_set_table
[start_unit_num
] [unit_num
];
4632 absence_set
[unit_num
]
4633 |= unit_absence_set_table
[start_unit_num
] [unit_num
];
4635 return (presence_p
? presence_set
: absence_set
);
4640 /* This page contains code for transformation of original reservations
4641 described in .md file. The main goal of transformations is
4642 simplifying reservation and lifting up all `|' on the top of IR
4643 reservation representation. */
4646 /* The following function makes copy of IR representation of
4647 reservation. The function also substitutes all reservations
4648 defined by define_reservation by corresponding value during making
4651 copy_insn_regexp (regexp
)
4657 if (regexp
->mode
== rm_reserv
)
4658 result
= copy_insn_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
);
4659 else if (regexp
->mode
== rm_unit
)
4660 result
= copy_node (regexp
, sizeof (struct regexp
));
4661 else if (regexp
->mode
== rm_repeat
)
4663 result
= copy_node (regexp
, sizeof (struct regexp
));
4664 REGEXP_REPEAT (result
)->regexp
4665 = copy_insn_regexp (REGEXP_REPEAT (regexp
)->regexp
);
4667 else if (regexp
->mode
== rm_sequence
)
4669 result
= copy_node (regexp
,
4670 sizeof (struct regexp
) + sizeof (regexp_t
)
4671 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4672 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4673 REGEXP_SEQUENCE (result
)->regexps
[i
]
4674 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4676 else if (regexp
->mode
== rm_allof
)
4678 result
= copy_node (regexp
,
4679 sizeof (struct regexp
) + sizeof (regexp_t
)
4680 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4681 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4682 REGEXP_ALLOF (result
)->regexps
[i
]
4683 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4685 else if (regexp
->mode
== rm_oneof
)
4687 result
= copy_node (regexp
,
4688 sizeof (struct regexp
) + sizeof (regexp_t
)
4689 * (REGEXP_ONEOF (regexp
)->regexps_num
- 1));
4690 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4691 REGEXP_ONEOF (result
)->regexps
[i
]
4692 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4696 if (regexp
->mode
!= rm_nothing
)
4698 result
= copy_node (regexp
, sizeof (struct regexp
));
4703 /* The following variable is set up 1 if a transformation has been
4705 static int regexp_transformed_p
;
4707 /* The function makes transformation
4710 transform_1 (regexp
)
4718 if (regexp
->mode
== rm_repeat
)
4720 repeat_num
= REGEXP_REPEAT (regexp
)->repeat_num
;
4721 if (repeat_num
<= 1)
4723 operand
= REGEXP_REPEAT (regexp
)->regexp
;
4725 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4726 * (repeat_num
- 1));
4727 regexp
->mode
= rm_sequence
;
4729 REGEXP_SEQUENCE (regexp
)->regexps_num
= repeat_num
;
4730 for (i
= 0; i
< repeat_num
; i
++)
4731 REGEXP_SEQUENCE (regexp
)->regexps
[i
] = copy_insn_regexp (operand
);
4732 regexp_transformed_p
= 1;
4737 /* The function makes transformations
4738 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4739 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4740 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4742 transform_2 (regexp
)
4745 if (regexp
->mode
== rm_sequence
)
4747 regexp_t sequence
= NULL
;
4749 int sequence_index
= 0;
4752 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4753 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4756 sequence
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4759 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4761 if ( REGEXP_SEQUENCE (sequence
)->regexps_num
<= 1
4762 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4764 result
= create_node (sizeof (struct regexp
)
4766 * (REGEXP_SEQUENCE (regexp
)->regexps_num
4767 + REGEXP_SEQUENCE (sequence
)->regexps_num
4769 result
->mode
= rm_sequence
;
4770 result
->pos
= regexp
->pos
;
4771 REGEXP_SEQUENCE (result
)->regexps_num
4772 = (REGEXP_SEQUENCE (regexp
)->regexps_num
4773 + REGEXP_SEQUENCE (sequence
)->regexps_num
- 1);
4774 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4775 if (i
< sequence_index
)
4776 REGEXP_SEQUENCE (result
)->regexps
[i
]
4777 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4778 else if (i
> sequence_index
)
4779 REGEXP_SEQUENCE (result
)->regexps
4780 [i
+ REGEXP_SEQUENCE (sequence
)->regexps_num
- 1]
4781 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4783 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4784 REGEXP_SEQUENCE (result
)->regexps
[i
+ j
]
4785 = copy_insn_regexp (REGEXP_SEQUENCE (sequence
)->regexps
[j
]);
4786 regexp_transformed_p
= 1;
4790 else if (regexp
->mode
== rm_allof
)
4792 regexp_t allof
= NULL
;
4794 int allof_index
= 0;
4797 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4798 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_allof
)
4801 allof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4804 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4806 if (REGEXP_ALLOF (allof
)->regexps_num
<= 1
4807 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4809 result
= create_node (sizeof (struct regexp
)
4811 * (REGEXP_ALLOF (regexp
)->regexps_num
4812 + REGEXP_ALLOF (allof
)->regexps_num
- 2));
4813 result
->mode
= rm_allof
;
4814 result
->pos
= regexp
->pos
;
4815 REGEXP_ALLOF (result
)->regexps_num
4816 = (REGEXP_ALLOF (regexp
)->regexps_num
4817 + REGEXP_ALLOF (allof
)->regexps_num
- 1);
4818 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4819 if (i
< allof_index
)
4820 REGEXP_ALLOF (result
)->regexps
[i
]
4821 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4822 else if (i
> allof_index
)
4823 REGEXP_ALLOF (result
)->regexps
4824 [i
+ REGEXP_ALLOF (allof
)->regexps_num
- 1]
4825 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4827 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4828 REGEXP_ALLOF (result
)->regexps
[i
+ j
]
4829 = copy_insn_regexp (REGEXP_ALLOF (allof
)->regexps
[j
]);
4830 regexp_transformed_p
= 1;
4834 else if (regexp
->mode
== rm_oneof
)
4836 regexp_t oneof
= NULL
;
4838 int oneof_index
= 0;
4841 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4842 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4845 oneof
= REGEXP_ONEOF (regexp
)->regexps
[i
];
4848 if (i
< REGEXP_ONEOF (regexp
)->regexps_num
)
4850 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4851 || REGEXP_ONEOF (regexp
)->regexps_num
<= 1)
4853 result
= create_node (sizeof (struct regexp
)
4855 * (REGEXP_ONEOF (regexp
)->regexps_num
4856 + REGEXP_ONEOF (oneof
)->regexps_num
- 2));
4857 result
->mode
= rm_oneof
;
4858 result
->pos
= regexp
->pos
;
4859 REGEXP_ONEOF (result
)->regexps_num
4860 = (REGEXP_ONEOF (regexp
)->regexps_num
4861 + REGEXP_ONEOF (oneof
)->regexps_num
- 1);
4862 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4863 if (i
< oneof_index
)
4864 REGEXP_ONEOF (result
)->regexps
[i
]
4865 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4866 else if (i
> oneof_index
)
4867 REGEXP_ONEOF (result
)->regexps
4868 [i
+ REGEXP_ONEOF (oneof
)->regexps_num
- 1]
4869 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4871 for (j
= 0; j
< REGEXP_ONEOF (oneof
)->regexps_num
; j
++)
4872 REGEXP_ONEOF (result
)->regexps
[i
+ j
]
4873 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[j
]);
4874 regexp_transformed_p
= 1;
4881 /* The function makes transformations
4882 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4883 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4884 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4885 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
4887 transform_3 (regexp
)
4890 if (regexp
->mode
== rm_sequence
)
4892 regexp_t oneof
= NULL
;
4893 int oneof_index
= 0;
4898 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4899 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4902 oneof
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4905 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4907 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4908 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4910 result
= create_node (sizeof (struct regexp
)
4912 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4913 result
->mode
= rm_oneof
;
4914 result
->pos
= regexp
->pos
;
4915 REGEXP_ONEOF (result
)->regexps_num
4916 = REGEXP_ONEOF (oneof
)->regexps_num
;
4917 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4920 = create_node (sizeof (struct regexp
)
4922 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4923 sequence
->mode
= rm_sequence
;
4924 sequence
->pos
= regexp
->pos
;
4925 REGEXP_SEQUENCE (sequence
)->regexps_num
4926 = REGEXP_SEQUENCE (regexp
)->regexps_num
;
4927 REGEXP_ONEOF (result
)->regexps
[i
] = sequence
;
4928 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4929 if (j
!= oneof_index
)
4930 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4931 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[j
]);
4933 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4934 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4936 regexp_transformed_p
= 1;
4940 else if (regexp
->mode
== rm_allof
)
4942 regexp_t oneof
= NULL
, seq
;
4943 int oneof_index
= 0, max_seq_length
, allof_length
;
4945 regexp_t allof
= NULL
, allof_op
= NULL
;
4948 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4949 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4952 oneof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4955 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4957 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4958 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4960 result
= create_node (sizeof (struct regexp
)
4962 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4963 result
->mode
= rm_oneof
;
4964 result
->pos
= regexp
->pos
;
4965 REGEXP_ONEOF (result
)->regexps_num
4966 = REGEXP_ONEOF (oneof
)->regexps_num
;
4967 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4970 = create_node (sizeof (struct regexp
)
4972 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4973 allof
->mode
= rm_allof
;
4974 allof
->pos
= regexp
->pos
;
4975 REGEXP_ALLOF (allof
)->regexps_num
4976 = REGEXP_ALLOF (regexp
)->regexps_num
;
4977 REGEXP_ONEOF (result
)->regexps
[i
] = allof
;
4978 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4979 if (j
!= oneof_index
)
4980 REGEXP_ALLOF (allof
)->regexps
[j
]
4981 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[j
]);
4983 REGEXP_ALLOF (allof
)->regexps
[j
]
4984 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4986 regexp_transformed_p
= 1;
4990 if (regexp
->mode
== rm_allof
)
4991 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4992 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4994 seq
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4995 if (max_seq_length
< REGEXP_SEQUENCE (seq
)->regexps_num
)
4996 max_seq_length
= REGEXP_SEQUENCE (seq
)->regexps_num
;
4998 else if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
!= rm_unit
)
5003 if (max_seq_length
!= 0)
5005 if (max_seq_length
== 1 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
5007 result
= create_node (sizeof (struct regexp
)
5008 + sizeof (regexp_t
) * (max_seq_length
- 1));
5009 result
->mode
= rm_sequence
;
5010 result
->pos
= regexp
->pos
;
5011 REGEXP_SEQUENCE (result
)->regexps_num
= max_seq_length
;
5012 for (i
= 0; i
< max_seq_length
; i
++)
5015 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5016 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5017 && (i
< (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5018 ->regexps
[j
])->regexps_num
)))
5021 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)->regexps
[j
])
5026 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5029 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5032 if (allof_length
== 1)
5033 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof_op
;
5036 allof
= create_node (sizeof (struct regexp
)
5038 * (allof_length
- 1));
5039 allof
->mode
= rm_allof
;
5040 allof
->pos
= regexp
->pos
;
5041 REGEXP_ALLOF (allof
)->regexps_num
= allof_length
;
5042 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof
;
5044 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5045 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5047 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5048 ->regexps
[j
])->regexps_num
)))
5050 allof_op
= (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5053 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5058 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5061 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5062 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5068 regexp_transformed_p
= 1;
5075 /* The function traverses IR of reservation and applies transformations
5076 implemented by FUNC. */
5078 regexp_transform_func (regexp
, func
)
5080 regexp_t (*func
) PARAMS ((regexp_t regexp
));
5084 if (regexp
->mode
== rm_sequence
)
5085 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5086 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
5087 = regexp_transform_func (REGEXP_SEQUENCE (regexp
)->regexps
[i
], func
);
5088 else if (regexp
->mode
== rm_allof
)
5089 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5090 REGEXP_ALLOF (regexp
)->regexps
[i
]
5091 = regexp_transform_func (REGEXP_ALLOF (regexp
)->regexps
[i
], func
);
5092 else if (regexp
->mode
== rm_oneof
)
5093 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
5094 REGEXP_ONEOF (regexp
)->regexps
[i
]
5095 = regexp_transform_func (REGEXP_ONEOF (regexp
)->regexps
[i
], func
);
5096 else if (regexp
->mode
== rm_repeat
)
5097 REGEXP_REPEAT (regexp
)->regexp
5098 = regexp_transform_func (REGEXP_REPEAT (regexp
)->regexp
, func
);
5099 else if (regexp
->mode
!= rm_nothing
&& regexp
->mode
!= rm_unit
)
5101 return (*func
) (regexp
);
5104 /* The function applies all transformations for IR representation of
5105 reservation REGEXP. */
5107 transform_regexp (regexp
)
5110 regexp
= regexp_transform_func (regexp
, transform_1
);
5113 regexp_transformed_p
= 0;
5114 regexp
= regexp_transform_func (regexp
, transform_2
);
5115 regexp
= regexp_transform_func (regexp
, transform_3
);
5117 while (regexp_transformed_p
);
5121 /* The function applys all transformations for reservations of all
5122 insn declarations. */
5124 transform_insn_regexps ()
5129 transform_time
= create_ticker ();
5130 add_advance_cycle_insn_decl ();
5131 fprintf (stderr
, "Reservation transformation...");
5133 for (i
= 0; i
< description
->decls_num
; i
++)
5135 decl
= description
->decls
[i
];
5136 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
5137 DECL_INSN_RESERV (decl
)->transformed_regexp
5138 = transform_regexp (copy_insn_regexp
5139 (DECL_INSN_RESERV (decl
)->regexp
));
5141 fprintf (stderr
, "done\n");
5142 ticker_off (&transform_time
);
5148 /* The following variable is an array indexed by cycle. Each element
5149 contains cyclic list of units which should be in the same cycle. */
5150 static unit_decl_t
*the_same_automaton_lists
;
5152 /* The function processes all alternative reservations on CYCLE in
5153 given REGEXP to check the UNIT is not reserved on the all
5154 alternatives. If it is true, the unit should be in the same
5155 automaton with other analogous units reserved on CYCLE in given
5158 process_unit_to_form_the_same_automaton_unit_lists (unit
, regexp
, cycle
)
5164 regexp_t seq
, allof
;
5165 unit_decl_t unit_decl
, last
;
5167 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5169 unit_decl
= REGEXP_UNIT (unit
)->unit_decl
;
5170 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5172 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5173 if (seq
->mode
== rm_sequence
)
5175 if (cycle
>= REGEXP_SEQUENCE (seq
)->regexps_num
)
5177 allof
= REGEXP_SEQUENCE (seq
)->regexps
[cycle
];
5178 if (allof
->mode
== rm_allof
)
5180 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5181 if (REGEXP_ALLOF (allof
)->regexps
[k
]->mode
== rm_unit
5182 && (REGEXP_UNIT (REGEXP_ALLOF (allof
)->regexps
[k
])
5183 ->unit_decl
== unit_decl
))
5185 if (k
>= REGEXP_ALLOF (allof
)->regexps_num
)
5188 else if (allof
->mode
== rm_unit
5189 && REGEXP_UNIT (allof
)->unit_decl
!= unit_decl
)
5192 else if (cycle
!= 0)
5194 else if (seq
->mode
== rm_allof
)
5196 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5197 if (REGEXP_ALLOF (seq
)->regexps
[k
]->mode
== rm_unit
5198 && (REGEXP_UNIT (REGEXP_ALLOF (seq
)->regexps
[k
])->unit_decl
5201 if (k
>= REGEXP_ALLOF (seq
)->regexps_num
)
5204 else if (seq
->mode
== rm_unit
5205 && REGEXP_UNIT (seq
)->unit_decl
!= unit_decl
)
5210 if (the_same_automaton_lists
[cycle
] == NULL
)
5211 the_same_automaton_lists
[cycle
] = unit_decl
;
5214 for (last
= the_same_automaton_lists
[cycle
];;)
5216 if (last
== unit_decl
)
5218 if (last
->the_same_automaton_unit
5219 == the_same_automaton_lists
[cycle
])
5221 last
= last
->the_same_automaton_unit
;
5223 last
->the_same_automaton_unit
= unit_decl
->the_same_automaton_unit
;
5224 unit_decl
->the_same_automaton_unit
5225 = the_same_automaton_lists
[cycle
];
5230 /* The function processes given REGEXP to find units which should be
5231 in the same automaton. */
5233 form_the_same_automaton_unit_lists_from_regexp (regexp
)
5237 regexp_t seq
, allof
, unit
;
5239 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5241 for (i
= 0; i
< description
->max_insn_reserv_cycles
; i
++)
5242 the_same_automaton_lists
[i
] = NULL
;
5243 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5245 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5246 if (seq
->mode
== rm_sequence
)
5247 for (j
= 0; j
< REGEXP_SEQUENCE (seq
)->regexps_num
; j
++)
5249 allof
= REGEXP_SEQUENCE (seq
)->regexps
[j
];
5250 if (allof
->mode
== rm_allof
)
5251 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5253 unit
= REGEXP_ALLOF (allof
)->regexps
[k
];
5254 if (unit
->mode
== rm_unit
)
5255 process_unit_to_form_the_same_automaton_unit_lists
5257 else if (unit
->mode
!= rm_nothing
)
5260 else if (allof
->mode
== rm_unit
)
5261 process_unit_to_form_the_same_automaton_unit_lists
5263 else if (allof
->mode
!= rm_nothing
)
5266 else if (seq
->mode
== rm_allof
)
5267 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5269 unit
= REGEXP_ALLOF (seq
)->regexps
[k
];
5270 if (unit
->mode
== rm_unit
)
5271 process_unit_to_form_the_same_automaton_unit_lists
5273 else if (unit
->mode
!= rm_nothing
)
5276 else if (seq
->mode
== rm_unit
)
5277 process_unit_to_form_the_same_automaton_unit_lists (seq
, regexp
, 0);
5278 else if (seq
->mode
!= rm_nothing
)
5283 /* The function initializes data to search for units which should be
5284 in the same automaton and call function
5285 `form_the_same_automaton_unit_lists_from_regexp' for each insn
5286 reservation regexp. */
5288 form_the_same_automaton_unit_lists ()
5293 the_same_automaton_lists
5294 = (unit_decl_t
*) xmalloc (description
->max_insn_reserv_cycles
5295 * sizeof (unit_decl_t
));
5296 for (i
= 0; i
< description
->decls_num
; i
++)
5298 decl
= description
->decls
[i
];
5299 if (decl
->mode
== dm_unit
)
5301 DECL_UNIT (decl
)->the_same_automaton_message_reported_p
= FALSE
;
5302 DECL_UNIT (decl
)->the_same_automaton_unit
= DECL_UNIT (decl
);
5305 for (i
= 0; i
< description
->decls_num
; i
++)
5307 decl
= description
->decls
[i
];
5308 if (decl
->mode
== dm_insn_reserv
)
5309 form_the_same_automaton_unit_lists_from_regexp
5310 (DECL_INSN_RESERV (decl
)->transformed_regexp
);
5312 free (the_same_automaton_lists
);
5315 /* The function finds units which should be in the same automaton and,
5316 if they are not, reports about it. */
5318 check_unit_distributions_to_automata ()
5321 unit_decl_t start_unit_decl
, unit_decl
;
5324 form_the_same_automaton_unit_lists ();
5325 for (i
= 0; i
< description
->decls_num
; i
++)
5327 decl
= description
->decls
[i
];
5328 if (decl
->mode
== dm_unit
)
5330 start_unit_decl
= DECL_UNIT (decl
);
5331 if (!start_unit_decl
->the_same_automaton_message_reported_p
)
5332 for (unit_decl
= start_unit_decl
->the_same_automaton_unit
;
5333 unit_decl
!= start_unit_decl
;
5334 unit_decl
= unit_decl
->the_same_automaton_unit
)
5335 if (start_unit_decl
->automaton_decl
!= unit_decl
->automaton_decl
)
5337 error ("Units `%s' and `%s' should be in the same automaton",
5338 start_unit_decl
->name
, unit_decl
->name
);
5339 unit_decl
->the_same_automaton_message_reported_p
= TRUE
;
5347 /* The page contains code for building alt_states (see comments for
5348 IR) describing all possible insns reservations of an automaton. */
5350 /* Current state being formed for which the current alt_state
5352 static state_t state_being_formed
;
5354 /* Current alt_state being formed. */
5355 static alt_state_t alt_state_being_formed
;
5357 /* This recursive function processes `,' and units in reservation
5358 REGEXP for forming alt_states of AUTOMATON. It is believed that
5359 CURR_CYCLE is start cycle of all reservation REGEXP. */
5361 process_seq_for_forming_states (regexp
, automaton
, curr_cycle
)
5363 automaton_t automaton
;
5370 else if (regexp
->mode
== rm_unit
)
5372 if (REGEXP_UNIT (regexp
)->unit_decl
->corresponding_automaton_num
5373 == automaton
->automaton_order_num
)
5374 set_state_reserv (state_being_formed
, curr_cycle
,
5375 REGEXP_UNIT (regexp
)->unit_decl
->unit_num
);
5378 else if (regexp
->mode
== rm_sequence
)
5380 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5382 = process_seq_for_forming_states
5383 (REGEXP_SEQUENCE (regexp
)->regexps
[i
], automaton
, curr_cycle
) + 1;
5386 else if (regexp
->mode
== rm_allof
)
5388 int finish_cycle
= 0;
5391 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5393 cycle
= process_seq_for_forming_states (REGEXP_ALLOF (regexp
)
5395 automaton
, curr_cycle
);
5396 if (finish_cycle
< cycle
)
5397 finish_cycle
= cycle
;
5399 return finish_cycle
;
5403 if (regexp
->mode
!= rm_nothing
)
5409 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5410 inserts alt_state into the table. */
5412 finish_forming_alt_state (alt_state
, automaton
)
5413 alt_state_t alt_state
;
5414 automaton_t automaton ATTRIBUTE_UNUSED
;
5416 state_t state_in_table
;
5417 state_t corresponding_state
;
5419 corresponding_state
= alt_state
->state
;
5420 state_in_table
= insert_state (corresponding_state
);
5421 if (state_in_table
!= corresponding_state
)
5423 free_state (corresponding_state
);
5424 alt_state
->state
= state_in_table
;
5428 /* The following variable value is current automaton insn for whose
5429 reservation the alt states are created. */
5430 static ainsn_t curr_ainsn
;
5432 /* This recursive function processes `|' in reservation REGEXP for
5433 forming alt_states of AUTOMATON. List of the alt states should
5434 have the same order as in the description. */
5436 process_alts_for_forming_states (regexp
, automaton
, inside_oneof_p
)
5438 automaton_t automaton
;
5443 if (regexp
->mode
!= rm_oneof
)
5445 alt_state_being_formed
= get_free_alt_state ();
5446 state_being_formed
= get_free_state (1, automaton
);
5447 alt_state_being_formed
->state
= state_being_formed
;
5448 /* We inserts in reverse order but we process alternatives also
5449 in reverse order. So we have the same order of alternative
5450 as in the description. */
5451 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5452 curr_ainsn
->alt_states
= alt_state_being_formed
;
5453 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5454 finish_forming_alt_state (alt_state_being_formed
, automaton
);
5460 /* We processes it in reverse order to get list with the same
5461 order as in the description. See also the previous
5463 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5464 process_alts_for_forming_states (REGEXP_ONEOF (regexp
)->regexps
[i
],
5469 /* Create nodes alt_state for all AUTOMATON insns. */
5471 create_alt_states (automaton
)
5472 automaton_t automaton
;
5474 struct insn_reserv_decl
*reserv_decl
;
5476 for (curr_ainsn
= automaton
->ainsn_list
;
5478 curr_ainsn
= curr_ainsn
->next_ainsn
)
5480 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5481 if (reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5483 curr_ainsn
->alt_states
= NULL
;
5484 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5486 curr_ainsn
->sorted_alt_states
5487 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5494 /* The page contains major code for building DFA(s) for fast pipeline
5495 hazards recognition. */
5497 /* The function forms list of ainsns of AUTOMATON with the same
5500 form_ainsn_with_same_reservs (automaton
)
5501 automaton_t automaton
;
5505 vla_ptr_t first_insns
;
5506 vla_ptr_t last_insns
;
5508 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5509 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5510 for (curr_ainsn
= automaton
->ainsn_list
;
5512 curr_ainsn
= curr_ainsn
->next_ainsn
)
5513 if (curr_ainsn
->insn_reserv_decl
5514 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
5516 curr_ainsn
->next_same_reservs_insn
= NULL
;
5517 curr_ainsn
->first_insn_with_same_reservs
= 1;
5521 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5523 (curr_ainsn
->sorted_alt_states
,
5524 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5526 curr_ainsn
->next_same_reservs_insn
= NULL
;
5527 if (i
< VLA_PTR_LENGTH (first_insns
))
5529 curr_ainsn
->first_insn_with_same_reservs
= 0;
5530 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5532 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5536 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5537 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5538 curr_ainsn
->first_insn_with_same_reservs
= 1;
5541 VLA_PTR_DELETE (first_insns
);
5542 VLA_PTR_DELETE (last_insns
);
5545 /* The following function creates all states of nondeterministic (if
5546 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5548 make_automaton (automaton
)
5549 automaton_t automaton
;
5552 struct insn_reserv_decl
*insn_reserv_decl
;
5553 alt_state_t alt_state
;
5555 state_t start_state
;
5557 ainsn_t advance_cycle_ainsn
;
5559 vla_ptr_t state_stack
;
5561 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5562 /* Create the start state (empty state). */
5563 start_state
= insert_state (get_free_state (1, automaton
));
5564 automaton
->start_state
= start_state
;
5565 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5566 VLA_PTR_ADD (state_stack
, start_state
);
5567 while (VLA_PTR_LENGTH (state_stack
) != 0)
5569 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5570 VLA_PTR_SHORTEN (state_stack
, 1);
5571 advance_cycle_ainsn
= NULL
;
5572 for (ainsn
= automaton
->ainsn_list
;
5574 ainsn
= ainsn
->next_ainsn
)
5575 if (ainsn
->first_insn_with_same_reservs
)
5577 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5578 if (insn_reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5580 /* We process alt_states in the same order as they are
5581 present in the description. */
5583 for (alt_state
= ainsn
->alt_states
;
5585 alt_state
= alt_state
->next_alt_state
)
5587 state2
= alt_state
->state
;
5588 if (!intersected_state_reservs_p (state
, state2
))
5590 state2
= states_union (state
, state2
);
5591 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5593 state2
->it_was_placed_in_stack_for_NDFA_forming
5595 VLA_PTR_ADD (state_stack
, state2
);
5597 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5602 if (!ndfa_flag
&& added_arc
!= NULL
)
5604 added_arc
->state_alts
= 0;
5605 for (alt_state
= ainsn
->alt_states
;
5607 alt_state
= alt_state
->next_alt_state
)
5609 state2
= alt_state
->state
;
5610 if (!intersected_state_reservs_p (state
, state2
))
5611 added_arc
->state_alts
++;
5616 advance_cycle_ainsn
= ainsn
;
5618 /* Add transition to advance cycle. */
5619 state2
= state_shift (state
);
5620 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5622 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5623 VLA_PTR_ADD (state_stack
, state2
);
5625 if (advance_cycle_ainsn
== NULL
)
5627 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5629 VLA_PTR_DELETE (state_stack
);
5632 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5634 form_arcs_marked_by_insn (state
)
5641 for (i
= 0; i
< description
->decls_num
; i
++)
5643 decl
= description
->decls
[i
];
5644 if (decl
->mode
== dm_insn_reserv
)
5645 DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
= NULL
;
5647 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5649 if (arc
->insn
== NULL
)
5651 arc
->next_arc_marked_by_insn
5652 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5653 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5657 /* The function creates composed state (see comments for IR) from
5658 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5659 same insn. If the composed state is not in STATE_STACK yet, it is
5660 popped to STATE_STACK. */
5662 create_composed_state (original_state
, arcs_marked_by_insn
, state_stack
)
5663 state_t original_state
;
5664 arc_t arcs_marked_by_insn
;
5665 vla_ptr_t
*state_stack
;
5668 alt_state_t curr_alt_state
;
5669 alt_state_t new_alt_state
;
5672 state_t state_in_table
;
5674 alt_state_t canonical_alt_states_list
;
5677 if (arcs_marked_by_insn
== NULL
)
5679 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5680 state
= arcs_marked_by_insn
->to_state
;
5685 /* Create composed state. */
5686 state
= get_free_state (0, arcs_marked_by_insn
->to_state
->automaton
);
5687 curr_alt_state
= NULL
;
5688 for (curr_arc
= arcs_marked_by_insn
;
5690 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5692 new_alt_state
= get_free_alt_state ();
5693 new_alt_state
->next_alt_state
= curr_alt_state
;
5694 new_alt_state
->state
= curr_arc
->to_state
;
5695 if (curr_arc
->to_state
->component_states
!= NULL
)
5697 curr_alt_state
= new_alt_state
;
5699 /* There are not identical sets in the alt state list. */
5700 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5701 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5704 state
= canonical_alt_states_list
->state
;
5705 free_state (temp_state
);
5709 state
->component_states
= canonical_alt_states_list
;
5710 state_in_table
= insert_state (state
);
5711 if (state_in_table
!= state
)
5713 if (!state_in_table
->it_was_placed_in_stack_for_DFA_forming
)
5716 state
= state_in_table
;
5720 if (state
->it_was_placed_in_stack_for_DFA_forming
)
5722 for (curr_alt_state
= state
->component_states
;
5723 curr_alt_state
!= NULL
;
5724 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
5725 for (curr_arc
= first_out_arc (curr_alt_state
->state
);
5727 curr_arc
= next_out_arc (curr_arc
))
5728 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5730 arcs_marked_by_insn
->to_state
= state
;
5731 for (alts_number
= 0,
5732 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5734 curr_arc
= next_arc
)
5736 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5737 remove_arc (original_state
, curr_arc
);
5740 arcs_marked_by_insn
->state_alts
= alts_number
;
5743 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5745 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5746 VLA_PTR_ADD (*state_stack
, state
);
5750 /* The function transformes nondeterminstic AUTOMATON into
5753 NDFA_to_DFA (automaton
)
5754 automaton_t automaton
;
5756 state_t start_state
;
5759 vla_ptr_t state_stack
;
5762 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5763 /* Create the start state (empty state). */
5764 start_state
= automaton
->start_state
;
5765 start_state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5766 VLA_PTR_ADD (state_stack
, start_state
);
5767 while (VLA_PTR_LENGTH (state_stack
) != 0)
5769 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5770 VLA_PTR_SHORTEN (state_stack
, 1);
5771 form_arcs_marked_by_insn (state
);
5772 for (i
= 0; i
< description
->decls_num
; i
++)
5774 decl
= description
->decls
[i
];
5775 if (decl
->mode
== dm_insn_reserv
)
5776 create_composed_state
5777 (state
, DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
,
5781 VLA_PTR_DELETE (state_stack
);
5784 /* The following variable value is current number (1, 2, ...) of passing
5786 static int curr_state_graph_pass_num
;
5788 /* This recursive function passes all states achieved from START_STATE
5789 and applies APPLIED_FUNC to them. */
5791 pass_state_graph (start_state
, applied_func
)
5792 state_t start_state
;
5793 void (*applied_func
) PARAMS ((state_t state
));
5797 if (start_state
->pass_num
== curr_state_graph_pass_num
)
5799 start_state
->pass_num
= curr_state_graph_pass_num
;
5800 (*applied_func
) (start_state
);
5801 for (arc
= first_out_arc (start_state
);
5803 arc
= next_out_arc (arc
))
5804 pass_state_graph (arc
->to_state
, applied_func
);
5807 /* This recursive function passes all states of AUTOMATON and applies
5808 APPLIED_FUNC to them. */
5810 pass_states (automaton
, applied_func
)
5811 automaton_t automaton
;
5812 void (*applied_func
) PARAMS ((state_t state
));
5814 curr_state_graph_pass_num
++;
5815 pass_state_graph (automaton
->start_state
, applied_func
);
5818 /* The function initializes code for passing of all states. */
5820 initiate_pass_states ()
5822 curr_state_graph_pass_num
= 0;
5825 /* The following vla is used for storing pointers to all achieved
5827 static vla_ptr_t all_achieved_states
;
5829 /* This function is called by function pass_states to add an achieved
5832 add_achieved_state (state
)
5835 VLA_PTR_ADD (all_achieved_states
, state
);
5838 /* The function sets up equivalence numbers of insns which mark all
5839 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5840 nonzero value) or by equiv_class_num_2 of the destination state.
5841 The function returns number of out arcs of STATE. */
5843 set_out_arc_insns_equiv_num (state
, odd_iteration_flag
)
5845 int odd_iteration_flag
;
5847 int state_out_arcs_num
;
5850 state_out_arcs_num
= 0;
5851 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5853 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
!= 0
5854 || arc
->insn
->insn_reserv_decl
->state_alts
!= 0)
5856 state_out_arcs_num
++;
5857 arc
->insn
->insn_reserv_decl
->equiv_class_num
5858 = (odd_iteration_flag
5859 ? arc
->to_state
->equiv_class_num_1
5860 : arc
->to_state
->equiv_class_num_2
);
5861 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
5862 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
== 0
5863 || arc
->insn
->insn_reserv_decl
->state_alts
<= 0)
5866 return state_out_arcs_num
;
5869 /* The function clears equivalence numbers and alt_states in all insns
5870 which mark all out arcs of STATE. */
5872 clear_arc_insns_equiv_num (state
)
5877 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5879 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
5880 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
5884 /* The function copies pointers to equivalent states from vla FROM
5887 copy_equiv_class (to
, from
)
5889 const vla_ptr_t
*from
;
5893 VLA_PTR_NULLIFY (*to
);
5894 for (class_ptr
= VLA_PTR_BEGIN (*from
);
5895 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
5897 VLA_PTR_ADD (*to
, *class_ptr
);
5900 /* The function returns nonzero value if STATE is not equivalent to
5901 another state from the same current partition on equivalence
5902 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5903 output arcs. Iteration of making equivalence partition is defined
5904 by ODD_ITERATION_FLAG. */
5906 state_is_differed (state
, original_state_out_arcs_num
, odd_iteration_flag
)
5908 int original_state_out_arcs_num
;
5909 int odd_iteration_flag
;
5912 int state_out_arcs_num
;
5914 state_out_arcs_num
= 0;
5915 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5917 state_out_arcs_num
++;
5918 if ((odd_iteration_flag
5919 ? arc
->to_state
->equiv_class_num_1
5920 : arc
->to_state
->equiv_class_num_2
)
5921 != arc
->insn
->insn_reserv_decl
->equiv_class_num
5922 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
5925 return state_out_arcs_num
!= original_state_out_arcs_num
;
5928 /* The function makes initial partition of STATES on equivalent
5931 init_equiv_class (states
, states_num
)
5936 state_t result_equiv_class
;
5938 result_equiv_class
= NULL
;
5939 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
5941 (*state_ptr
)->equiv_class_num_1
= 1;
5942 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
5943 result_equiv_class
= *state_ptr
;
5945 return result_equiv_class
;
5948 /* The function processes equivalence class given by its pointer
5949 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5950 are not equvalent states, the function partitions the class
5951 removing nonequivalent states and placing them in
5952 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5953 assigns it to the state equivalence number. If the class has been
5954 partitioned, the function returns nonzero value. */
5956 partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5957 next_iteration_classes
, new_equiv_class_num_ptr
)
5958 state_t
*equiv_class_ptr
;
5959 int odd_iteration_flag
;
5960 vla_ptr_t
*next_iteration_classes
;
5961 int *new_equiv_class_num_ptr
;
5963 state_t new_equiv_class
;
5965 state_t first_state
;
5972 if (*equiv_class_ptr
== NULL
)
5974 for (first_state
= *equiv_class_ptr
;
5975 first_state
!= NULL
;
5976 first_state
= new_equiv_class
)
5978 new_equiv_class
= NULL
;
5979 if (first_state
->next_equiv_class_state
!= NULL
)
5981 /* There are more one states in the class equivalence. */
5982 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
5983 odd_iteration_flag
);
5984 for (prev_state
= first_state
,
5985 curr_state
= first_state
->next_equiv_class_state
;
5987 curr_state
= next_state
)
5989 next_state
= curr_state
->next_equiv_class_state
;
5990 if (state_is_differed (curr_state
, out_arcs_num
,
5991 odd_iteration_flag
))
5993 /* Remove curr state from the class equivalence. */
5994 prev_state
->next_equiv_class_state
= next_state
;
5995 /* Add curr state to the new class equivalence. */
5996 curr_state
->next_equiv_class_state
= new_equiv_class
;
5997 if (new_equiv_class
== NULL
)
5998 (*new_equiv_class_num_ptr
)++;
5999 if (odd_iteration_flag
)
6000 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
6002 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
6003 new_equiv_class
= curr_state
;
6007 prev_state
= curr_state
;
6009 clear_arc_insns_equiv_num (first_state
);
6011 if (new_equiv_class
!= NULL
)
6012 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
6017 /* The function finds equivalent states of AUTOMATON. */
6019 evaluate_equiv_classes (automaton
, equiv_classes
)
6020 automaton_t automaton
;
6021 vla_ptr_t
*equiv_classes
;
6023 state_t new_equiv_class
;
6024 int new_equiv_class_num
;
6025 int odd_iteration_flag
;
6027 vla_ptr_t next_iteration_classes
;
6028 state_t
*equiv_class_ptr
;
6031 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
6032 pass_states (automaton
, add_achieved_state
);
6033 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
6034 VLA_PTR_LENGTH (all_achieved_states
));
6035 odd_iteration_flag
= 0;
6036 new_equiv_class_num
= 1;
6037 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
6038 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
6041 odd_iteration_flag
= !odd_iteration_flag
;
6043 copy_equiv_class (equiv_classes
, &next_iteration_classes
);
6044 /* Transfer equiv numbers for the next iteration. */
6045 for (state_ptr
= VLA_PTR_BEGIN (all_achieved_states
);
6046 state_ptr
<= (state_t
*) VLA_PTR_LAST (all_achieved_states
);
6048 if (odd_iteration_flag
)
6049 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
6051 (*state_ptr
)->equiv_class_num_1
= (*state_ptr
)->equiv_class_num_2
;
6052 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6053 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6055 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
6056 &next_iteration_classes
,
6057 &new_equiv_class_num
))
6060 while (!finish_flag
);
6061 VLA_PTR_DELETE (next_iteration_classes
);
6062 VLA_PTR_DELETE (all_achieved_states
);
6065 /* The function merges equivalent states of AUTOMATON. */
6067 merge_states (automaton
, equiv_classes
)
6068 automaton_t automaton
;
6069 vla_ptr_t
*equiv_classes
;
6071 state_t
*equiv_class_ptr
;
6074 state_t first_class_state
;
6075 alt_state_t alt_states
;
6076 alt_state_t new_alt_state
;
6080 /* Create states corresponding to equivalence classes containing two
6082 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6083 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6085 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6087 /* There are more one states in the class equivalence. */
6088 /* Create new compound state. */
6089 new_state
= get_free_state (0, automaton
);
6091 first_class_state
= *equiv_class_ptr
;
6092 for (curr_state
= first_class_state
;
6094 curr_state
= curr_state
->next_equiv_class_state
)
6096 curr_state
->equiv_class_state
= new_state
;
6097 new_alt_state
= get_free_alt_state ();
6098 new_alt_state
->state
= curr_state
;
6099 new_alt_state
->next_sorted_alt_state
= alt_states
;
6100 alt_states
= new_alt_state
;
6102 new_state
->component_states
= alt_states
;
6105 (*equiv_class_ptr
)->equiv_class_state
= *equiv_class_ptr
;
6106 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6107 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6109 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6111 first_class_state
= *equiv_class_ptr
;
6112 /* Create new arcs output from the state corresponding to
6114 for (curr_arc
= first_out_arc (first_class_state
);
6116 curr_arc
= next_out_arc (curr_arc
))
6117 add_arc (first_class_state
->equiv_class_state
,
6118 curr_arc
->to_state
->equiv_class_state
,
6119 curr_arc
->insn
, curr_arc
->state_alts
);
6120 /* Delete output arcs from states of given class equivalence. */
6121 for (curr_state
= first_class_state
;
6123 curr_state
= curr_state
->next_equiv_class_state
)
6125 if (automaton
->start_state
== curr_state
)
6126 automaton
->start_state
= curr_state
->equiv_class_state
;
6127 /* Delete the state and its output arcs. */
6128 for (curr_arc
= first_out_arc (curr_state
);
6130 curr_arc
= next_arc
)
6132 next_arc
= next_out_arc (curr_arc
);
6133 free_arc (curr_arc
);
6139 /* Change `to_state' of arcs output from the state of given
6140 equivalence class. */
6141 for (curr_arc
= first_out_arc (*equiv_class_ptr
);
6143 curr_arc
= next_out_arc (curr_arc
))
6144 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
6148 /* The function sets up new_cycle_p for states if there is arc to the
6149 state marked by advance_cycle_insn_decl. */
6151 set_new_cycle_flags (state
)
6156 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6157 if (arc
->insn
->insn_reserv_decl
6158 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
6159 arc
->to_state
->new_cycle_p
= 1;
6162 /* The top level function for minimization of deterministic
6165 minimize_DFA (automaton
)
6166 automaton_t automaton
;
6168 vla_ptr_t equiv_classes
;
6170 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
6171 evaluate_equiv_classes (automaton
, &equiv_classes
);
6172 merge_states (automaton
, &equiv_classes
);
6173 pass_states (automaton
, set_new_cycle_flags
);
6174 VLA_PTR_DELETE (equiv_classes
);
6177 /* Values of two variables are counted number of states and arcs in an
6179 static int curr_counted_states_num
;
6180 static int curr_counted_arcs_num
;
6182 /* The function is called by function `pass_states' to count states
6183 and arcs of an automaton. */
6185 incr_states_and_arcs_nums (state
)
6190 curr_counted_states_num
++;
6191 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6192 curr_counted_arcs_num
++;
6195 /* The function counts states and arcs of AUTOMATON. */
6197 count_states_and_arcs (automaton
, states_num
, arcs_num
)
6198 automaton_t automaton
;
6202 curr_counted_states_num
= 0;
6203 curr_counted_arcs_num
= 0;
6204 pass_states (automaton
, incr_states_and_arcs_nums
);
6205 *states_num
= curr_counted_states_num
;
6206 *arcs_num
= curr_counted_arcs_num
;
6209 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6210 recognition after checking and simplifying IR of the
6213 build_automaton (automaton
)
6214 automaton_t automaton
;
6219 ticker_on (&NDFA_time
);
6220 make_automaton (automaton
);
6221 ticker_off (&NDFA_time
);
6222 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6223 automaton
->NDFA_states_num
= states_num
;
6224 automaton
->NDFA_arcs_num
= arcs_num
;
6225 ticker_on (&NDFA_to_DFA_time
);
6226 NDFA_to_DFA (automaton
);
6227 ticker_off (&NDFA_to_DFA_time
);
6228 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6229 automaton
->DFA_states_num
= states_num
;
6230 automaton
->DFA_arcs_num
= arcs_num
;
6231 if (!no_minimization_flag
)
6233 ticker_on (&minimize_time
);
6234 minimize_DFA (automaton
);
6235 ticker_off (&minimize_time
);
6236 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6237 automaton
->minimal_DFA_states_num
= states_num
;
6238 automaton
->minimal_DFA_arcs_num
= arcs_num
;
6244 /* The page contains code for enumeration of all states of an automaton. */
6246 /* Variable used for enumeration of all states of an automaton. Its
6247 value is current number of automaton states. */
6248 static int curr_state_order_num
;
6250 /* The function is called by function `pass_states' for enumerating
6253 set_order_state_num (state
)
6256 state
->order_state_num
= curr_state_order_num
;
6257 curr_state_order_num
++;
6260 /* The function enumerates all states of AUTOMATON. */
6262 enumerate_states (automaton
)
6263 automaton_t automaton
;
6265 curr_state_order_num
= 0;
6266 pass_states (automaton
, set_order_state_num
);
6267 automaton
->achieved_states_num
= curr_state_order_num
;
6272 /* The page contains code for finding equivalent automaton insns
6275 /* The function inserts AINSN into cyclic list
6276 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6278 insert_ainsn_into_equiv_class (ainsn
, cyclic_equiv_class_insn_list
)
6280 ainsn_t cyclic_equiv_class_insn_list
;
6282 if (cyclic_equiv_class_insn_list
== NULL
)
6283 ainsn
->next_equiv_class_insn
= ainsn
;
6286 ainsn
->next_equiv_class_insn
6287 = cyclic_equiv_class_insn_list
->next_equiv_class_insn
;
6288 cyclic_equiv_class_insn_list
->next_equiv_class_insn
= ainsn
;
6293 /* The function deletes equiv_class_insn into cyclic list of
6294 equivalent ainsns. */
6296 delete_ainsn_from_equiv_class (equiv_class_insn
)
6297 ainsn_t equiv_class_insn
;
6299 ainsn_t curr_equiv_class_insn
;
6300 ainsn_t prev_equiv_class_insn
;
6302 prev_equiv_class_insn
= equiv_class_insn
;
6303 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
6304 curr_equiv_class_insn
!= equiv_class_insn
;
6305 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
6306 prev_equiv_class_insn
= curr_equiv_class_insn
;
6307 if (prev_equiv_class_insn
!= equiv_class_insn
)
6308 prev_equiv_class_insn
->next_equiv_class_insn
6309 = equiv_class_insn
->next_equiv_class_insn
;
6312 /* The function processes AINSN of a state in order to find equivalent
6313 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6316 process_insn_equiv_class (ainsn
, insn_arcs_array
)
6318 arc_t
*insn_arcs_array
;
6322 ainsn_t cyclic_insn_list
;
6325 if (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
] == NULL
)
6328 /* New class of ainsns which are not equivalent to given ainsn. */
6329 cyclic_insn_list
= NULL
;
6332 next_insn
= curr_insn
->next_equiv_class_insn
;
6333 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6335 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6338 delete_ainsn_from_equiv_class (curr_insn
);
6339 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6342 curr_insn
= next_insn
;
6344 while (curr_insn
!= ainsn
);
6347 /* The function processes STATE in order to find equivalent ainsns. */
6349 process_state_for_insn_equiv_partition (state
)
6353 arc_t
*insn_arcs_array
;
6355 vla_ptr_t insn_arcs_vect
;
6357 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6358 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6359 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6360 /* Process insns of the arcs. */
6361 for (i
= 0; i
< description
->insns_num
; i
++)
6362 insn_arcs_array
[i
] = NULL
;
6363 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6364 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6365 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6366 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6367 VLA_PTR_DELETE (insn_arcs_vect
);
6370 /* The function searches for equivalent ainsns of AUTOMATON. */
6372 set_insn_equiv_classes (automaton
)
6373 automaton_t automaton
;
6378 ainsn_t cyclic_insn_list
;
6379 ainsn_t insn_with_same_reservs
;
6380 int equiv_classes_num
;
6382 /* All insns are included in one equivalence class. */
6383 cyclic_insn_list
= NULL
;
6384 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6385 if (ainsn
->first_insn_with_same_reservs
)
6386 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
6388 /* Process insns in order to make equivalence partition. */
6389 pass_states (automaton
, process_state_for_insn_equiv_partition
);
6390 /* Enumerate equiv classes. */
6391 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6392 /* Set undefined value. */
6393 ainsn
->insn_equiv_class_num
= -1;
6394 equiv_classes_num
= 0;
6395 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6396 if (ainsn
->insn_equiv_class_num
< 0)
6399 if (!first_insn
->first_insn_with_same_reservs
)
6401 first_insn
->first_ainsn_with_given_equialence_num
= 1;
6402 curr_insn
= first_insn
;
6405 for (insn_with_same_reservs
= curr_insn
;
6406 insn_with_same_reservs
!= NULL
;
6407 insn_with_same_reservs
6408 = insn_with_same_reservs
->next_same_reservs_insn
)
6409 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6410 curr_insn
= curr_insn
->next_equiv_class_insn
;
6412 while (curr_insn
!= first_insn
);
6413 equiv_classes_num
++;
6415 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6420 /* This page contains code for creating DFA(s) and calls functions
6424 /* The following value is used to prevent floating point overflow for
6425 estimating an automaton bound. The value should be less DBL_MAX on
6426 the host machine. We use here approximate minimum of maximal
6427 double floating point value required by ANSI C standard. It
6428 will work for non ANSI sun compiler too. */
6430 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6432 /* The function estimate size of the single DFA used by PHR (pipeline
6433 hazards recognizer). */
6435 estimate_one_automaton_bound ()
6438 double one_automaton_estimation_bound
;
6442 one_automaton_estimation_bound
= 1.0;
6443 for (i
= 0; i
< description
->decls_num
; i
++)
6445 decl
= description
->decls
[i
];
6446 if (decl
->mode
== dm_unit
)
6448 root_value
= exp (log (DECL_UNIT (decl
)->max_occ_cycle_num
+ 1.0)
6450 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6451 > one_automaton_estimation_bound
)
6452 one_automaton_estimation_bound
*= root_value
;
6455 return one_automaton_estimation_bound
;
6458 /* The function compares unit declarations acoording to their maximal
6459 cycle in reservations. */
6461 compare_max_occ_cycle_nums (unit_decl_1
, unit_decl_2
)
6462 const void *unit_decl_1
;
6463 const void *unit_decl_2
;
6465 if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6466 < (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6468 else if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6469 == (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6475 /* The function makes heuristic assigning automata to units. Actually
6476 efficacy of the algorithm has been checked yet??? */
6478 units_to_automata_heuristic_distr ()
6480 double estimation_bound
;
6482 decl_t
*unit_decl_ptr
;
6486 vla_ptr_t unit_decls
;
6489 if (description
->units_num
== 0)
6491 estimation_bound
= estimate_one_automaton_bound ();
6492 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6493 for (i
= 0; i
< description
->decls_num
; i
++)
6495 decl
= description
->decls
[i
];
6496 if (decl
->mode
== dm_unit
)
6497 VLA_PTR_ADD (unit_decls
, decl
);
6499 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6500 sizeof (decl_t
), compare_max_occ_cycle_nums
);
6502 unit_decl_ptr
= VLA_PTR_BEGIN (unit_decls
);
6503 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6504 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6505 for (unit_decl_ptr
++;
6506 unit_decl_ptr
<= (decl_t
*) VLA_PTR_LAST (unit_decls
);
6510 = ((decl_t
*) VLA_PTR_LAST (unit_decls
) - unit_decl_ptr
+ 1);
6511 if (automata_num
- automaton_num
- 1 > rest_units_num
)
6513 if (automaton_num
< automata_num
- 1
6514 && ((automata_num
- automaton_num
- 1 == rest_units_num
)
6517 / (DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
)))))
6519 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6523 bound_value
*= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6524 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6526 if (automaton_num
!= automata_num
- 1)
6528 VLA_PTR_DELETE (unit_decls
);
6531 /* The functions creates automaton insns for each automata. Automaton
6532 insn is simply insn for given automaton which makes reservation
6533 only of units of the automaton. */
6538 ainsn_t first_ainsn
;
6545 for (i
= 0; i
< description
->decls_num
; i
++)
6547 decl
= description
->decls
[i
];
6548 if (decl
->mode
== dm_insn_reserv
)
6550 curr_ainsn
= create_node (sizeof (struct ainsn
));
6551 curr_ainsn
->insn_reserv_decl
= DECL_INSN_RESERV (decl
);
6552 curr_ainsn
->important_p
= FALSE
;
6553 curr_ainsn
->next_ainsn
= NULL
;
6554 if (prev_ainsn
== NULL
)
6555 first_ainsn
= curr_ainsn
;
6557 prev_ainsn
->next_ainsn
= curr_ainsn
;
6558 prev_ainsn
= curr_ainsn
;
6564 /* The function assigns automata to units according to constructions
6565 `define_automaton' in the description. */
6567 units_to_automata_distr ()
6572 for (i
= 0; i
< description
->decls_num
; i
++)
6574 decl
= description
->decls
[i
];
6575 if (decl
->mode
== dm_unit
)
6577 if (DECL_UNIT (decl
)->automaton_decl
== NULL
6578 || (DECL_UNIT (decl
)->automaton_decl
->corresponding_automaton
6580 /* Distribute to the first automaton. */
6581 DECL_UNIT (decl
)->corresponding_automaton_num
= 0;
6583 DECL_UNIT (decl
)->corresponding_automaton_num
6584 = (DECL_UNIT (decl
)->automaton_decl
6585 ->corresponding_automaton
->automaton_order_num
);
6590 /* The function creates DFA(s) for fast pipeline hazards recognition
6591 after checking and simplifying IR of the description. */
6595 automaton_t curr_automaton
;
6596 automaton_t prev_automaton
;
6598 int curr_automaton_num
;
6601 if (automata_num
!= 0)
6603 units_to_automata_heuristic_distr ();
6604 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6605 curr_automaton_num
< automata_num
;
6606 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6608 curr_automaton
= create_node (sizeof (struct automaton
));
6609 curr_automaton
->ainsn_list
= create_ainsns ();
6610 curr_automaton
->corresponding_automaton_decl
= NULL
;
6611 curr_automaton
->next_automaton
= NULL
;
6612 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6613 if (prev_automaton
== NULL
)
6614 description
->first_automaton
= curr_automaton
;
6616 prev_automaton
->next_automaton
= curr_automaton
;
6621 curr_automaton_num
= 0;
6622 prev_automaton
= NULL
;
6623 for (i
= 0; i
< description
->decls_num
; i
++)
6625 decl
= description
->decls
[i
];
6626 if (decl
->mode
== dm_automaton
6627 && DECL_AUTOMATON (decl
)->automaton_is_used
)
6629 curr_automaton
= create_node (sizeof (struct automaton
));
6630 curr_automaton
->ainsn_list
= create_ainsns ();
6631 curr_automaton
->corresponding_automaton_decl
6632 = DECL_AUTOMATON (decl
);
6633 curr_automaton
->next_automaton
= NULL
;
6634 DECL_AUTOMATON (decl
)->corresponding_automaton
= curr_automaton
;
6635 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6636 if (prev_automaton
== NULL
)
6637 description
->first_automaton
= curr_automaton
;
6639 prev_automaton
->next_automaton
= curr_automaton
;
6640 curr_automaton_num
++;
6641 prev_automaton
= curr_automaton
;
6644 if (curr_automaton_num
== 0)
6646 curr_automaton
= create_node (sizeof (struct automaton
));
6647 curr_automaton
->ainsn_list
= create_ainsns ();
6648 curr_automaton
->corresponding_automaton_decl
= NULL
;
6649 curr_automaton
->next_automaton
= NULL
;
6650 description
->first_automaton
= curr_automaton
;
6652 units_to_automata_distr ();
6654 NDFA_time
= create_ticker ();
6655 ticker_off (&NDFA_time
);
6656 NDFA_to_DFA_time
= create_ticker ();
6657 ticker_off (&NDFA_to_DFA_time
);
6658 minimize_time
= create_ticker ();
6659 ticker_off (&minimize_time
);
6660 equiv_time
= create_ticker ();
6661 ticker_off (&equiv_time
);
6662 for (curr_automaton
= description
->first_automaton
;
6663 curr_automaton
!= NULL
;
6664 curr_automaton
= curr_automaton
->next_automaton
)
6666 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6667 fprintf (stderr
, "Create anonymous automaton ...");
6669 fprintf (stderr
, "Create automaton `%s'...",
6670 curr_automaton
->corresponding_automaton_decl
->name
);
6671 create_alt_states (curr_automaton
);
6672 form_ainsn_with_same_reservs (curr_automaton
);
6673 build_automaton (curr_automaton
);
6674 enumerate_states (curr_automaton
);
6675 ticker_on (&equiv_time
);
6676 set_insn_equiv_classes (curr_automaton
);
6677 ticker_off (&equiv_time
);
6678 fprintf (stderr
, "done\n");
6684 /* This page contains code for forming string representation of
6685 regexp. The representation is formed on IR obstack. So you should
6686 not work with IR obstack between regexp_representation and
6687 finish_regexp_representation calls. */
6689 /* This recursive function forms string representation of regexp
6690 (without tailing '\0'). */
6692 form_regexp (regexp
)
6697 if (regexp
->mode
== rm_unit
|| regexp
->mode
== rm_reserv
)
6699 const char *name
= (regexp
->mode
== rm_unit
6700 ? REGEXP_UNIT (regexp
)->name
6701 : REGEXP_RESERV (regexp
)->name
);
6703 obstack_grow (&irp
, name
, strlen (name
));
6705 else if (regexp
->mode
== rm_sequence
)
6706 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
6709 obstack_1grow (&irp
, ',');
6710 form_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
6712 else if (regexp
->mode
== rm_allof
)
6714 obstack_1grow (&irp
, '(');
6715 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
6718 obstack_1grow (&irp
, '+');
6719 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6720 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6721 obstack_1grow (&irp
, '(');
6722 form_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
6723 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6724 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6725 obstack_1grow (&irp
, ')');
6727 obstack_1grow (&irp
, ')');
6729 else if (regexp
->mode
== rm_oneof
)
6730 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
6733 obstack_1grow (&irp
, '|');
6734 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6735 obstack_1grow (&irp
, '(');
6736 form_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
6737 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6738 obstack_1grow (&irp
, ')');
6740 else if (regexp
->mode
== rm_repeat
)
6744 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6745 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6746 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6747 obstack_1grow (&irp
, '(');
6748 form_regexp (REGEXP_REPEAT (regexp
)->regexp
);
6749 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6750 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6751 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6752 obstack_1grow (&irp
, ')');
6753 sprintf (digits
, "*%d", REGEXP_REPEAT (regexp
)->repeat_num
);
6754 obstack_grow (&irp
, digits
, strlen (digits
));
6756 else if (regexp
->mode
== rm_nothing
)
6757 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
6762 /* The function returns string representation of REGEXP on IR
6765 regexp_representation (regexp
)
6768 form_regexp (regexp
);
6769 obstack_1grow (&irp
, '\0');
6770 return obstack_base (&irp
);
6773 /* The function frees memory allocated for last formed string
6774 representation of regexp. */
6776 finish_regexp_representation ()
6778 int length
= obstack_object_size (&irp
);
6780 obstack_blank_fast (&irp
, -length
);
6785 /* This page contains code for output PHR (pipeline hazards recognizer). */
6787 /* The function outputs minimal C type which is sufficient for
6788 representation numbers in range min_range_value and
6789 max_range_value. Because host machine and build machine may be
6790 different, we use here minimal values required by ANSI C standard
6791 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6795 output_range_type (f
, min_range_value
, max_range_value
)
6797 long int min_range_value
;
6798 long int max_range_value
;
6800 if (min_range_value
>= 0 && max_range_value
<= 255)
6801 fprintf (f
, "unsigned char");
6802 else if (min_range_value
>= -127 && max_range_value
<= 127)
6803 fprintf (f
, "signed char");
6804 else if (min_range_value
>= 0 && max_range_value
<= 65535)
6805 fprintf (f
, "unsigned short");
6806 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
6807 fprintf (f
, "short");
6812 /* The following macro value is used as value of member
6813 `longest_path_length' of state when we are processing path and the
6814 state on the path. */
6816 #define ON_THE_PATH -2
6818 /* The following recursive function searches for the length of the
6819 longest path starting from STATE which does not contain cycles and
6820 `cycle advance' arcs. */
6823 longest_path_length (state
)
6829 if (state
->longest_path_length
== ON_THE_PATH
)
6830 /* We don't expect the path cycle here. Our graph may contain
6831 only cycles with one state on the path not containing `cycle
6832 advance' arcs -- see comment below. */
6834 else if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
6835 /* We alreday visited the state. */
6836 return state
->longest_path_length
;
6839 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6840 /* Ignore cycles containing one state and `cycle advance' arcs. */
6841 if (arc
->to_state
!= state
6842 && (arc
->insn
->insn_reserv_decl
6843 != DECL_INSN_RESERV (advance_cycle_insn_decl
)))
6845 length
= longest_path_length (arc
->to_state
);
6846 if (length
> result
)
6849 state
->longest_path_length
= result
+ 1;
6853 /* The following variable value is value of the corresponding global
6854 variable in the automaton based pipeline interface. */
6856 static int max_dfa_issue_rate
;
6858 /* The following function processes the longest path length staring
6859 from STATE to find MAX_DFA_ISSUE_RATE. */
6862 process_state_longest_path_length (state
)
6867 value
= longest_path_length (state
);
6868 if (value
> max_dfa_issue_rate
)
6869 max_dfa_issue_rate
= value
;
6872 /* The following macro value is name of the corresponding global
6873 variable in the automaton based pipeline interface. */
6875 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6877 /* The following function calculates value of the the corresponding
6878 global variable and outputs its declaration. */
6881 output_dfa_max_issue_rate ()
6883 automaton_t automaton
;
6885 if (UNDEFINED_LONGEST_PATH_LENGTH
== ON_THE_PATH
|| ON_THE_PATH
>= 0)
6887 max_dfa_issue_rate
= 0;
6888 for (automaton
= description
->first_automaton
;
6890 automaton
= automaton
->next_automaton
)
6891 pass_states (automaton
, process_state_longest_path_length
);
6892 fprintf (output_file
, "\nint %s = %d;\n",
6893 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
6896 /* The function outputs all initialization values of VECT with length
6899 output_vect (vect
, vect_length
)
6906 if (vect_length
== 0)
6907 fprintf (output_file
,
6908 "0 /* This is dummy el because the vect is empty */");
6913 fprintf (output_file
, "%5ld", (long) *vect
);
6915 if (els_on_line
== 10)
6918 fprintf (output_file
, ",\n");
6920 else if (vect_length
!= 0)
6921 fprintf (output_file
, ", ");
6925 while (vect_length
!= 0);
6929 /* The following is name of the structure which represents DFA(s) for
6931 #define CHIP_NAME "DFA_chip"
6933 /* The following is name of member which represents state of a DFA for
6936 output_chip_member_name (f
, automaton
)
6938 automaton_t automaton
;
6940 if (automaton
->corresponding_automaton_decl
== NULL
)
6941 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
6943 fprintf (f
, "%s_automaton_state",
6944 automaton
->corresponding_automaton_decl
->name
);
6947 /* The following is name of temporary variable which stores state of a
6950 output_temp_chip_member_name (f
, automaton
)
6952 automaton_t automaton
;
6955 output_chip_member_name (f
, automaton
);
6958 /* This is name of macro value which is code of pseudo_insn
6959 representing advancing cpu cycle. Its value is used as internal
6960 code unknown insn. */
6961 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6963 /* Output name of translate vector for given automaton. */
6965 output_translate_vect_name (f
, automaton
)
6967 automaton_t automaton
;
6969 if (automaton
->corresponding_automaton_decl
== NULL
)
6970 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
6972 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
6975 /* Output name for simple transition table representation. */
6977 output_trans_full_vect_name (f
, automaton
)
6979 automaton_t automaton
;
6981 if (automaton
->corresponding_automaton_decl
== NULL
)
6982 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6984 fprintf (f
, "%s_transitions",
6985 automaton
->corresponding_automaton_decl
->name
);
6988 /* Output name of comb vector of the transition table for given
6991 output_trans_comb_vect_name (f
, automaton
)
6993 automaton_t automaton
;
6995 if (automaton
->corresponding_automaton_decl
== NULL
)
6996 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6998 fprintf (f
, "%s_transitions",
6999 automaton
->corresponding_automaton_decl
->name
);
7002 /* Output name of check vector of the transition table for given
7005 output_trans_check_vect_name (f
, automaton
)
7007 automaton_t automaton
;
7009 if (automaton
->corresponding_automaton_decl
== NULL
)
7010 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
7012 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
7015 /* Output name of base vector of the transition table for given
7018 output_trans_base_vect_name (f
, automaton
)
7020 automaton_t automaton
;
7022 if (automaton
->corresponding_automaton_decl
== NULL
)
7023 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
7025 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
7028 /* Output name for simple alternatives number representation. */
7030 output_state_alts_full_vect_name (f
, automaton
)
7032 automaton_t automaton
;
7034 if (automaton
->corresponding_automaton_decl
== NULL
)
7035 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7037 fprintf (f
, "%s_state_alts",
7038 automaton
->corresponding_automaton_decl
->name
);
7041 /* Output name of comb vector of the alternatives number table for given
7044 output_state_alts_comb_vect_name (f
, automaton
)
7046 automaton_t automaton
;
7048 if (automaton
->corresponding_automaton_decl
== NULL
)
7049 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7051 fprintf (f
, "%s_state_alts",
7052 automaton
->corresponding_automaton_decl
->name
);
7055 /* Output name of check vector of the alternatives number table for given
7058 output_state_alts_check_vect_name (f
, automaton
)
7060 automaton_t automaton
;
7062 if (automaton
->corresponding_automaton_decl
== NULL
)
7063 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
7065 fprintf (f
, "%s_check_state_alts",
7066 automaton
->corresponding_automaton_decl
->name
);
7069 /* Output name of base vector of the alternatives number table for given
7072 output_state_alts_base_vect_name (f
, automaton
)
7074 automaton_t automaton
;
7076 if (automaton
->corresponding_automaton_decl
== NULL
)
7077 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
7079 fprintf (f
, "%s_base_state_alts",
7080 automaton
->corresponding_automaton_decl
->name
);
7083 /* Output name of simple min issue delay table representation. */
7085 output_min_issue_delay_vect_name (f
, automaton
)
7087 automaton_t automaton
;
7089 if (automaton
->corresponding_automaton_decl
== NULL
)
7090 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
7092 fprintf (f
, "%s_min_issue_delay",
7093 automaton
->corresponding_automaton_decl
->name
);
7096 /* Output name of deadlock vector for given automaton. */
7098 output_dead_lock_vect_name (f
, automaton
)
7100 automaton_t automaton
;
7102 if (automaton
->corresponding_automaton_decl
== NULL
)
7103 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
7105 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
7108 /* Output name of reserved units table for AUTOMATON into file F. */
7110 output_reserved_units_table_name (f
, automaton
)
7112 automaton_t automaton
;
7114 if (automaton
->corresponding_automaton_decl
== NULL
)
7115 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
7117 fprintf (f
, "%s_reserved_units",
7118 automaton
->corresponding_automaton_decl
->name
);
7121 /* Name of the PHR interface macro. */
7122 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7124 /* Name of the PHR interface macro. */
7125 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7127 /* Names of an internal functions: */
7128 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7130 /* This is external type of DFA(s) state. */
7131 #define STATE_TYPE_NAME "state_t"
7133 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7135 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7137 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7139 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7141 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7143 /* Name of cache of insn dfa codes. */
7144 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7146 /* Name of length of cache of insn dfa codes. */
7147 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7149 /* Names of the PHR interface functions: */
7150 #define SIZE_FUNC_NAME "state_size"
7152 #define TRANSITION_FUNC_NAME "state_transition"
7154 #define STATE_ALTS_FUNC_NAME "state_alts"
7156 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7158 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7160 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7162 #define RESET_FUNC_NAME "state_reset"
7164 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7166 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7168 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7170 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7172 #define DFA_START_FUNC_NAME "dfa_start"
7174 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7176 /* Names of parameters of the PHR interface functions. */
7177 #define STATE_NAME "state"
7179 #define INSN_PARAMETER_NAME "insn"
7181 #define INSN2_PARAMETER_NAME "insn2"
7183 #define CHIP_PARAMETER_NAME "chip"
7185 #define FILE_PARAMETER_NAME "f"
7187 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7189 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7191 /* Names of the variables whose values are internal insn code of rtx
7193 #define INTERNAL_INSN_CODE_NAME "insn_code"
7195 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7197 /* Names of temporary variables in some functions. */
7198 #define TEMPORARY_VARIABLE_NAME "temp"
7200 #define I_VARIABLE_NAME "i"
7202 /* Name of result variable in some functions. */
7203 #define RESULT_VARIABLE_NAME "res"
7205 /* Name of function (attribute) to translate insn into number of insn
7206 alternatives reservation. */
7207 #define INSN_ALTS_FUNC_NAME "insn_alts"
7209 /* Name of function (attribute) to translate insn into internal insn
7211 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7213 /* Name of function (attribute) to translate insn into internal insn
7214 code with caching. */
7215 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7217 /* Name of function (attribute) to translate insn into internal insn
7219 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7221 /* Name of function (attribute) to translate insn into internal insn
7223 #define BYPASS_P_FUNC_NAME "bypass_p"
7225 /* Output C type which is used for representation of codes of states
7228 output_state_member_type (f
, automaton
)
7230 automaton_t automaton
;
7232 output_range_type (f
, 0, automaton
->achieved_states_num
);
7235 /* Output definition of the structure representing current DFA(s)
7238 output_chip_definitions ()
7240 automaton_t automaton
;
7242 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
7243 for (automaton
= description
->first_automaton
;
7245 automaton
= automaton
->next_automaton
)
7247 fprintf (output_file
, " ");
7248 output_state_member_type (output_file
, automaton
);
7249 fprintf (output_file
, " ");
7250 output_chip_member_name (output_file
, automaton
);
7251 fprintf (output_file
, ";\n");
7253 fprintf (output_file
, "};\n\n");
7255 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
7260 /* The function outputs translate vector of internal insn code into
7261 insn equivalence class number. The equivalence class number is
7262 used to access to table and vectors reprewsenting DFA(s). */
7264 output_translate_vect (automaton
)
7265 automaton_t automaton
;
7269 vla_hwint_t translate_vect
;
7271 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
7272 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
7273 for (insn_value
= 0; insn_value
<= description
->insns_num
; insn_value
++)
7274 /* Undefined value */
7275 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
7276 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7277 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
7278 = ainsn
->insn_equiv_class_num
;
7279 fprintf (output_file
,
7280 "/* Vector translating external insn codes to internal ones.*/\n");
7281 fprintf (output_file
, "static const ");
7282 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
7283 fprintf (output_file
, " ");
7284 output_translate_vect_name (output_file
, automaton
);
7285 fprintf (output_file
, "[] = {\n");
7286 output_vect (VLA_HWINT_BEGIN (translate_vect
),
7287 VLA_HWINT_LENGTH (translate_vect
));
7288 fprintf (output_file
, "};\n\n");
7289 VLA_HWINT_DELETE (translate_vect
);
7292 /* The value in a table state x ainsn -> something which represents
7294 static int undefined_vect_el_value
;
7296 /* The following function returns nonzero value if the best
7297 representation of the table is comb vector. */
7300 state_ainsn_table_t tab
;
7302 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
7303 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
7306 /* The following function creates new table for AUTOMATON. */
7307 static state_ainsn_table_t
7308 create_state_ainsn_table (automaton
)
7309 automaton_t automaton
;
7311 state_ainsn_table_t tab
;
7312 int full_vect_length
;
7315 tab
= create_node (sizeof (struct state_ainsn_table
));
7316 tab
->automaton
= automaton
;
7317 VLA_HWINT_CREATE (tab
->comb_vect
, 10000, "comb vector");
7318 VLA_HWINT_CREATE (tab
->check_vect
, 10000, "check vector");
7319 VLA_HWINT_CREATE (tab
->base_vect
, 1000, "base vector");
7320 VLA_HWINT_EXPAND (tab
->base_vect
, automaton
->achieved_states_num
);
7321 VLA_HWINT_CREATE (tab
->full_vect
, 10000, "full vector");
7322 full_vect_length
= (automaton
->insn_equiv_classes_num
7323 * automaton
->achieved_states_num
);
7324 VLA_HWINT_EXPAND (tab
->full_vect
, full_vect_length
);
7325 for (i
= 0; i
< full_vect_length
; i
++)
7326 VLA_HWINT (tab
->full_vect
, i
) = undefined_vect_el_value
;
7327 tab
->min_base_vect_el_value
= 0;
7328 tab
->max_base_vect_el_value
= 0;
7329 tab
->min_comb_vect_el_value
= 0;
7330 tab
->max_comb_vect_el_value
= 0;
7334 /* The following function outputs the best C representation of the
7335 table TAB of given TABLE_NAME. */
7337 output_state_ainsn_table (tab
, table_name
, output_full_vect_name_func
,
7338 output_comb_vect_name_func
,
7339 output_check_vect_name_func
,
7340 output_base_vect_name_func
)
7341 state_ainsn_table_t tab
;
7343 void (*output_full_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7344 void (*output_comb_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7345 void (*output_check_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7346 void (*output_base_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7348 if (!comb_vect_p (tab
))
7350 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7351 fprintf (output_file
, "static const ");
7352 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7353 tab
->max_comb_vect_el_value
);
7354 fprintf (output_file
, " ");
7355 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7356 fprintf (output_file
, "[] = {\n");
7357 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7358 VLA_HWINT_LENGTH (tab
->full_vect
));
7359 fprintf (output_file
, "};\n\n");
7363 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7364 fprintf (output_file
, "static const ");
7365 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7366 tab
->max_comb_vect_el_value
);
7367 fprintf (output_file
, " ");
7368 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7369 fprintf (output_file
, "[] = {\n");
7370 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7371 VLA_HWINT_LENGTH (tab
->comb_vect
));
7372 fprintf (output_file
, "};\n\n");
7373 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7374 fprintf (output_file
, "static const ");
7375 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7376 fprintf (output_file
, " ");
7377 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7378 fprintf (output_file
, "[] = {\n");
7379 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7380 VLA_HWINT_LENGTH (tab
->check_vect
));
7381 fprintf (output_file
, "};\n\n");
7382 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7383 fprintf (output_file
, "static const ");
7384 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7385 tab
->max_base_vect_el_value
);
7386 fprintf (output_file
, " ");
7387 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7388 fprintf (output_file
, "[] = {\n");
7389 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7390 VLA_HWINT_LENGTH (tab
->base_vect
));
7391 fprintf (output_file
, "};\n\n");
7395 /* The following function adds vector with length VECT_LENGTH and
7396 elements pointed by VECT to table TAB as its line with number
7399 add_vect (tab
, vect_num
, vect
, vect_length
)
7400 state_ainsn_table_t tab
;
7405 int real_vect_length
;
7406 vect_el_t
*comb_vect_start
;
7407 vect_el_t
*check_vect_start
;
7408 int comb_vect_index
;
7409 int comb_vect_els_num
;
7411 int first_unempty_vect_index
;
7412 int additional_els_num
;
7417 if (vect_length
== 0)
7419 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7420 if (vect
[vect_length
- 1] == undefined_vect_el_value
)
7422 /* Form full vector in the table: */
7423 for (i
= 0; i
< vect_length
; i
++)
7424 VLA_HWINT (tab
->full_vect
,
7425 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
7427 /* Form comb vector in the table: */
7428 if (VLA_HWINT_LENGTH (tab
->comb_vect
) != VLA_HWINT_LENGTH (tab
->check_vect
))
7430 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7431 comb_vect_els_num
= VLA_HWINT_LENGTH (tab
->comb_vect
);
7432 for (first_unempty_vect_index
= 0;
7433 first_unempty_vect_index
< vect_length
;
7434 first_unempty_vect_index
++)
7435 if (vect
[first_unempty_vect_index
] != undefined_vect_el_value
)
7437 /* Search for the place in comb vect for the inserted vect. */
7438 for (comb_vect_index
= 0;
7439 comb_vect_index
< comb_vect_els_num
;
7442 for (vect_index
= first_unempty_vect_index
;
7443 vect_index
< vect_length
7444 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7446 if (vect
[vect_index
] != undefined_vect_el_value
7447 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7448 != undefined_vect_el_value
))
7450 if (vect_index
>= vect_length
7451 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7454 /* Slot was found. */
7455 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7456 if (additional_els_num
< 0)
7457 additional_els_num
= 0;
7458 /* Expand comb and check vectors. */
7459 vect_el
= undefined_vect_el_value
;
7460 no_state_value
= tab
->automaton
->achieved_states_num
;
7461 while (additional_els_num
> 0)
7463 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7464 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7465 additional_els_num
--;
7467 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7468 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7469 if (VLA_HWINT_LENGTH (tab
->comb_vect
)
7470 < (size_t) (comb_vect_index
+ real_vect_length
))
7472 /* Fill comb and check vectors. */
7473 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7474 if (vect
[vect_index
] != undefined_vect_el_value
)
7476 if (comb_vect_start
[comb_vect_index
+ vect_index
]
7477 != undefined_vect_el_value
)
7479 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7480 if (vect
[vect_index
] < 0)
7482 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7483 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7484 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7485 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7486 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7488 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7489 tab
->max_base_vect_el_value
= comb_vect_index
;
7490 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7491 tab
->min_base_vect_el_value
= comb_vect_index
;
7492 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7495 /* Return number of out arcs of STATE. */
7497 out_state_arcs_num (state
)
7504 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7506 if (arc
->insn
== NULL
)
7508 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7514 /* Compare number of possible transitions from the states. */
7516 compare_transition_els_num (state_ptr_1
, state_ptr_2
)
7517 const void *state_ptr_1
;
7518 const void *state_ptr_2
;
7520 int transition_els_num_1
;
7521 int transition_els_num_2
;
7523 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7524 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7525 if (transition_els_num_1
< transition_els_num_2
)
7527 else if (transition_els_num_1
== transition_els_num_2
)
7533 /* The function adds element EL_VALUE to vector VECT for a table state
7536 add_vect_el (vect
, ainsn
, el_value
)
7541 int equiv_class_num
;
7546 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7547 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7548 vect_index
<= equiv_class_num
;
7550 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7551 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7554 /* This is for forming vector of states of an automaton. */
7555 static vla_ptr_t output_states_vect
;
7557 /* The function is called by function pass_states. The function adds
7558 STATE to `output_states_vect'. */
7560 add_states_vect_el (state
)
7563 VLA_PTR_ADD (output_states_vect
, state
);
7566 /* Form and output vectors (comb, check, base or full vector)
7567 representing transition table of AUTOMATON. */
7569 output_trans_table (automaton
)
7570 automaton_t automaton
;
7574 vla_hwint_t transition_vect
;
7576 undefined_vect_el_value
= automaton
->achieved_states_num
;
7577 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7578 /* Create vect of pointers to states ordered by num of transitions
7579 from the state (state with the maximum num is the first). */
7580 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7581 pass_states (automaton
, add_states_vect_el
);
7582 qsort (VLA_PTR_BEGIN (output_states_vect
),
7583 VLA_PTR_LENGTH (output_states_vect
),
7584 sizeof (state_t
), compare_transition_els_num
);
7585 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7586 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7587 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7590 VLA_HWINT_NULLIFY (transition_vect
);
7591 for (arc
= first_out_arc (*state_ptr
);
7593 arc
= next_out_arc (arc
))
7595 if (arc
->insn
== NULL
)
7597 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7598 add_vect_el (&transition_vect
, arc
->insn
,
7599 arc
->to_state
->order_state_num
);
7601 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7602 VLA_HWINT_BEGIN (transition_vect
),
7603 VLA_HWINT_LENGTH (transition_vect
));
7605 output_state_ainsn_table
7606 (automaton
->trans_table
, (char *) "state transitions",
7607 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7608 output_trans_check_vect_name
, output_trans_base_vect_name
);
7609 VLA_PTR_DELETE (output_states_vect
);
7610 VLA_HWINT_DELETE (transition_vect
);
7613 /* Form and output vectors (comb, check, base or simple vect)
7614 representing alts number table of AUTOMATON. The table is state x
7615 ainsn -> number of possible alternative reservations by the
7618 output_state_alts_table (automaton
)
7619 automaton_t automaton
;
7623 vla_hwint_t state_alts_vect
;
7625 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7626 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7627 /* Create vect of pointers to states ordered by num of transitions
7628 from the state (state with the maximum num is the first). */
7629 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7630 pass_states (automaton
, add_states_vect_el
);
7631 qsort (VLA_PTR_BEGIN (output_states_vect
),
7632 VLA_PTR_LENGTH (output_states_vect
),
7633 sizeof (state_t
), compare_transition_els_num
);
7634 /* Create base, comb, and check vectors. */
7635 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7636 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7637 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7640 VLA_HWINT_NULLIFY (state_alts_vect
);
7641 for (arc
= first_out_arc (*state_ptr
);
7643 arc
= next_out_arc (arc
))
7645 if (arc
->insn
== NULL
)
7647 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7648 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7650 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7651 VLA_HWINT_BEGIN (state_alts_vect
),
7652 VLA_HWINT_LENGTH (state_alts_vect
));
7654 output_state_ainsn_table
7655 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7656 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7657 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7658 VLA_PTR_DELETE (output_states_vect
);
7659 VLA_HWINT_DELETE (state_alts_vect
);
7662 /* The current number of passing states to find minimal issue delay
7663 value for an ainsn and state. */
7664 static int curr_state_pass_num
;
7667 /* This recursive function passes states to find minimal issue delay
7668 value for AINSN. The state being visited is STATE. The function
7669 returns minimal issue delay value for AINSN in STATE or -1 if we
7670 enter into a loop. */
7672 min_issue_delay_pass_states (state
, ainsn
)
7677 int min_insn_issue_delay
, insn_issue_delay
;
7679 if (state
->state_pass_num
== curr_state_pass_num
7680 || state
->min_insn_issue_delay
!= -1)
7681 /* We've entered into a loop or already have the correct value for
7682 given state and ainsn. */
7683 return state
->min_insn_issue_delay
;
7684 state
->state_pass_num
= curr_state_pass_num
;
7685 min_insn_issue_delay
= -1;
7686 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7687 if (arc
->insn
== ainsn
)
7689 min_insn_issue_delay
= 0;
7694 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7695 if (insn_issue_delay
!= -1)
7697 if (arc
->insn
->insn_reserv_decl
7698 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
7700 if (min_insn_issue_delay
== -1
7701 || min_insn_issue_delay
> insn_issue_delay
)
7703 min_insn_issue_delay
= insn_issue_delay
;
7704 if (insn_issue_delay
== 0)
7709 return min_insn_issue_delay
;
7712 /* The function searches minimal issue delay value for AINSN in STATE.
7713 The function can return negative value if we can not issue AINSN. We
7714 will report about it later. */
7716 min_issue_delay (state
, ainsn
)
7720 curr_state_pass_num
++;
7721 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7722 return state
->min_insn_issue_delay
;
7725 /* The function initiates code for finding minimal issue delay values.
7726 It should be called only once. */
7728 initiate_min_issue_delay_pass_states ()
7730 curr_state_pass_num
= 0;
7733 /* Form and output vectors representing minimal issue delay table of
7734 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7737 output_min_issue_delay_table (automaton
)
7738 automaton_t automaton
;
7740 vla_hwint_t min_issue_delay_vect
;
7741 vla_hwint_t compressed_min_issue_delay_vect
;
7742 vect_el_t min_delay
;
7747 /* Create vect of pointers to states ordered by num of transitions
7748 from the state (state with the maximum num is the first). */
7749 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7750 pass_states (automaton
, add_states_vect_el
);
7751 VLA_HWINT_CREATE (min_issue_delay_vect
, 1500, "min issue delay vector");
7752 VLA_HWINT_EXPAND (min_issue_delay_vect
,
7753 VLA_HWINT_LENGTH (output_states_vect
)
7754 * automaton
->insn_equiv_classes_num
);
7756 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
7757 * automaton
->insn_equiv_classes_num
);
7759 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
7760 automaton
->max_min_delay
= 0;
7761 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7762 if (ainsn
->first_ainsn_with_given_equialence_num
)
7764 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7765 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7767 (*state_ptr
)->min_insn_issue_delay
= -1;
7768 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7769 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7772 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
7773 if (automaton
->max_min_delay
< min_delay
)
7774 automaton
->max_min_delay
= min_delay
;
7775 VLA_HWINT (min_issue_delay_vect
,
7776 (*state_ptr
)->order_state_num
7777 * automaton
->insn_equiv_classes_num
7778 + ainsn
->insn_equiv_class_num
) = min_delay
;
7781 fprintf (output_file
, "/* Vector of min issue delay of insns.*/\n");
7782 fprintf (output_file
, "static const ");
7783 output_range_type (output_file
, 0, automaton
->max_min_delay
);
7784 fprintf (output_file
, " ");
7785 output_min_issue_delay_vect_name (output_file
, automaton
);
7786 fprintf (output_file
, "[] = {\n");
7787 /* Compress the vector */
7788 if (automaton
->max_min_delay
< 2)
7789 automaton
->min_issue_delay_table_compression_factor
= 8;
7790 else if (automaton
->max_min_delay
< 4)
7791 automaton
->min_issue_delay_table_compression_factor
= 4;
7792 else if (automaton
->max_min_delay
< 16)
7793 automaton
->min_issue_delay_table_compression_factor
= 2;
7795 automaton
->min_issue_delay_table_compression_factor
= 1;
7796 VLA_HWINT_CREATE (compressed_min_issue_delay_vect
, 1500,
7797 "compressed min issue delay vector");
7798 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect
,
7799 (VLA_HWINT_LENGTH (min_issue_delay_vect
)
7800 + automaton
->min_issue_delay_table_compression_factor
7802 / automaton
->min_issue_delay_table_compression_factor
);
7804 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
7806 VLA_HWINT (compressed_min_issue_delay_vect
, i
) = 0;
7807 for (i
= 0; i
< (int) VLA_HWINT_LENGTH (min_issue_delay_vect
); i
++)
7808 VLA_HWINT (compressed_min_issue_delay_vect
,
7809 i
/ automaton
->min_issue_delay_table_compression_factor
)
7810 |= (VLA_HWINT (min_issue_delay_vect
, i
)
7811 << (8 - (i
% automaton
->min_issue_delay_table_compression_factor
7813 * (8 / automaton
->min_issue_delay_table_compression_factor
)));
7814 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect
),
7815 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
));
7816 fprintf (output_file
, "};\n\n");
7817 VLA_PTR_DELETE (output_states_vect
);
7818 VLA_HWINT_DELETE (min_issue_delay_vect
);
7819 VLA_HWINT_DELETE (compressed_min_issue_delay_vect
);
7823 /* Number of states which contains transition only by advancing cpu
7825 static int locked_states_num
;
7828 /* Form and output vector representing the locked states of
7831 output_dead_lock_vect (automaton
)
7832 automaton_t automaton
;
7836 vla_hwint_t dead_lock_vect
;
7838 /* Create vect of pointers to states ordered by num of
7839 transitions from the state (state with the maximum num is the
7841 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7842 pass_states (automaton
, add_states_vect_el
);
7843 VLA_HWINT_CREATE (dead_lock_vect
, 1500, "is dead locked vector");
7844 VLA_HWINT_EXPAND (dead_lock_vect
, VLA_HWINT_LENGTH (output_states_vect
));
7845 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7846 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7849 arc
= first_out_arc (*state_ptr
);
7852 VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
)
7853 = (next_out_arc (arc
) == NULL
7854 && (arc
->insn
->insn_reserv_decl
7855 == DECL_INSN_RESERV (advance_cycle_insn_decl
)) ? 1 : 0);
7857 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
7858 locked_states_num
++;
7861 fprintf (output_file
, "/* Vector for locked state flags. */\n");
7862 fprintf (output_file
, "static const ");
7863 output_range_type (output_file
, 0, 1);
7864 fprintf (output_file
, " ");
7865 output_dead_lock_vect_name (output_file
, automaton
);
7866 fprintf (output_file
, "[] = {\n");
7867 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
7868 VLA_HWINT_LENGTH (dead_lock_vect
));
7869 fprintf (output_file
, "};\n\n");
7870 VLA_HWINT_DELETE (dead_lock_vect
);
7871 VLA_PTR_DELETE (output_states_vect
);
7874 /* Form and output vector representing reserved units of the states of
7877 output_reserved_units_table (automaton
)
7878 automaton_t automaton
;
7880 state_t
*curr_state_ptr
;
7881 vla_hwint_t reserved_units_table
;
7882 size_t state_byte_size
;
7885 /* Create vect of pointers to states. */
7886 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7887 pass_states (automaton
, add_states_vect_el
);
7888 /* Create vector. */
7889 VLA_HWINT_CREATE (reserved_units_table
, 1500, "reserved units vector");
7890 state_byte_size
= (description
->query_units_num
+ 7) / 8;
7891 VLA_HWINT_EXPAND (reserved_units_table
,
7892 VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7894 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7896 VLA_HWINT (reserved_units_table
, i
) = 0;
7897 for (curr_state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7898 curr_state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7901 for (i
= 0; i
< description
->units_num
; i
++)
7902 if (units_array
[i
]->query_p
)
7904 if (test_unit_reserv ((*curr_state_ptr
)->reservs
, 0, i
))
7905 VLA_HWINT (reserved_units_table
,
7906 (*curr_state_ptr
)->order_state_num
* state_byte_size
7907 + units_array
[i
]->query_num
/ 8)
7908 += (1 << (units_array
[i
]->query_num
% 8));
7911 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
7912 fprintf (output_file
, "static const ");
7913 output_range_type (output_file
, 0, 255);
7914 fprintf (output_file
, " ");
7915 output_reserved_units_table_name (output_file
, automaton
);
7916 fprintf (output_file
, "[] = {\n");
7917 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
7918 VLA_HWINT_LENGTH (reserved_units_table
));
7919 fprintf (output_file
, "};\n\n");
7920 VLA_HWINT_DELETE (reserved_units_table
);
7921 VLA_PTR_DELETE (output_states_vect
);
7924 /* The function outputs all tables representing DFA(s) used for fast
7925 pipeline hazards recognition. */
7929 automaton_t automaton
;
7932 locked_states_num
= 0;
7934 initiate_min_issue_delay_pass_states ();
7935 for (automaton
= description
->first_automaton
;
7937 automaton
= automaton
->next_automaton
)
7939 output_translate_vect (automaton
);
7940 output_trans_table (automaton
);
7941 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
7942 output_state_alts_table (automaton
);
7943 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7944 AUTOMATON_STATE_ALTS_MACRO_NAME
);
7945 output_min_issue_delay_table (automaton
);
7946 output_dead_lock_vect (automaton
);
7947 if (no_minimization_flag
)
7949 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
7950 output_reserved_units_table (automaton
);
7951 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7952 CPU_UNITS_QUERY_MACRO_NAME
);
7955 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
7956 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
7959 /* The function outputs definition and value of PHR interface variable
7960 `max_insn_queue_index'. Its value is not less than maximal queue
7961 length needed for the insn scheduler. */
7963 output_max_insn_queue_index_def ()
7965 int i
, max
, latency
;
7968 max
= description
->max_insn_reserv_cycles
;
7969 for (i
= 0; i
< description
->decls_num
; i
++)
7971 decl
= description
->decls
[i
];
7972 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
7974 latency
= DECL_INSN_RESERV (decl
)->default_latency
;
7978 else if (decl
->mode
== dm_bypass
)
7980 latency
= DECL_BYPASS (decl
)->latency
;
7985 for (i
= 0; (1 << i
) <= max
; i
++)
7989 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
7993 /* The function outputs switch cases for insn reseravtions using
7994 function *output_automata_list_code. */
7996 output_insn_code_cases (output_automata_list_code
)
7997 void (*output_automata_list_code
) (automata_list_el_t
);
8002 for (i
= 0; i
< description
->decls_num
; i
++)
8004 decl
= description
->decls
[i
];
8005 if (decl
->mode
== dm_insn_reserv
)
8006 DECL_INSN_RESERV (decl
)->processed_p
= FALSE
;
8008 for (i
= 0; i
< description
->decls_num
; i
++)
8010 decl
= description
->decls
[i
];
8011 if (decl
->mode
== dm_insn_reserv
8012 && !DECL_INSN_RESERV (decl
)->processed_p
)
8014 for (j
= i
; j
< description
->decls_num
; j
++)
8016 decl2
= description
->decls
[j
];
8017 if (decl2
->mode
== dm_insn_reserv
8018 && (DECL_INSN_RESERV (decl2
)->important_automata_list
8019 == DECL_INSN_RESERV (decl
)->important_automata_list
))
8021 DECL_INSN_RESERV (decl2
)->processed_p
= TRUE
;
8022 fprintf (output_file
, " case %d: /* %s */\n",
8023 DECL_INSN_RESERV (decl2
)->insn_num
,
8024 DECL_INSN_RESERV (decl2
)->name
);
8027 (*output_automata_list_code
)
8028 (DECL_INSN_RESERV (decl
)->important_automata_list
);
8034 /* The function outputs a code for evaluation of a minimal delay of
8035 issue of insns which have reservations in given AUTOMATA_LIST. */
8037 output_automata_list_min_issue_delay_code (automata_list
)
8038 automata_list_el_t automata_list
;
8040 automata_list_el_t el
;
8041 automaton_t automaton
;
8043 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8045 automaton
= el
->automaton
;
8046 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8047 output_min_issue_delay_vect_name (output_file
, automaton
);
8048 fprintf (output_file
,
8049 (automaton
->min_issue_delay_table_compression_factor
!= 1
8051 output_translate_vect_name (output_file
, automaton
);
8052 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8053 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8054 output_chip_member_name (output_file
, automaton
);
8055 fprintf (output_file
, " * %d", automaton
->insn_equiv_classes_num
);
8056 if (automaton
->min_issue_delay_table_compression_factor
== 1)
8057 fprintf (output_file
, "];\n");
8060 fprintf (output_file
, ") / %d];\n",
8061 automaton
->min_issue_delay_table_compression_factor
);
8062 fprintf (output_file
, " %s = (%s >> (8 - (",
8063 TEMPORARY_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8064 output_translate_vect_name (output_file
, automaton
);
8066 (output_file
, " [%s] %% %d + 1) * %d)) & %d;\n",
8067 INTERNAL_INSN_CODE_NAME
,
8068 automaton
->min_issue_delay_table_compression_factor
,
8069 8 / automaton
->min_issue_delay_table_compression_factor
,
8070 (1 << (8 / automaton
->min_issue_delay_table_compression_factor
))
8073 if (el
== automata_list
)
8074 fprintf (output_file
, " %s = %s;\n",
8075 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8078 fprintf (output_file
, " if (%s > %s)\n",
8079 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8080 fprintf (output_file
, " %s = %s;\n",
8081 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8084 fprintf (output_file
, " break;\n\n");
8087 /* Output function `internal_min_issue_delay'. */
8089 output_internal_min_issue_delay_func ()
8091 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8092 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, CHIP_NAME
);
8093 fprintf (output_file
,
8094 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8095 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8096 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8097 CHIP_PARAMETER_NAME
);
8098 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n int %s;\n",
8099 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8100 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8101 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
8102 fprintf (output_file
,
8103 "\n default:\n %s = -1;\n break;\n }\n",
8104 RESULT_VARIABLE_NAME
);
8105 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8106 fprintf (output_file
, "}\n\n");
8109 /* The function outputs a code changing state after issue of insns
8110 which have reservations in given AUTOMATA_LIST. */
8112 output_automata_list_transition_code (automata_list
)
8113 automata_list_el_t automata_list
;
8115 automata_list_el_t el
, next_el
;
8117 fprintf (output_file
, " {\n");
8118 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8119 for (el
= automata_list
;; el
= next_el
)
8121 next_el
= el
->next_automata_list_el
;
8122 if (next_el
== NULL
)
8124 fprintf (output_file
, " ");
8125 output_state_member_type (output_file
, el
->automaton
);
8126 fprintf (output_file
, " ");
8127 output_temp_chip_member_name (output_file
, el
->automaton
);
8128 fprintf (output_file
, ";\n");
8130 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8131 if (comb_vect_p (el
->automaton
->trans_table
))
8133 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8134 output_trans_base_vect_name (output_file
, el
->automaton
);
8135 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8136 output_chip_member_name (output_file
, el
->automaton
);
8137 fprintf (output_file
, "] + ");
8138 output_translate_vect_name (output_file
, el
->automaton
);
8139 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8140 fprintf (output_file
, " if (");
8141 output_trans_check_vect_name (output_file
, el
->automaton
);
8142 fprintf (output_file
, " [%s] != %s->",
8143 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8144 output_chip_member_name (output_file
, el
->automaton
);
8145 fprintf (output_file
, ")\n");
8146 fprintf (output_file
, " return %s (%s, %s);\n",
8147 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8148 CHIP_PARAMETER_NAME
);
8149 fprintf (output_file
, " else\n");
8150 fprintf (output_file
, " ");
8151 if (el
->next_automata_list_el
!= NULL
)
8152 output_temp_chip_member_name (output_file
, el
->automaton
);
8155 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8156 output_chip_member_name (output_file
, el
->automaton
);
8158 fprintf (output_file
, " = ");
8159 output_trans_comb_vect_name (output_file
, el
->automaton
);
8160 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8164 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8165 output_trans_full_vect_name (output_file
, el
->automaton
);
8166 fprintf (output_file
, " [");
8167 output_translate_vect_name (output_file
, el
->automaton
);
8168 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8169 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8170 output_chip_member_name (output_file
, el
->automaton
);
8171 fprintf (output_file
, " * %d];\n",
8172 el
->automaton
->insn_equiv_classes_num
);
8173 fprintf (output_file
, " if (%s >= %d)\n",
8174 TEMPORARY_VARIABLE_NAME
, el
->automaton
->achieved_states_num
);
8175 fprintf (output_file
, " return %s (%s, %s);\n",
8176 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8177 CHIP_PARAMETER_NAME
);
8178 fprintf (output_file
, " else\n ");
8179 if (el
->next_automata_list_el
!= NULL
)
8180 output_temp_chip_member_name (output_file
, el
->automaton
);
8183 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8184 output_chip_member_name (output_file
, el
->automaton
);
8186 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
8188 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8189 for (el
= automata_list
;; el
= next_el
)
8191 next_el
= el
->next_automata_list_el
;
8192 if (next_el
== NULL
)
8194 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
8195 output_chip_member_name (output_file
, el
->automaton
);
8196 fprintf (output_file
, " = ");
8197 output_temp_chip_member_name (output_file
, el
->automaton
);
8198 fprintf (output_file
, ";\n");
8200 fprintf (output_file
, " return -1;\n");
8201 fprintf (output_file
, " }\n");
8204 /* Output function `internal_state_transition'. */
8206 output_internal_trans_func ()
8208 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8209 INTERNAL_TRANSITION_FUNC_NAME
, CHIP_NAME
);
8210 fprintf (output_file
,
8211 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8212 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8213 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
,
8214 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8215 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME
);
8216 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8217 output_insn_code_cases (output_automata_list_transition_code
);
8218 fprintf (output_file
, "\n default:\n return -1;\n }\n");
8219 fprintf (output_file
, "}\n\n");
8226 insn_code = dfa_insn_code (insn);
8227 if (insn_code > DFA__ADVANCE_CYCLE)
8231 insn_code = DFA__ADVANCE_CYCLE;
8233 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8234 code denotes CODE. */
8236 output_internal_insn_code_evaluation (insn_name
, insn_code_name
, code
)
8237 const char *insn_name
;
8238 const char *insn_code_name
;
8241 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
8242 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
8243 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
8244 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
8245 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
8246 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
8247 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
8251 /* The function outputs function `dfa_insn_code'. */
8253 output_dfa_insn_code_func ()
8255 fprintf (output_file
, "#ifdef __GNUC__\n__inline__\n#endif\n");
8256 fprintf (output_file
, "static int %s PARAMS ((rtx));\n",
8257 DFA_INSN_CODE_FUNC_NAME
);
8258 fprintf (output_file
, "static int\n%s (%s)\n\trtx %s;\n",
8259 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN_PARAMETER_NAME
);
8260 fprintf (output_file
, "{\n int %s;\n int %s;\n\n",
8261 INTERNAL_INSN_CODE_NAME
, TEMPORARY_VARIABLE_NAME
);
8262 fprintf (output_file
, " if (INSN_UID (%s) >= %s)\n {\n",
8263 INSN_PARAMETER_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8264 fprintf (output_file
, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
8265 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8266 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, INSN_PARAMETER_NAME
);
8267 fprintf (output_file
, " %s = xrealloc (%s, %s * sizeof (int));\n",
8268 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8269 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8270 fprintf (output_file
,
8271 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
8272 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8273 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8274 TEMPORARY_VARIABLE_NAME
);
8275 fprintf (output_file
, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
8276 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8277 INSN_PARAMETER_NAME
);
8278 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8279 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8280 fprintf (output_file
, " %s [INSN_UID (%s)] = %s;\n",
8281 DFA_INSN_CODES_VARIABLE_NAME
, INSN_PARAMETER_NAME
,
8282 INTERNAL_INSN_CODE_NAME
);
8283 fprintf (output_file
, " }\n return %s;\n}\n\n",
8284 INTERNAL_INSN_CODE_NAME
);
8287 /* The function outputs PHR interface function `state_transition'. */
8289 output_trans_func ()
8291 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8292 TRANSITION_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8293 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8294 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8295 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8296 INTERNAL_INSN_CODE_NAME
, -1);
8297 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8298 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8301 /* The function outputs a code for evaluation of alternative states
8302 number for insns which have reservations in given AUTOMATA_LIST. */
8304 output_automata_list_state_alts_code (automata_list
)
8305 automata_list_el_t automata_list
;
8307 automata_list_el_t el
;
8308 automaton_t automaton
;
8310 fprintf (output_file
, " {\n");
8311 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8312 if (comb_vect_p (el
->automaton
->state_alts_table
))
8314 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
8317 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8319 automaton
= el
->automaton
;
8320 if (comb_vect_p (automaton
->state_alts_table
))
8322 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8323 output_state_alts_base_vect_name (output_file
, automaton
);
8324 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8325 output_chip_member_name (output_file
, automaton
);
8326 fprintf (output_file
, "] + ");
8327 output_translate_vect_name (output_file
, automaton
);
8328 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8329 fprintf (output_file
, " if (");
8330 output_state_alts_check_vect_name (output_file
, automaton
);
8331 fprintf (output_file
, " [%s] != %s->",
8332 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8333 output_chip_member_name (output_file
, automaton
);
8334 fprintf (output_file
, ")\n");
8335 fprintf (output_file
, " return 0;\n");
8336 fprintf (output_file
, " else\n");
8337 fprintf (output_file
,
8338 (el
== automata_list
8339 ? " %s = " : " %s += "),
8340 RESULT_VARIABLE_NAME
);
8341 output_state_alts_comb_vect_name (output_file
, automaton
);
8342 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8346 fprintf (output_file
,
8347 (el
== automata_list
8348 ? "\n %s = " : " %s += "),
8349 RESULT_VARIABLE_NAME
);
8350 output_state_alts_full_vect_name (output_file
, automaton
);
8351 fprintf (output_file
, " [");
8352 output_translate_vect_name (output_file
, automaton
);
8353 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8354 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8355 output_chip_member_name (output_file
, automaton
);
8356 fprintf (output_file
, " * %d];\n",
8357 automaton
->insn_equiv_classes_num
);
8360 fprintf (output_file
, " break;\n }\n\n");
8363 /* Output function `internal_state_alts'. */
8365 output_internal_state_alts_func ()
8367 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8368 INTERNAL_STATE_ALTS_FUNC_NAME
, CHIP_NAME
);
8369 fprintf (output_file
,
8370 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8371 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8372 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8373 CHIP_PARAMETER_NAME
);
8374 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8375 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8376 output_insn_code_cases (output_automata_list_state_alts_code
);
8377 fprintf (output_file
,
8378 "\n default:\n %s = 0;\n break;\n }\n",
8379 RESULT_VARIABLE_NAME
);
8380 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8381 fprintf (output_file
, "}\n\n");
8384 /* The function outputs PHR interface function `state_alts'. */
8386 output_state_alts_func ()
8388 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8389 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8390 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8391 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8392 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8393 INTERNAL_INSN_CODE_NAME
, 0);
8394 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8395 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8398 /* Output function `min_issue_delay'. */
8400 output_min_issue_delay_func ()
8402 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8403 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8404 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8405 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8406 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8407 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8408 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8409 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8410 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8411 fprintf (output_file
, " }\n else\n %s = %s;\n",
8412 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8413 fprintf (output_file
, "\n return %s (%s, %s);\n",
8414 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8416 fprintf (output_file
, "}\n\n");
8419 /* Output function `internal_dead_lock'. */
8421 output_internal_dead_lock_func ()
8423 automaton_t automaton
;
8425 fprintf (output_file
, "static int %s PARAMS ((struct %s *));\n",
8426 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
);
8427 fprintf (output_file
, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8428 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_PARAMETER_NAME
, CHIP_NAME
,
8429 CHIP_PARAMETER_NAME
);
8430 fprintf (output_file
, "{\n");
8431 for (automaton
= description
->first_automaton
;
8433 automaton
= automaton
->next_automaton
)
8435 fprintf (output_file
, " if (");
8436 output_dead_lock_vect_name (output_file
, automaton
);
8437 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8438 output_chip_member_name (output_file
, automaton
);
8439 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8441 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8444 /* The function outputs PHR interface function `state_dead_lock_p'. */
8446 output_dead_lock_func ()
8448 fprintf (output_file
, "int\n%s (%s)\n\t%s %s;\n",
8449 DEAD_LOCK_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8450 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8451 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8454 /* Output function `internal_reset'. */
8456 output_internal_reset_func ()
8458 fprintf (output_file
, "static void %s PARAMS ((struct %s *));\n",
8459 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8460 fprintf (output_file
, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8461 INTERNAL_RESET_FUNC_NAME
, CHIP_PARAMETER_NAME
,
8462 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8463 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8464 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8467 /* The function outputs PHR interface function `state_size'. */
8471 fprintf (output_file
, "int\n%s ()\n", SIZE_FUNC_NAME
);
8472 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8475 /* The function outputs PHR interface function `state_reset'. */
8477 output_reset_func ()
8479 fprintf (output_file
, "void\n%s (%s)\n\t %s %s;\n",
8480 RESET_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8481 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8485 /* Output function `min_insn_conflict_delay'. */
8487 output_min_insn_conflict_delay_func ()
8489 fprintf (output_file
,
8490 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8491 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
,
8492 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8493 STATE_TYPE_NAME
, STATE_NAME
,
8494 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8495 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s;\n",
8496 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8497 INTERNAL_INSN2_CODE_NAME
);
8498 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8499 INTERNAL_INSN_CODE_NAME
, 0);
8500 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8501 INTERNAL_INSN2_CODE_NAME
, 0);
8502 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8503 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8504 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8505 fprintf (output_file
, " if (%s (%s, &%s) > 0)\n abort ();\n",
8506 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8507 fprintf (output_file
, " return %s (%s, &%s);\n",
8508 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8510 fprintf (output_file
, "}\n\n");
8513 /* Output function `internal_insn_latency'. */
8515 output_internal_insn_latency_func ()
8518 struct bypass_decl
*bypass
;
8521 fprintf (output_file
, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8522 INTERNAL_INSN_LATENCY_FUNC_NAME
);
8523 fprintf (output_file
, "static int\n%s (%s, %s, %s, %s)",
8524 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8525 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8526 INSN2_PARAMETER_NAME
);
8527 fprintf (output_file
, "\n\tint %s;\n\tint %s;\n",
8528 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8529 fprintf (output_file
,
8530 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8531 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8532 fprintf (output_file
, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8533 for (i
= 0; i
< description
->decls_num
; i
++)
8535 decl
= description
->decls
[i
];
8536 if (decl
->mode
== dm_insn_reserv
)
8538 fprintf (output_file
, " case %d:\n",
8539 DECL_INSN_RESERV (decl
)->insn_num
);
8540 if (DECL_INSN_RESERV (decl
)->bypass_list
== NULL
)
8541 fprintf (output_file
, " return (%s != %s ? %d : 0);\n",
8542 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8543 DECL_INSN_RESERV (decl
)->default_latency
);
8546 fprintf (output_file
, " switch (%s)\n {\n",
8547 INTERNAL_INSN2_CODE_NAME
);
8548 for (bypass
= DECL_INSN_RESERV (decl
)->bypass_list
;
8550 bypass
= bypass
->next
)
8552 fprintf (output_file
, " case %d:\n",
8553 bypass
->in_insn_reserv
->insn_num
);
8554 if (bypass
->bypass_guard_name
== NULL
)
8555 fprintf (output_file
, " return %d;\n",
8558 fprintf (output_file
,
8559 " return (%s (%s, %s) ? %d : %d);\n",
8560 bypass
->bypass_guard_name
, INSN_PARAMETER_NAME
,
8561 INSN2_PARAMETER_NAME
, bypass
->latency
,
8562 DECL_INSN_RESERV (decl
)->default_latency
);
8564 fprintf (output_file
, " default:\n");
8565 fprintf (output_file
,
8566 " return (%s != %s ? %d : 0);\n }\n",
8567 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8568 DECL_INSN_RESERV (decl
)->default_latency
);
8573 fprintf (output_file
, " default:\n return 0;\n }\n}\n\n");
8576 /* The function outputs PHR interface function `insn_latency'. */
8578 output_insn_latency_func ()
8580 fprintf (output_file
, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8581 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8582 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8583 fprintf (output_file
, "{\n int %s, %s;\n",
8584 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8585 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8586 INTERNAL_INSN_CODE_NAME
, 0);
8587 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8588 INTERNAL_INSN2_CODE_NAME
, 0);
8589 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8590 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8591 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8592 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8595 /* The function outputs PHR interface function `print_reservation'. */
8597 output_print_reservation_func ()
8602 fprintf (output_file
, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8603 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8604 INSN_PARAMETER_NAME
, FILE_PARAMETER_NAME
,
8605 INSN_PARAMETER_NAME
);
8606 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8607 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8608 fprintf (output_file
, " %s = %s (%s);\n",
8609 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8610 INSN_PARAMETER_NAME
);
8611 fprintf (output_file
, " if (%s > %s)\n",
8612 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8613 fprintf (output_file
, " {\n fprintf (%s, \"%s\");\n",
8614 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8615 fprintf (output_file
, " return;\n }\n");
8616 fprintf (output_file
, " }\n else\n");
8617 fprintf (output_file
,
8618 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8619 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8620 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8621 for (i
= 0; i
< description
->decls_num
; i
++)
8623 decl
= description
->decls
[i
];
8624 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8626 fprintf (output_file
,
8627 " case %d:\n", DECL_INSN_RESERV (decl
)->insn_num
);
8628 fprintf (output_file
,
8629 " fprintf (%s, \"%s\");\n break;\n",
8630 FILE_PARAMETER_NAME
,
8631 regexp_representation (DECL_INSN_RESERV (decl
)->regexp
));
8632 finish_regexp_representation ();
8635 fprintf (output_file
, " default:\n fprintf (%s, \"%s\");\n }\n",
8636 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8637 fprintf (output_file
, "}\n\n");
8640 /* The following function is used to sort unit declaration by their
8643 units_cmp (unit1
, unit2
)
8644 const void *unit1
, *unit2
;
8646 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8647 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8649 return strcmp (u1
->name
, u2
->name
);
8652 /* The following macro value is name of struct containing unit name
8654 #define NAME_CODE_STRUCT_NAME "name_code"
8656 /* The following macro value is name of table of struct name_code. */
8657 #define NAME_CODE_TABLE_NAME "name_code_table"
8659 /* The following macro values are member names for struct name_code. */
8660 #define NAME_MEMBER_NAME "name"
8661 #define CODE_MEMBER_NAME "code"
8663 /* The following macro values are local variable names for function
8664 `get_cpu_unit_code'. */
8665 #define CMP_VARIABLE_NAME "cmp"
8666 #define LOW_VARIABLE_NAME "l"
8667 #define MIDDLE_VARIABLE_NAME "m"
8668 #define HIGH_VARIABLE_NAME "h"
8670 /* The following function outputs function to obtain internal cpu unit
8671 code by the cpu unit name. */
8673 output_get_cpu_unit_code_func ()
8678 fprintf (output_file
, "int\n%s (%s)\n\tconst char *%s;\n",
8679 GET_CPU_UNIT_CODE_FUNC_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8680 CPU_UNIT_NAME_PARAMETER_NAME
);
8681 fprintf (output_file
, "{\n struct %s {const char *%s; int %s;};\n",
8682 NAME_CODE_STRUCT_NAME
, NAME_MEMBER_NAME
, CODE_MEMBER_NAME
);
8683 fprintf (output_file
, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME
,
8684 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8685 fprintf (output_file
, " static struct %s %s [] =\n {\n",
8686 NAME_CODE_STRUCT_NAME
, NAME_CODE_TABLE_NAME
);
8687 units
= (unit_decl_t
*) xmalloc (sizeof (unit_decl_t
)
8688 * description
->units_num
);
8689 memcpy (units
, units_array
, sizeof (unit_decl_t
) * description
->units_num
);
8690 qsort (units
, description
->units_num
, sizeof (unit_decl_t
), units_cmp
);
8691 for (i
= 0; i
< description
->units_num
; i
++)
8692 if (units
[i
]->query_p
)
8693 fprintf (output_file
, " {\"%s\", %d},\n",
8694 units
[i
]->name
, units
[i
]->query_num
);
8695 fprintf (output_file
, " };\n\n");
8696 fprintf (output_file
, " /* The following is binary search: */\n");
8697 fprintf (output_file
, " %s = 0;\n", LOW_VARIABLE_NAME
);
8698 fprintf (output_file
, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8699 HIGH_VARIABLE_NAME
, NAME_CODE_TABLE_NAME
, NAME_CODE_STRUCT_NAME
);
8700 fprintf (output_file
, " while (%s <= %s)\n {\n",
8701 LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8702 fprintf (output_file
, " %s = (%s + %s) / 2;\n",
8703 MIDDLE_VARIABLE_NAME
, LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8704 fprintf (output_file
, " %s = strcmp (%s, %s [%s].%s);\n",
8705 CMP_VARIABLE_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8706 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, NAME_MEMBER_NAME
);
8707 fprintf (output_file
, " if (%s < 0)\n", CMP_VARIABLE_NAME
);
8708 fprintf (output_file
, " %s = %s - 1;\n",
8709 HIGH_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8710 fprintf (output_file
, " else if (%s > 0)\n", CMP_VARIABLE_NAME
);
8711 fprintf (output_file
, " %s = %s + 1;\n",
8712 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8713 fprintf (output_file
, " else\n");
8714 fprintf (output_file
, " return %s [%s].%s;\n }\n",
8715 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, CODE_MEMBER_NAME
);
8716 fprintf (output_file
, " return -1;\n}\n\n");
8720 /* The following function outputs function to check reservation of cpu
8721 unit (its internal code will be passed as the function argument) in
8724 output_cpu_unit_reservation_p ()
8726 automaton_t automaton
;
8728 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8729 CPU_UNIT_RESERVATION_P_FUNC_NAME
, STATE_NAME
,
8730 CPU_CODE_PARAMETER_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8731 CPU_CODE_PARAMETER_NAME
);
8732 fprintf (output_file
, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8733 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
8734 description
->query_units_num
);
8735 for (automaton
= description
->first_automaton
;
8737 automaton
= automaton
->next_automaton
)
8739 fprintf (output_file
, " if ((");
8740 output_reserved_units_table_name (output_file
, automaton
);
8741 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
8742 output_chip_member_name (output_file
, automaton
);
8743 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8744 (description
->query_units_num
+ 7) / 8,
8745 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
8746 fprintf (output_file
, " return 1;\n");
8748 fprintf (output_file
, " return 0;\n}\n\n");
8751 /* The function outputs PHR interface function `dfa_start'. */
8753 output_dfa_start_func ()
8755 fprintf (output_file
,
8756 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8757 DFA_START_FUNC_NAME
, I_VARIABLE_NAME
,
8758 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8759 fprintf (output_file
, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8760 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8761 fprintf (output_file
,
8762 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8763 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
8764 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
8765 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
8768 /* The function outputs PHR interface function `dfa_finish'. */
8770 output_dfa_finish_func ()
8772 fprintf (output_file
, "void\n%s ()\n{\n free (%s);\n}\n\n",
8773 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8778 /* The page contains code for output description file (readable
8779 representation of original description and generated DFA(s). */
8781 /* The function outputs string representation of IR reservation. */
8783 output_regexp (regexp
)
8786 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
8787 finish_regexp_representation ();
8790 /* Output names of units in LIST separated by comma. */
8792 output_unit_set_el_list (list
)
8797 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
8800 fprintf (output_description_file
, ",");
8801 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
8805 /* The function outputs string representation of IR define_reservation
8806 and define_insn_reservation. */
8808 output_description ()
8813 for (i
= 0; i
< description
->decls_num
; i
++)
8815 decl
= description
->decls
[i
];
8816 if (decl
->mode
== dm_unit
)
8818 if (DECL_UNIT (decl
)->excl_list
!= NULL
)
8820 fprintf (output_description_file
, "unit %s exlusion_set: ",
8821 DECL_UNIT (decl
)->name
);
8822 output_unit_set_el_list (DECL_UNIT (decl
)->excl_list
);
8823 fprintf (output_description_file
, "\n");
8825 if (DECL_UNIT (decl
)->presence_list
!= NULL
)
8827 fprintf (output_description_file
, "unit %s presence_set: ",
8828 DECL_UNIT (decl
)->name
);
8829 output_unit_set_el_list (DECL_UNIT (decl
)->presence_list
);
8830 fprintf (output_description_file
, "\n");
8832 if (DECL_UNIT (decl
)->absence_list
!= NULL
)
8834 fprintf (output_description_file
, "unit %s absence_set: ",
8835 DECL_UNIT (decl
)->name
);
8836 output_unit_set_el_list (DECL_UNIT (decl
)->absence_list
);
8837 fprintf (output_description_file
, "\n");
8841 fprintf (output_description_file
, "\n");
8842 for (i
= 0; i
< description
->decls_num
; i
++)
8844 decl
= description
->decls
[i
];
8845 if (decl
->mode
== dm_reserv
)
8847 fprintf (output_description_file
, "reservation ");
8848 fprintf (output_description_file
, DECL_RESERV (decl
)->name
);
8849 fprintf (output_description_file
, ": ");
8850 output_regexp (DECL_RESERV (decl
)->regexp
);
8851 fprintf (output_description_file
, "\n");
8853 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8855 fprintf (output_description_file
, "insn reservation %s ",
8856 DECL_INSN_RESERV (decl
)->name
);
8857 print_rtl (output_description_file
,
8858 DECL_INSN_RESERV (decl
)->condexp
);
8859 fprintf (output_description_file
, ": ");
8860 output_regexp (DECL_INSN_RESERV (decl
)->regexp
);
8861 fprintf (output_description_file
, "\n");
8863 else if (decl
->mode
== dm_bypass
)
8864 fprintf (output_description_file
, "bypass %d %s %s\n",
8865 DECL_BYPASS (decl
)->latency
,
8866 DECL_BYPASS (decl
)->out_insn_name
,
8867 DECL_BYPASS (decl
)->in_insn_name
);
8869 fprintf (output_description_file
, "\n\f\n");
8872 /* The function outputs name of AUTOMATON. */
8874 output_automaton_name (f
, automaton
)
8876 automaton_t automaton
;
8878 if (automaton
->corresponding_automaton_decl
== NULL
)
8879 fprintf (f
, "#%d", automaton
->automaton_order_num
);
8881 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
8884 /* Maximal length of line for pretty printing into description
8886 #define MAX_LINE_LENGTH 70
8888 /* The function outputs units name belonging to AUTOMATON. */
8890 output_automaton_units (automaton
)
8891 automaton_t automaton
;
8895 int curr_line_length
;
8896 int there_is_an_automaton_unit
;
8899 fprintf (output_description_file
, "\n Coresponding units:\n");
8900 fprintf (output_description_file
, " ");
8901 curr_line_length
= 4;
8902 there_is_an_automaton_unit
= 0;
8903 for (i
= 0; i
< description
->decls_num
; i
++)
8905 decl
= description
->decls
[i
];
8906 if (decl
->mode
== dm_unit
8907 && (DECL_UNIT (decl
)->corresponding_automaton_num
8908 == automaton
->automaton_order_num
))
8910 there_is_an_automaton_unit
= 1;
8911 name
= DECL_UNIT (decl
)->name
;
8912 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
8914 curr_line_length
= strlen (name
) + 4;
8915 fprintf (output_description_file
, "\n ");
8919 curr_line_length
+= strlen (name
) + 1;
8920 fprintf (output_description_file
, " ");
8922 fprintf (output_description_file
, name
);
8925 if (!there_is_an_automaton_unit
)
8926 fprintf (output_description_file
, "<None>");
8927 fprintf (output_description_file
, "\n\n");
8930 /* The following variable is used for forming array of all possible cpu unit
8931 reservations described by the current DFA state. */
8932 static vla_ptr_t state_reservs
;
8934 /* The function forms `state_reservs' for STATE. */
8936 add_state_reservs (state
)
8939 alt_state_t curr_alt_state
;
8940 reserv_sets_t reservs
;
8942 if (state
->component_states
!= NULL
)
8943 for (curr_alt_state
= state
->component_states
;
8944 curr_alt_state
!= NULL
;
8945 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
8946 add_state_reservs (curr_alt_state
->state
);
8949 reservs
= state
->reservs
;
8950 VLA_PTR_ADD (state_reservs
, reservs
);
8954 /* The function outputs readable represenatation of all out arcs of
8957 output_state_arcs (state
)
8963 int curr_line_length
;
8965 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
8968 if (!ainsn
->first_insn_with_same_reservs
)
8970 fprintf (output_description_file
, " ");
8971 curr_line_length
= 7;
8972 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
8975 insn_name
= ainsn
->insn_reserv_decl
->name
;
8976 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
8978 if (ainsn
!= arc
->insn
)
8980 fprintf (output_description_file
, ",\n ");
8981 curr_line_length
= strlen (insn_name
) + 6;
8984 curr_line_length
+= strlen (insn_name
);
8988 curr_line_length
+= strlen (insn_name
);
8989 if (ainsn
!= arc
->insn
)
8991 curr_line_length
+= 2;
8992 fprintf (output_description_file
, ", ");
8995 fprintf (output_description_file
, insn_name
);
8996 ainsn
= ainsn
->next_same_reservs_insn
;
8998 while (ainsn
!= NULL
);
8999 fprintf (output_description_file
, " %d (%d)\n",
9000 arc
->to_state
->order_state_num
, arc
->state_alts
);
9002 fprintf (output_description_file
, "\n");
9005 /* The following function is used for sorting possible cpu unit
9006 reservation of a DFA state. */
9008 state_reservs_cmp (reservs_ptr_1
, reservs_ptr_2
)
9009 const void *reservs_ptr_1
;
9010 const void *reservs_ptr_2
;
9012 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
9013 *(reserv_sets_t
*) reservs_ptr_2
);
9016 /* The following function is used for sorting possible cpu unit
9017 reservation of a DFA state. */
9019 remove_state_duplicate_reservs ()
9021 reserv_sets_t
*reservs_ptr
;
9022 reserv_sets_t
*last_formed_reservs_ptr
;
9024 last_formed_reservs_ptr
= NULL
;
9025 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9026 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9028 if (last_formed_reservs_ptr
== NULL
)
9029 last_formed_reservs_ptr
= reservs_ptr
;
9030 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
9032 ++last_formed_reservs_ptr
;
9033 *last_formed_reservs_ptr
= *reservs_ptr
;
9035 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
9038 /* The following function output readable representation of DFA(s)
9039 state used for fast recognition of pipeline hazards. State is
9040 described by possible (current and scehduled) cpu unit
9043 output_state (state
)
9046 reserv_sets_t
*reservs_ptr
;
9048 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
9049 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
9050 fprintf (output_description_file
,
9051 state
->new_cycle_p
? " (new cycle)\n" : "\n");
9052 add_state_reservs (state
);
9053 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
9054 sizeof (reserv_sets_t
), state_reservs_cmp
);
9055 remove_state_duplicate_reservs ();
9056 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9057 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9060 fprintf (output_description_file
, " ");
9061 output_reserv_sets (output_description_file
, *reservs_ptr
);
9062 fprintf (output_description_file
, "\n");
9064 fprintf (output_description_file
, "\n");
9065 output_state_arcs (state
);
9066 VLA_PTR_DELETE (state_reservs
);
9069 /* The following function output readable representation of
9070 DFAs used for fast recognition of pipeline hazards. */
9072 output_automaton_descriptions ()
9074 automaton_t automaton
;
9076 for (automaton
= description
->first_automaton
;
9078 automaton
= automaton
->next_automaton
)
9080 fprintf (output_description_file
, "\nAutomaton ");
9081 output_automaton_name (output_description_file
, automaton
);
9082 fprintf (output_description_file
, "\n");
9083 output_automaton_units (automaton
);
9084 pass_states (automaton
, output_state
);
9090 /* The page contains top level function for generation DFA(s) used for
9093 /* The function outputs statistics about work of different phases of
9096 output_statistics (f
)
9099 automaton_t automaton
;
9101 int transition_comb_vect_els
= 0;
9102 int transition_full_vect_els
= 0;
9103 int state_alts_comb_vect_els
= 0;
9104 int state_alts_full_vect_els
= 0;
9105 int min_issue_delay_vect_els
= 0;
9108 for (automaton
= description
->first_automaton
;
9110 automaton
= automaton
->next_automaton
)
9112 fprintf (f
, "\nAutomaton ");
9113 output_automaton_name (f
, automaton
);
9114 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
9115 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
9116 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
9117 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
9118 if (!no_minimization_flag
)
9119 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9120 automaton
->minimal_DFA_states_num
,
9121 automaton
->minimal_DFA_arcs_num
);
9122 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
9123 description
->insns_num
, automaton
->insn_equiv_classes_num
);
9126 (f
, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9127 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
),
9128 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
),
9129 (comb_vect_p (automaton
->trans_table
)
9130 ? "use comb vect" : "use simple vect"));
9132 (f
, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9133 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
),
9134 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
),
9135 (comb_vect_p (automaton
->state_alts_table
)
9136 ? "use comb vect" : "use simple vect"));
9138 (f
, "%5ld min delay table els, compression factor %d\n",
9139 (long) automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
,
9140 automaton
->min_issue_delay_table_compression_factor
);
9141 transition_comb_vect_els
9142 += VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
);
9143 transition_full_vect_els
9144 += VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
);
9145 state_alts_comb_vect_els
9146 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
);
9147 state_alts_full_vect_els
9148 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
);
9149 min_issue_delay_vect_els
9150 += automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
;
9154 fprintf (f
, "\n%5d all allocated states, %5d all allocated arcs\n",
9155 allocated_states_num
, allocated_arcs_num
);
9156 fprintf (f
, "%5d all allocated alternative states\n",
9157 allocated_alt_states_num
);
9158 fprintf (f
, "%5d all transition comb vector els, %5d all trans table els\n",
9159 transition_comb_vect_els
, transition_full_vect_els
);
9161 (f
, "%5d all state alts comb vector els, %5d all state alts table els\n",
9162 state_alts_comb_vect_els
, state_alts_full_vect_els
);
9163 fprintf (f
, "%5d all min delay table els\n", min_issue_delay_vect_els
);
9164 fprintf (f
, "%5d locked states num\n", locked_states_num
);
9168 /* The function output times of work of different phases of DFA
9171 output_time_statistics (f
)
9174 fprintf (f
, "\n transformation: ");
9175 print_active_time (f
, transform_time
);
9176 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
9177 print_active_time (f
, NDFA_time
);
9180 fprintf (f
, ", NDFA -> DFA: ");
9181 print_active_time (f
, NDFA_to_DFA_time
);
9183 fprintf (f
, "\n DFA minimization: ");
9184 print_active_time (f
, minimize_time
);
9185 fprintf (f
, ", making insn equivalence: ");
9186 print_active_time (f
, equiv_time
);
9187 fprintf (f
, "\n all automaton generation: ");
9188 print_active_time (f
, automaton_generation_time
);
9189 fprintf (f
, ", output: ");
9190 print_active_time (f
, output_time
);
9194 /* The function generates DFA (deterministic finate state automaton)
9195 for fast recognition of pipeline hazards. No errors during
9196 checking must be fixed before this function call. */
9200 automata_num
= split_argument
;
9201 if (description
->units_num
< automata_num
)
9202 automata_num
= description
->units_num
;
9205 initiate_automata_lists ();
9206 initiate_pass_states ();
9207 initiate_excl_sets ();
9208 initiate_presence_absence_sets ();
9209 automaton_generation_time
= create_ticker ();
9211 ticker_off (&automaton_generation_time
);
9216 /* The following function creates insn attribute whose values are
9217 number alternatives in insn reservations. */
9219 make_insn_alts_attr ()
9225 condexp
= rtx_alloc (COND
);
9226 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9227 XEXP (condexp
, 1) = make_numeric_value (0);
9228 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9230 decl
= description
->decls
[i
];
9231 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9233 XVECEXP (condexp
, 0, 2 * insn_num
)
9234 = DECL_INSN_RESERV (decl
)->condexp
;
9235 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9236 = make_numeric_value
9237 (DECL_INSN_RESERV (decl
)->transformed_regexp
->mode
!= rm_oneof
9238 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl
)
9239 ->transformed_regexp
)->regexps_num
);
9243 if (description
->insns_num
!= insn_num
+ 1)
9245 make_internal_attr (attr_printf (sizeof ("*")
9246 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
9247 "*%s", INSN_ALTS_FUNC_NAME
),
9253 /* The following function creates attribute which is order number of
9254 insn in pipeline hazard description translator. */
9256 make_internal_dfa_insn_code_attr ()
9262 condexp
= rtx_alloc (COND
);
9263 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9265 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl
)
9267 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9269 decl
= description
->decls
[i
];
9270 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9272 XVECEXP (condexp
, 0, 2 * insn_num
)
9273 = DECL_INSN_RESERV (decl
)->condexp
;
9274 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9275 = make_numeric_value (DECL_INSN_RESERV (decl
)->insn_num
);
9279 if (description
->insns_num
!= insn_num
+ 1)
9282 (attr_printf (sizeof ("*")
9283 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
9284 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
9290 /* The following function creates attribute which order number of insn
9291 in pipeline hazard description translator. */
9293 make_default_insn_latency_attr ()
9299 condexp
= rtx_alloc (COND
);
9300 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9301 XEXP (condexp
, 1) = make_numeric_value (0);
9302 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9304 decl
= description
->decls
[i
];
9305 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9307 XVECEXP (condexp
, 0, 2 * insn_num
)
9308 = DECL_INSN_RESERV (decl
)->condexp
;
9309 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9310 = make_numeric_value (DECL_INSN_RESERV (decl
)->default_latency
);
9314 if (description
->insns_num
!= insn_num
+ 1)
9316 make_internal_attr (attr_printf (sizeof ("*")
9317 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
9318 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
9324 /* The following function creates attribute which returns 1 if given
9325 output insn has bypassing and 0 otherwise. */
9330 int bypass_insns_num
= 0;
9334 for (i
= 0; i
< description
->decls_num
; i
++)
9336 decl
= description
->decls
[i
];
9337 if (decl
->mode
== dm_insn_reserv
9338 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9339 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9342 if (bypass_insns_num
== 0)
9343 result_rtx
= make_numeric_value (0);
9346 result_rtx
= rtx_alloc (COND
);
9347 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
9348 XEXP (result_rtx
, 1) = make_numeric_value (0);
9350 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
9352 decl
= description
->decls
[i
];
9353 if (decl
->mode
== dm_insn_reserv
9354 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9355 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9357 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9358 = DECL_INSN_RESERV (decl
)->condexp
;
9359 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9360 = make_numeric_value (1);
9365 make_internal_attr (attr_printf (sizeof ("*")
9366 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9367 "*%s", BYPASS_P_FUNC_NAME
),
9373 /* This page mainly contains top level functions of pipeline hazards
9374 description translator. */
9376 /* The following macro value is suffix of name of description file of
9377 pipeline hazards description translator. */
9378 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9380 /* The function returns suffix of given file name. The returned
9381 string can not be changed. */
9383 file_name_suffix (file_name
)
9384 const char *file_name
;
9386 const char *last_period
;
9388 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9389 if (*file_name
== '.')
9390 last_period
= file_name
;
9391 return (last_period
== NULL
? file_name
: last_period
);
9394 /* The function returns base name of given file name, i.e. pointer to
9395 first char after last `/' (or `\' for WIN32) in given file name,
9396 given file name itself if the directory name is absent. The
9397 returned string can not be changed. */
9399 base_file_name (file_name
)
9400 const char *file_name
;
9402 int directory_name_length
;
9404 directory_name_length
= strlen (file_name
);
9406 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9407 && file_name
[directory_name_length
] != '\\')
9409 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9411 directory_name_length
--;
9412 return file_name
+ directory_name_length
+ 1;
9415 /* The following is top level function to initialize the work of
9416 pipeline hazards description translator. */
9418 initiate_automaton_gen (argc
, argv
)
9422 const char *base_name
;
9426 split_argument
= 0; /* default value */
9427 no_minimization_flag
= 0;
9431 for (i
= 2; i
< argc
; i
++)
9432 if (strcmp (argv
[i
], NO_MINIMIZATION_OPTION
) == 0)
9433 no_minimization_flag
= 1;
9434 else if (strcmp (argv
[i
], TIME_OPTION
) == 0)
9436 else if (strcmp (argv
[i
], V_OPTION
) == 0)
9438 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9440 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9442 else if (strcmp (argv
[i
], "-split") == 0)
9445 fatal ("-split has no argument.");
9446 fatal ("option `-split' has not been implemented yet\n");
9447 /* split_argument = atoi (argument_vect [i + 1]); */
9449 VLA_PTR_CREATE (decls
, 150, "decls");
9450 /* Initialize IR storage. */
9451 obstack_init (&irp
);
9452 initiate_automaton_decl_table ();
9453 initiate_insn_decl_table ();
9454 initiate_decl_table ();
9455 output_file
= stdout
;
9456 output_description_file
= NULL
;
9457 base_name
= base_file_name (argv
[1]);
9458 obstack_grow (&irp
, base_name
,
9459 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9460 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9461 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9462 obstack_1grow (&irp
, '\0');
9463 output_description_file_name
= obstack_base (&irp
);
9464 obstack_finish (&irp
);
9467 /* The following function checks existence at least one arc marked by
9470 check_automata_insn_issues ()
9472 automaton_t automaton
;
9473 ainsn_t ainsn
, reserv_ainsn
;
9475 for (automaton
= description
->first_automaton
;
9477 automaton
= automaton
->next_automaton
)
9479 for (ainsn
= automaton
->ainsn_list
;
9481 ainsn
= ainsn
->next_ainsn
)
9482 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9484 for (reserv_ainsn
= ainsn
;
9485 reserv_ainsn
!= NULL
;
9486 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9487 if (automaton
->corresponding_automaton_decl
!= NULL
)
9490 error ("Automaton `%s': Insn `%s' will never be issued",
9491 automaton
->corresponding_automaton_decl
->name
,
9492 reserv_ainsn
->insn_reserv_decl
->name
);
9495 ("Automaton `%s': Insn `%s' will never be issued",
9496 automaton
->corresponding_automaton_decl
->name
,
9497 reserv_ainsn
->insn_reserv_decl
->name
);
9502 error ("Insn `%s' will never be issued",
9503 reserv_ainsn
->insn_reserv_decl
->name
);
9505 warning ("Insn `%s' will never be issued",
9506 reserv_ainsn
->insn_reserv_decl
->name
);
9512 /* The following vla is used for storing pointers to all achieved
9514 static vla_ptr_t automaton_states
;
9516 /* This function is called by function pass_states to add an achieved
9519 add_automaton_state (state
)
9522 VLA_PTR_ADD (automaton_states
, state
);
9525 /* The following function forms list of important automata (whose
9526 states may be changed after the insn issue) for each insn. */
9528 form_important_insn_automata_lists ()
9530 automaton_t automaton
;
9537 VLA_PTR_CREATE (automaton_states
, 1500,
9538 "automaton states for forming important insn automata sets");
9539 /* Mark important ainsns. */
9540 for (automaton
= description
->first_automaton
;
9542 automaton
= automaton
->next_automaton
)
9544 VLA_PTR_NULLIFY (automaton_states
);
9545 pass_states (automaton
, add_automaton_state
);
9546 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9547 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9550 for (arc
= first_out_arc (*state_ptr
);
9552 arc
= next_out_arc (arc
))
9553 if (arc
->to_state
!= *state_ptr
)
9555 if (!arc
->insn
->first_insn_with_same_reservs
)
9557 for (ainsn
= arc
->insn
;
9559 ainsn
= ainsn
->next_same_reservs_insn
)
9560 ainsn
->important_p
= TRUE
;
9564 VLA_PTR_DELETE (automaton_states
);
9565 /* Create automata sets for the insns. */
9566 for (i
= 0; i
< description
->decls_num
; i
++)
9568 decl
= description
->decls
[i
];
9569 if (decl
->mode
== dm_insn_reserv
)
9571 automata_list_start ();
9572 for (automaton
= description
->first_automaton
;
9574 automaton
= automaton
->next_automaton
)
9575 for (ainsn
= automaton
->ainsn_list
;
9577 ainsn
= ainsn
->next_ainsn
)
9578 if (ainsn
->important_p
9579 && ainsn
->insn_reserv_decl
== DECL_INSN_RESERV (decl
))
9581 automata_list_add (automaton
);
9584 DECL_INSN_RESERV (decl
)->important_automata_list
9585 = automata_list_finish ();
9591 /* The following is top level function to generate automat(a,on) for
9592 fast recognition of pipeline hazards. */
9598 description
= create_node (sizeof (struct description
)
9599 /* One entry for cycle advancing insn. */
9600 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9601 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9602 description
->query_units_num
= 0;
9603 for (i
= 0; i
< description
->decls_num
; i
++)
9605 description
->decls
[i
] = VLA_PTR (decls
, i
);
9606 if (description
->decls
[i
]->mode
== dm_unit
9607 && DECL_UNIT (description
->decls
[i
])->query_p
)
9608 DECL_UNIT (description
->decls
[i
])->query_num
9609 = description
->query_units_num
++;
9611 all_time
= create_ticker ();
9612 check_time
= create_ticker ();
9613 fprintf (stderr
, "Check description...");
9615 check_all_description ();
9616 fprintf (stderr
, "done\n");
9617 ticker_off (&check_time
);
9618 generation_time
= create_ticker ();
9621 transform_insn_regexps ();
9622 check_unit_distributions_to_automata ();
9627 check_automata_insn_issues ();
9631 form_important_insn_automata_lists ();
9632 fprintf (stderr
, "Generation of attributes...");
9634 make_internal_dfa_insn_code_attr ();
9635 make_insn_alts_attr ();
9636 make_default_insn_latency_attr ();
9637 make_bypass_attr ();
9638 fprintf (stderr
, "done\n");
9640 ticker_off (&generation_time
);
9641 ticker_off (&all_time
);
9642 fprintf (stderr
, "All other genattrtab stuff...");
9646 /* The following is top level function to output PHR and to finish
9647 work with pipeline description translator. */
9651 fprintf (stderr
, "done\n");
9653 fatal ("Errors in DFA description");
9654 ticker_on (&all_time
);
9655 output_time
= create_ticker ();
9656 fprintf (stderr
, "Forming and outputing automata tables...");
9658 output_dfa_max_issue_rate ();
9660 fprintf (stderr
, "done\n");
9661 fprintf (stderr
, "Output functions to work with automata...");
9663 output_chip_definitions ();
9664 output_max_insn_queue_index_def ();
9665 output_internal_min_issue_delay_func ();
9666 output_internal_trans_func ();
9667 /* Cache of insn dfa codes: */
9668 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9669 fprintf (output_file
, "\nstatic int %s;\n\n",
9670 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9671 output_dfa_insn_code_func ();
9672 output_trans_func ();
9673 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
9674 output_internal_state_alts_func ();
9675 output_state_alts_func ();
9676 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9677 AUTOMATON_STATE_ALTS_MACRO_NAME
);
9678 output_min_issue_delay_func ();
9679 output_internal_dead_lock_func ();
9680 output_dead_lock_func ();
9681 output_size_func ();
9682 output_internal_reset_func ();
9683 output_reset_func ();
9684 output_min_insn_conflict_delay_func ();
9685 output_internal_insn_latency_func ();
9686 output_insn_latency_func ();
9687 output_print_reservation_func ();
9688 if (no_minimization_flag
)
9690 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
9691 output_get_cpu_unit_code_func ();
9692 output_cpu_unit_reservation_p ();
9693 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9694 CPU_UNITS_QUERY_MACRO_NAME
);
9696 output_dfa_start_func ();
9697 output_dfa_finish_func ();
9698 fprintf (stderr
, "done\n");
9701 output_description_file
= fopen (output_description_file_name
, "w");
9702 if (output_description_file
== NULL
)
9704 perror (output_description_file_name
);
9705 exit (FATAL_EXIT_CODE
);
9707 fprintf (stderr
, "Output automata description...");
9709 output_description ();
9710 output_automaton_descriptions ();
9711 fprintf (stderr
, "done\n");
9712 output_statistics (output_description_file
);
9714 output_statistics (stderr
);
9715 ticker_off (&output_time
);
9716 output_time_statistics (stderr
);
9719 finish_automata_lists ();
9722 fprintf (stderr
, "Summary:\n");
9723 fprintf (stderr
, " check time ");
9724 print_active_time (stderr
, check_time
);
9725 fprintf (stderr
, ", generation time ");
9726 print_active_time (stderr
, generation_time
);
9727 fprintf (stderr
, ", all time ");
9728 print_active_time (stderr
, all_time
);
9729 fprintf (stderr
, "\n");
9731 /* Finish all work. */
9732 if (output_description_file
!= NULL
)
9734 fflush (output_description_file
);
9735 if (ferror (stdout
) != 0)
9736 fatal ("Error in writing DFA description file %s",
9737 output_description_file_name
);
9738 fclose (output_description_file
);
9740 finish_automaton_decl_table ();
9741 finish_insn_decl_table ();
9742 finish_decl_table ();
9743 obstack_free (&irp
, NULL
);
9744 if (have_error
&& output_description_file
!= NULL
)
9745 remove (output_description_file_name
);