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 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
600 #define VLA_HWINT_EXPAND(vla, n) \
602 vla_hwint_t *const expand_vla_ptr = &(vla); \
603 const size_t new_length = (n) + expand_vla_ptr->length; \
605 if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
606 VARRAY_GROW (expand_vla_ptr->varray, \
607 (new_length - expand_vla_ptr->length < 128 \
608 ? expand_vla_ptr->length + 128 : new_length)); \
609 expand_vla_ptr->length = new_length; \
612 #define VLA_HWINT_ADD(vla, ptr) \
614 vla_hwint_t *const vla_ptr = &(vla); \
616 VLA_HWINT_EXPAND (*vla_ptr, 1); \
617 VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
620 #define VLA_HWINT_LENGTH(vla) ((vla).length)
622 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
626 /* Options with the following names can be set up in automata_option
627 construction. Because the strings occur more one time we use the
630 #define NO_MINIMIZATION_OPTION "-no-minimization"
632 #define TIME_OPTION "-time"
634 #define V_OPTION "-v"
636 #define W_OPTION "-w"
638 #define NDFA_OPTION "-ndfa"
640 /* The following flags are set up by function `initiate_automaton_gen'. */
642 /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
643 static int ndfa_flag
;
645 /* Do not make minimization of DFA (`-no-minimization'). */
646 static int no_minimization_flag
;
648 /* Value of this variable is number of automata being generated. The
649 actual number of automata may be less this value if there is not
650 sufficient number of units. This value is defined by argument of
651 option `-split' or by constructions automaton if the value is zero
652 (it is default value of the argument). */
653 static int split_argument
;
655 /* Flag of output time statistics (`-time'). */
656 static int time_flag
;
658 /* Flag of creation of description file which contains description of
659 result automaton and statistics information (`-v'). */
662 /* Flag of generating warning instead of error for non-critical errors
667 /* Output file for pipeline hazard recognizer (PHR) being generated.
668 The value is NULL if the file is not defined. */
669 static FILE *output_file
;
671 /* Description file of PHR. The value is NULL if the file is not
673 static FILE *output_description_file
;
675 /* PHR description file name. */
676 static char *output_description_file_name
;
678 /* Value of the following variable is node representing description
679 being processed. This is start point of IR. */
680 static struct description
*description
;
684 /* This page contains description of IR structure (nodes). */
698 /* This describes define_cpu_unit and define_query_cpu_unit (see file
703 /* NULL if the automaton name is absent. */
704 char *automaton_name
;
705 /* If the following value is not zero, the cpu unit reservation is
706 described in define_query_cpu_unit. */
709 /* The following fields are defined by checker. */
711 /* The following field value is nonzero if the unit is used in an
715 /* The following field value is used to form cyclic lists of units
716 which should be in the same automaton because the unit is
717 reserved not on all alternatives of a regexp on a cycle. */
718 unit_decl_t the_same_automaton_unit
;
719 /* The following field is TRUE if we already reported that the unit
720 is not in the same automaton. */
721 int the_same_automaton_message_reported_p
;
723 /* The following field value is order number (0, 1, ...) of given
726 /* The following field value is corresponding declaration of
727 automaton which was given in description. If the field value is
728 NULL then automaton in the unit declaration was absent. */
729 struct automaton_decl
*automaton_decl
;
730 /* The following field value is maximal cycle number (1, ...) on
731 which given unit occurs in insns. Zero value means that given
732 unit is not used in insns. */
733 int max_occ_cycle_num
;
734 /* The following list contains units which conflict with given
736 unit_set_el_t excl_list
;
737 /* The following list contains units which are required to
738 reservation of given unit. */
739 unit_set_el_t presence_list
;
740 /* The following list contains units which should be not present in
741 reservation for given unit. */
742 unit_set_el_t absence_list
;
743 /* The following is used only when `query_p' has nonzero value.
744 This is query number for the unit. */
747 /* The following fields are defined by automaton generator. */
749 /* The following field value is number of the automaton to which
750 given unit belongs. */
751 int corresponding_automaton_num
;
754 /* This describes define_bypass (see file rtl.def). */
760 char *bypass_guard_name
;
762 /* The following fields are defined by checker. */
764 /* output and input insns of given bypass. */
765 struct insn_reserv_decl
*out_insn_reserv
;
766 struct insn_reserv_decl
*in_insn_reserv
;
767 /* The next bypass for given output insn. */
768 struct bypass_decl
*next
;
771 /* This describes define_automaton (see file rtl.def). */
772 struct automaton_decl
776 /* The following fields are defined by automaton generator. */
778 /* The following field value is nonzero if the automaton is used in
779 an regexp definition. */
780 char automaton_is_used
;
782 /* The following fields are defined by checker. */
784 /* The following field value is the corresponding automaton. This
785 field is not NULL only if the automaton is present in unit
786 declarations and the automatic partition on automata is not
788 automaton_t corresponding_automaton
;
791 /* This describes unit relations: exclusion_set, presence_set, or
792 absence_set (see file rtl.def). */
796 int first_list_length
;
800 /* This describes define_reservation (see file rtl.def). */
806 /* The following fields are defined by checker. */
808 /* The following field value is nonzero if the unit is used in an
811 /* The following field is used to check up cycle in expression
816 /* This describes define_insn_reservartion (see file rtl.def). */
817 struct insn_reserv_decl
824 /* The following fields are defined by checker. */
826 /* The following field value is order number (0, 1, ...) of given
829 /* The following field value is list of bypasses in which given insn
831 struct bypass_decl
*bypass_list
;
833 /* The following fields are defined by automaton generator. */
835 /* The following field is the insn regexp transformed that
836 the regexp has not optional regexp, repetition regexp, and an
837 reservation name (i.e. reservation identifiers are changed by the
838 corresponding regexp) and all alternations are the topest level
839 of the regexp. The value can be NULL only if it is special
840 insn `cycle advancing'. */
841 regexp_t transformed_regexp
;
842 /* The following field value is list of arcs marked given
843 insn. The field is used in transfromation NDFA -> DFA. */
844 arc_t arcs_marked_by_insn
;
845 /* The two following fields are used during minimization of a finite state
847 /* The field value is number of equivalence class of state into
848 which arc marked by given insn enters from a state (fixed during
849 an automaton minimization). */
851 /* The field value is state_alts of arc leaving a state (fixed
852 during an automaton minimization) and marked by given insn
855 /* The following member value is the list to automata which can be
856 changed by the insn issue. */
857 automata_list_el_t important_automata_list
;
858 /* The following member is used to process insn once for output. */
862 /* This contains a declaration mentioned above. */
865 /* What node in the union? */
870 struct unit_decl unit
;
871 struct bypass_decl bypass
;
872 struct automaton_decl automaton
;
873 struct unit_rel_decl excl
;
874 struct unit_rel_decl presence
;
875 struct unit_rel_decl absence
;
876 struct reserv_decl reserv
;
877 struct insn_reserv_decl insn_reserv
;
881 /* The following structures represent parsed reservation strings. */
893 /* Cpu unit in reservation. */
897 unit_decl_t unit_decl
;
900 /* Define_reservation in a reservation. */
904 struct reserv_decl
*reserv_decl
;
907 /* Absence of reservation (represented by string `nothing'). */
908 struct nothing_regexp
910 /* This used to be empty but ISO C doesn't allow that. */
914 /* Representation of reservations separated by ',' (see file
916 struct sequence_regexp
919 regexp_t regexps
[1];
922 /* Representation of construction `repeat' (see file rtl.def). */
929 /* Representation of reservations separated by '+' (see file
934 regexp_t regexps
[1];
937 /* Representation of reservations separated by '|' (see file
942 regexp_t regexps
[1];
945 /* Representation of a reservation string. */
948 /* What node in the union? */
949 enum regexp_mode mode
;
953 struct unit_regexp unit
;
954 struct reserv_regexp reserv
;
955 struct nothing_regexp nothing
;
956 struct sequence_regexp sequence
;
957 struct repeat_regexp repeat
;
958 struct allof_regexp allof
;
959 struct oneof_regexp oneof
;
963 /* Reperesents description of pipeline hazard description based on
969 /* The following fields are defined by checker. */
971 /* The following fields values are correspondingly number of all
972 units, query units, and insns in the description. */
976 /* The following field value is max length (in cycles) of
977 reservations of insns. The field value is defined only for
979 int max_insn_reserv_cycles
;
981 /* The following fields are defined by automaton generator. */
983 /* The following field value is the first automaton. */
984 automaton_t first_automaton
;
986 /* The following field is created by pipeline hazard parser and
987 contains all declarations. We allocate additional entry for
988 special insn "cycle advancing" which is added by the automaton
995 /* The following nodes are created in automaton checker. */
997 /* The following nodes represent exclusion, presence, absence set for
998 cpu units. Each element are accessed through only one excl_list,
999 presence_list, absence_list. */
1002 unit_decl_t unit_decl
;
1003 unit_set_el_t next_unit_set_el
;
1008 /* The following nodes are created in automaton generator. */
1010 /* The following node type describes state automaton. The state may
1011 be deterministic or non-deterministic. Non-deterministic state has
1012 several component states which represent alternative cpu units
1013 reservations. The state also is used for describing a
1014 deterministic reservation of automaton insn. */
1017 /* The following member value is nonzero if there is a transition by
1020 /* The following field is list of processor unit reservations on
1022 reserv_sets_t reservs
;
1023 /* The following field is unique number of given state between other
1026 /* The following field value is automaton to which given state
1028 automaton_t automaton
;
1029 /* The following field value is the first arc output from given
1031 arc_t first_out_arc
;
1032 /* The following field is used to form NDFA. */
1033 char it_was_placed_in_stack_for_NDFA_forming
;
1034 /* The following field is used to form DFA. */
1035 char it_was_placed_in_stack_for_DFA_forming
;
1036 /* The following field is used to transform NDFA to DFA. The field
1037 value is not NULL if the state is a compound state. In this case
1038 the value of field `unit_sets_list' is NULL. All states in the
1039 list are in the hash table. The list is formed through field
1040 `next_sorted_alt_state'. */
1041 alt_state_t component_states
;
1042 /* The following field is used for passing graph of states. */
1044 /* The list of states belonging to one equivalence class is formed
1045 with the aid of the following field. */
1046 state_t next_equiv_class_state
;
1047 /* The two following fields are used during minimization of a finite
1049 int equiv_class_num_1
, equiv_class_num_2
;
1050 /* The following field is used during minimization of a finite state
1051 automaton. The field value is state corresponding to equivalence
1052 class to which given state belongs. */
1053 state_t equiv_class_state
;
1054 /* The following field value is the order number of given state.
1055 The states in final DFA is enumerated with the aid of the
1057 int order_state_num
;
1058 /* This member is used for passing states for searching minimal
1061 /* The following member is used to evaluate min issue delay of insn
1063 int min_insn_issue_delay
;
1064 /* The following member is used to evaluate max issue rate of the
1065 processor. The value of the member is maximal length of the path
1066 from given state no containing arcs marked by special insn `cycle
1068 int longest_path_length
;
1071 /* The following macro is an initial value of member
1072 `longest_path_length' of a state. */
1073 #define UNDEFINED_LONGEST_PATH_LENGTH -1
1075 /* Automaton arc. */
1078 /* The following field refers for the state into which given arc
1081 /* The following field describes that the insn issue (with cycle
1082 advancing for special insn `cycle advancing' and without cycle
1083 advancing for others) makes transition from given state to
1084 another given state. */
1086 /* The following field value is the next arc output from the same
1089 /* List of arcs marked given insn is formed with the following
1090 field. The field is used in transfromation NDFA -> DFA. */
1091 arc_t next_arc_marked_by_insn
;
1092 /* The following field is defined if NDFA_FLAG is zero. The member
1093 value is number of alternative reservations which can be used for
1094 transition for given state by given insn. */
1098 /* The following node type describes a deterministic alternative in
1099 non-deterministic state which characterizes cpu unit reservations
1100 of automaton insn or which is part of NDFA. */
1103 /* The following field is a determinist state which characterizes
1104 unit reservations of the instruction. */
1106 /* The following field refers to the next state which characterizes
1107 unit reservations of the instruction. */
1108 alt_state_t next_alt_state
;
1109 /* The following field refers to the next state in sorted list. */
1110 alt_state_t next_sorted_alt_state
;
1113 /* The following node type describes insn of automaton. They are
1114 labels of FA arcs. */
1117 /* The following field value is the corresponding insn declaration
1119 struct insn_reserv_decl
*insn_reserv_decl
;
1120 /* The following field value is the next insn declaration for an
1123 /* The following field is states which characterize automaton unit
1124 reservations of the instruction. The value can be NULL only if it
1125 is special insn `cycle advancing'. */
1126 alt_state_t alt_states
;
1127 /* The following field is sorted list of states which characterize
1128 automaton unit reservations of the instruction. The value can be
1129 NULL only if it is special insn `cycle advancing'. */
1130 alt_state_t sorted_alt_states
;
1131 /* The following field refers the next automaton insn with
1132 the same reservations. */
1133 ainsn_t next_same_reservs_insn
;
1134 /* The following field is flag of the first automaton insn with the
1135 same reservations in the declaration list. Only arcs marked such
1136 insn is present in the automaton. This significantly decreases
1137 memory requirements especially when several automata are
1139 char first_insn_with_same_reservs
;
1140 /* The following member has nonzero value if there is arc from state of
1141 the automaton marked by the ainsn. */
1143 /* Cyclic list of insns of an equivalence class is formed with the
1144 aid of the following field. */
1145 ainsn_t next_equiv_class_insn
;
1146 /* The following field value is nonzero if the insn declaration is
1147 the first insn declaration with given equivalence number. */
1148 char first_ainsn_with_given_equialence_num
;
1149 /* The following field is number of class of equivalence of insns.
1150 It is necessary because many insns may be equivalent with the
1151 point of view of pipeline hazards. */
1152 int insn_equiv_class_num
;
1153 /* The following member value is TRUE if there is an arc in the
1154 automaton marked by the insn into another state. In other
1155 words, the insn can change the state of the automaton. */
1159 /* The folowing describes an automaton for PHR. */
1162 /* The following field value is the list of insn declarations for
1165 /* The following field value is the corresponding automaton
1166 declaration. This field is not NULL only if the automatic
1167 partition on automata is not used. */
1168 struct automaton_decl
*corresponding_automaton_decl
;
1169 /* The following field value is the next automaton. */
1170 automaton_t next_automaton
;
1171 /* The following field is start state of FA. There are not unit
1172 reservations in the state. */
1173 state_t start_state
;
1174 /* The following field value is number of equivalence classes of
1175 insns (see field `insn_equiv_class_num' in
1176 `insn_reserv_decl'). */
1177 int insn_equiv_classes_num
;
1178 /* The following field value is number of states of final DFA. */
1179 int achieved_states_num
;
1180 /* The following field value is the order number (0, 1, ...) of
1182 int automaton_order_num
;
1183 /* The following fields contain statistics information about
1184 building automaton. */
1185 int NDFA_states_num
, DFA_states_num
;
1186 /* The following field value is defined only if minimization of DFA
1188 int minimal_DFA_states_num
;
1189 int NDFA_arcs_num
, DFA_arcs_num
;
1190 /* The following field value is defined only if minimization of DFA
1192 int minimal_DFA_arcs_num
;
1193 /* The following two members refer for two table state x ainsn ->
1195 state_ainsn_table_t trans_table
;
1196 state_ainsn_table_t state_alts_table
;
1197 /* The following member value is maximal value of min issue delay
1198 for insns of the automaton. */
1200 /* Usually min issue delay is small and we can place several (2, 4,
1201 8) elements in one vector element. So the compression factor can
1202 be 1 (no compression), 2, 4, 8. */
1203 int min_issue_delay_table_compression_factor
;
1206 /* The following is the element of the list of automata. */
1207 struct automata_list_el
1209 /* The automaton itself. */
1210 automaton_t automaton
;
1211 /* The next automata set element. */
1212 automata_list_el_t next_automata_list_el
;
1215 /* The following structure describes a table state X ainsn -> int(>= 0). */
1216 struct state_ainsn_table
1218 /* Automaton to which given table belongs. */
1219 automaton_t automaton
;
1220 /* The following tree vectors for comb vector implementation of the
1222 vla_hwint_t comb_vect
;
1223 vla_hwint_t check_vect
;
1224 vla_hwint_t base_vect
;
1225 /* This is simple implementation of the table. */
1226 vla_hwint_t full_vect
;
1227 /* Minimal and maximal values of the previous vectors. */
1228 int min_comb_vect_el_value
, max_comb_vect_el_value
;
1229 int min_base_vect_el_value
, max_base_vect_el_value
;
1232 /* Macros to access members of unions. Use only them for access to
1233 union members of declarations and regexps. */
1235 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1237 #define DECL_UNIT(d) __extension__ \
1238 (({ struct decl *const _decl = (d); \
1239 if (_decl->mode != dm_unit) \
1240 decl_mode_check_failed (_decl->mode, "dm_unit", \
1241 __FILE__, __LINE__, __FUNCTION__); \
1242 &(_decl)->decl.unit; }))
1244 #define DECL_BYPASS(d) __extension__ \
1245 (({ struct decl *const _decl = (d); \
1246 if (_decl->mode != dm_bypass) \
1247 decl_mode_check_failed (_decl->mode, "dm_bypass", \
1248 __FILE__, __LINE__, __FUNCTION__); \
1249 &(_decl)->decl.bypass; }))
1251 #define DECL_AUTOMATON(d) __extension__ \
1252 (({ struct decl *const _decl = (d); \
1253 if (_decl->mode != dm_automaton) \
1254 decl_mode_check_failed (_decl->mode, "dm_automaton", \
1255 __FILE__, __LINE__, __FUNCTION__); \
1256 &(_decl)->decl.automaton; }))
1258 #define DECL_EXCL(d) __extension__ \
1259 (({ struct decl *const _decl = (d); \
1260 if (_decl->mode != dm_excl) \
1261 decl_mode_check_failed (_decl->mode, "dm_excl", \
1262 __FILE__, __LINE__, __FUNCTION__); \
1263 &(_decl)->decl.excl; }))
1265 #define DECL_PRESENCE(d) __extension__ \
1266 (({ struct decl *const _decl = (d); \
1267 if (_decl->mode != dm_presence) \
1268 decl_mode_check_failed (_decl->mode, "dm_presence", \
1269 __FILE__, __LINE__, __FUNCTION__); \
1270 &(_decl)->decl.presence; }))
1272 #define DECL_ABSENCE(d) __extension__ \
1273 (({ struct decl *const _decl = (d); \
1274 if (_decl->mode != dm_absence) \
1275 decl_mode_check_failed (_decl->mode, "dm_absence", \
1276 __FILE__, __LINE__, __FUNCTION__); \
1277 &(_decl)->decl.absence; }))
1279 #define DECL_RESERV(d) __extension__ \
1280 (({ struct decl *const _decl = (d); \
1281 if (_decl->mode != dm_reserv) \
1282 decl_mode_check_failed (_decl->mode, "dm_reserv", \
1283 __FILE__, __LINE__, __FUNCTION__); \
1284 &(_decl)->decl.reserv; }))
1286 #define DECL_INSN_RESERV(d) __extension__ \
1287 (({ struct decl *const _decl = (d); \
1288 if (_decl->mode != dm_insn_reserv) \
1289 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
1290 __FILE__, __LINE__, __FUNCTION__); \
1291 &(_decl)->decl.insn_reserv; }))
1293 static const char *decl_name
PARAMS ((enum decl_mode
));
1294 static void decl_mode_check_failed
PARAMS ((enum decl_mode
, const char *,
1295 const char *, int, const char *));
1297 /* Return string representation of declaration mode MODE. */
1300 enum decl_mode mode
;
1302 static char str
[100];
1304 if (mode
== dm_unit
)
1306 else if (mode
== dm_bypass
)
1308 else if (mode
== dm_automaton
)
1309 return "dm_automaton";
1310 else if (mode
== dm_excl
)
1312 else if (mode
== dm_presence
)
1313 return "dm_presence";
1314 else if (mode
== dm_absence
)
1315 return "dm_absence";
1316 else if (mode
== dm_reserv
)
1318 else if (mode
== dm_insn_reserv
)
1319 return "dm_insn_reserv";
1321 sprintf (str
, "unknown (%d)", (int) mode
);
1325 /* The function prints message about unexpected declaration and finish
1328 decl_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1329 enum decl_mode mode
;
1330 const char *expected_mode_str
;
1337 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1338 file
, line
, func
, expected_mode_str
, decl_name (mode
));
1343 #define REGEXP_UNIT(r) __extension__ \
1344 (({ struct regexp *const _regexp = (r); \
1345 if (_regexp->mode != rm_unit) \
1346 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
1347 __FILE__, __LINE__, __FUNCTION__); \
1348 &(_regexp)->regexp.unit; }))
1350 #define REGEXP_RESERV(r) __extension__ \
1351 (({ struct regexp *const _regexp = (r); \
1352 if (_regexp->mode != rm_reserv) \
1353 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
1354 __FILE__, __LINE__, __FUNCTION__); \
1355 &(_regexp)->regexp.reserv; }))
1357 #define REGEXP_SEQUENCE(r) __extension__ \
1358 (({ struct regexp *const _regexp = (r); \
1359 if (_regexp->mode != rm_sequence) \
1360 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1361 __FILE__, __LINE__, __FUNCTION__); \
1362 &(_regexp)->regexp.sequence; }))
1364 #define REGEXP_REPEAT(r) __extension__ \
1365 (({ struct regexp *const _regexp = (r); \
1366 if (_regexp->mode != rm_repeat) \
1367 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1368 __FILE__, __LINE__, __FUNCTION__); \
1369 &(_regexp)->regexp.repeat; }))
1371 #define REGEXP_ALLOF(r) __extension__ \
1372 (({ struct regexp *const _regexp = (r); \
1373 if (_regexp->mode != rm_allof) \
1374 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1375 __FILE__, __LINE__, __FUNCTION__); \
1376 &(_regexp)->regexp.allof; }))
1378 #define REGEXP_ONEOF(r) __extension__ \
1379 (({ struct regexp *const _regexp = (r); \
1380 if (_regexp->mode != rm_oneof) \
1381 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1382 __FILE__, __LINE__, __FUNCTION__); \
1383 &(_regexp)->regexp.oneof; }))
1385 static const char *regexp_name
PARAMS ((enum regexp_mode
));
1386 static void regexp_mode_check_failed
PARAMS ((enum regexp_mode
, const char *,
1391 /* Return string representation of regexp mode MODE. */
1394 enum regexp_mode mode
;
1396 static char str
[100];
1398 if (mode
== rm_unit
)
1400 else if (mode
== rm_reserv
)
1402 else if (mode
== rm_nothing
)
1403 return "rm_nothing";
1404 else if (mode
== rm_sequence
)
1405 return "rm_sequence";
1406 else if (mode
== rm_repeat
)
1408 else if (mode
== rm_allof
)
1410 else if (mode
== rm_oneof
)
1413 sprintf (str
, "unknown (%d)", (int) mode
);
1417 /* The function prints message about unexpected regexp and finish the
1420 regexp_mode_check_failed (mode
, expected_mode_str
, file
, line
, func
)
1421 enum regexp_mode mode
;
1422 const char *expected_mode_str
;
1429 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1430 file
, line
, func
, expected_mode_str
, regexp_name (mode
));
1434 #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1436 #define DECL_UNIT(d) (&(d)->decl.unit)
1437 #define DECL_BYPASS(d) (&(d)->decl.bypass)
1438 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1439 #define DECL_EXCL(d) (&(d)->decl.excl)
1440 #define DECL_PRESENCE(d) (&(d)->decl.presence)
1441 #define DECL_ABSENCE(d) (&(d)->decl.absence)
1442 #define DECL_RESERV(d) (&(d)->decl.reserv)
1443 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1445 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
1446 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1447 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1448 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1449 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1450 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1452 #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1454 /* Create IR structure (node). */
1461 obstack_blank (&irp
, size
);
1462 result
= obstack_base (&irp
);
1463 obstack_finish (&irp
);
1464 /* Default values of members are NULL and zero. */
1465 memset (result
, 0, size
);
1469 /* Copy IR structure (node). */
1471 copy_node (from
, size
)
1475 void *const result
= create_node (size
);
1476 memcpy (result
, from
, size
);
1480 /* The function checks that NAME does not contain quotes (`"'). */
1482 check_name (name
, pos
)
1484 pos_t pos ATTRIBUTE_UNUSED
;
1488 for (str
= name
; *str
!= '\0'; str
++)
1490 error ("Name `%s' contains quotes", name
);
1494 /* Pointers top all declartions during IR generation are stored in the
1496 static vla_ptr_t decls
;
1498 /* Given a pointer to a (char *) and a separator, return an alloc'ed
1499 string containing the next separated element, taking parentheses
1500 into account if PAR_FLAG has nonzero value. Advance the pointer to
1501 after the string scanned, or the end-of-string. Return NULL if at
1504 next_sep_el (pstr
, sep
, par_flag
)
1514 /* Remove leading whitespaces. */
1515 while (ISSPACE ((int) **pstr
))
1522 for (pars_num
= 0, p
= *pstr
; *p
!= '\0'; p
++)
1524 if (par_flag
&& *p
== '(')
1526 else if (par_flag
&& *p
== ')')
1528 else if (pars_num
== 0 && *p
== sep
)
1530 if (pars_num
== 0 && ISSPACE ((int) *p
))
1534 for (; n_spaces
!= 0; n_spaces
--)
1535 obstack_1grow (&irp
, p
[-n_spaces
]);
1536 obstack_1grow (&irp
, *p
);
1539 obstack_1grow (&irp
, '\0');
1540 out_str
= obstack_base (&irp
);
1541 obstack_finish (&irp
);
1550 /* Given a string and a separator, return the number of separated
1551 elements in it, taking parentheses into account if PAR_FLAG has
1552 nonzero value. Return 0 for the null string, -1 if parantheses is
1555 n_sep_els (s
, sep
, par_flag
)
1566 for (pars_num
= 0, n
= 1; *s
; s
++)
1567 if (par_flag
&& *s
== '(')
1569 else if (par_flag
&& *s
== ')')
1571 else if (pars_num
== 0 && *s
== sep
)
1574 return (pars_num
!= 0 ? -1 : n
);
1577 /* Given a string and a separator, return vector of strings which are
1578 elements in the string and number of elements through els_num.
1579 Take parentheses into account if PAR_FLAG has nonzero value.
1580 Return 0 for the null string, -1 if parantheses are not balanced. */
1582 get_str_vect (str
, els_num
, sep
, par_flag
)
1592 *els_num
= n_sep_els (str
, sep
, par_flag
);
1595 obstack_blank (&irp
, sizeof (char *) * (*els_num
));
1596 vect
= (char **) obstack_base (&irp
);
1597 obstack_finish (&irp
);
1599 for (i
= 0; i
< *els_num
; i
++)
1600 vect
[i
] = next_sep_el (pstr
, sep
, par_flag
);
1601 if (next_sep_el (pstr
, sep
, par_flag
) != NULL
)
1606 /* Process a DEFINE_CPU_UNIT.
1608 This gives information about a unit contained in CPU. We fill a
1609 struct unit_decl with information used later by `expand_automata'. */
1615 char **str_cpu_units
;
1619 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1620 if (str_cpu_units
== NULL
)
1621 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def
, 0));
1622 for (i
= 0; i
< vect_length
; i
++)
1624 decl
= create_node (sizeof (struct decl
));
1625 decl
->mode
= dm_unit
;
1627 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1628 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1629 DECL_UNIT (decl
)->query_p
= 0;
1630 VLA_PTR_ADD (decls
, decl
);
1635 /* Process a DEFINE_QUERY_CPU_UNIT.
1637 This gives information about a unit contained in CPU. We fill a
1638 struct unit_decl with information used later by `expand_automata'. */
1640 gen_query_cpu_unit (def
)
1644 char **str_cpu_units
;
1648 str_cpu_units
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1649 if (str_cpu_units
== NULL
)
1650 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def
, 0));
1651 for (i
= 0; i
< vect_length
; i
++)
1653 decl
= create_node (sizeof (struct decl
));
1654 decl
->mode
= dm_unit
;
1656 DECL_UNIT (decl
)->name
= check_name (str_cpu_units
[i
], decl
->pos
);
1657 DECL_UNIT (decl
)->automaton_name
= (char *) XSTR (def
, 1);
1658 DECL_UNIT (decl
)->query_p
= 1;
1659 VLA_PTR_ADD (decls
, decl
);
1664 /* Process a DEFINE_BYPASS.
1666 This gives information about a unit contained in the CPU. We fill
1667 in a struct bypass_decl with information used later by
1668 `expand_automata'. */
1680 out_insns
= get_str_vect ((char *) XSTR (def
, 1), &out_length
, ',', 0);
1681 if (out_insns
== NULL
)
1682 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 1));
1683 in_insns
= get_str_vect ((char *) XSTR (def
, 2), &in_length
, ',', 0);
1684 if (in_insns
== NULL
)
1685 fatal ("invalid string `%s' in define_bypass", XSTR (def
, 2));
1686 for (i
= 0; i
< out_length
; i
++)
1687 for (j
= 0; j
< in_length
; j
++)
1689 decl
= create_node (sizeof (struct decl
));
1690 decl
->mode
= dm_bypass
;
1692 DECL_BYPASS (decl
)->latency
= XINT (def
, 0);
1693 DECL_BYPASS (decl
)->out_insn_name
= out_insns
[i
];
1694 DECL_BYPASS (decl
)->in_insn_name
= in_insns
[j
];
1695 DECL_BYPASS (decl
)->bypass_guard_name
= (char *) XSTR (def
, 3);
1696 VLA_PTR_ADD (decls
, decl
);
1701 /* Process an EXCLUSION_SET.
1703 This gives information about a cpu unit conflicts. We fill a
1704 struct unit_rel_decl (excl) with information used later by
1705 `expand_automata'. */
1711 char **first_str_cpu_units
;
1712 char **second_str_cpu_units
;
1713 int first_vect_length
;
1718 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1719 if (first_str_cpu_units
== NULL
)
1720 fatal ("invalid first string `%s' in exclusion_set", XSTR (def
, 0));
1721 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1723 if (second_str_cpu_units
== NULL
)
1724 fatal ("invalid second string `%s' in exclusion_set", XSTR (def
, 1));
1725 length
+= first_vect_length
;
1726 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1727 decl
->mode
= dm_excl
;
1729 DECL_EXCL (decl
)->names_num
= length
;
1730 DECL_EXCL (decl
)->first_list_length
= first_vect_length
;
1731 for (i
= 0; i
< length
; i
++)
1732 if (i
< first_vect_length
)
1733 DECL_EXCL (decl
)->names
[i
] = first_str_cpu_units
[i
];
1735 DECL_EXCL (decl
)->names
[i
]
1736 = second_str_cpu_units
[i
- first_vect_length
];
1737 VLA_PTR_ADD (decls
, decl
);
1741 /* Process a PRESENCE_SET.
1743 This gives information about a cpu unit reservation requirements.
1744 We fill a struct unit_rel_decl (presence) with information used
1745 later by `expand_automata'. */
1747 gen_presence_set (def
)
1751 char **first_str_cpu_units
;
1752 char **second_str_cpu_units
;
1753 int first_vect_length
;
1758 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1759 if (first_str_cpu_units
== NULL
)
1760 fatal ("invalid first string `%s' in presence_set", XSTR (def
, 0));
1761 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1763 if (second_str_cpu_units
== NULL
)
1764 fatal ("invalid second string `%s' in presence_set", XSTR (def
, 1));
1765 length
+= first_vect_length
;
1766 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1767 decl
->mode
= dm_presence
;
1769 DECL_PRESENCE (decl
)->names_num
= length
;
1770 DECL_PRESENCE (decl
)->first_list_length
= first_vect_length
;
1771 for (i
= 0; i
< length
; i
++)
1772 if (i
< first_vect_length
)
1773 DECL_PRESENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1775 DECL_PRESENCE (decl
)->names
[i
]
1776 = second_str_cpu_units
[i
- first_vect_length
];
1777 VLA_PTR_ADD (decls
, decl
);
1781 /* Process an ABSENCE_SET.
1783 This gives information about a cpu unit reservation requirements.
1784 We fill a struct unit_rel_decl (absence) with information used
1785 later by `expand_automata'. */
1787 gen_absence_set (def
)
1791 char **first_str_cpu_units
;
1792 char **second_str_cpu_units
;
1793 int first_vect_length
;
1798 = get_str_vect ((char *) XSTR (def
, 0), &first_vect_length
, ',', 0);
1799 if (first_str_cpu_units
== NULL
)
1800 fatal ("invalid first string `%s' in absence_set", XSTR (def
, 0));
1801 second_str_cpu_units
= get_str_vect ((char *) XSTR (def
, 1), &length
, ',',
1803 if (second_str_cpu_units
== NULL
)
1804 fatal ("invalid second string `%s' in absence_set", XSTR (def
, 1));
1805 length
+= first_vect_length
;
1806 decl
= create_node (sizeof (struct decl
) + (length
- 1) * sizeof (char *));
1807 decl
->mode
= dm_absence
;
1809 DECL_ABSENCE (decl
)->names_num
= length
;
1810 DECL_ABSENCE (decl
)->first_list_length
= first_vect_length
;
1811 for (i
= 0; i
< length
; i
++)
1812 if (i
< first_vect_length
)
1813 DECL_ABSENCE (decl
)->names
[i
] = first_str_cpu_units
[i
];
1815 DECL_ABSENCE (decl
)->names
[i
]
1816 = second_str_cpu_units
[i
- first_vect_length
];
1817 VLA_PTR_ADD (decls
, decl
);
1821 /* Process a DEFINE_AUTOMATON.
1823 This gives information about a finite state automaton used for
1824 recognizing pipeline hazards. We fill a struct automaton_decl
1825 with information used later by `expand_automata'. */
1831 char **str_automata
;
1835 str_automata
= get_str_vect ((char *) XSTR (def
, 0), &vect_length
, ',', 0);
1836 if (str_automata
== NULL
)
1837 fatal ("invalid string `%s' in define_automaton", XSTR (def
, 0));
1838 for (i
= 0; i
< vect_length
; i
++)
1840 decl
= create_node (sizeof (struct decl
));
1841 decl
->mode
= dm_automaton
;
1843 DECL_AUTOMATON (decl
)->name
= check_name (str_automata
[i
], decl
->pos
);
1844 VLA_PTR_ADD (decls
, decl
);
1849 /* Process an AUTOMATA_OPTION.
1851 This gives information how to generate finite state automaton used
1852 for recognizing pipeline hazards. */
1854 gen_automata_option (def
)
1857 if (strcmp ((char *) XSTR (def
, 0), NO_MINIMIZATION_OPTION
+ 1) == 0)
1858 no_minimization_flag
= 1;
1859 else if (strcmp ((char *) XSTR (def
, 0), TIME_OPTION
+ 1) == 0)
1861 else if (strcmp ((char *) XSTR (def
, 0), V_OPTION
+ 1) == 0)
1863 else if (strcmp ((char *) XSTR (def
, 0), W_OPTION
+ 1) == 0)
1865 else if (strcmp ((char *) XSTR (def
, 0), NDFA_OPTION
+ 1) == 0)
1868 fatal ("invalid option `%s' in automata_option", XSTR (def
, 0));
1871 /* Name in reservation to denote absence reservation. */
1872 #define NOTHING_NAME "nothing"
1874 /* The following string contains original reservation string being
1876 static char *reserv_str
;
1878 /* Parse an element in STR. */
1889 if (str
[len
- 1] != ')')
1890 fatal ("garbage after ) in reservation `%s'", reserv_str
);
1891 str
[len
- 1] = '\0';
1892 regexp
= gen_regexp_sequence (str
+ 1);
1894 else if (strcmp (str
, NOTHING_NAME
) == 0)
1896 regexp
= create_node (sizeof (struct decl
));
1897 regexp
->mode
= rm_nothing
;
1901 regexp
= create_node (sizeof (struct decl
));
1902 regexp
->mode
= rm_unit
;
1903 REGEXP_UNIT (regexp
)->name
= str
;
1908 /* Parse construction `repeat' in STR. */
1910 gen_regexp_repeat (str
)
1919 repeat_vect
= get_str_vect (str
, &els_num
, '*', 1);
1920 if (repeat_vect
== NULL
)
1921 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1924 regexp
= gen_regexp_el (repeat_vect
[0]);
1925 for (i
= 1; i
< els_num
; i
++)
1927 repeat
= create_node (sizeof (struct regexp
));
1928 repeat
->mode
= rm_repeat
;
1929 REGEXP_REPEAT (repeat
)->regexp
= regexp
;
1930 REGEXP_REPEAT (repeat
)->repeat_num
= atoi (repeat_vect
[i
]);
1931 if (REGEXP_REPEAT (repeat
)->repeat_num
<= 1)
1932 fatal ("repetition `%s' <= 1 in reservation `%s'",
1939 return gen_regexp_el (str
);
1942 /* Parse reservation STR which possibly contains separator '+'. */
1944 gen_regexp_allof (str
)
1952 allof_vect
= get_str_vect (str
, &els_num
, '+', 1);
1953 if (allof_vect
== NULL
)
1954 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1957 allof
= create_node (sizeof (struct regexp
)
1958 + sizeof (regexp_t
) * (els_num
- 1));
1959 allof
->mode
= rm_allof
;
1960 REGEXP_ALLOF (allof
)->regexps_num
= els_num
;
1961 for (i
= 0; i
< els_num
; i
++)
1962 REGEXP_ALLOF (allof
)->regexps
[i
] = gen_regexp_repeat (allof_vect
[i
]);
1966 return gen_regexp_repeat (str
);
1969 /* Parse reservation STR which possibly contains separator '|'. */
1971 gen_regexp_oneof (str
)
1979 oneof_vect
= get_str_vect (str
, &els_num
, '|', 1);
1980 if (oneof_vect
== NULL
)
1981 fatal ("invalid `%s' in reservation `%s'", str
, reserv_str
);
1984 oneof
= create_node (sizeof (struct regexp
)
1985 + sizeof (regexp_t
) * (els_num
- 1));
1986 oneof
->mode
= rm_oneof
;
1987 REGEXP_ONEOF (oneof
)->regexps_num
= els_num
;
1988 for (i
= 0; i
< els_num
; i
++)
1989 REGEXP_ONEOF (oneof
)->regexps
[i
] = gen_regexp_allof (oneof_vect
[i
]);
1993 return gen_regexp_allof (str
);
1996 /* Parse reservation STR which possibly contains separator ','. */
1998 gen_regexp_sequence (str
)
2002 char **sequence_vect
;
2006 sequence_vect
= get_str_vect (str
, &els_num
, ',', 1);
2009 sequence
= create_node (sizeof (struct regexp
)
2010 + sizeof (regexp_t
) * (els_num
- 1));
2011 sequence
->mode
= rm_sequence
;
2012 REGEXP_SEQUENCE (sequence
)->regexps_num
= els_num
;
2013 for (i
= 0; i
< els_num
; i
++)
2014 REGEXP_SEQUENCE (sequence
)->regexps
[i
]
2015 = gen_regexp_oneof (sequence_vect
[i
]);
2019 return gen_regexp_oneof (str
);
2022 /* Parse construction reservation STR. */
2028 return gen_regexp_sequence (str
);;
2031 /* Process a DEFINE_RESERVATION.
2033 This gives information about a reservation of cpu units. We fill
2034 in a struct reserv_decl with information used later by
2035 `expand_automata'. */
2042 decl
= create_node (sizeof (struct decl
));
2043 decl
->mode
= dm_reserv
;
2045 DECL_RESERV (decl
)->name
= check_name ((char *) XSTR (def
, 0), decl
->pos
);
2046 DECL_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 1));
2047 VLA_PTR_ADD (decls
, decl
);
2051 /* Process a DEFINE_INSN_RESERVATION.
2053 This gives information about the reservation of cpu units by an
2054 insn. We fill a struct insn_reserv_decl with information used
2055 later by `expand_automata'. */
2057 gen_insn_reserv (def
)
2062 decl
= create_node (sizeof (struct decl
));
2063 decl
->mode
= dm_insn_reserv
;
2065 DECL_INSN_RESERV (decl
)->name
2066 = check_name ((char *) XSTR (def
, 0), decl
->pos
);
2067 DECL_INSN_RESERV (decl
)->default_latency
= XINT (def
, 1);
2068 DECL_INSN_RESERV (decl
)->condexp
= XEXP (def
, 2);
2069 DECL_INSN_RESERV (decl
)->regexp
= gen_regexp ((char *) XSTR (def
, 3));
2070 VLA_PTR_ADD (decls
, decl
);
2076 /* The function evaluates hash value (0..UINT_MAX) of string. */
2078 string_hash (string
)
2083 for (result
= i
= 0;*string
++ != '\0'; i
++)
2084 result
+= ((unsigned char) *string
<< (i
% CHAR_BIT
));
2090 /* This page contains abstract data `table of automaton declarations'.
2091 Elements of the table is nodes representing automaton declarations.
2092 Key of the table elements is name of given automaton. Rememeber
2093 that automaton names have own space. */
2095 /* The function evaluates hash value of an automaton declaration. The
2096 function is used by abstract data `hashtab'. The function returns
2097 hash value (0..UINT_MAX) of given automaton declaration. */
2099 automaton_decl_hash (automaton_decl
)
2100 const void *automaton_decl
;
2102 const decl_t decl
= (decl_t
) automaton_decl
;
2104 if (decl
->mode
== dm_automaton
&& DECL_AUTOMATON (decl
)->name
== NULL
)
2106 return string_hash (DECL_AUTOMATON (decl
)->name
);
2109 /* The function tests automaton declarations on equality of their
2110 keys. The function is used by abstract data `hashtab'. The
2111 function returns 1 if the declarations have the same key, 0
2114 automaton_decl_eq_p (automaton_decl_1
, automaton_decl_2
)
2115 const void* automaton_decl_1
;
2116 const void* automaton_decl_2
;
2118 const decl_t decl1
= (decl_t
) automaton_decl_1
;
2119 const decl_t decl2
= (decl_t
) automaton_decl_2
;
2121 if (decl1
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl1
)->name
== NULL
2122 || decl2
->mode
!= dm_automaton
|| DECL_AUTOMATON (decl2
)->name
== NULL
)
2124 return strcmp (DECL_AUTOMATON (decl1
)->name
,
2125 DECL_AUTOMATON (decl2
)->name
) == 0;
2128 /* The automaton declaration table itself is represented by the
2129 following variable. */
2130 static htab_t automaton_decl_table
;
2132 /* The function inserts automaton declaration into the table. The
2133 function does nothing if an automaton declaration with the same key
2134 exists already in the table. The function returns automaton
2135 declaration node in the table with the same key as given automaton
2136 declaration node. */
2138 insert_automaton_decl (automaton_decl
)
2139 decl_t automaton_decl
;
2143 entry_ptr
= htab_find_slot (automaton_decl_table
, automaton_decl
, 1);
2144 if (*entry_ptr
== NULL
)
2145 *entry_ptr
= (void *) automaton_decl
;
2146 return (decl_t
) *entry_ptr
;
2149 /* The following variable value is node representing automaton
2150 declaration. The node used for searching automaton declaration
2152 static struct decl work_automaton_decl
;
2154 /* The function searches for automaton declaration in the table with
2155 the same key as node representing name of the automaton
2156 declaration. The function returns node found in the table, NULL if
2157 such node does not exist in the table. */
2159 find_automaton_decl (name
)
2164 work_automaton_decl
.mode
= dm_automaton
;
2165 DECL_AUTOMATON (&work_automaton_decl
)->name
= name
;
2166 entry
= htab_find (automaton_decl_table
, &work_automaton_decl
);
2167 return (decl_t
) entry
;
2170 /* The function creates empty automaton declaration table and node
2171 representing automaton declaration and used for searching automaton
2172 declaration with given name. The function must be called only once
2173 before any work with the automaton declaration table. */
2175 initiate_automaton_decl_table ()
2177 work_automaton_decl
.mode
= dm_automaton
;
2178 automaton_decl_table
= htab_create (10, automaton_decl_hash
,
2179 automaton_decl_eq_p
, (htab_del
) 0);
2182 /* The function deletes the automaton declaration table. Only call of
2183 function `initiate_automaton_decl_table' is possible immediately
2184 after this function call. */
2186 finish_automaton_decl_table ()
2188 htab_delete (automaton_decl_table
);
2193 /* This page contains abstract data `table of insn declarations'.
2194 Elements of the table is nodes representing insn declarations. Key
2195 of the table elements is name of given insn (in corresponding
2196 define_insn_reservation). Rememeber that insn names have own
2199 /* The function evaluates hash value of an insn declaration. The
2200 function is used by abstract data `hashtab'. The function returns
2201 hash value (0..UINT_MAX) of given insn declaration. */
2203 insn_decl_hash (insn_decl
)
2204 const void *insn_decl
;
2206 const decl_t decl
= (decl_t
) insn_decl
;
2208 if (decl
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl
)->name
== NULL
)
2210 return string_hash (DECL_INSN_RESERV (decl
)->name
);
2213 /* The function tests insn declarations on equality of their keys.
2214 The function is used by abstract data `hashtab'. The function
2215 returns 1 if declarations have the same key, 0 otherwise. */
2217 insn_decl_eq_p (insn_decl_1
, insn_decl_2
)
2218 const void *insn_decl_1
;
2219 const void *insn_decl_2
;
2221 const decl_t decl1
= (decl_t
) insn_decl_1
;
2222 const decl_t decl2
= (decl_t
) insn_decl_2
;
2224 if (decl1
->mode
!= dm_insn_reserv
|| DECL_INSN_RESERV (decl1
)->name
== NULL
2225 || decl2
->mode
!= dm_insn_reserv
2226 || DECL_INSN_RESERV (decl2
)->name
== NULL
)
2228 return strcmp (DECL_INSN_RESERV (decl1
)->name
,
2229 DECL_INSN_RESERV (decl2
)->name
) == 0;
2232 /* The insn declaration table itself is represented by the following
2233 variable. The table does not contain insn reservation
2235 static htab_t insn_decl_table
;
2237 /* The function inserts insn declaration into the table. The function
2238 does nothing if an insn declaration with the same key exists
2239 already in the table. The function returns insn declaration node
2240 in the table with the same key as given insn declaration node. */
2242 insert_insn_decl (insn_decl
)
2247 entry_ptr
= htab_find_slot (insn_decl_table
, insn_decl
, 1);
2248 if (*entry_ptr
== NULL
)
2249 *entry_ptr
= (void *) insn_decl
;
2250 return (decl_t
) *entry_ptr
;
2253 /* The following variable value is node representing insn reservation
2254 declaration. The node used for searching insn reservation
2255 declaration with given name. */
2256 static struct decl work_insn_decl
;
2258 /* The function searches for insn reservation declaration in the table
2259 with the same key as node representing name of the insn reservation
2260 declaration. The function returns node found in the table, NULL if
2261 such node does not exist in the table. */
2263 find_insn_decl (name
)
2268 work_insn_decl
.mode
= dm_insn_reserv
;
2269 DECL_INSN_RESERV (&work_insn_decl
)->name
= name
;
2270 entry
= htab_find (insn_decl_table
, &work_insn_decl
);
2271 return (decl_t
) entry
;
2274 /* The function creates empty insn declaration table and node
2275 representing insn declaration and used for searching insn
2276 declaration with given name. The function must be called only once
2277 before any work with the insn declaration table. */
2279 initiate_insn_decl_table ()
2281 work_insn_decl
.mode
= dm_insn_reserv
;
2282 insn_decl_table
= htab_create (10, insn_decl_hash
, insn_decl_eq_p
,
2286 /* The function deletes the insn declaration table. Only call of
2287 function `initiate_insn_decl_table' is possible immediately after
2288 this function call. */
2290 finish_insn_decl_table ()
2292 htab_delete (insn_decl_table
);
2297 /* This page contains abstract data `table of declarations'. Elements
2298 of the table is nodes representing declarations (of units and
2299 reservations). Key of the table elements is names of given
2302 /* The function evaluates hash value of a declaration. The function
2303 is used by abstract data `hashtab'. The function returns hash
2304 value (0..UINT_MAX) of given declaration. */
2309 const decl_t d
= (const decl_t
) decl
;
2311 if ((d
->mode
!= dm_unit
|| DECL_UNIT (d
)->name
== NULL
)
2312 && (d
->mode
!= dm_reserv
|| DECL_RESERV (d
)->name
== NULL
))
2314 return string_hash (d
->mode
== dm_unit
2315 ? DECL_UNIT (d
)->name
: DECL_RESERV (d
)->name
);
2318 /* The function tests declarations on equality of their keys. The
2319 function is used by abstract data `hashtab'. The function
2320 returns 1 if the declarations have the same key, 0 otherwise. */
2322 decl_eq_p (decl_1
, decl_2
)
2326 const decl_t d1
= (const decl_t
) decl_1
;
2327 const decl_t d2
= (const decl_t
) decl_2
;
2329 if (((d1
->mode
!= dm_unit
|| DECL_UNIT (d1
)->name
== NULL
)
2330 && (d1
->mode
!= dm_reserv
|| DECL_RESERV (d1
)->name
== NULL
))
2331 || ((d2
->mode
!= dm_unit
|| DECL_UNIT (d2
)->name
== NULL
)
2332 && (d2
->mode
!= dm_reserv
|| DECL_RESERV (d2
)->name
== NULL
)))
2334 return strcmp ((d1
->mode
== dm_unit
2335 ? DECL_UNIT (d1
)->name
: DECL_RESERV (d1
)->name
),
2336 (d2
->mode
== dm_unit
2337 ? DECL_UNIT (d2
)->name
: DECL_RESERV (d2
)->name
)) == 0;
2340 /* The declaration table itself is represented by the following
2342 static htab_t decl_table
;
2344 /* The function inserts declaration into the table. The function does
2345 nothing if a declaration with the same key exists already in the
2346 table. The function returns declaration node in the table with the
2347 same key as given declaration node. */
2355 entry_ptr
= htab_find_slot (decl_table
, decl
, 1);
2356 if (*entry_ptr
== NULL
)
2357 *entry_ptr
= (void *) decl
;
2358 return (decl_t
) *entry_ptr
;
2361 /* The following variable value is node representing declaration. The
2362 node used for searching declaration with given name. */
2363 static struct decl work_decl
;
2365 /* The function searches for declaration in the table with the same
2366 key as node representing name of the declaration. The function
2367 returns node found in the table, NULL if such node does not exist
2375 work_decl
.mode
= dm_unit
;
2376 DECL_UNIT (&work_decl
)->name
= name
;
2377 entry
= htab_find (decl_table
, &work_decl
);
2378 return (decl_t
) entry
;
2381 /* The function creates empty declaration table and node representing
2382 declaration and used for searching declaration with given name.
2383 The function must be called only once before any work with the
2384 declaration table. */
2386 initiate_decl_table ()
2388 work_decl
.mode
= dm_unit
;
2389 decl_table
= htab_create (10, decl_hash
, decl_eq_p
, (htab_del
) 0);
2392 /* The function deletes the declaration table. Only call of function
2393 `initiate_declaration_table' is possible immediately after this
2396 finish_decl_table ()
2398 htab_delete (decl_table
);
2403 /* This page contains checker of pipeline hazard description. */
2405 /* Checking NAMES in an exclusion clause vector and returning formed
2406 unit_set_el_list. */
2407 static unit_set_el_t
2408 process_excls (names
, num
, excl_pos
)
2411 pos_t excl_pos ATTRIBUTE_UNUSED
;
2413 unit_set_el_t el_list
;
2414 unit_set_el_t last_el
;
2415 unit_set_el_t new_el
;
2416 decl_t decl_in_table
;
2421 for (i
= 0; i
< num
; i
++)
2423 decl_in_table
= find_decl (names
[i
]);
2424 if (decl_in_table
== NULL
)
2425 error ("unit `%s' in exclusion is not declared", names
[i
]);
2426 else if (decl_in_table
->mode
!= dm_unit
)
2427 error ("`%s' in exclusion is not unit", names
[i
]);
2430 new_el
= create_node (sizeof (struct unit_set_el
));
2431 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2432 new_el
->next_unit_set_el
= NULL
;
2433 if (last_el
== NULL
)
2434 el_list
= last_el
= new_el
;
2437 last_el
->next_unit_set_el
= new_el
;
2438 last_el
= last_el
->next_unit_set_el
;
2445 /* The function adds each element from SOURCE_LIST to the exclusion
2446 list of the each element from DEST_LIST. Checking situation "unit
2447 excludes itself". */
2449 add_excls (dest_list
, source_list
, excl_pos
)
2450 unit_set_el_t dest_list
;
2451 unit_set_el_t source_list
;
2452 pos_t excl_pos ATTRIBUTE_UNUSED
;
2456 unit_set_el_t curr_el
;
2457 unit_set_el_t prev_el
;
2460 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2461 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2463 if (dst
->unit_decl
== src
->unit_decl
)
2465 error ("unit `%s' excludes itself", src
->unit_decl
->name
);
2468 if (dst
->unit_decl
->automaton_name
!= NULL
2469 && src
->unit_decl
->automaton_name
!= NULL
2470 && strcmp (dst
->unit_decl
->automaton_name
,
2471 src
->unit_decl
->automaton_name
) != 0)
2473 error ("units `%s' and `%s' in exclusion set belong to different automata",
2474 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2477 for (curr_el
= dst
->unit_decl
->excl_list
, prev_el
= NULL
;
2479 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2480 if (curr_el
->unit_decl
== src
->unit_decl
)
2482 if (curr_el
== NULL
)
2484 /* Element not found - insert. */
2485 copy
= copy_node (src
, sizeof (*src
));
2486 copy
->next_unit_set_el
= NULL
;
2487 if (prev_el
== NULL
)
2488 dst
->unit_decl
->excl_list
= copy
;
2490 prev_el
->next_unit_set_el
= copy
;
2495 /* Checking NAMES in an presence clause vector and returning formed
2496 unit_set_el_list. The function is called only after processing all
2498 static unit_set_el_t
2499 process_presence_absence (names
, num
, req_pos
, presence_p
)
2502 pos_t req_pos ATTRIBUTE_UNUSED
;
2505 unit_set_el_t el_list
;
2506 unit_set_el_t last_el
;
2507 unit_set_el_t new_el
;
2508 decl_t decl_in_table
;
2513 for (i
= 0; i
< num
; i
++)
2515 decl_in_table
= find_decl (names
[i
]);
2516 if (decl_in_table
== NULL
)
2518 ? "unit `%s' in presence set is not declared"
2519 : "unit `%s' in absence set is not declared"), names
[i
]);
2520 else if (decl_in_table
->mode
!= dm_unit
)
2522 ? "`%s' in presence set is not unit"
2523 : "`%s' in absence set is not unit"), names
[i
]);
2526 new_el
= create_node (sizeof (struct unit_set_el
));
2527 new_el
->unit_decl
= DECL_UNIT (decl_in_table
);
2528 new_el
->next_unit_set_el
= NULL
;
2529 if (last_el
== NULL
)
2530 el_list
= last_el
= new_el
;
2533 last_el
->next_unit_set_el
= new_el
;
2534 last_el
= last_el
->next_unit_set_el
;
2541 /* The function adds each element from SOURCE_LIST to presence (if
2542 PRESENCE_P) or absence list of the each element from DEST_LIST.
2543 Checking situations "unit requires own presence", "unit requires
2544 own absence", and "unit excludes and requires presence of ...".
2545 Remember that we process absence sets only after all presence
2548 add_presence_absence (dest_list
, source_list
, req_pos
, presence_p
)
2549 unit_set_el_t dest_list
;
2550 unit_set_el_t source_list
;
2551 pos_t req_pos ATTRIBUTE_UNUSED
;
2556 unit_set_el_t curr_el
;
2557 unit_set_el_t prev_el
;
2560 for (dst
= dest_list
; dst
!= NULL
; dst
= dst
->next_unit_set_el
)
2561 for (src
= source_list
; src
!= NULL
; src
= src
->next_unit_set_el
)
2563 if (dst
->unit_decl
== src
->unit_decl
)
2566 ? "unit `%s' requires own presence"
2567 : "unit `%s' requires own absence"), src
->unit_decl
->name
);
2570 if (dst
->unit_decl
->automaton_name
!= NULL
2571 && src
->unit_decl
->automaton_name
!= NULL
2572 && strcmp (dst
->unit_decl
->automaton_name
,
2573 src
->unit_decl
->automaton_name
) != 0)
2576 ? "units `%s' and `%s' in presence set belong to different automata"
2577 : "units `%s' and `%s' in absence set belong to different automata"),
2578 src
->unit_decl
->name
, dst
->unit_decl
->name
);
2581 for (curr_el
= (presence_p
2582 ? dst
->unit_decl
->presence_list
2583 : dst
->unit_decl
->absence_list
), prev_el
= NULL
;
2585 prev_el
= curr_el
, curr_el
= curr_el
->next_unit_set_el
)
2586 if (curr_el
->unit_decl
== src
->unit_decl
)
2588 if (curr_el
== NULL
)
2590 /* Element not found - insert if there is no error. */
2591 int no_error_flag
= 1;
2594 for (curr_el
= dst
->unit_decl
->excl_list
;
2596 curr_el
= curr_el
->next_unit_set_el
)
2598 if (src
->unit_decl
== curr_el
->unit_decl
)
2603 ("unit `%s' excludes and requires presence of `%s'",
2604 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2609 ("unit `%s' excludes and requires presence of `%s'",
2610 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2614 for (curr_el
= dst
->unit_decl
->presence_list
;
2616 curr_el
= curr_el
->next_unit_set_el
)
2618 if (src
->unit_decl
== curr_el
->unit_decl
)
2623 ("unit `%s' requires absence and presence of `%s'",
2624 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2629 ("unit `%s' requires absence and presence of `%s'",
2630 dst
->unit_decl
->name
, src
->unit_decl
->name
);
2635 copy
= copy_node (src
, sizeof (*src
));
2636 copy
->next_unit_set_el
= NULL
;
2637 if (prev_el
== NULL
)
2640 dst
->unit_decl
->presence_list
= copy
;
2642 dst
->unit_decl
->absence_list
= copy
;
2645 prev_el
->next_unit_set_el
= copy
;
2651 /* The function searches for bypass with given IN_INSN_RESERV in given
2653 static struct bypass_decl
*
2654 find_bypass (bypass_list
, in_insn_reserv
)
2655 struct bypass_decl
*bypass_list
;
2656 struct insn_reserv_decl
*in_insn_reserv
;
2658 struct bypass_decl
*bypass
;
2660 for (bypass
= bypass_list
; bypass
!= NULL
; bypass
= bypass
->next
)
2661 if (bypass
->in_insn_reserv
== in_insn_reserv
)
2666 /* The function processes pipeline description declarations, checks
2667 their correctness, and forms exclusion/presence/absence sets. */
2672 decl_t automaton_decl
;
2673 decl_t decl_in_table
;
2674 decl_t out_insn_reserv
;
2675 decl_t in_insn_reserv
;
2676 struct bypass_decl
*bypass
;
2677 int automaton_presence
;
2680 /* Checking repeated automata declarations. */
2681 automaton_presence
= 0;
2682 for (i
= 0; i
< description
->decls_num
; i
++)
2684 decl
= description
->decls
[i
];
2685 if (decl
->mode
== dm_automaton
)
2687 automaton_presence
= 1;
2688 decl_in_table
= insert_automaton_decl (decl
);
2689 if (decl_in_table
!= decl
)
2692 error ("repeated declaration of automaton `%s'",
2693 DECL_AUTOMATON (decl
)->name
);
2695 warning ("repeated declaration of automaton `%s'",
2696 DECL_AUTOMATON (decl
)->name
);
2700 /* Checking undeclared automata, repeated declarations (except for
2701 automata) and correctness of their attributes (insn latency times
2703 for (i
= 0; i
< description
->decls_num
; i
++)
2705 decl
= description
->decls
[i
];
2706 if (decl
->mode
== dm_insn_reserv
)
2708 DECL_INSN_RESERV (decl
)->condexp
2709 = check_attr_test (DECL_INSN_RESERV (decl
)->condexp
, 0, 0);
2710 if (DECL_INSN_RESERV (decl
)->default_latency
< 0)
2711 error ("define_insn_reservation `%s' has negative latency time",
2712 DECL_INSN_RESERV (decl
)->name
);
2713 DECL_INSN_RESERV (decl
)->insn_num
= description
->insns_num
;
2714 description
->insns_num
++;
2715 decl_in_table
= insert_insn_decl (decl
);
2716 if (decl_in_table
!= decl
)
2717 error ("`%s' is already used as insn reservation name",
2718 DECL_INSN_RESERV (decl
)->name
);
2720 else if (decl
->mode
== dm_bypass
)
2722 if (DECL_BYPASS (decl
)->latency
< 0)
2723 error ("define_bypass `%s - %s' has negative latency time",
2724 DECL_BYPASS (decl
)->out_insn_name
,
2725 DECL_BYPASS (decl
)->in_insn_name
);
2727 else if (decl
->mode
== dm_unit
|| decl
->mode
== dm_reserv
)
2729 if (decl
->mode
== dm_unit
)
2731 DECL_UNIT (decl
)->automaton_decl
= NULL
;
2732 if (DECL_UNIT (decl
)->automaton_name
!= NULL
)
2735 = find_automaton_decl (DECL_UNIT (decl
)->automaton_name
);
2736 if (automaton_decl
== NULL
)
2737 error ("automaton `%s' is not declared",
2738 DECL_UNIT (decl
)->automaton_name
);
2741 DECL_AUTOMATON (automaton_decl
)->automaton_is_used
= 1;
2742 DECL_UNIT (decl
)->automaton_decl
2743 = DECL_AUTOMATON (automaton_decl
);
2746 else if (automaton_presence
)
2747 error ("define_unit `%s' without automaton when one defined",
2748 DECL_UNIT (decl
)->name
);
2749 DECL_UNIT (decl
)->unit_num
= description
->units_num
;
2750 description
->units_num
++;
2751 if (strcmp (DECL_UNIT (decl
)->name
, NOTHING_NAME
) == 0)
2753 error ("`%s' is declared as cpu unit", NOTHING_NAME
);
2756 decl_in_table
= find_decl (DECL_UNIT (decl
)->name
);
2760 if (strcmp (DECL_RESERV (decl
)->name
, NOTHING_NAME
) == 0)
2762 error ("`%s' is declared as cpu reservation", NOTHING_NAME
);
2765 decl_in_table
= find_decl (DECL_RESERV (decl
)->name
);
2767 if (decl_in_table
== NULL
)
2768 decl_in_table
= insert_decl (decl
);
2771 if (decl
->mode
== dm_unit
)
2772 error ("repeated declaration of unit `%s'",
2773 DECL_UNIT (decl
)->name
);
2775 error ("repeated declaration of reservation `%s'",
2776 DECL_RESERV (decl
)->name
);
2780 /* Check bypasses and form list of bypasses for each (output)
2782 for (i
= 0; i
< description
->decls_num
; i
++)
2784 decl
= description
->decls
[i
];
2785 if (decl
->mode
== dm_bypass
)
2787 out_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->out_insn_name
);
2788 in_insn_reserv
= find_insn_decl (DECL_BYPASS (decl
)->in_insn_name
);
2789 if (out_insn_reserv
== NULL
)
2790 error ("there is no insn reservation `%s'",
2791 DECL_BYPASS (decl
)->out_insn_name
);
2792 else if (in_insn_reserv
== NULL
)
2793 error ("there is no insn reservation `%s'",
2794 DECL_BYPASS (decl
)->in_insn_name
);
2797 DECL_BYPASS (decl
)->out_insn_reserv
2798 = DECL_INSN_RESERV (out_insn_reserv
);
2799 DECL_BYPASS (decl
)->in_insn_reserv
2800 = DECL_INSN_RESERV (in_insn_reserv
);
2802 = find_bypass (DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
,
2803 DECL_BYPASS (decl
)->in_insn_reserv
);
2806 if (DECL_BYPASS (decl
)->latency
== bypass
->latency
)
2810 ("the same bypass `%s - %s' is already defined",
2811 DECL_BYPASS (decl
)->out_insn_name
,
2812 DECL_BYPASS (decl
)->in_insn_name
);
2815 ("the same bypass `%s - %s' is already defined",
2816 DECL_BYPASS (decl
)->out_insn_name
,
2817 DECL_BYPASS (decl
)->in_insn_name
);
2820 error ("bypass `%s - %s' is already defined",
2821 DECL_BYPASS (decl
)->out_insn_name
,
2822 DECL_BYPASS (decl
)->in_insn_name
);
2826 DECL_BYPASS (decl
)->next
2827 = DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
;
2828 DECL_INSN_RESERV (out_insn_reserv
)->bypass_list
2829 = DECL_BYPASS (decl
);
2835 /* Check exclusion set declarations and form exclussion sets. */
2836 for (i
= 0; i
< description
->decls_num
; i
++)
2838 decl
= description
->decls
[i
];
2839 if (decl
->mode
== dm_excl
)
2841 unit_set_el_t unit_set_el_list
;
2842 unit_set_el_t unit_set_el_list_2
;
2845 = process_excls (DECL_EXCL (decl
)->names
,
2846 DECL_EXCL (decl
)->first_list_length
, decl
->pos
);
2848 = process_excls (&DECL_EXCL (decl
)->names
2849 [DECL_EXCL (decl
)->first_list_length
],
2850 DECL_EXCL (decl
)->names_num
2851 - DECL_EXCL (decl
)->first_list_length
,
2853 add_excls (unit_set_el_list
, unit_set_el_list_2
, decl
->pos
);
2854 add_excls (unit_set_el_list_2
, unit_set_el_list
, decl
->pos
);
2858 /* Check presence set declarations and form presence sets. */
2859 for (i
= 0; i
< description
->decls_num
; i
++)
2861 decl
= description
->decls
[i
];
2862 if (decl
->mode
== dm_presence
)
2864 unit_set_el_t unit_set_el_list
;
2865 unit_set_el_t unit_set_el_list_2
;
2868 = process_presence_absence
2869 (DECL_PRESENCE (decl
)->names
,
2870 DECL_PRESENCE (decl
)->first_list_length
, decl
->pos
, 1);
2872 = process_presence_absence
2873 (&DECL_PRESENCE (decl
)->names
2874 [DECL_PRESENCE (decl
)->first_list_length
],
2875 DECL_PRESENCE (decl
)->names_num
2876 - DECL_PRESENCE (decl
)->first_list_length
,
2878 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2883 /* Check absence set declarations and form absence sets. */
2884 for (i
= 0; i
< description
->decls_num
; i
++)
2886 decl
= description
->decls
[i
];
2887 if (decl
->mode
== dm_absence
)
2889 unit_set_el_t unit_set_el_list
;
2890 unit_set_el_t unit_set_el_list_2
;
2893 = process_presence_absence
2894 (DECL_ABSENCE (decl
)->names
,
2895 DECL_ABSENCE (decl
)->first_list_length
, decl
->pos
, 0);
2897 = process_presence_absence
2898 (&DECL_ABSENCE (decl
)->names
2899 [DECL_ABSENCE (decl
)->first_list_length
],
2900 DECL_ABSENCE (decl
)->names_num
2901 - DECL_ABSENCE (decl
)->first_list_length
,
2903 add_presence_absence (unit_set_el_list
, unit_set_el_list_2
,
2909 /* The following function checks that declared automaton is used. If
2910 the automaton is not used, the function fixes error/warning. The
2911 following function must be called only after `process_decls'. */
2913 check_automaton_usage ()
2918 for (i
= 0; i
< description
->decls_num
; i
++)
2920 decl
= description
->decls
[i
];
2921 if (decl
->mode
== dm_automaton
2922 && !DECL_AUTOMATON (decl
)->automaton_is_used
)
2925 error ("automaton `%s' is not used", DECL_AUTOMATON (decl
)->name
);
2927 warning ("automaton `%s' is not used",
2928 DECL_AUTOMATON (decl
)->name
);
2933 /* The following recursive function processes all regexp in order to
2934 fix usage of units or reservations and to fix errors of undeclared
2935 name. The function may change unit_regexp onto reserv_regexp.
2936 Remember that reserv_regexp does not exist before the function
2939 process_regexp (regexp
)
2942 decl_t decl_in_table
;
2943 regexp_t new_regexp
;
2946 if (regexp
->mode
== rm_unit
)
2948 decl_in_table
= find_decl (REGEXP_UNIT (regexp
)->name
);
2949 if (decl_in_table
== NULL
)
2950 error ("undeclared unit or reservation `%s'",
2951 REGEXP_UNIT (regexp
)->name
);
2952 else if (decl_in_table
->mode
== dm_unit
)
2954 DECL_UNIT (decl_in_table
)->unit_is_used
= 1;
2955 REGEXP_UNIT (regexp
)->unit_decl
= DECL_UNIT (decl_in_table
);
2957 else if (decl_in_table
->mode
== dm_reserv
)
2959 DECL_RESERV (decl_in_table
)->reserv_is_used
= 1;
2960 new_regexp
= create_node (sizeof (struct regexp
));
2961 new_regexp
->mode
= rm_reserv
;
2962 new_regexp
->pos
= regexp
->pos
;
2963 REGEXP_RESERV (new_regexp
)->name
= REGEXP_UNIT (regexp
)->name
;
2964 REGEXP_RESERV (new_regexp
)->reserv_decl
2965 = DECL_RESERV (decl_in_table
);
2966 regexp
= new_regexp
;
2971 else if (regexp
->mode
== rm_sequence
)
2972 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
2973 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
2974 = process_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
2975 else if (regexp
->mode
== rm_allof
)
2976 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
2977 REGEXP_ALLOF (regexp
)->regexps
[i
]
2978 = process_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
2979 else if (regexp
->mode
== rm_oneof
)
2980 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
2981 REGEXP_ONEOF (regexp
)->regexps
[i
]
2982 = process_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
2983 else if (regexp
->mode
== rm_repeat
)
2984 REGEXP_REPEAT (regexp
)->regexp
2985 = process_regexp (REGEXP_REPEAT (regexp
)->regexp
);
2986 else if (regexp
->mode
!= rm_nothing
)
2991 /* The following function processes regexp of define_reservation and
2992 define_insn_reservation with the aid of function
2993 `process_regexp'. */
2995 process_regexp_decls ()
3000 for (i
= 0; i
< description
->decls_num
; i
++)
3002 decl
= description
->decls
[i
];
3003 if (decl
->mode
== dm_reserv
)
3004 DECL_RESERV (decl
)->regexp
3005 = process_regexp (DECL_RESERV (decl
)->regexp
);
3006 else if (decl
->mode
== dm_insn_reserv
)
3007 DECL_INSN_RESERV (decl
)->regexp
3008 = process_regexp (DECL_INSN_RESERV (decl
)->regexp
);
3012 /* The following function checks that declared unit is used. If the
3013 unit is not used, the function fixes errors/warnings. The
3014 following function must be called only after `process_decls',
3015 `process_regexp_decls'. */
3022 for (i
= 0; i
< description
->decls_num
; i
++)
3024 decl
= description
->decls
[i
];
3025 if (decl
->mode
== dm_unit
&& !DECL_UNIT (decl
)->unit_is_used
)
3028 error ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3030 warning ("unit `%s' is not used", DECL_UNIT (decl
)->name
);
3032 else if (decl
->mode
== dm_reserv
&& !DECL_RESERV (decl
)->reserv_is_used
)
3035 error ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3037 warning ("reservation `%s' is not used", DECL_RESERV (decl
)->name
);
3042 /* The following variable value is number of reservation being
3043 processed on loop recognition. */
3044 static int curr_loop_pass_num
;
3046 /* The following recursive function returns nonzero value if REGEXP
3047 contains given decl or reservations in given regexp refers for
3050 loop_in_regexp (regexp
, start_decl
)
3058 if (regexp
->mode
== rm_unit
)
3060 else if (regexp
->mode
== rm_reserv
)
3062 if (start_decl
->mode
== dm_reserv
3063 && REGEXP_RESERV (regexp
)->reserv_decl
== DECL_RESERV (start_decl
))
3065 else if (REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3066 == curr_loop_pass_num
)
3067 /* declaration has been processed. */
3071 REGEXP_RESERV (regexp
)->reserv_decl
->loop_pass_num
3072 = curr_loop_pass_num
;
3073 return loop_in_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3077 else if (regexp
->mode
== rm_sequence
)
3079 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3080 if (loop_in_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
], start_decl
))
3084 else if (regexp
->mode
== rm_allof
)
3086 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3087 if (loop_in_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
], start_decl
))
3091 else if (regexp
->mode
== rm_oneof
)
3093 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3094 if (loop_in_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
], start_decl
))
3098 else if (regexp
->mode
== rm_repeat
)
3099 return loop_in_regexp (REGEXP_REPEAT (regexp
)->regexp
, start_decl
);
3102 if (regexp
->mode
!= rm_nothing
)
3108 /* The following function fixes errors "cycle in definition ...". The
3109 function uses function `loop_in_regexp' for that. */
3111 check_loops_in_regexps ()
3116 for (i
= 0; i
< description
->decls_num
; i
++)
3118 decl
= description
->decls
[i
];
3119 if (decl
->mode
== dm_reserv
)
3120 DECL_RESERV (decl
)->loop_pass_num
= 0;
3122 for (i
= 0; i
< description
->decls_num
; i
++)
3124 decl
= description
->decls
[i
];
3125 curr_loop_pass_num
= i
;
3127 if (decl
->mode
== dm_reserv
)
3129 DECL_RESERV (decl
)->loop_pass_num
= curr_loop_pass_num
;
3130 if (loop_in_regexp (DECL_RESERV (decl
)->regexp
, decl
))
3132 if (DECL_RESERV (decl
)->regexp
== NULL
)
3134 error ("cycle in definition of reservation `%s'",
3135 DECL_RESERV (decl
)->name
);
3141 /* The function recursively processes IR of reservation and defines
3142 max and min cycle for reservation of unit and for result in the
3145 process_regexp_cycles (regexp
, start_cycle
)
3151 if (regexp
->mode
== rm_unit
)
3153 if (REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
< start_cycle
)
3154 REGEXP_UNIT (regexp
)->unit_decl
->max_occ_cycle_num
= start_cycle
;
3157 else if (regexp
->mode
== rm_reserv
)
3158 return process_regexp_cycles (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
,
3160 else if (regexp
->mode
== rm_repeat
)
3162 for (i
= 0; i
< REGEXP_REPEAT (regexp
)->repeat_num
; i
++)
3163 start_cycle
= process_regexp_cycles (REGEXP_REPEAT (regexp
)->regexp
,
3167 else if (regexp
->mode
== rm_sequence
)
3169 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
3171 = process_regexp_cycles (REGEXP_SEQUENCE (regexp
)->regexps
[i
],
3175 else if (regexp
->mode
== rm_allof
)
3177 int finish_cycle
= 0;
3180 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
3182 cycle
= process_regexp_cycles (REGEXP_ALLOF (regexp
)->regexps
[i
],
3184 if (finish_cycle
< cycle
)
3185 finish_cycle
= cycle
;
3187 return finish_cycle
;
3189 else if (regexp
->mode
== rm_oneof
)
3191 int finish_cycle
= 0;
3194 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
3196 cycle
= process_regexp_cycles (REGEXP_ONEOF (regexp
)->regexps
[i
],
3198 if (finish_cycle
< cycle
)
3199 finish_cycle
= cycle
;
3201 return finish_cycle
;
3205 if (regexp
->mode
!= rm_nothing
)
3211 /* The following function is called only for correct program. The
3212 function defines max reservation of insns in cycles. */
3214 evaluate_max_reserv_cycles ()
3216 int max_insn_cycles_num
;
3220 description
->max_insn_reserv_cycles
= 0;
3221 for (i
= 0; i
< description
->decls_num
; i
++)
3223 decl
= description
->decls
[i
];
3224 if (decl
->mode
== dm_insn_reserv
)
3227 = process_regexp_cycles (DECL_INSN_RESERV (decl
)->regexp
, 0);
3228 if (description
->max_insn_reserv_cycles
< max_insn_cycles_num
)
3229 description
->max_insn_reserv_cycles
= max_insn_cycles_num
;
3232 description
->max_insn_reserv_cycles
++;
3235 /* The following function calls functions for checking all
3238 check_all_description ()
3241 check_automaton_usage ();
3242 process_regexp_decls ();
3244 check_loops_in_regexps ();
3246 evaluate_max_reserv_cycles ();
3251 /* The page contains abstract data `ticker'. This data is used to
3252 report time of different phases of building automata. It is
3253 possibly to write a description for which automata will be built
3254 during several minutes even on fast machine. */
3256 /* The following function creates ticker and makes it active. */
3262 ticker
.modified_creation_time
= get_run_time ();
3263 ticker
.incremented_off_time
= 0;
3267 /* The following function switches off given ticker. */
3272 if (ticker
->incremented_off_time
== 0)
3273 ticker
->incremented_off_time
= get_run_time () + 1;
3276 /* The following function switches on given ticker. */
3281 if (ticker
->incremented_off_time
!= 0)
3283 ticker
->modified_creation_time
3284 += get_run_time () - ticker
->incremented_off_time
+ 1;
3285 ticker
->incremented_off_time
= 0;
3289 /* The following function returns current time in milliseconds since
3290 the moment when given ticker was created. */
3292 active_time (ticker
)
3295 if (ticker
.incremented_off_time
!= 0)
3296 return ticker
.incremented_off_time
- 1 - ticker
.modified_creation_time
;
3298 return get_run_time () - ticker
.modified_creation_time
;
3301 /* The following function returns string representation of active time
3302 of given ticker. The result is string representation of seconds
3303 with accuracy of 1/100 second. Only result of the last call of the
3304 function exists. Therefore the following code is not correct
3306 printf ("parser time: %s\ngeneration time: %s\n",
3307 active_time_string (parser_ticker),
3308 active_time_string (generation_ticker));
3310 Correct code has to be the following
3312 printf ("parser time: %s\n", active_time_string (parser_ticker));
3313 printf ("generation time: %s\n",
3314 active_time_string (generation_ticker));
3318 print_active_time (f
, ticker
)
3324 msecs
= active_time (ticker
);
3325 fprintf (f
, "%d.%06d", msecs
/ 1000000, msecs
% 1000000);
3330 /* The following variable value is number of automaton which are
3331 really being created. This value is defined on the base of
3332 argument of option `-split'. If the variable has zero value the
3333 number of automata is defined by the constructions `%automaton'.
3334 This case occures when option `-split' is absent or has zero
3335 argument. If constructions `define_automaton' is absent only one
3336 automaton is created. */
3337 static int automata_num
;
3339 /* The following variable values are times of
3340 o transformation of regular expressions
3341 o building NDFA (DFA if !ndfa_flag)
3342 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3344 o building insn equivalence classes
3347 static ticker_t transform_time
;
3348 static ticker_t NDFA_time
;
3349 static ticker_t NDFA_to_DFA_time
;
3350 static ticker_t minimize_time
;
3351 static ticker_t equiv_time
;
3352 static ticker_t automaton_generation_time
;
3353 static ticker_t output_time
;
3355 /* The following variable values are times of
3358 all pipeline hazard translator work */
3359 static ticker_t check_time
;
3360 static ticker_t generation_time
;
3361 static ticker_t all_time
;
3365 /* Pseudo insn decl which denotes advancing cycle. */
3366 static decl_t advance_cycle_insn_decl
;
3368 add_advance_cycle_insn_decl ()
3370 advance_cycle_insn_decl
= create_node (sizeof (struct decl
));
3371 advance_cycle_insn_decl
->mode
= dm_insn_reserv
;
3372 advance_cycle_insn_decl
->pos
= no_pos
;
3373 DECL_INSN_RESERV (advance_cycle_insn_decl
)->regexp
= NULL
;
3374 DECL_INSN_RESERV (advance_cycle_insn_decl
)->name
= (char *) "$advance_cycle";
3375 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
3376 = description
->insns_num
;
3377 description
->decls
[description
->decls_num
] = advance_cycle_insn_decl
;
3378 description
->decls_num
++;
3379 description
->insns_num
++;
3384 /* Abstract data `alternative states' which reperesents
3385 nondeterministic nature of the description (see comments for
3386 structures alt_state and state). */
3388 /* List of free states. */
3389 static alt_state_t first_free_alt_state
;
3392 /* The following variables is maximal number of allocated nodes
3394 static int allocated_alt_states_num
= 0;
3397 /* The following function returns free node alt_state. It may be new
3398 allocated node or node freed eralier. */
3400 get_free_alt_state ()
3404 if (first_free_alt_state
!= NULL
)
3406 result
= first_free_alt_state
;
3407 first_free_alt_state
= first_free_alt_state
->next_alt_state
;
3412 allocated_alt_states_num
++;
3414 result
= create_node (sizeof (struct alt_state
));
3416 result
->state
= NULL
;
3417 result
->next_alt_state
= NULL
;
3418 result
->next_sorted_alt_state
= NULL
;
3422 /* The function frees node ALT_STATE. */
3424 free_alt_state (alt_state
)
3425 alt_state_t alt_state
;
3427 if (alt_state
== NULL
)
3429 alt_state
->next_alt_state
= first_free_alt_state
;
3430 first_free_alt_state
= alt_state
;
3433 /* The function frees list started with node ALT_STATE_LIST. */
3435 free_alt_states (alt_states_list
)
3436 alt_state_t alt_states_list
;
3438 alt_state_t curr_alt_state
;
3439 alt_state_t next_alt_state
;
3441 for (curr_alt_state
= alt_states_list
;
3442 curr_alt_state
!= NULL
;
3443 curr_alt_state
= next_alt_state
)
3445 next_alt_state
= curr_alt_state
->next_alt_state
;
3446 free_alt_state (curr_alt_state
);
3450 /* The function compares unique numbers of alt states. */
3452 alt_state_cmp (alt_state_ptr_1
, alt_state_ptr_2
)
3453 const void *alt_state_ptr_1
;
3454 const void *alt_state_ptr_2
;
3456 if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3457 == (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3459 else if ((*(alt_state_t
*) alt_state_ptr_1
)->state
->unique_num
3460 < (*(alt_state_t
*) alt_state_ptr_2
)->state
->unique_num
)
3466 /* The function sorts ALT_STATES_LIST and removes duplicated alt
3467 states from the list. The comparison key is alt state unique
3470 uniq_sort_alt_states (alt_states_list
)
3471 alt_state_t alt_states_list
;
3473 alt_state_t curr_alt_state
;
3474 vla_ptr_t alt_states
;
3476 size_t prev_unique_state_ind
;
3478 alt_state_t
*result_ptr
;
3480 VLA_PTR_CREATE (alt_states
, 150, "alt_states");
3481 for (curr_alt_state
= alt_states_list
;
3482 curr_alt_state
!= NULL
;
3483 curr_alt_state
= curr_alt_state
->next_alt_state
)
3484 VLA_PTR_ADD (alt_states
, curr_alt_state
);
3485 qsort (VLA_PTR_BEGIN (alt_states
), VLA_PTR_LENGTH (alt_states
),
3486 sizeof (alt_state_t
), alt_state_cmp
);
3487 if (VLA_PTR_LENGTH (alt_states
) == 0)
3491 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3492 prev_unique_state_ind
= 0;
3493 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3494 if (result_ptr
[prev_unique_state_ind
]->state
!= result_ptr
[i
]->state
)
3496 prev_unique_state_ind
++;
3497 result_ptr
[prev_unique_state_ind
] = result_ptr
[i
];
3500 for (i
= prev_unique_state_ind
+ 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3501 free_alt_state (result_ptr
[i
]);
3503 VLA_PTR_SHORTEN (alt_states
, i
- prev_unique_state_ind
- 1);
3504 result_ptr
= VLA_PTR_BEGIN (alt_states
);
3505 for (i
= 1; i
< VLA_PTR_LENGTH (alt_states
); i
++)
3506 result_ptr
[i
- 1]->next_sorted_alt_state
= result_ptr
[i
];
3507 result_ptr
[i
- 1]->next_sorted_alt_state
= NULL
;
3508 result
= *result_ptr
;
3510 VLA_PTR_DELETE (alt_states
);
3514 /* The function checks equality of alt state lists. Remember that the
3515 lists must be already sorted by the previous function. */
3517 alt_states_eq (alt_states_1
, alt_states_2
)
3518 alt_state_t alt_states_1
;
3519 alt_state_t alt_states_2
;
3521 while (alt_states_1
!= NULL
&& alt_states_2
!= NULL
3522 && alt_state_cmp (&alt_states_1
, &alt_states_2
) == 0)
3524 alt_states_1
= alt_states_1
->next_sorted_alt_state
;
3525 alt_states_2
= alt_states_2
->next_sorted_alt_state
;
3527 return alt_states_1
== alt_states_2
;
3530 /* Initialization of the abstract data. */
3532 initiate_alt_states ()
3534 first_free_alt_state
= NULL
;
3537 /* Finishing work with the abstract data. */
3539 finish_alt_states ()
3545 /* The page contains macros for work with bits strings. We could use
3546 standard gcc bitmap or sbitmap but it would result in difficulties
3547 of building canadian cross. */
3549 /* Set bit number bitno in the bit string. The macro is not side
3551 #define SET_BIT(bitstring, bitno) \
3552 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3554 /* Test if bit number bitno in the bitstring is set. The macro is not
3555 side effect proof. */
3556 #define TEST_BIT(bitstring, bitno) \
3557 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3561 /* This page contains abstract data `state'. */
3563 /* Maximal length of reservations in cycles (>= 1). */
3564 static int max_cycles_num
;
3566 /* Number of set elements (see type set_el_t) needed for
3567 representation of one cycle reservation. It is depended on units
3569 static int els_in_cycle_reserv
;
3571 /* Number of set elements (see type set_el_t) needed for
3572 representation of maximal length reservation. Deterministic
3573 reservation is stored as set (bit string) of length equal to the
3574 variable value * number of bits in set_el_t. */
3575 static int els_in_reservs
;
3577 /* VLA for representation of array of pointers to unit
3579 static vla_ptr_t units_container
;
3581 /* The start address of the array. */
3582 static unit_decl_t
*units_array
;
3584 /* Empty reservation of maximal length. */
3585 static reserv_sets_t empty_reserv
;
3587 /* The state table itself is represented by the following variable. */
3588 static htab_t state_table
;
3590 /* VLA for representation of array of pointers to free nodes
3592 static vla_ptr_t free_states
;
3594 static int curr_unique_state_num
;
3597 /* The following variables is maximal number of allocated nodes
3599 static int allocated_states_num
= 0;
3602 /* Allocate new reservation set. */
3603 static reserv_sets_t
3604 alloc_empty_reserv_sets ()
3606 reserv_sets_t result
;
3608 obstack_blank (&irp
, els_in_reservs
* sizeof (set_el_t
));
3609 result
= (reserv_sets_t
) obstack_base (&irp
);
3610 obstack_finish (&irp
);
3611 memset (result
, 0, els_in_reservs
* sizeof (set_el_t
));
3615 /* Hash value of reservation set. */
3617 reserv_sets_hash_value (reservs
)
3618 reserv_sets_t reservs
;
3620 set_el_t hash_value
;
3623 set_el_t
*reserv_ptr
;
3626 reservs_num
= els_in_reservs
;
3627 reserv_ptr
= reservs
;
3629 while (reservs_num
!= 0)
3632 hash_value
+= ((*reserv_ptr
>> i
)
3633 | (*reserv_ptr
<< (sizeof (set_el_t
) * CHAR_BIT
- i
)));
3635 if (i
== sizeof (set_el_t
) * CHAR_BIT
)
3639 if (sizeof (set_el_t
) <= sizeof (unsigned))
3642 for (i
= sizeof (set_el_t
); i
> 0; i
-= sizeof (unsigned) - 1)
3644 result
+= (unsigned) hash_value
;
3645 hash_value
>>= (sizeof (unsigned) - 1) * CHAR_BIT
;
3650 /* Comparison of given reservation sets. */
3652 reserv_sets_cmp (reservs_1
, reservs_2
)
3653 reserv_sets_t reservs_1
;
3654 reserv_sets_t reservs_2
;
3657 set_el_t
*reserv_ptr_1
;
3658 set_el_t
*reserv_ptr_2
;
3660 if (reservs_1
== NULL
|| reservs_2
== NULL
)
3662 reservs_num
= els_in_reservs
;
3663 reserv_ptr_1
= reservs_1
;
3664 reserv_ptr_2
= reservs_2
;
3665 while (reservs_num
!= 0 && *reserv_ptr_1
== *reserv_ptr_2
)
3671 if (reservs_num
== 0)
3673 else if (*reserv_ptr_1
< *reserv_ptr_2
)
3679 /* The function checks equality of the reservation sets. */
3681 reserv_sets_eq (reservs_1
, reservs_2
)
3682 reserv_sets_t reservs_1
;
3683 reserv_sets_t reservs_2
;
3685 return reserv_sets_cmp (reservs_1
, reservs_2
) == 0;
3688 /* Set up in the reservation set that unit with UNIT_NUM is used on
3691 set_unit_reserv (reservs
, cycle_num
, unit_num
)
3692 reserv_sets_t reservs
;
3696 if (cycle_num
>= max_cycles_num
)
3698 SET_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3699 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3702 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3703 used on CYCLE_NUM. */
3705 test_unit_reserv (reservs
, cycle_num
, unit_num
)
3706 reserv_sets_t reservs
;
3710 if (cycle_num
>= max_cycles_num
)
3712 return TEST_BIT (reservs
, cycle_num
* els_in_cycle_reserv
3713 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
);
3716 /* The function checks that the reservation set represents no one unit
3719 it_is_empty_reserv_sets (operand
)
3720 reserv_sets_t operand
;
3722 set_el_t
*reserv_ptr
;
3725 if (operand
== NULL
)
3727 for (reservs_num
= els_in_reservs
, reserv_ptr
= operand
;
3729 reserv_ptr
++, reservs_num
--)
3730 if (*reserv_ptr
!= 0)
3735 /* The function checks that the reservation sets are intersected,
3736 i.e. there is a unit reservation on a cycle in both reservation
3739 reserv_sets_are_intersected (operand_1
, operand_2
)
3740 reserv_sets_t operand_1
;
3741 reserv_sets_t operand_2
;
3745 set_el_t
*cycle_ptr_1
;
3746 set_el_t
*cycle_ptr_2
;
3749 if (operand_1
== NULL
|| operand_2
== NULL
)
3751 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
;
3752 el_ptr_1
< operand_1
+ els_in_reservs
;
3753 el_ptr_1
++, el_ptr_2
++)
3754 if (*el_ptr_1
& *el_ptr_2
)
3756 for (cycle_ptr_1
= operand_1
, cycle_ptr_2
= operand_2
;
3757 cycle_ptr_1
< operand_1
+ els_in_reservs
;
3758 cycle_ptr_1
+= els_in_cycle_reserv
, cycle_ptr_2
+= els_in_cycle_reserv
)
3760 for (el_ptr_1
= cycle_ptr_1
, el_ptr_2
= get_excl_set (cycle_ptr_2
);
3761 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3762 el_ptr_1
++, el_ptr_2
++)
3763 if (*el_ptr_1
& *el_ptr_2
)
3766 for (el_ptr_1
= cycle_ptr_1
,
3767 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 1);
3768 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3769 el_ptr_1
++, el_ptr_2
++)
3770 if (*el_ptr_1
& *el_ptr_2
)
3772 else if (*el_ptr_2
!= 0)
3774 if (nonzero_p
&& el_ptr_1
>= cycle_ptr_1
+ els_in_cycle_reserv
)
3776 for (el_ptr_1
= cycle_ptr_1
,
3777 el_ptr_2
= get_presence_absence_set (cycle_ptr_2
, 0);
3778 el_ptr_1
< cycle_ptr_1
+ els_in_cycle_reserv
;
3779 el_ptr_1
++, el_ptr_2
++)
3780 /* It looks like code for exclusion but exclusion set is
3781 made as symmetric relation preliminary. */
3782 if (*el_ptr_1
& *el_ptr_2
)
3788 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3789 cpu cycle. The remaining bits of OPERAND (representing the last
3790 cycle unit reservations) are not chenged. */
3792 reserv_sets_shift (result
, operand
)
3793 reserv_sets_t result
;
3794 reserv_sets_t operand
;
3798 if (result
== NULL
|| operand
== NULL
|| result
== operand
)
3800 for (i
= els_in_cycle_reserv
; i
< els_in_reservs
; i
++)
3801 result
[i
- els_in_cycle_reserv
] = operand
[i
];
3804 /* OR of the reservation sets. */
3806 reserv_sets_or (result
, operand_1
, operand_2
)
3807 reserv_sets_t result
;
3808 reserv_sets_t operand_1
;
3809 reserv_sets_t operand_2
;
3813 set_el_t
*result_set_el_ptr
;
3815 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3817 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3818 el_ptr_1
< operand_1
+ els_in_reservs
;
3819 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3820 *result_set_el_ptr
= *el_ptr_1
| *el_ptr_2
;
3823 /* AND of the reservation sets. */
3825 reserv_sets_and (result
, operand_1
, operand_2
)
3826 reserv_sets_t result
;
3827 reserv_sets_t operand_1
;
3828 reserv_sets_t operand_2
;
3832 set_el_t
*result_set_el_ptr
;
3834 if (result
== NULL
|| operand_1
== NULL
|| operand_2
== NULL
)
3836 for (el_ptr_1
= operand_1
, el_ptr_2
= operand_2
, result_set_el_ptr
= result
;
3837 el_ptr_1
< operand_1
+ els_in_reservs
;
3838 el_ptr_1
++, el_ptr_2
++, result_set_el_ptr
++)
3839 *result_set_el_ptr
= *el_ptr_1
& *el_ptr_2
;
3842 /* The function outputs string representation of units reservation on
3843 cycle START_CYCLE in the reservation set. The function uses repeat
3844 construction if REPETITION_NUM > 1. */
3846 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
)
3848 reserv_sets_t reservs
;
3853 int reserved_units_num
;
3855 reserved_units_num
= 0;
3856 for (unit_num
= 0; unit_num
< description
->units_num
; unit_num
++)
3857 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3858 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3859 reserved_units_num
++;
3860 if (repetition_num
<= 0)
3862 if (repetition_num
!= 1 && reserved_units_num
> 1)
3864 reserved_units_num
= 0;
3866 unit_num
< description
->units_num
;
3868 if (TEST_BIT (reservs
, start_cycle
* els_in_cycle_reserv
3869 * sizeof (set_el_t
) * CHAR_BIT
+ unit_num
))
3871 if (reserved_units_num
!= 0)
3873 reserved_units_num
++;
3874 fprintf (f
, "%s", units_array
[unit_num
]->name
);
3876 if (reserved_units_num
== 0)
3877 fprintf (f
, NOTHING_NAME
);
3878 if (repetition_num
<= 0)
3880 if (reserved_units_num
> 1)
3882 if (repetition_num
!= 1)
3883 fprintf (f
, "*%d", repetition_num
);
3886 /* The function outputs string representation of units reservation in
3887 the reservation set. */
3889 output_reserv_sets (f
, reservs
)
3891 reserv_sets_t reservs
;
3893 int start_cycle
= 0;
3898 for (cycle
= 0; cycle
< max_cycles_num
; cycle
++)
3899 if (repetition_num
== 0)
3902 start_cycle
= cycle
;
3905 ((char *) reservs
+ start_cycle
* els_in_cycle_reserv
3906 * sizeof (set_el_t
),
3907 (char *) reservs
+ cycle
* els_in_cycle_reserv
3908 * sizeof (set_el_t
),
3909 els_in_cycle_reserv
* sizeof (set_el_t
)) == 0)
3913 if (start_cycle
!= 0)
3915 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3917 start_cycle
= cycle
;
3919 if (start_cycle
< max_cycles_num
)
3921 if (start_cycle
!= 0)
3923 output_cycle_reservs (f
, reservs
, start_cycle
, repetition_num
);
3927 /* The following function returns free node state for AUTOMATON. It
3928 may be new allocated node or node freed eralier. The function also
3929 allocates reservation set if WITH_RESERVS has nonzero value. */
3931 get_free_state (with_reservs
, automaton
)
3933 automaton_t automaton
;
3937 if (max_cycles_num
<= 0 || automaton
== NULL
)
3939 if (VLA_PTR_LENGTH (free_states
) != 0)
3941 result
= VLA_PTR (free_states
, VLA_PTR_LENGTH (free_states
) - 1);
3942 VLA_PTR_SHORTEN (free_states
, 1);
3943 result
->automaton
= automaton
;
3944 result
->first_out_arc
= NULL
;
3945 result
->it_was_placed_in_stack_for_NDFA_forming
= 0;
3946 result
->it_was_placed_in_stack_for_DFA_forming
= 0;
3947 result
->component_states
= NULL
;
3948 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3953 allocated_states_num
++;
3955 result
= create_node (sizeof (struct state
));
3956 result
->automaton
= automaton
;
3957 result
->first_out_arc
= NULL
;
3958 result
->unique_num
= curr_unique_state_num
;
3959 result
->longest_path_length
= UNDEFINED_LONGEST_PATH_LENGTH
;
3960 curr_unique_state_num
++;
3964 if (result
->reservs
== NULL
)
3965 result
->reservs
= alloc_empty_reserv_sets ();
3967 memset (result
->reservs
, 0, els_in_reservs
* sizeof (set_el_t
));
3972 /* The function frees node STATE. */
3977 free_alt_states (state
->component_states
);
3978 VLA_PTR_ADD (free_states
, state
);
3981 /* Hash value of STATE. If STATE represents deterministic state it is
3982 simply hash value of the corresponding reservation set. Otherwise
3983 it is formed from hash values of the component deterministic
3984 states. One more key is order number of state automaton. */
3989 unsigned int hash_value
;
3990 alt_state_t alt_state
;
3992 if (((state_t
) state
)->component_states
== NULL
)
3993 hash_value
= reserv_sets_hash_value (((state_t
) state
)->reservs
);
3997 for (alt_state
= ((state_t
) state
)->component_states
;
3999 alt_state
= alt_state
->next_sorted_alt_state
)
4000 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4001 | (hash_value
<< CHAR_BIT
))
4002 + alt_state
->state
->unique_num
);
4004 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4005 | (hash_value
<< CHAR_BIT
))
4006 + ((state_t
) state
)->automaton
->automaton_order_num
);
4010 /* Return nonzero value if the states are the same. */
4012 state_eq_p (state_1
, state_2
)
4013 const void *state_1
;
4014 const void *state_2
;
4016 alt_state_t alt_state_1
;
4017 alt_state_t alt_state_2
;
4019 if (((state_t
) state_1
)->automaton
!= ((state_t
) state_2
)->automaton
)
4021 else if (((state_t
) state_1
)->component_states
== NULL
4022 && ((state_t
) state_2
)->component_states
== NULL
)
4023 return reserv_sets_eq (((state_t
) state_1
)->reservs
,
4024 ((state_t
) state_2
)->reservs
);
4025 else if (((state_t
) state_1
)->component_states
!= NULL
4026 && ((state_t
) state_2
)->component_states
!= NULL
)
4028 for (alt_state_1
= ((state_t
) state_1
)->component_states
,
4029 alt_state_2
= ((state_t
) state_2
)->component_states
;
4030 alt_state_1
!= NULL
&& alt_state_2
!= NULL
;
4031 alt_state_1
= alt_state_1
->next_sorted_alt_state
,
4032 alt_state_2
= alt_state_2
->next_sorted_alt_state
)
4033 /* All state in the list must be already in the hash table.
4034 Also the lists must be sorted. */
4035 if (alt_state_1
->state
!= alt_state_2
->state
)
4037 return alt_state_1
== alt_state_2
;
4043 /* Insert STATE into the state table. */
4045 insert_state (state
)
4050 entry_ptr
= htab_find_slot (state_table
, (void *) state
, 1);
4051 if (*entry_ptr
== NULL
)
4052 *entry_ptr
= (void *) state
;
4053 return (state_t
) *entry_ptr
;
4056 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4057 deterministic STATE. */
4059 set_state_reserv (state
, cycle_num
, unit_num
)
4064 set_unit_reserv (state
->reservs
, cycle_num
, unit_num
);
4067 /* Return nonzero value if the deterministic states contains a
4068 reservation of the same cpu unit on the same cpu cycle. */
4070 intersected_state_reservs_p (state1
, state2
)
4074 if (state1
->automaton
!= state2
->automaton
)
4076 return reserv_sets_are_intersected (state1
->reservs
, state2
->reservs
);
4079 /* Return deterministic state (inserted into the table) which
4080 representing the automaton state whic is union of reservations of
4081 deterministic states. */
4083 states_union (state1
, state2
)
4088 state_t state_in_table
;
4090 if (state1
->automaton
!= state2
->automaton
)
4092 result
= get_free_state (1, state1
->automaton
);
4093 reserv_sets_or (result
->reservs
, state1
->reservs
, state2
->reservs
);
4094 state_in_table
= insert_state (result
);
4095 if (result
!= state_in_table
)
4097 free_state (result
);
4098 result
= state_in_table
;
4103 /* Return deterministic state (inserted into the table) which
4104 represent the automaton state is obtained from deterministic STATE
4105 by advancing cpu cycle. */
4111 state_t state_in_table
;
4113 result
= get_free_state (1, state
->automaton
);
4114 reserv_sets_shift (result
->reservs
, state
->reservs
);
4115 state_in_table
= insert_state (result
);
4116 if (result
!= state_in_table
)
4118 free_state (result
);
4119 result
= state_in_table
;
4124 /* Initialization of the abstract data. */
4131 VLA_PTR_CREATE (units_container
, description
->units_num
, "units_container");
4133 = (description
->decls_num
&& description
->units_num
4134 ? VLA_PTR_BEGIN (units_container
) : NULL
);
4135 for (i
= 0; i
< description
->decls_num
; i
++)
4137 decl
= description
->decls
[i
];
4138 if (decl
->mode
== dm_unit
)
4139 units_array
[DECL_UNIT (decl
)->unit_num
] = DECL_UNIT (decl
);
4141 max_cycles_num
= description
->max_insn_reserv_cycles
;
4143 = ((description
->units_num
+ sizeof (set_el_t
) * CHAR_BIT
- 1)
4144 / (sizeof (set_el_t
) * CHAR_BIT
));
4145 els_in_reservs
= els_in_cycle_reserv
* max_cycles_num
;
4146 curr_unique_state_num
= 0;
4147 initiate_alt_states ();
4148 VLA_PTR_CREATE (free_states
, 1500, "free states");
4149 state_table
= htab_create (1500, state_hash
, state_eq_p
, (htab_del
) 0);
4150 empty_reserv
= alloc_empty_reserv_sets ();
4153 /* Finisging work with the abstract data. */
4157 VLA_PTR_DELETE (units_container
);
4158 htab_delete (state_table
);
4159 VLA_PTR_DELETE (free_states
);
4160 finish_alt_states ();
4165 /* Abstract data `arcs'. */
4167 /* List of free arcs. */
4168 static arc_t first_free_arc
;
4171 /* The following variables is maximal number of allocated nodes
4173 static int allocated_arcs_num
= 0;
4176 /* The function frees node ARC. */
4181 arc
->next_out_arc
= first_free_arc
;
4182 first_free_arc
= arc
;
4185 /* The function removes and frees ARC staring from FROM_STATE. */
4187 remove_arc (from_state
, arc
)
4196 for (prev_arc
= NULL
, curr_arc
= from_state
->first_out_arc
;
4198 prev_arc
= curr_arc
, curr_arc
= curr_arc
->next_out_arc
)
4199 if (curr_arc
== arc
)
4201 if (curr_arc
== NULL
)
4203 if (prev_arc
== NULL
)
4204 from_state
->first_out_arc
= arc
->next_out_arc
;
4206 prev_arc
->next_out_arc
= arc
->next_out_arc
;
4210 /* The functions returns arc with given characteristics (or NULL if
4211 the arc does not exist). */
4213 find_arc (from_state
, to_state
, insn
)
4220 for (arc
= first_out_arc (from_state
); arc
!= NULL
; arc
= next_out_arc (arc
))
4221 if (arc
->to_state
== to_state
&& arc
->insn
== insn
)
4226 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4227 and with given STATE_ALTS. The function returns added arc (or
4228 already existing arc). */
4230 add_arc (from_state
, to_state
, ainsn
, state_alts
)
4238 new_arc
= find_arc (from_state
, to_state
, ainsn
);
4239 if (new_arc
!= NULL
)
4241 if (first_free_arc
== NULL
)
4244 allocated_arcs_num
++;
4246 new_arc
= create_node (sizeof (struct arc
));
4247 new_arc
->to_state
= NULL
;
4248 new_arc
->insn
= NULL
;
4249 new_arc
->next_out_arc
= NULL
;
4253 new_arc
= first_free_arc
;
4254 first_free_arc
= first_free_arc
->next_out_arc
;
4256 new_arc
->to_state
= to_state
;
4257 new_arc
->insn
= ainsn
;
4258 ainsn
->arc_exists_p
= 1;
4259 new_arc
->next_out_arc
= from_state
->first_out_arc
;
4260 from_state
->first_out_arc
= new_arc
;
4261 new_arc
->next_arc_marked_by_insn
= NULL
;
4262 new_arc
->state_alts
= state_alts
;
4266 /* The function returns the first arc starting from STATE. */
4268 first_out_arc (state
)
4271 return state
->first_out_arc
;
4274 /* The function returns next out arc after ARC. */
4279 return arc
->next_out_arc
;
4282 /* Initialization of the abstract data. */
4286 first_free_arc
= NULL
;
4289 /* Finishing work with the abstract data. */
4297 /* Abstract data `automata lists'. */
4299 /* List of free states. */
4300 static automata_list_el_t first_free_automata_list_el
;
4302 /* The list being formed. */
4303 static automata_list_el_t current_automata_list
;
4305 /* Hash table of automata lists. */
4306 static htab_t automata_list_table
;
4308 /* The following function returns free automata list el. It may be
4309 new allocated node or node freed earlier. */
4310 static automata_list_el_t
4311 get_free_automata_list_el ()
4313 automata_list_el_t result
;
4315 if (first_free_automata_list_el
!= NULL
)
4317 result
= first_free_automata_list_el
;
4318 first_free_automata_list_el
4319 = first_free_automata_list_el
->next_automata_list_el
;
4322 result
= create_node (sizeof (struct automata_list_el
));
4323 result
->automaton
= NULL
;
4324 result
->next_automata_list_el
= NULL
;
4328 /* The function frees node AUTOMATA_LIST_EL. */
4330 free_automata_list_el (automata_list_el
)
4331 automata_list_el_t automata_list_el
;
4333 if (automata_list_el
== NULL
)
4335 automata_list_el
->next_automata_list_el
= first_free_automata_list_el
;
4336 first_free_automata_list_el
= automata_list_el
;
4339 /* The function frees list AUTOMATA_LIST. */
4341 free_automata_list (automata_list
)
4342 automata_list_el_t automata_list
;
4344 automata_list_el_t curr_automata_list_el
;
4345 automata_list_el_t next_automata_list_el
;
4347 for (curr_automata_list_el
= automata_list
;
4348 curr_automata_list_el
!= NULL
;
4349 curr_automata_list_el
= next_automata_list_el
)
4351 next_automata_list_el
= curr_automata_list_el
->next_automata_list_el
;
4352 free_automata_list_el (curr_automata_list_el
);
4356 /* Hash value of AUTOMATA_LIST. */
4358 automata_list_hash (automata_list
)
4359 const void *automata_list
;
4361 unsigned int hash_value
;
4362 automata_list_el_t curr_automata_list_el
;
4365 for (curr_automata_list_el
= (automata_list_el_t
) automata_list
;
4366 curr_automata_list_el
!= NULL
;
4367 curr_automata_list_el
= curr_automata_list_el
->next_automata_list_el
)
4368 hash_value
= (((hash_value
>> (sizeof (unsigned) - 1) * CHAR_BIT
)
4369 | (hash_value
<< CHAR_BIT
))
4370 + curr_automata_list_el
->automaton
->automaton_order_num
);
4374 /* Return nonzero value if the automata_lists are the same. */
4376 automata_list_eq_p (automata_list_1
, automata_list_2
)
4377 const void *automata_list_1
;
4378 const void *automata_list_2
;
4380 automata_list_el_t automata_list_el_1
;
4381 automata_list_el_t automata_list_el_2
;
4383 for (automata_list_el_1
= (automata_list_el_t
) automata_list_1
,
4384 automata_list_el_2
= (automata_list_el_t
) automata_list_2
;
4385 automata_list_el_1
!= NULL
&& automata_list_el_2
!= NULL
;
4386 automata_list_el_1
= automata_list_el_1
->next_automata_list_el
,
4387 automata_list_el_2
= automata_list_el_2
->next_automata_list_el
)
4388 if (automata_list_el_1
->automaton
!= automata_list_el_2
->automaton
)
4390 return automata_list_el_1
== automata_list_el_2
;
4393 /* Initialization of the abstract data. */
4395 initiate_automata_lists ()
4397 first_free_automata_list_el
= NULL
;
4398 automata_list_table
= htab_create (1500, automata_list_hash
,
4399 automata_list_eq_p
, (htab_del
) 0);
4402 /* The following function starts new automata list and makes it the
4405 automata_list_start ()
4407 current_automata_list
= NULL
;
4410 /* The following function adds AUTOMATON to the current list. */
4412 automata_list_add (automaton
)
4413 automaton_t automaton
;
4415 automata_list_el_t el
;
4417 el
= get_free_automata_list_el ();
4418 el
->automaton
= automaton
;
4419 el
->next_automata_list_el
= current_automata_list
;
4420 current_automata_list
= el
;
4423 /* The following function finishes forming the current list, inserts
4424 it into the table and returns it. */
4425 static automata_list_el_t
4426 automata_list_finish ()
4430 if (current_automata_list
== NULL
)
4432 entry_ptr
= htab_find_slot (automata_list_table
,
4433 (void *) current_automata_list
, 1);
4434 if (*entry_ptr
== NULL
)
4435 *entry_ptr
= (void *) current_automata_list
;
4437 free_automata_list (current_automata_list
);
4438 current_automata_list
= NULL
;
4439 return (automata_list_el_t
) *entry_ptr
;
4442 /* Finishing work with the abstract data. */
4444 finish_automata_lists ()
4446 htab_delete (automata_list_table
);
4451 /* The page contains abstract data for work with exclusion sets (see
4452 exclusion_set in file rtl.def). */
4454 /* The following variable refers to an exclusion set returned by
4455 get_excl_set. This is bit string of length equal to cpu units
4456 number. If exclusion set for given unit contains 1 for a unit,
4457 then simultaneous reservation of the units is prohibited. */
4458 static reserv_sets_t excl_set
;
4460 /* The array contains exclusion sets for each unit. */
4461 static reserv_sets_t
*unit_excl_set_table
;
4463 /* The following function forms the array containing exclusion sets
4466 initiate_excl_sets ()
4469 reserv_sets_t unit_excl_set
;
4473 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4474 excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4475 obstack_finish (&irp
);
4476 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4477 unit_excl_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4478 obstack_finish (&irp
);
4479 /* Evaluate unit exclusion sets. */
4480 for (i
= 0; i
< description
->decls_num
; i
++)
4482 decl
= description
->decls
[i
];
4483 if (decl
->mode
== dm_unit
)
4485 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4486 unit_excl_set
= (reserv_sets_t
) obstack_base (&irp
);
4487 obstack_finish (&irp
);
4488 memset (unit_excl_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4489 for (el
= DECL_UNIT (decl
)->excl_list
;
4491 el
= el
->next_unit_set_el
)
4492 SET_BIT (unit_excl_set
, el
->unit_decl
->unit_num
);
4493 unit_excl_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_excl_set
;
4498 /* The function sets up and return EXCL_SET which is union of
4499 exclusion sets for each unit in IN_SET. */
4500 static reserv_sets_t
4501 get_excl_set (in_set
)
4502 reserv_sets_t in_set
;
4510 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4511 memset (excl_set
, 0, chars_num
);
4512 for (excl_char_num
= 0; excl_char_num
< chars_num
; excl_char_num
++)
4513 if (((unsigned char *) in_set
) [excl_char_num
])
4514 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4515 if ((((unsigned char *) in_set
) [excl_char_num
] >> i
) & 1)
4517 start_unit_num
= excl_char_num
* CHAR_BIT
+ i
;
4518 if (start_unit_num
>= description
->units_num
)
4520 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4523 |= unit_excl_set_table
[start_unit_num
] [unit_num
];
4531 /* The page contains abstract data for work with presence/absence sets
4532 (see presence_set/absence_set in file rtl.def). */
4534 /* The following variables refer to correspondingly an presence and an
4535 absence set returned by get_presence_absence_set. This is bit
4536 string of length equal to cpu units number. */
4537 static reserv_sets_t presence_set
, absence_set
;
4539 /* The following arrays contain correspondingly presence and absence
4540 sets for each unit. */
4541 static reserv_sets_t
*unit_presence_set_table
, *unit_absence_set_table
;
4543 /* The following function forms the array containing presence and
4544 absence sets for each unit */
4546 initiate_presence_absence_sets ()
4549 reserv_sets_t unit_set
;
4553 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4554 presence_set
= (reserv_sets_t
) obstack_base (&irp
);
4555 obstack_finish (&irp
);
4556 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4557 unit_presence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4558 obstack_finish (&irp
);
4559 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4560 absence_set
= (reserv_sets_t
) obstack_base (&irp
);
4561 obstack_finish (&irp
);
4562 obstack_blank (&irp
, description
->units_num
* sizeof (reserv_sets_t
));
4563 unit_absence_set_table
= (reserv_sets_t
*) obstack_base (&irp
);
4564 obstack_finish (&irp
);
4565 /* Evaluate unit presence/absence sets. */
4566 for (i
= 0; i
< description
->decls_num
; i
++)
4568 decl
= description
->decls
[i
];
4569 if (decl
->mode
== dm_unit
)
4571 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4572 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4573 obstack_finish (&irp
);
4574 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4575 for (el
= DECL_UNIT (decl
)->presence_list
;
4577 el
= el
->next_unit_set_el
)
4578 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4579 unit_presence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4581 obstack_blank (&irp
, els_in_cycle_reserv
* sizeof (set_el_t
));
4582 unit_set
= (reserv_sets_t
) obstack_base (&irp
);
4583 obstack_finish (&irp
);
4584 memset (unit_set
, 0, els_in_cycle_reserv
* sizeof (set_el_t
));
4585 for (el
= DECL_UNIT (decl
)->absence_list
;
4587 el
= el
->next_unit_set_el
)
4588 SET_BIT (unit_set
, el
->unit_decl
->unit_num
);
4589 unit_absence_set_table
[DECL_UNIT (decl
)->unit_num
] = unit_set
;
4594 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4595 ABSENCE_SET which is union of corresponding sets for each unit in
4597 static reserv_sets_t
4598 get_presence_absence_set (in_set
, presence_p
)
4599 reserv_sets_t in_set
;
4608 chars_num
= els_in_cycle_reserv
* sizeof (set_el_t
);
4610 memset (presence_set
, 0, chars_num
);
4612 memset (absence_set
, 0, chars_num
);
4613 for (char_num
= 0; char_num
< chars_num
; char_num
++)
4614 if (((unsigned char *) in_set
) [char_num
])
4615 for (i
= CHAR_BIT
- 1; i
>= 0; i
--)
4616 if ((((unsigned char *) in_set
) [char_num
] >> i
) & 1)
4618 start_unit_num
= char_num
* CHAR_BIT
+ i
;
4619 if (start_unit_num
>= description
->units_num
)
4620 return (presence_p
? presence_set
: absence_set
);
4621 for (unit_num
= 0; unit_num
< els_in_cycle_reserv
; unit_num
++)
4623 presence_set
[unit_num
]
4624 |= unit_presence_set_table
[start_unit_num
] [unit_num
];
4626 absence_set
[unit_num
]
4627 |= unit_absence_set_table
[start_unit_num
] [unit_num
];
4629 return (presence_p
? presence_set
: absence_set
);
4634 /* This page contains code for transformation of original reservations
4635 described in .md file. The main goal of transformations is
4636 simplifying reservation and lifting up all `|' on the top of IR
4637 reservation representation. */
4640 /* The following function makes copy of IR representation of
4641 reservation. The function also substitutes all reservations
4642 defined by define_reservation by corresponding value during making
4645 copy_insn_regexp (regexp
)
4651 if (regexp
->mode
== rm_reserv
)
4652 result
= copy_insn_regexp (REGEXP_RESERV (regexp
)->reserv_decl
->regexp
);
4653 else if (regexp
->mode
== rm_unit
)
4654 result
= copy_node (regexp
, sizeof (struct regexp
));
4655 else if (regexp
->mode
== rm_repeat
)
4657 result
= copy_node (regexp
, sizeof (struct regexp
));
4658 REGEXP_REPEAT (result
)->regexp
4659 = copy_insn_regexp (REGEXP_REPEAT (regexp
)->regexp
);
4661 else if (regexp
->mode
== rm_sequence
)
4663 result
= copy_node (regexp
,
4664 sizeof (struct regexp
) + sizeof (regexp_t
)
4665 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4666 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4667 REGEXP_SEQUENCE (result
)->regexps
[i
]
4668 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4670 else if (regexp
->mode
== rm_allof
)
4672 result
= copy_node (regexp
,
4673 sizeof (struct regexp
) + sizeof (regexp_t
)
4674 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4675 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4676 REGEXP_ALLOF (result
)->regexps
[i
]
4677 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4679 else if (regexp
->mode
== rm_oneof
)
4681 result
= copy_node (regexp
,
4682 sizeof (struct regexp
) + sizeof (regexp_t
)
4683 * (REGEXP_ONEOF (regexp
)->regexps_num
- 1));
4684 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4685 REGEXP_ONEOF (result
)->regexps
[i
]
4686 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4690 if (regexp
->mode
!= rm_nothing
)
4692 result
= copy_node (regexp
, sizeof (struct regexp
));
4697 /* The following variable is set up 1 if a transformation has been
4699 static int regexp_transformed_p
;
4701 /* The function makes transformation
4704 transform_1 (regexp
)
4712 if (regexp
->mode
== rm_repeat
)
4714 repeat_num
= REGEXP_REPEAT (regexp
)->repeat_num
;
4715 if (repeat_num
<= 1)
4717 operand
= REGEXP_REPEAT (regexp
)->regexp
;
4719 regexp
= create_node (sizeof (struct regexp
) + sizeof (regexp_t
)
4720 * (repeat_num
- 1));
4721 regexp
->mode
= rm_sequence
;
4723 REGEXP_SEQUENCE (regexp
)->regexps_num
= repeat_num
;
4724 for (i
= 0; i
< repeat_num
; i
++)
4725 REGEXP_SEQUENCE (regexp
)->regexps
[i
] = copy_insn_regexp (operand
);
4726 regexp_transformed_p
= 1;
4731 /* The function makes transformations
4732 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4733 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4734 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4736 transform_2 (regexp
)
4739 if (regexp
->mode
== rm_sequence
)
4741 regexp_t sequence
= NULL
;
4743 int sequence_index
= 0;
4746 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4747 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4750 sequence
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4753 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4755 if ( REGEXP_SEQUENCE (sequence
)->regexps_num
<= 1
4756 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4758 result
= create_node (sizeof (struct regexp
)
4760 * (REGEXP_SEQUENCE (regexp
)->regexps_num
4761 + REGEXP_SEQUENCE (sequence
)->regexps_num
4763 result
->mode
= rm_sequence
;
4764 result
->pos
= regexp
->pos
;
4765 REGEXP_SEQUENCE (result
)->regexps_num
4766 = (REGEXP_SEQUENCE (regexp
)->regexps_num
4767 + REGEXP_SEQUENCE (sequence
)->regexps_num
- 1);
4768 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4769 if (i
< sequence_index
)
4770 REGEXP_SEQUENCE (result
)->regexps
[i
]
4771 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4772 else if (i
> sequence_index
)
4773 REGEXP_SEQUENCE (result
)->regexps
4774 [i
+ REGEXP_SEQUENCE (sequence
)->regexps_num
- 1]
4775 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
4777 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4778 REGEXP_SEQUENCE (result
)->regexps
[i
+ j
]
4779 = copy_insn_regexp (REGEXP_SEQUENCE (sequence
)->regexps
[j
]);
4780 regexp_transformed_p
= 1;
4784 else if (regexp
->mode
== rm_allof
)
4786 regexp_t allof
= NULL
;
4788 int allof_index
= 0;
4791 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4792 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_allof
)
4795 allof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4798 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4800 if (REGEXP_ALLOF (allof
)->regexps_num
<= 1
4801 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4803 result
= create_node (sizeof (struct regexp
)
4805 * (REGEXP_ALLOF (regexp
)->regexps_num
4806 + REGEXP_ALLOF (allof
)->regexps_num
- 2));
4807 result
->mode
= rm_allof
;
4808 result
->pos
= regexp
->pos
;
4809 REGEXP_ALLOF (result
)->regexps_num
4810 = (REGEXP_ALLOF (regexp
)->regexps_num
4811 + REGEXP_ALLOF (allof
)->regexps_num
- 1);
4812 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4813 if (i
< allof_index
)
4814 REGEXP_ALLOF (result
)->regexps
[i
]
4815 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4816 else if (i
> allof_index
)
4817 REGEXP_ALLOF (result
)->regexps
4818 [i
+ REGEXP_ALLOF (allof
)->regexps_num
- 1]
4819 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
4821 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4822 REGEXP_ALLOF (result
)->regexps
[i
+ j
]
4823 = copy_insn_regexp (REGEXP_ALLOF (allof
)->regexps
[j
]);
4824 regexp_transformed_p
= 1;
4828 else if (regexp
->mode
== rm_oneof
)
4830 regexp_t oneof
= NULL
;
4832 int oneof_index
= 0;
4835 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4836 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4839 oneof
= REGEXP_ONEOF (regexp
)->regexps
[i
];
4842 if (i
< REGEXP_ONEOF (regexp
)->regexps_num
)
4844 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4845 || REGEXP_ONEOF (regexp
)->regexps_num
<= 1)
4847 result
= create_node (sizeof (struct regexp
)
4849 * (REGEXP_ONEOF (regexp
)->regexps_num
4850 + REGEXP_ONEOF (oneof
)->regexps_num
- 2));
4851 result
->mode
= rm_oneof
;
4852 result
->pos
= regexp
->pos
;
4853 REGEXP_ONEOF (result
)->regexps_num
4854 = (REGEXP_ONEOF (regexp
)->regexps_num
4855 + REGEXP_ONEOF (oneof
)->regexps_num
- 1);
4856 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
4857 if (i
< oneof_index
)
4858 REGEXP_ONEOF (result
)->regexps
[i
]
4859 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4860 else if (i
> oneof_index
)
4861 REGEXP_ONEOF (result
)->regexps
4862 [i
+ REGEXP_ONEOF (oneof
)->regexps_num
- 1]
4863 = copy_insn_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
4865 for (j
= 0; j
< REGEXP_ONEOF (oneof
)->regexps_num
; j
++)
4866 REGEXP_ONEOF (result
)->regexps
[i
+ j
]
4867 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[j
]);
4868 regexp_transformed_p
= 1;
4875 /* The function makes transformations
4876 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4877 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4878 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4879 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
4881 transform_3 (regexp
)
4884 if (regexp
->mode
== rm_sequence
)
4886 regexp_t oneof
= NULL
;
4887 int oneof_index
= 0;
4892 for (i
= 0; i
<REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
4893 if (REGEXP_SEQUENCE (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4896 oneof
= REGEXP_SEQUENCE (regexp
)->regexps
[i
];
4899 if (i
< REGEXP_SEQUENCE (regexp
)->regexps_num
)
4901 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4902 || REGEXP_SEQUENCE (regexp
)->regexps_num
<= 1)
4904 result
= create_node (sizeof (struct regexp
)
4906 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4907 result
->mode
= rm_oneof
;
4908 result
->pos
= regexp
->pos
;
4909 REGEXP_ONEOF (result
)->regexps_num
4910 = REGEXP_ONEOF (oneof
)->regexps_num
;
4911 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4914 = create_node (sizeof (struct regexp
)
4916 * (REGEXP_SEQUENCE (regexp
)->regexps_num
- 1));
4917 sequence
->mode
= rm_sequence
;
4918 sequence
->pos
= regexp
->pos
;
4919 REGEXP_SEQUENCE (sequence
)->regexps_num
4920 = REGEXP_SEQUENCE (regexp
)->regexps_num
;
4921 REGEXP_ONEOF (result
)->regexps
[i
] = sequence
;
4922 for (j
= 0; j
< REGEXP_SEQUENCE (sequence
)->regexps_num
; j
++)
4923 if (j
!= oneof_index
)
4924 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4925 = copy_insn_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[j
]);
4927 REGEXP_SEQUENCE (sequence
)->regexps
[j
]
4928 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4930 regexp_transformed_p
= 1;
4934 else if (regexp
->mode
== rm_allof
)
4936 regexp_t oneof
= NULL
, seq
;
4937 int oneof_index
= 0, max_seq_length
, allof_length
;
4939 regexp_t allof
= NULL
, allof_op
= NULL
;
4942 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4943 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
4946 oneof
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4949 if (i
< REGEXP_ALLOF (regexp
)->regexps_num
)
4951 if (REGEXP_ONEOF (oneof
)->regexps_num
<= 1
4952 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
4954 result
= create_node (sizeof (struct regexp
)
4956 * (REGEXP_ONEOF (oneof
)->regexps_num
- 1));
4957 result
->mode
= rm_oneof
;
4958 result
->pos
= regexp
->pos
;
4959 REGEXP_ONEOF (result
)->regexps_num
4960 = REGEXP_ONEOF (oneof
)->regexps_num
;
4961 for (i
= 0; i
< REGEXP_ONEOF (result
)->regexps_num
; i
++)
4964 = create_node (sizeof (struct regexp
)
4966 * (REGEXP_ALLOF (regexp
)->regexps_num
- 1));
4967 allof
->mode
= rm_allof
;
4968 allof
->pos
= regexp
->pos
;
4969 REGEXP_ALLOF (allof
)->regexps_num
4970 = REGEXP_ALLOF (regexp
)->regexps_num
;
4971 REGEXP_ONEOF (result
)->regexps
[i
] = allof
;
4972 for (j
= 0; j
< REGEXP_ALLOF (allof
)->regexps_num
; j
++)
4973 if (j
!= oneof_index
)
4974 REGEXP_ALLOF (allof
)->regexps
[j
]
4975 = copy_insn_regexp (REGEXP_ALLOF (regexp
)->regexps
[j
]);
4977 REGEXP_ALLOF (allof
)->regexps
[j
]
4978 = copy_insn_regexp (REGEXP_ONEOF (oneof
)->regexps
[i
]);
4980 regexp_transformed_p
= 1;
4984 if (regexp
->mode
== rm_allof
)
4985 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
4987 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
4989 seq
= REGEXP_ALLOF (regexp
)->regexps
[i
];
4990 if (max_seq_length
< REGEXP_SEQUENCE (seq
)->regexps_num
)
4991 max_seq_length
= REGEXP_SEQUENCE (seq
)->regexps_num
;
4993 else if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
!= rm_unit
)
4999 if (max_seq_length
!= 0)
5001 if (max_seq_length
== 1 || REGEXP_ALLOF (regexp
)->regexps_num
<= 1)
5003 result
= create_node (sizeof (struct regexp
)
5004 + sizeof (regexp_t
) * (max_seq_length
- 1));
5005 result
->mode
= rm_sequence
;
5006 result
->pos
= regexp
->pos
;
5007 REGEXP_SEQUENCE (result
)->regexps_num
= max_seq_length
;
5008 for (i
= 0; i
< max_seq_length
; i
++)
5011 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5012 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5013 && (i
< (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5014 ->regexps
[j
])->regexps_num
)))
5017 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)->regexps
[j
])
5022 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5025 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5028 if (allof_length
== 1)
5029 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof_op
;
5032 allof
= create_node (sizeof (struct regexp
)
5034 * (allof_length
- 1));
5035 allof
->mode
= rm_allof
;
5036 allof
->pos
= regexp
->pos
;
5037 REGEXP_ALLOF (allof
)->regexps_num
= allof_length
;
5038 REGEXP_SEQUENCE (result
)->regexps
[i
] = allof
;
5040 for (j
= 0; j
< REGEXP_ALLOF (regexp
)->regexps_num
; j
++)
5041 if (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
== rm_sequence
5043 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5044 ->regexps
[j
])->regexps_num
)))
5046 allof_op
= (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp
)
5049 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5054 && (REGEXP_ALLOF (regexp
)->regexps
[j
]->mode
5057 allof_op
= REGEXP_ALLOF (regexp
)->regexps
[j
];
5058 REGEXP_ALLOF (allof
)->regexps
[allof_length
]
5064 regexp_transformed_p
= 1;
5071 /* The function traverses IR of reservation and applies transformations
5072 implemented by FUNC. */
5074 regexp_transform_func (regexp
, func
)
5076 regexp_t (*func
) PARAMS ((regexp_t regexp
));
5080 if (regexp
->mode
== rm_sequence
)
5081 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5082 REGEXP_SEQUENCE (regexp
)->regexps
[i
]
5083 = regexp_transform_func (REGEXP_SEQUENCE (regexp
)->regexps
[i
], func
);
5084 else if (regexp
->mode
== rm_allof
)
5085 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5086 REGEXP_ALLOF (regexp
)->regexps
[i
]
5087 = regexp_transform_func (REGEXP_ALLOF (regexp
)->regexps
[i
], func
);
5088 else if (regexp
->mode
== rm_oneof
)
5089 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
5090 REGEXP_ONEOF (regexp
)->regexps
[i
]
5091 = regexp_transform_func (REGEXP_ONEOF (regexp
)->regexps
[i
], func
);
5092 else if (regexp
->mode
== rm_repeat
)
5093 REGEXP_REPEAT (regexp
)->regexp
5094 = regexp_transform_func (REGEXP_REPEAT (regexp
)->regexp
, func
);
5095 else if (regexp
->mode
!= rm_nothing
&& regexp
->mode
!= rm_unit
)
5097 return (*func
) (regexp
);
5100 /* The function applies all transformations for IR representation of
5101 reservation REGEXP. */
5103 transform_regexp (regexp
)
5106 regexp
= regexp_transform_func (regexp
, transform_1
);
5109 regexp_transformed_p
= 0;
5110 regexp
= regexp_transform_func (regexp
, transform_2
);
5111 regexp
= regexp_transform_func (regexp
, transform_3
);
5113 while (regexp_transformed_p
);
5117 /* The function applys all transformations for reservations of all
5118 insn declarations. */
5120 transform_insn_regexps ()
5125 transform_time
= create_ticker ();
5126 add_advance_cycle_insn_decl ();
5127 fprintf (stderr
, "Reservation transformation...");
5129 for (i
= 0; i
< description
->decls_num
; i
++)
5131 decl
= description
->decls
[i
];
5132 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
5133 DECL_INSN_RESERV (decl
)->transformed_regexp
5134 = transform_regexp (copy_insn_regexp
5135 (DECL_INSN_RESERV (decl
)->regexp
));
5137 fprintf (stderr
, "done\n");
5138 ticker_off (&transform_time
);
5144 /* The following variable is an array indexed by cycle. Each element
5145 contains cyclic list of units which should be in the same cycle. */
5146 static unit_decl_t
*the_same_automaton_lists
;
5148 /* The function processes all alternative reservations on CYCLE in
5149 given REGEXP to check the UNIT is not reserved on the all
5150 alternatives. If it is true, the unit should be in the same
5151 automaton with other analogous units reserved on CYCLE in given
5154 process_unit_to_form_the_same_automaton_unit_lists (unit
, regexp
, cycle
)
5160 regexp_t seq
, allof
;
5161 unit_decl_t unit_decl
, last
;
5163 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5165 unit_decl
= REGEXP_UNIT (unit
)->unit_decl
;
5166 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5168 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5169 if (seq
->mode
== rm_sequence
)
5171 if (cycle
>= REGEXP_SEQUENCE (seq
)->regexps_num
)
5173 allof
= REGEXP_SEQUENCE (seq
)->regexps
[cycle
];
5174 if (allof
->mode
== rm_allof
)
5176 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5177 if (REGEXP_ALLOF (allof
)->regexps
[k
]->mode
== rm_unit
5178 && (REGEXP_UNIT (REGEXP_ALLOF (allof
)->regexps
[k
])
5179 ->unit_decl
== unit_decl
))
5181 if (k
>= REGEXP_ALLOF (allof
)->regexps_num
)
5184 else if (allof
->mode
== rm_unit
5185 && REGEXP_UNIT (allof
)->unit_decl
!= unit_decl
)
5188 else if (cycle
!= 0)
5190 else if (seq
->mode
== rm_allof
)
5192 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5193 if (REGEXP_ALLOF (seq
)->regexps
[k
]->mode
== rm_unit
5194 && (REGEXP_UNIT (REGEXP_ALLOF (seq
)->regexps
[k
])->unit_decl
5197 if (k
>= REGEXP_ALLOF (seq
)->regexps_num
)
5200 else if (seq
->mode
== rm_unit
5201 && REGEXP_UNIT (seq
)->unit_decl
!= unit_decl
)
5206 if (the_same_automaton_lists
[cycle
] == NULL
)
5207 the_same_automaton_lists
[cycle
] = unit_decl
;
5210 for (last
= the_same_automaton_lists
[cycle
];;)
5212 if (last
== unit_decl
)
5214 if (last
->the_same_automaton_unit
5215 == the_same_automaton_lists
[cycle
])
5217 last
= last
->the_same_automaton_unit
;
5219 last
->the_same_automaton_unit
= unit_decl
->the_same_automaton_unit
;
5220 unit_decl
->the_same_automaton_unit
5221 = the_same_automaton_lists
[cycle
];
5226 /* The function processes given REGEXP to find units which should be
5227 in the same automaton. */
5229 form_the_same_automaton_unit_lists_from_regexp (regexp
)
5233 regexp_t seq
, allof
, unit
;
5235 if (regexp
== NULL
|| regexp
->mode
!= rm_oneof
)
5237 for (i
= 0; i
< description
->max_insn_reserv_cycles
; i
++)
5238 the_same_automaton_lists
[i
] = NULL
;
5239 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5241 seq
= REGEXP_ONEOF (regexp
)->regexps
[i
];
5242 if (seq
->mode
== rm_sequence
)
5243 for (j
= 0; j
< REGEXP_SEQUENCE (seq
)->regexps_num
; j
++)
5245 allof
= REGEXP_SEQUENCE (seq
)->regexps
[j
];
5246 if (allof
->mode
== rm_allof
)
5247 for (k
= 0; k
< REGEXP_ALLOF (allof
)->regexps_num
; k
++)
5249 unit
= REGEXP_ALLOF (allof
)->regexps
[k
];
5250 if (unit
->mode
== rm_unit
)
5251 process_unit_to_form_the_same_automaton_unit_lists
5253 else if (unit
->mode
!= rm_nothing
)
5256 else if (allof
->mode
== rm_unit
)
5257 process_unit_to_form_the_same_automaton_unit_lists
5259 else if (allof
->mode
!= rm_nothing
)
5262 else if (seq
->mode
== rm_allof
)
5263 for (k
= 0; k
< REGEXP_ALLOF (seq
)->regexps_num
; k
++)
5265 unit
= REGEXP_ALLOF (seq
)->regexps
[k
];
5266 if (unit
->mode
== rm_unit
)
5267 process_unit_to_form_the_same_automaton_unit_lists
5269 else if (unit
->mode
!= rm_nothing
)
5272 else if (seq
->mode
== rm_unit
)
5273 process_unit_to_form_the_same_automaton_unit_lists (seq
, regexp
, 0);
5274 else if (seq
->mode
!= rm_nothing
)
5279 /* The function initializes data to search for units which should be
5280 in the same automaton and call function
5281 `form_the_same_automaton_unit_lists_from_regexp' for each insn
5282 reservation regexp. */
5284 form_the_same_automaton_unit_lists ()
5289 the_same_automaton_lists
5290 = (unit_decl_t
*) xmalloc (description
->max_insn_reserv_cycles
5291 * sizeof (unit_decl_t
));
5292 for (i
= 0; i
< description
->decls_num
; i
++)
5294 decl
= description
->decls
[i
];
5295 if (decl
->mode
== dm_unit
)
5297 DECL_UNIT (decl
)->the_same_automaton_message_reported_p
= FALSE
;
5298 DECL_UNIT (decl
)->the_same_automaton_unit
= DECL_UNIT (decl
);
5301 for (i
= 0; i
< description
->decls_num
; i
++)
5303 decl
= description
->decls
[i
];
5304 if (decl
->mode
== dm_insn_reserv
)
5305 form_the_same_automaton_unit_lists_from_regexp
5306 (DECL_INSN_RESERV (decl
)->transformed_regexp
);
5308 free (the_same_automaton_lists
);
5311 /* The function finds units which should be in the same automaton and,
5312 if they are not, reports about it. */
5314 check_unit_distributions_to_automata ()
5317 unit_decl_t start_unit_decl
, unit_decl
;
5320 form_the_same_automaton_unit_lists ();
5321 for (i
= 0; i
< description
->decls_num
; i
++)
5323 decl
= description
->decls
[i
];
5324 if (decl
->mode
== dm_unit
)
5326 start_unit_decl
= DECL_UNIT (decl
);
5327 if (!start_unit_decl
->the_same_automaton_message_reported_p
)
5328 for (unit_decl
= start_unit_decl
->the_same_automaton_unit
;
5329 unit_decl
!= start_unit_decl
;
5330 unit_decl
= unit_decl
->the_same_automaton_unit
)
5331 if (start_unit_decl
->automaton_decl
!= unit_decl
->automaton_decl
)
5333 error ("Units `%s' and `%s' should be in the same automaton",
5334 start_unit_decl
->name
, unit_decl
->name
);
5335 unit_decl
->the_same_automaton_message_reported_p
= TRUE
;
5343 /* The page contains code for building alt_states (see comments for
5344 IR) describing all possible insns reservations of an automaton. */
5346 /* Current state being formed for which the current alt_state
5348 static state_t state_being_formed
;
5350 /* Current alt_state being formed. */
5351 static alt_state_t alt_state_being_formed
;
5353 /* This recursive function processes `,' and units in reservation
5354 REGEXP for forming alt_states of AUTOMATON. It is believed that
5355 CURR_CYCLE is start cycle of all reservation REGEXP. */
5357 process_seq_for_forming_states (regexp
, automaton
, curr_cycle
)
5359 automaton_t automaton
;
5366 else if (regexp
->mode
== rm_unit
)
5368 if (REGEXP_UNIT (regexp
)->unit_decl
->corresponding_automaton_num
5369 == automaton
->automaton_order_num
)
5370 set_state_reserv (state_being_formed
, curr_cycle
,
5371 REGEXP_UNIT (regexp
)->unit_decl
->unit_num
);
5374 else if (regexp
->mode
== rm_sequence
)
5376 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
5378 = process_seq_for_forming_states
5379 (REGEXP_SEQUENCE (regexp
)->regexps
[i
], automaton
, curr_cycle
) + 1;
5382 else if (regexp
->mode
== rm_allof
)
5384 int finish_cycle
= 0;
5387 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
5389 cycle
= process_seq_for_forming_states (REGEXP_ALLOF (regexp
)
5391 automaton
, curr_cycle
);
5392 if (finish_cycle
< cycle
)
5393 finish_cycle
= cycle
;
5395 return finish_cycle
;
5399 if (regexp
->mode
!= rm_nothing
)
5405 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5406 inserts alt_state into the table. */
5408 finish_forming_alt_state (alt_state
, automaton
)
5409 alt_state_t alt_state
;
5410 automaton_t automaton ATTRIBUTE_UNUSED
;
5412 state_t state_in_table
;
5413 state_t corresponding_state
;
5415 corresponding_state
= alt_state
->state
;
5416 state_in_table
= insert_state (corresponding_state
);
5417 if (state_in_table
!= corresponding_state
)
5419 free_state (corresponding_state
);
5420 alt_state
->state
= state_in_table
;
5424 /* The following variable value is current automaton insn for whose
5425 reservation the alt states are created. */
5426 static ainsn_t curr_ainsn
;
5428 /* This recursive function processes `|' in reservation REGEXP for
5429 forming alt_states of AUTOMATON. List of the alt states should
5430 have the same order as in the description. */
5432 process_alts_for_forming_states (regexp
, automaton
, inside_oneof_p
)
5434 automaton_t automaton
;
5439 if (regexp
->mode
!= rm_oneof
)
5441 alt_state_being_formed
= get_free_alt_state ();
5442 state_being_formed
= get_free_state (1, automaton
);
5443 alt_state_being_formed
->state
= state_being_formed
;
5444 /* We inserts in reverse order but we process alternatives also
5445 in reverse order. So we have the same order of alternative
5446 as in the description. */
5447 alt_state_being_formed
->next_alt_state
= curr_ainsn
->alt_states
;
5448 curr_ainsn
->alt_states
= alt_state_being_formed
;
5449 (void) process_seq_for_forming_states (regexp
, automaton
, 0);
5450 finish_forming_alt_state (alt_state_being_formed
, automaton
);
5456 /* We processes it in reverse order to get list with the same
5457 order as in the description. See also the previous
5459 for (i
= REGEXP_ONEOF (regexp
)->regexps_num
- 1; i
>= 0; i
--)
5460 process_alts_for_forming_states (REGEXP_ONEOF (regexp
)->regexps
[i
],
5465 /* Create nodes alt_state for all AUTOMATON insns. */
5467 create_alt_states (automaton
)
5468 automaton_t automaton
;
5470 struct insn_reserv_decl
*reserv_decl
;
5472 for (curr_ainsn
= automaton
->ainsn_list
;
5474 curr_ainsn
= curr_ainsn
->next_ainsn
)
5476 reserv_decl
= curr_ainsn
->insn_reserv_decl
;
5477 if (reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5479 curr_ainsn
->alt_states
= NULL
;
5480 process_alts_for_forming_states (reserv_decl
->transformed_regexp
,
5482 curr_ainsn
->sorted_alt_states
5483 = uniq_sort_alt_states (curr_ainsn
->alt_states
);
5490 /* The page contains major code for building DFA(s) for fast pipeline
5491 hazards recognition. */
5493 /* The function forms list of ainsns of AUTOMATON with the same
5496 form_ainsn_with_same_reservs (automaton
)
5497 automaton_t automaton
;
5501 vla_ptr_t first_insns
;
5502 vla_ptr_t last_insns
;
5504 VLA_PTR_CREATE (first_insns
, 150, "first insns with the same reservs");
5505 VLA_PTR_CREATE (last_insns
, 150, "last insns with the same reservs");
5506 for (curr_ainsn
= automaton
->ainsn_list
;
5508 curr_ainsn
= curr_ainsn
->next_ainsn
)
5509 if (curr_ainsn
->insn_reserv_decl
5510 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
5512 curr_ainsn
->next_same_reservs_insn
= NULL
;
5513 curr_ainsn
->first_insn_with_same_reservs
= 1;
5517 for (i
= 0; i
< VLA_PTR_LENGTH (first_insns
); i
++)
5519 (curr_ainsn
->sorted_alt_states
,
5520 ((ainsn_t
) VLA_PTR (first_insns
, i
))->sorted_alt_states
))
5522 curr_ainsn
->next_same_reservs_insn
= NULL
;
5523 if (i
< VLA_PTR_LENGTH (first_insns
))
5525 curr_ainsn
->first_insn_with_same_reservs
= 0;
5526 ((ainsn_t
) VLA_PTR (last_insns
, i
))->next_same_reservs_insn
5528 VLA_PTR (last_insns
, i
) = curr_ainsn
;
5532 VLA_PTR_ADD (first_insns
, curr_ainsn
);
5533 VLA_PTR_ADD (last_insns
, curr_ainsn
);
5534 curr_ainsn
->first_insn_with_same_reservs
= 1;
5537 VLA_PTR_DELETE (first_insns
);
5538 VLA_PTR_DELETE (last_insns
);
5541 /* The following function creates all states of nondeterministic (if
5542 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5544 make_automaton (automaton
)
5545 automaton_t automaton
;
5548 struct insn_reserv_decl
*insn_reserv_decl
;
5549 alt_state_t alt_state
;
5551 state_t start_state
;
5553 ainsn_t advance_cycle_ainsn
;
5555 vla_ptr_t state_stack
;
5557 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5558 /* Create the start state (empty state). */
5559 start_state
= insert_state (get_free_state (1, automaton
));
5560 automaton
->start_state
= start_state
;
5561 start_state
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5562 VLA_PTR_ADD (state_stack
, start_state
);
5563 while (VLA_PTR_LENGTH (state_stack
) != 0)
5565 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5566 VLA_PTR_SHORTEN (state_stack
, 1);
5567 advance_cycle_ainsn
= NULL
;
5568 for (ainsn
= automaton
->ainsn_list
;
5570 ainsn
= ainsn
->next_ainsn
)
5571 if (ainsn
->first_insn_with_same_reservs
)
5573 insn_reserv_decl
= ainsn
->insn_reserv_decl
;
5574 if (insn_reserv_decl
!= DECL_INSN_RESERV (advance_cycle_insn_decl
))
5576 /* We process alt_states in the same order as they are
5577 present in the description. */
5579 for (alt_state
= ainsn
->alt_states
;
5581 alt_state
= alt_state
->next_alt_state
)
5583 state2
= alt_state
->state
;
5584 if (!intersected_state_reservs_p (state
, state2
))
5586 state2
= states_union (state
, state2
);
5587 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5589 state2
->it_was_placed_in_stack_for_NDFA_forming
5591 VLA_PTR_ADD (state_stack
, state2
);
5593 added_arc
= add_arc (state
, state2
, ainsn
, 1);
5598 if (!ndfa_flag
&& added_arc
!= NULL
)
5600 added_arc
->state_alts
= 0;
5601 for (alt_state
= ainsn
->alt_states
;
5603 alt_state
= alt_state
->next_alt_state
)
5605 state2
= alt_state
->state
;
5606 if (!intersected_state_reservs_p (state
, state2
))
5607 added_arc
->state_alts
++;
5612 advance_cycle_ainsn
= ainsn
;
5614 /* Add transition to advance cycle. */
5615 state2
= state_shift (state
);
5616 if (!state2
->it_was_placed_in_stack_for_NDFA_forming
)
5618 state2
->it_was_placed_in_stack_for_NDFA_forming
= 1;
5619 VLA_PTR_ADD (state_stack
, state2
);
5621 if (advance_cycle_ainsn
== NULL
)
5623 add_arc (state
, state2
, advance_cycle_ainsn
, 1);
5625 VLA_PTR_DELETE (state_stack
);
5628 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5630 form_arcs_marked_by_insn (state
)
5637 for (i
= 0; i
< description
->decls_num
; i
++)
5639 decl
= description
->decls
[i
];
5640 if (decl
->mode
== dm_insn_reserv
)
5641 DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
= NULL
;
5643 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5645 if (arc
->insn
== NULL
)
5647 arc
->next_arc_marked_by_insn
5648 = arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
;
5649 arc
->insn
->insn_reserv_decl
->arcs_marked_by_insn
= arc
;
5653 /* The function creates composed state (see comments for IR) from
5654 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5655 same insn. If the composed state is not in STATE_STACK yet, it is
5656 popped to STATE_STACK. */
5658 create_composed_state (original_state
, arcs_marked_by_insn
, state_stack
)
5659 state_t original_state
;
5660 arc_t arcs_marked_by_insn
;
5661 vla_ptr_t
*state_stack
;
5664 alt_state_t curr_alt_state
;
5665 alt_state_t new_alt_state
;
5668 state_t state_in_table
;
5670 alt_state_t canonical_alt_states_list
;
5673 if (arcs_marked_by_insn
== NULL
)
5675 if (arcs_marked_by_insn
->next_arc_marked_by_insn
== NULL
)
5676 state
= arcs_marked_by_insn
->to_state
;
5681 /* Create composed state. */
5682 state
= get_free_state (0, arcs_marked_by_insn
->to_state
->automaton
);
5683 curr_alt_state
= NULL
;
5684 for (curr_arc
= arcs_marked_by_insn
;
5686 curr_arc
= curr_arc
->next_arc_marked_by_insn
)
5688 new_alt_state
= get_free_alt_state ();
5689 new_alt_state
->next_alt_state
= curr_alt_state
;
5690 new_alt_state
->state
= curr_arc
->to_state
;
5691 if (curr_arc
->to_state
->component_states
!= NULL
)
5693 curr_alt_state
= new_alt_state
;
5695 /* There are not identical sets in the alt state list. */
5696 canonical_alt_states_list
= uniq_sort_alt_states (curr_alt_state
);
5697 if (canonical_alt_states_list
->next_sorted_alt_state
== NULL
)
5700 state
= canonical_alt_states_list
->state
;
5701 free_state (temp_state
);
5705 state
->component_states
= canonical_alt_states_list
;
5706 state_in_table
= insert_state (state
);
5707 if (state_in_table
!= state
)
5709 if (!state_in_table
->it_was_placed_in_stack_for_DFA_forming
)
5712 state
= state_in_table
;
5716 if (state
->it_was_placed_in_stack_for_DFA_forming
)
5718 for (curr_alt_state
= state
->component_states
;
5719 curr_alt_state
!= NULL
;
5720 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
5721 for (curr_arc
= first_out_arc (curr_alt_state
->state
);
5723 curr_arc
= next_out_arc (curr_arc
))
5724 add_arc (state
, curr_arc
->to_state
, curr_arc
->insn
, 1);
5726 arcs_marked_by_insn
->to_state
= state
;
5727 for (alts_number
= 0,
5728 curr_arc
= arcs_marked_by_insn
->next_arc_marked_by_insn
;
5730 curr_arc
= next_arc
)
5732 next_arc
= curr_arc
->next_arc_marked_by_insn
;
5733 remove_arc (original_state
, curr_arc
);
5736 arcs_marked_by_insn
->state_alts
= alts_number
;
5739 if (!state
->it_was_placed_in_stack_for_DFA_forming
)
5741 state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5742 VLA_PTR_ADD (*state_stack
, state
);
5746 /* The function transformes nondeterminstic AUTOMATON into
5749 NDFA_to_DFA (automaton
)
5750 automaton_t automaton
;
5752 state_t start_state
;
5755 vla_ptr_t state_stack
;
5758 VLA_PTR_CREATE (state_stack
, 150, "state stack");
5759 /* Create the start state (empty state). */
5760 start_state
= automaton
->start_state
;
5761 start_state
->it_was_placed_in_stack_for_DFA_forming
= 1;
5762 VLA_PTR_ADD (state_stack
, start_state
);
5763 while (VLA_PTR_LENGTH (state_stack
) != 0)
5765 state
= VLA_PTR (state_stack
, VLA_PTR_LENGTH (state_stack
) - 1);
5766 VLA_PTR_SHORTEN (state_stack
, 1);
5767 form_arcs_marked_by_insn (state
);
5768 for (i
= 0; i
< description
->decls_num
; i
++)
5770 decl
= description
->decls
[i
];
5771 if (decl
->mode
== dm_insn_reserv
)
5772 create_composed_state
5773 (state
, DECL_INSN_RESERV (decl
)->arcs_marked_by_insn
,
5777 VLA_PTR_DELETE (state_stack
);
5780 /* The following variable value is current number (1, 2, ...) of passing
5782 static int curr_state_graph_pass_num
;
5784 /* This recursive function passes all states achieved from START_STATE
5785 and applies APPLIED_FUNC to them. */
5787 pass_state_graph (start_state
, applied_func
)
5788 state_t start_state
;
5789 void (*applied_func
) PARAMS ((state_t state
));
5793 if (start_state
->pass_num
== curr_state_graph_pass_num
)
5795 start_state
->pass_num
= curr_state_graph_pass_num
;
5796 (*applied_func
) (start_state
);
5797 for (arc
= first_out_arc (start_state
);
5799 arc
= next_out_arc (arc
))
5800 pass_state_graph (arc
->to_state
, applied_func
);
5803 /* This recursive function passes all states of AUTOMATON and applies
5804 APPLIED_FUNC to them. */
5806 pass_states (automaton
, applied_func
)
5807 automaton_t automaton
;
5808 void (*applied_func
) PARAMS ((state_t state
));
5810 curr_state_graph_pass_num
++;
5811 pass_state_graph (automaton
->start_state
, applied_func
);
5814 /* The function initializes code for passing of all states. */
5816 initiate_pass_states ()
5818 curr_state_graph_pass_num
= 0;
5821 /* The following vla is used for storing pointers to all achieved
5823 static vla_ptr_t all_achieved_states
;
5825 /* This function is called by function pass_states to add an achieved
5828 add_achieved_state (state
)
5831 VLA_PTR_ADD (all_achieved_states
, state
);
5834 /* The function sets up equivalence numbers of insns which mark all
5835 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5836 nonzero value) or by equiv_class_num_2 of the destination state.
5837 The function returns number of out arcs of STATE. */
5839 set_out_arc_insns_equiv_num (state
, odd_iteration_flag
)
5841 int odd_iteration_flag
;
5843 int state_out_arcs_num
;
5846 state_out_arcs_num
= 0;
5847 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5849 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
!= 0
5850 || arc
->insn
->insn_reserv_decl
->state_alts
!= 0)
5852 state_out_arcs_num
++;
5853 arc
->insn
->insn_reserv_decl
->equiv_class_num
5854 = (odd_iteration_flag
5855 ? arc
->to_state
->equiv_class_num_1
5856 : arc
->to_state
->equiv_class_num_2
);
5857 arc
->insn
->insn_reserv_decl
->state_alts
= arc
->state_alts
;
5858 if (arc
->insn
->insn_reserv_decl
->equiv_class_num
== 0
5859 || arc
->insn
->insn_reserv_decl
->state_alts
<= 0)
5862 return state_out_arcs_num
;
5865 /* The function clears equivalence numbers and alt_states in all insns
5866 which mark all out arcs of STATE. */
5868 clear_arc_insns_equiv_num (state
)
5873 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5875 arc
->insn
->insn_reserv_decl
->equiv_class_num
= 0;
5876 arc
->insn
->insn_reserv_decl
->state_alts
= 0;
5880 /* The function copies pointers to equivalent states from vla FROM
5883 copy_equiv_class (to
, from
)
5885 const vla_ptr_t
*from
;
5889 VLA_PTR_NULLIFY (*to
);
5890 for (class_ptr
= VLA_PTR_BEGIN (*from
);
5891 class_ptr
<= (state_t
*) VLA_PTR_LAST (*from
);
5893 VLA_PTR_ADD (*to
, *class_ptr
);
5896 /* The function returns nonzero value if STATE is not equivalent to
5897 another state from the same current partition on equivalence
5898 classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5899 output arcs. Iteration of making equivalence partition is defined
5900 by ODD_ITERATION_FLAG. */
5902 state_is_differed (state
, original_state_out_arcs_num
, odd_iteration_flag
)
5904 int original_state_out_arcs_num
;
5905 int odd_iteration_flag
;
5908 int state_out_arcs_num
;
5910 state_out_arcs_num
= 0;
5911 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
5913 state_out_arcs_num
++;
5914 if ((odd_iteration_flag
5915 ? arc
->to_state
->equiv_class_num_1
5916 : arc
->to_state
->equiv_class_num_2
)
5917 != arc
->insn
->insn_reserv_decl
->equiv_class_num
5918 || (arc
->insn
->insn_reserv_decl
->state_alts
!= arc
->state_alts
))
5921 return state_out_arcs_num
!= original_state_out_arcs_num
;
5924 /* The function makes initial partition of STATES on equivalent
5927 init_equiv_class (states
, states_num
)
5932 state_t result_equiv_class
;
5934 result_equiv_class
= NULL
;
5935 for (state_ptr
= states
; state_ptr
< states
+ states_num
; state_ptr
++)
5937 (*state_ptr
)->equiv_class_num_1
= 1;
5938 (*state_ptr
)->next_equiv_class_state
= result_equiv_class
;
5939 result_equiv_class
= *state_ptr
;
5941 return result_equiv_class
;
5944 /* The function processes equivalence class given by its pointer
5945 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
5946 are not equvalent states, the function partitions the class
5947 removing nonequivalent states and placing them in
5948 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5949 assigns it to the state equivalence number. If the class has been
5950 partitioned, the function returns nonzero value. */
5952 partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
5953 next_iteration_classes
, new_equiv_class_num_ptr
)
5954 state_t
*equiv_class_ptr
;
5955 int odd_iteration_flag
;
5956 vla_ptr_t
*next_iteration_classes
;
5957 int *new_equiv_class_num_ptr
;
5959 state_t new_equiv_class
;
5961 state_t first_state
;
5968 if (*equiv_class_ptr
== NULL
)
5970 for (first_state
= *equiv_class_ptr
;
5971 first_state
!= NULL
;
5972 first_state
= new_equiv_class
)
5974 new_equiv_class
= NULL
;
5975 if (first_state
->next_equiv_class_state
!= NULL
)
5977 /* There are more one states in the class equivalence. */
5978 out_arcs_num
= set_out_arc_insns_equiv_num (first_state
,
5979 odd_iteration_flag
);
5980 for (prev_state
= first_state
,
5981 curr_state
= first_state
->next_equiv_class_state
;
5983 curr_state
= next_state
)
5985 next_state
= curr_state
->next_equiv_class_state
;
5986 if (state_is_differed (curr_state
, out_arcs_num
,
5987 odd_iteration_flag
))
5989 /* Remove curr state from the class equivalence. */
5990 prev_state
->next_equiv_class_state
= next_state
;
5991 /* Add curr state to the new class equivalence. */
5992 curr_state
->next_equiv_class_state
= new_equiv_class
;
5993 if (new_equiv_class
== NULL
)
5994 (*new_equiv_class_num_ptr
)++;
5995 if (odd_iteration_flag
)
5996 curr_state
->equiv_class_num_2
= *new_equiv_class_num_ptr
;
5998 curr_state
->equiv_class_num_1
= *new_equiv_class_num_ptr
;
5999 new_equiv_class
= curr_state
;
6003 prev_state
= curr_state
;
6005 clear_arc_insns_equiv_num (first_state
);
6007 if (new_equiv_class
!= NULL
)
6008 VLA_PTR_ADD (*next_iteration_classes
, new_equiv_class
);
6013 /* The function finds equivalent states of AUTOMATON. */
6015 evaluate_equiv_classes (automaton
, equiv_classes
)
6016 automaton_t automaton
;
6017 vla_ptr_t
*equiv_classes
;
6019 state_t new_equiv_class
;
6020 int new_equiv_class_num
;
6021 int odd_iteration_flag
;
6023 vla_ptr_t next_iteration_classes
;
6024 state_t
*equiv_class_ptr
;
6027 VLA_PTR_CREATE (all_achieved_states
, 1500, "all achieved states");
6028 pass_states (automaton
, add_achieved_state
);
6029 new_equiv_class
= init_equiv_class (VLA_PTR_BEGIN (all_achieved_states
),
6030 VLA_PTR_LENGTH (all_achieved_states
));
6031 odd_iteration_flag
= 0;
6032 new_equiv_class_num
= 1;
6033 VLA_PTR_CREATE (next_iteration_classes
, 150, "next iteration classes");
6034 VLA_PTR_ADD (next_iteration_classes
, new_equiv_class
);
6037 odd_iteration_flag
= !odd_iteration_flag
;
6039 copy_equiv_class (equiv_classes
, &next_iteration_classes
);
6040 /* Transfer equiv numbers for the next iteration. */
6041 for (state_ptr
= VLA_PTR_BEGIN (all_achieved_states
);
6042 state_ptr
<= (state_t
*) VLA_PTR_LAST (all_achieved_states
);
6044 if (odd_iteration_flag
)
6045 (*state_ptr
)->equiv_class_num_2
= (*state_ptr
)->equiv_class_num_1
;
6047 (*state_ptr
)->equiv_class_num_1
= (*state_ptr
)->equiv_class_num_2
;
6048 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6049 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6051 if (partition_equiv_class (equiv_class_ptr
, odd_iteration_flag
,
6052 &next_iteration_classes
,
6053 &new_equiv_class_num
))
6056 while (!finish_flag
);
6057 VLA_PTR_DELETE (next_iteration_classes
);
6058 VLA_PTR_DELETE (all_achieved_states
);
6061 /* The function merges equivalent states of AUTOMATON. */
6063 merge_states (automaton
, equiv_classes
)
6064 automaton_t automaton
;
6065 vla_ptr_t
*equiv_classes
;
6067 state_t
*equiv_class_ptr
;
6070 state_t first_class_state
;
6071 alt_state_t alt_states
;
6072 alt_state_t new_alt_state
;
6076 /* Create states corresponding to equivalence classes containing two
6078 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6079 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6081 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6083 /* There are more one states in the class equivalence. */
6084 /* Create new compound state. */
6085 new_state
= get_free_state (0, automaton
);
6087 first_class_state
= *equiv_class_ptr
;
6088 for (curr_state
= first_class_state
;
6090 curr_state
= curr_state
->next_equiv_class_state
)
6092 curr_state
->equiv_class_state
= new_state
;
6093 new_alt_state
= get_free_alt_state ();
6094 new_alt_state
->state
= curr_state
;
6095 new_alt_state
->next_sorted_alt_state
= alt_states
;
6096 alt_states
= new_alt_state
;
6098 new_state
->component_states
= alt_states
;
6101 (*equiv_class_ptr
)->equiv_class_state
= *equiv_class_ptr
;
6102 for (equiv_class_ptr
= VLA_PTR_BEGIN (*equiv_classes
);
6103 equiv_class_ptr
<= (state_t
*) VLA_PTR_LAST (*equiv_classes
);
6105 if ((*equiv_class_ptr
)->next_equiv_class_state
!= NULL
)
6107 first_class_state
= *equiv_class_ptr
;
6108 /* Create new arcs output from the state corresponding to
6110 for (curr_arc
= first_out_arc (first_class_state
);
6112 curr_arc
= next_out_arc (curr_arc
))
6113 add_arc (first_class_state
->equiv_class_state
,
6114 curr_arc
->to_state
->equiv_class_state
,
6115 curr_arc
->insn
, curr_arc
->state_alts
);
6116 /* Delete output arcs from states of given class equivalence. */
6117 for (curr_state
= first_class_state
;
6119 curr_state
= curr_state
->next_equiv_class_state
)
6121 if (automaton
->start_state
== curr_state
)
6122 automaton
->start_state
= curr_state
->equiv_class_state
;
6123 /* Delete the state and its output arcs. */
6124 for (curr_arc
= first_out_arc (curr_state
);
6126 curr_arc
= next_arc
)
6128 next_arc
= next_out_arc (curr_arc
);
6129 free_arc (curr_arc
);
6135 /* Change `to_state' of arcs output from the state of given
6136 equivalence class. */
6137 for (curr_arc
= first_out_arc (*equiv_class_ptr
);
6139 curr_arc
= next_out_arc (curr_arc
))
6140 curr_arc
->to_state
= curr_arc
->to_state
->equiv_class_state
;
6144 /* The function sets up new_cycle_p for states if there is arc to the
6145 state marked by advance_cycle_insn_decl. */
6147 set_new_cycle_flags (state
)
6152 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6153 if (arc
->insn
->insn_reserv_decl
6154 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
6155 arc
->to_state
->new_cycle_p
= 1;
6158 /* The top level function for minimization of deterministic
6161 minimize_DFA (automaton
)
6162 automaton_t automaton
;
6164 vla_ptr_t equiv_classes
;
6166 VLA_PTR_CREATE (equiv_classes
, 1500, "equivalence classes");
6167 evaluate_equiv_classes (automaton
, &equiv_classes
);
6168 merge_states (automaton
, &equiv_classes
);
6169 pass_states (automaton
, set_new_cycle_flags
);
6170 VLA_PTR_DELETE (equiv_classes
);
6173 /* Values of two variables are counted number of states and arcs in an
6175 static int curr_counted_states_num
;
6176 static int curr_counted_arcs_num
;
6178 /* The function is called by function `pass_states' to count states
6179 and arcs of an automaton. */
6181 incr_states_and_arcs_nums (state
)
6186 curr_counted_states_num
++;
6187 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6188 curr_counted_arcs_num
++;
6191 /* The function counts states and arcs of AUTOMATON. */
6193 count_states_and_arcs (automaton
, states_num
, arcs_num
)
6194 automaton_t automaton
;
6198 curr_counted_states_num
= 0;
6199 curr_counted_arcs_num
= 0;
6200 pass_states (automaton
, incr_states_and_arcs_nums
);
6201 *states_num
= curr_counted_states_num
;
6202 *arcs_num
= curr_counted_arcs_num
;
6205 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6206 recognition after checking and simplifying IR of the
6209 build_automaton (automaton
)
6210 automaton_t automaton
;
6215 ticker_on (&NDFA_time
);
6216 make_automaton (automaton
);
6217 ticker_off (&NDFA_time
);
6218 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6219 automaton
->NDFA_states_num
= states_num
;
6220 automaton
->NDFA_arcs_num
= arcs_num
;
6221 ticker_on (&NDFA_to_DFA_time
);
6222 NDFA_to_DFA (automaton
);
6223 ticker_off (&NDFA_to_DFA_time
);
6224 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6225 automaton
->DFA_states_num
= states_num
;
6226 automaton
->DFA_arcs_num
= arcs_num
;
6227 if (!no_minimization_flag
)
6229 ticker_on (&minimize_time
);
6230 minimize_DFA (automaton
);
6231 ticker_off (&minimize_time
);
6232 count_states_and_arcs (automaton
, &states_num
, &arcs_num
);
6233 automaton
->minimal_DFA_states_num
= states_num
;
6234 automaton
->minimal_DFA_arcs_num
= arcs_num
;
6240 /* The page contains code for enumeration of all states of an automaton. */
6242 /* Variable used for enumeration of all states of an automaton. Its
6243 value is current number of automaton states. */
6244 static int curr_state_order_num
;
6246 /* The function is called by function `pass_states' for enumerating
6249 set_order_state_num (state
)
6252 state
->order_state_num
= curr_state_order_num
;
6253 curr_state_order_num
++;
6256 /* The function enumerates all states of AUTOMATON. */
6258 enumerate_states (automaton
)
6259 automaton_t automaton
;
6261 curr_state_order_num
= 0;
6262 pass_states (automaton
, set_order_state_num
);
6263 automaton
->achieved_states_num
= curr_state_order_num
;
6268 /* The page contains code for finding equivalent automaton insns
6271 /* The function inserts AINSN into cyclic list
6272 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6274 insert_ainsn_into_equiv_class (ainsn
, cyclic_equiv_class_insn_list
)
6276 ainsn_t cyclic_equiv_class_insn_list
;
6278 if (cyclic_equiv_class_insn_list
== NULL
)
6279 ainsn
->next_equiv_class_insn
= ainsn
;
6282 ainsn
->next_equiv_class_insn
6283 = cyclic_equiv_class_insn_list
->next_equiv_class_insn
;
6284 cyclic_equiv_class_insn_list
->next_equiv_class_insn
= ainsn
;
6289 /* The function deletes equiv_class_insn into cyclic list of
6290 equivalent ainsns. */
6292 delete_ainsn_from_equiv_class (equiv_class_insn
)
6293 ainsn_t equiv_class_insn
;
6295 ainsn_t curr_equiv_class_insn
;
6296 ainsn_t prev_equiv_class_insn
;
6298 prev_equiv_class_insn
= equiv_class_insn
;
6299 for (curr_equiv_class_insn
= equiv_class_insn
->next_equiv_class_insn
;
6300 curr_equiv_class_insn
!= equiv_class_insn
;
6301 curr_equiv_class_insn
= curr_equiv_class_insn
->next_equiv_class_insn
)
6302 prev_equiv_class_insn
= curr_equiv_class_insn
;
6303 if (prev_equiv_class_insn
!= equiv_class_insn
)
6304 prev_equiv_class_insn
->next_equiv_class_insn
6305 = equiv_class_insn
->next_equiv_class_insn
;
6308 /* The function processes AINSN of a state in order to find equivalent
6309 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6312 process_insn_equiv_class (ainsn
, insn_arcs_array
)
6314 arc_t
*insn_arcs_array
;
6318 ainsn_t cyclic_insn_list
;
6321 if (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
] == NULL
)
6324 /* New class of ainsns which are not equivalent to given ainsn. */
6325 cyclic_insn_list
= NULL
;
6328 next_insn
= curr_insn
->next_equiv_class_insn
;
6329 arc
= insn_arcs_array
[curr_insn
->insn_reserv_decl
->insn_num
];
6331 || (insn_arcs_array
[ainsn
->insn_reserv_decl
->insn_num
]->to_state
6334 delete_ainsn_from_equiv_class (curr_insn
);
6335 cyclic_insn_list
= insert_ainsn_into_equiv_class (curr_insn
,
6338 curr_insn
= next_insn
;
6340 while (curr_insn
!= ainsn
);
6343 /* The function processes STATE in order to find equivalent ainsns. */
6345 process_state_for_insn_equiv_partition (state
)
6349 arc_t
*insn_arcs_array
;
6351 vla_ptr_t insn_arcs_vect
;
6353 VLA_PTR_CREATE (insn_arcs_vect
, 500, "insn arcs vector");
6354 VLA_PTR_EXPAND (insn_arcs_vect
, description
->insns_num
);
6355 insn_arcs_array
= VLA_PTR_BEGIN (insn_arcs_vect
);
6356 /* Process insns of the arcs. */
6357 for (i
= 0; i
< description
->insns_num
; i
++)
6358 insn_arcs_array
[i
] = NULL
;
6359 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6360 insn_arcs_array
[arc
->insn
->insn_reserv_decl
->insn_num
] = arc
;
6361 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6362 process_insn_equiv_class (arc
->insn
, insn_arcs_array
);
6363 VLA_PTR_DELETE (insn_arcs_vect
);
6366 /* The function searches for equivalent ainsns of AUTOMATON. */
6368 set_insn_equiv_classes (automaton
)
6369 automaton_t automaton
;
6374 ainsn_t cyclic_insn_list
;
6375 ainsn_t insn_with_same_reservs
;
6376 int equiv_classes_num
;
6378 /* All insns are included in one equivalence class. */
6379 cyclic_insn_list
= NULL
;
6380 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6381 if (ainsn
->first_insn_with_same_reservs
)
6382 cyclic_insn_list
= insert_ainsn_into_equiv_class (ainsn
,
6384 /* Process insns in order to make equivalence partition. */
6385 pass_states (automaton
, process_state_for_insn_equiv_partition
);
6386 /* Enumerate equiv classes. */
6387 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6388 /* Set undefined value. */
6389 ainsn
->insn_equiv_class_num
= -1;
6390 equiv_classes_num
= 0;
6391 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
6392 if (ainsn
->insn_equiv_class_num
< 0)
6395 if (!first_insn
->first_insn_with_same_reservs
)
6397 first_insn
->first_ainsn_with_given_equialence_num
= 1;
6398 curr_insn
= first_insn
;
6401 for (insn_with_same_reservs
= curr_insn
;
6402 insn_with_same_reservs
!= NULL
;
6403 insn_with_same_reservs
6404 = insn_with_same_reservs
->next_same_reservs_insn
)
6405 insn_with_same_reservs
->insn_equiv_class_num
= equiv_classes_num
;
6406 curr_insn
= curr_insn
->next_equiv_class_insn
;
6408 while (curr_insn
!= first_insn
);
6409 equiv_classes_num
++;
6411 automaton
->insn_equiv_classes_num
= equiv_classes_num
;
6416 /* This page contains code for creating DFA(s) and calls functions
6420 /* The following value is used to prevent floating point overflow for
6421 estimating an automaton bound. The value should be less DBL_MAX on
6422 the host machine. We use here approximate minimum of maximal
6423 double floating point value required by ANSI C standard. It
6424 will work for non ANSI sun compiler too. */
6426 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6428 /* The function estimate size of the single DFA used by PHR (pipeline
6429 hazards recognizer). */
6431 estimate_one_automaton_bound ()
6434 double one_automaton_estimation_bound
;
6438 one_automaton_estimation_bound
= 1.0;
6439 for (i
= 0; i
< description
->decls_num
; i
++)
6441 decl
= description
->decls
[i
];
6442 if (decl
->mode
== dm_unit
)
6444 root_value
= exp (log (DECL_UNIT (decl
)->max_occ_cycle_num
+ 1.0)
6446 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND
/ root_value
6447 > one_automaton_estimation_bound
)
6448 one_automaton_estimation_bound
*= root_value
;
6451 return one_automaton_estimation_bound
;
6454 /* The function compares unit declarations acoording to their maximal
6455 cycle in reservations. */
6457 compare_max_occ_cycle_nums (unit_decl_1
, unit_decl_2
)
6458 const void *unit_decl_1
;
6459 const void *unit_decl_2
;
6461 if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6462 < (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6464 else if ((DECL_UNIT (*(decl_t
*) unit_decl_1
)->max_occ_cycle_num
)
6465 == (DECL_UNIT (*(decl_t
*) unit_decl_2
)->max_occ_cycle_num
))
6471 /* The function makes heuristic assigning automata to units. Actually
6472 efficacy of the algorithm has been checked yet??? */
6474 units_to_automata_heuristic_distr ()
6476 double estimation_bound
;
6478 decl_t
*unit_decl_ptr
;
6482 vla_ptr_t unit_decls
;
6485 if (description
->units_num
== 0)
6487 estimation_bound
= estimate_one_automaton_bound ();
6488 VLA_PTR_CREATE (unit_decls
, 150, "unit decls");
6489 for (i
= 0; i
< description
->decls_num
; i
++)
6491 decl
= description
->decls
[i
];
6492 if (decl
->mode
== dm_unit
)
6493 VLA_PTR_ADD (unit_decls
, decl
);
6495 qsort (VLA_PTR_BEGIN (unit_decls
), VLA_PTR_LENGTH (unit_decls
),
6496 sizeof (decl_t
), compare_max_occ_cycle_nums
);
6498 unit_decl_ptr
= VLA_PTR_BEGIN (unit_decls
);
6499 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6500 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6501 for (unit_decl_ptr
++;
6502 unit_decl_ptr
<= (decl_t
*) VLA_PTR_LAST (unit_decls
);
6506 = ((decl_t
*) VLA_PTR_LAST (unit_decls
) - unit_decl_ptr
+ 1);
6507 if (automata_num
- automaton_num
- 1 > rest_units_num
)
6509 if (automaton_num
< automata_num
- 1
6510 && ((automata_num
- automaton_num
- 1 == rest_units_num
)
6513 / (DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
)))))
6515 bound_value
= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6519 bound_value
*= DECL_UNIT (*unit_decl_ptr
)->max_occ_cycle_num
;
6520 DECL_UNIT (*unit_decl_ptr
)->corresponding_automaton_num
= automaton_num
;
6522 if (automaton_num
!= automata_num
- 1)
6524 VLA_PTR_DELETE (unit_decls
);
6527 /* The functions creates automaton insns for each automata. Automaton
6528 insn is simply insn for given automaton which makes reservation
6529 only of units of the automaton. */
6534 ainsn_t first_ainsn
;
6541 for (i
= 0; i
< description
->decls_num
; i
++)
6543 decl
= description
->decls
[i
];
6544 if (decl
->mode
== dm_insn_reserv
)
6546 curr_ainsn
= create_node (sizeof (struct ainsn
));
6547 curr_ainsn
->insn_reserv_decl
= DECL_INSN_RESERV (decl
);
6548 curr_ainsn
->important_p
= FALSE
;
6549 curr_ainsn
->next_ainsn
= NULL
;
6550 if (prev_ainsn
== NULL
)
6551 first_ainsn
= curr_ainsn
;
6553 prev_ainsn
->next_ainsn
= curr_ainsn
;
6554 prev_ainsn
= curr_ainsn
;
6560 /* The function assigns automata to units according to constructions
6561 `define_automaton' in the description. */
6563 units_to_automata_distr ()
6568 for (i
= 0; i
< description
->decls_num
; i
++)
6570 decl
= description
->decls
[i
];
6571 if (decl
->mode
== dm_unit
)
6573 if (DECL_UNIT (decl
)->automaton_decl
== NULL
6574 || (DECL_UNIT (decl
)->automaton_decl
->corresponding_automaton
6576 /* Distribute to the first automaton. */
6577 DECL_UNIT (decl
)->corresponding_automaton_num
= 0;
6579 DECL_UNIT (decl
)->corresponding_automaton_num
6580 = (DECL_UNIT (decl
)->automaton_decl
6581 ->corresponding_automaton
->automaton_order_num
);
6586 /* The function creates DFA(s) for fast pipeline hazards recognition
6587 after checking and simplifying IR of the description. */
6591 automaton_t curr_automaton
;
6592 automaton_t prev_automaton
;
6594 int curr_automaton_num
;
6597 if (automata_num
!= 0)
6599 units_to_automata_heuristic_distr ();
6600 for (prev_automaton
= NULL
, curr_automaton_num
= 0;
6601 curr_automaton_num
< automata_num
;
6602 curr_automaton_num
++, prev_automaton
= curr_automaton
)
6604 curr_automaton
= create_node (sizeof (struct automaton
));
6605 curr_automaton
->ainsn_list
= create_ainsns ();
6606 curr_automaton
->corresponding_automaton_decl
= NULL
;
6607 curr_automaton
->next_automaton
= NULL
;
6608 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6609 if (prev_automaton
== NULL
)
6610 description
->first_automaton
= curr_automaton
;
6612 prev_automaton
->next_automaton
= curr_automaton
;
6617 curr_automaton_num
= 0;
6618 prev_automaton
= NULL
;
6619 for (i
= 0; i
< description
->decls_num
; i
++)
6621 decl
= description
->decls
[i
];
6622 if (decl
->mode
== dm_automaton
6623 && DECL_AUTOMATON (decl
)->automaton_is_used
)
6625 curr_automaton
= create_node (sizeof (struct automaton
));
6626 curr_automaton
->ainsn_list
= create_ainsns ();
6627 curr_automaton
->corresponding_automaton_decl
6628 = DECL_AUTOMATON (decl
);
6629 curr_automaton
->next_automaton
= NULL
;
6630 DECL_AUTOMATON (decl
)->corresponding_automaton
= curr_automaton
;
6631 curr_automaton
->automaton_order_num
= curr_automaton_num
;
6632 if (prev_automaton
== NULL
)
6633 description
->first_automaton
= curr_automaton
;
6635 prev_automaton
->next_automaton
= curr_automaton
;
6636 curr_automaton_num
++;
6637 prev_automaton
= curr_automaton
;
6640 if (curr_automaton_num
== 0)
6642 curr_automaton
= create_node (sizeof (struct automaton
));
6643 curr_automaton
->ainsn_list
= create_ainsns ();
6644 curr_automaton
->corresponding_automaton_decl
= NULL
;
6645 curr_automaton
->next_automaton
= NULL
;
6646 description
->first_automaton
= curr_automaton
;
6648 units_to_automata_distr ();
6650 NDFA_time
= create_ticker ();
6651 ticker_off (&NDFA_time
);
6652 NDFA_to_DFA_time
= create_ticker ();
6653 ticker_off (&NDFA_to_DFA_time
);
6654 minimize_time
= create_ticker ();
6655 ticker_off (&minimize_time
);
6656 equiv_time
= create_ticker ();
6657 ticker_off (&equiv_time
);
6658 for (curr_automaton
= description
->first_automaton
;
6659 curr_automaton
!= NULL
;
6660 curr_automaton
= curr_automaton
->next_automaton
)
6662 if (curr_automaton
->corresponding_automaton_decl
== NULL
)
6663 fprintf (stderr
, "Create anonymous automaton ...");
6665 fprintf (stderr
, "Create automaton `%s'...",
6666 curr_automaton
->corresponding_automaton_decl
->name
);
6667 create_alt_states (curr_automaton
);
6668 form_ainsn_with_same_reservs (curr_automaton
);
6669 build_automaton (curr_automaton
);
6670 enumerate_states (curr_automaton
);
6671 ticker_on (&equiv_time
);
6672 set_insn_equiv_classes (curr_automaton
);
6673 ticker_off (&equiv_time
);
6674 fprintf (stderr
, "done\n");
6680 /* This page contains code for forming string representation of
6681 regexp. The representation is formed on IR obstack. So you should
6682 not work with IR obstack between regexp_representation and
6683 finish_regexp_representation calls. */
6685 /* This recursive function forms string representation of regexp
6686 (without tailing '\0'). */
6688 form_regexp (regexp
)
6693 if (regexp
->mode
== rm_unit
|| regexp
->mode
== rm_reserv
)
6695 const char *name
= (regexp
->mode
== rm_unit
6696 ? REGEXP_UNIT (regexp
)->name
6697 : REGEXP_RESERV (regexp
)->name
);
6699 obstack_grow (&irp
, name
, strlen (name
));
6701 else if (regexp
->mode
== rm_sequence
)
6702 for (i
= 0; i
< REGEXP_SEQUENCE (regexp
)->regexps_num
; i
++)
6705 obstack_1grow (&irp
, ',');
6706 form_regexp (REGEXP_SEQUENCE (regexp
)->regexps
[i
]);
6708 else if (regexp
->mode
== rm_allof
)
6710 obstack_1grow (&irp
, '(');
6711 for (i
= 0; i
< REGEXP_ALLOF (regexp
)->regexps_num
; i
++)
6714 obstack_1grow (&irp
, '+');
6715 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6716 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6717 obstack_1grow (&irp
, '(');
6718 form_regexp (REGEXP_ALLOF (regexp
)->regexps
[i
]);
6719 if (REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_sequence
6720 || REGEXP_ALLOF (regexp
)->regexps
[i
]->mode
== rm_oneof
)
6721 obstack_1grow (&irp
, ')');
6723 obstack_1grow (&irp
, ')');
6725 else if (regexp
->mode
== rm_oneof
)
6726 for (i
= 0; i
< REGEXP_ONEOF (regexp
)->regexps_num
; i
++)
6729 obstack_1grow (&irp
, '|');
6730 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6731 obstack_1grow (&irp
, '(');
6732 form_regexp (REGEXP_ONEOF (regexp
)->regexps
[i
]);
6733 if (REGEXP_ONEOF (regexp
)->regexps
[i
]->mode
== rm_sequence
)
6734 obstack_1grow (&irp
, ')');
6736 else if (regexp
->mode
== rm_repeat
)
6740 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6741 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6742 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6743 obstack_1grow (&irp
, '(');
6744 form_regexp (REGEXP_REPEAT (regexp
)->regexp
);
6745 if (REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_sequence
6746 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_allof
6747 || REGEXP_REPEAT (regexp
)->regexp
->mode
== rm_oneof
)
6748 obstack_1grow (&irp
, ')');
6749 sprintf (digits
, "*%d", REGEXP_REPEAT (regexp
)->repeat_num
);
6750 obstack_grow (&irp
, digits
, strlen (digits
));
6752 else if (regexp
->mode
== rm_nothing
)
6753 obstack_grow (&irp
, NOTHING_NAME
, strlen (NOTHING_NAME
));
6758 /* The function returns string representation of REGEXP on IR
6761 regexp_representation (regexp
)
6764 form_regexp (regexp
);
6765 obstack_1grow (&irp
, '\0');
6766 return obstack_base (&irp
);
6769 /* The function frees memory allocated for last formed string
6770 representation of regexp. */
6772 finish_regexp_representation ()
6774 int length
= obstack_object_size (&irp
);
6776 obstack_blank_fast (&irp
, -length
);
6781 /* This page contains code for output PHR (pipeline hazards recognizer). */
6783 /* The function outputs minimal C type which is sufficient for
6784 representation numbers in range min_range_value and
6785 max_range_value. Because host machine and build machine may be
6786 different, we use here minimal values required by ANSI C standard
6787 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6791 output_range_type (f
, min_range_value
, max_range_value
)
6793 long int min_range_value
;
6794 long int max_range_value
;
6796 if (min_range_value
>= 0 && max_range_value
<= 255)
6797 fprintf (f
, "unsigned char");
6798 else if (min_range_value
>= -127 && max_range_value
<= 127)
6799 fprintf (f
, "signed char");
6800 else if (min_range_value
>= 0 && max_range_value
<= 65535)
6801 fprintf (f
, "unsigned short");
6802 else if (min_range_value
>= -32767 && max_range_value
<= 32767)
6803 fprintf (f
, "short");
6808 /* The following macro value is used as value of member
6809 `longest_path_length' of state when we are processing path and the
6810 state on the path. */
6812 #define ON_THE_PATH -2
6814 /* The following recursive function searches for the length of the
6815 longest path starting from STATE which does not contain cycles and
6816 `cycle advance' arcs. */
6819 longest_path_length (state
)
6825 if (state
->longest_path_length
== ON_THE_PATH
)
6826 /* We don't expect the path cycle here. Our graph may contain
6827 only cycles with one state on the path not containing `cycle
6828 advance' arcs -- see comment below. */
6830 else if (state
->longest_path_length
!= UNDEFINED_LONGEST_PATH_LENGTH
)
6831 /* We alreday visited the state. */
6832 return state
->longest_path_length
;
6835 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
6836 /* Ignore cycles containing one state and `cycle advance' arcs. */
6837 if (arc
->to_state
!= state
6838 && (arc
->insn
->insn_reserv_decl
6839 != DECL_INSN_RESERV (advance_cycle_insn_decl
)))
6841 length
= longest_path_length (arc
->to_state
);
6842 if (length
> result
)
6845 state
->longest_path_length
= result
+ 1;
6849 /* The following variable value is value of the corresponding global
6850 variable in the automaton based pipeline interface. */
6852 static int max_dfa_issue_rate
;
6854 /* The following function processes the longest path length staring
6855 from STATE to find MAX_DFA_ISSUE_RATE. */
6858 process_state_longest_path_length (state
)
6863 value
= longest_path_length (state
);
6864 if (value
> max_dfa_issue_rate
)
6865 max_dfa_issue_rate
= value
;
6868 /* The following macro value is name of the corresponding global
6869 variable in the automaton based pipeline interface. */
6871 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6873 /* The following function calculates value of the corresponding
6874 global variable and outputs its declaration. */
6877 output_dfa_max_issue_rate ()
6879 automaton_t automaton
;
6881 if (UNDEFINED_LONGEST_PATH_LENGTH
== ON_THE_PATH
|| ON_THE_PATH
>= 0)
6883 max_dfa_issue_rate
= 0;
6884 for (automaton
= description
->first_automaton
;
6886 automaton
= automaton
->next_automaton
)
6887 pass_states (automaton
, process_state_longest_path_length
);
6888 fprintf (output_file
, "\nint %s = %d;\n",
6889 MAX_DFA_ISSUE_RATE_VAR_NAME
, max_dfa_issue_rate
);
6892 /* The function outputs all initialization values of VECT with length
6895 output_vect (vect
, vect_length
)
6902 if (vect_length
== 0)
6903 fprintf (output_file
,
6904 "0 /* This is dummy el because the vect is empty */");
6909 fprintf (output_file
, "%5ld", (long) *vect
);
6911 if (els_on_line
== 10)
6914 fprintf (output_file
, ",\n");
6916 else if (vect_length
!= 0)
6917 fprintf (output_file
, ", ");
6921 while (vect_length
!= 0);
6925 /* The following is name of the structure which represents DFA(s) for
6927 #define CHIP_NAME "DFA_chip"
6929 /* The following is name of member which represents state of a DFA for
6932 output_chip_member_name (f
, automaton
)
6934 automaton_t automaton
;
6936 if (automaton
->corresponding_automaton_decl
== NULL
)
6937 fprintf (f
, "automaton_state_%d", automaton
->automaton_order_num
);
6939 fprintf (f
, "%s_automaton_state",
6940 automaton
->corresponding_automaton_decl
->name
);
6943 /* The following is name of temporary variable which stores state of a
6946 output_temp_chip_member_name (f
, automaton
)
6948 automaton_t automaton
;
6951 output_chip_member_name (f
, automaton
);
6954 /* This is name of macro value which is code of pseudo_insn
6955 representing advancing cpu cycle. Its value is used as internal
6956 code unknown insn. */
6957 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6959 /* Output name of translate vector for given automaton. */
6961 output_translate_vect_name (f
, automaton
)
6963 automaton_t automaton
;
6965 if (automaton
->corresponding_automaton_decl
== NULL
)
6966 fprintf (f
, "translate_%d", automaton
->automaton_order_num
);
6968 fprintf (f
, "%s_translate", automaton
->corresponding_automaton_decl
->name
);
6971 /* Output name for simple transition table representation. */
6973 output_trans_full_vect_name (f
, automaton
)
6975 automaton_t automaton
;
6977 if (automaton
->corresponding_automaton_decl
== NULL
)
6978 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6980 fprintf (f
, "%s_transitions",
6981 automaton
->corresponding_automaton_decl
->name
);
6984 /* Output name of comb vector of the transition table for given
6987 output_trans_comb_vect_name (f
, automaton
)
6989 automaton_t automaton
;
6991 if (automaton
->corresponding_automaton_decl
== NULL
)
6992 fprintf (f
, "transitions_%d", automaton
->automaton_order_num
);
6994 fprintf (f
, "%s_transitions",
6995 automaton
->corresponding_automaton_decl
->name
);
6998 /* Output name of check vector of the transition table for given
7001 output_trans_check_vect_name (f
, automaton
)
7003 automaton_t automaton
;
7005 if (automaton
->corresponding_automaton_decl
== NULL
)
7006 fprintf (f
, "check_%d", automaton
->automaton_order_num
);
7008 fprintf (f
, "%s_check", automaton
->corresponding_automaton_decl
->name
);
7011 /* Output name of base vector of the transition table for given
7014 output_trans_base_vect_name (f
, automaton
)
7016 automaton_t automaton
;
7018 if (automaton
->corresponding_automaton_decl
== NULL
)
7019 fprintf (f
, "base_%d", automaton
->automaton_order_num
);
7021 fprintf (f
, "%s_base", automaton
->corresponding_automaton_decl
->name
);
7024 /* Output name for simple alternatives number representation. */
7026 output_state_alts_full_vect_name (f
, automaton
)
7028 automaton_t automaton
;
7030 if (automaton
->corresponding_automaton_decl
== NULL
)
7031 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7033 fprintf (f
, "%s_state_alts",
7034 automaton
->corresponding_automaton_decl
->name
);
7037 /* Output name of comb vector of the alternatives number table for given
7040 output_state_alts_comb_vect_name (f
, automaton
)
7042 automaton_t automaton
;
7044 if (automaton
->corresponding_automaton_decl
== NULL
)
7045 fprintf (f
, "state_alts_%d", automaton
->automaton_order_num
);
7047 fprintf (f
, "%s_state_alts",
7048 automaton
->corresponding_automaton_decl
->name
);
7051 /* Output name of check vector of the alternatives number table for given
7054 output_state_alts_check_vect_name (f
, automaton
)
7056 automaton_t automaton
;
7058 if (automaton
->corresponding_automaton_decl
== NULL
)
7059 fprintf (f
, "check_state_alts_%d", automaton
->automaton_order_num
);
7061 fprintf (f
, "%s_check_state_alts",
7062 automaton
->corresponding_automaton_decl
->name
);
7065 /* Output name of base vector of the alternatives number table for given
7068 output_state_alts_base_vect_name (f
, automaton
)
7070 automaton_t automaton
;
7072 if (automaton
->corresponding_automaton_decl
== NULL
)
7073 fprintf (f
, "base_state_alts_%d", automaton
->automaton_order_num
);
7075 fprintf (f
, "%s_base_state_alts",
7076 automaton
->corresponding_automaton_decl
->name
);
7079 /* Output name of simple min issue delay table representation. */
7081 output_min_issue_delay_vect_name (f
, automaton
)
7083 automaton_t automaton
;
7085 if (automaton
->corresponding_automaton_decl
== NULL
)
7086 fprintf (f
, "min_issue_delay_%d", automaton
->automaton_order_num
);
7088 fprintf (f
, "%s_min_issue_delay",
7089 automaton
->corresponding_automaton_decl
->name
);
7092 /* Output name of deadlock vector for given automaton. */
7094 output_dead_lock_vect_name (f
, automaton
)
7096 automaton_t automaton
;
7098 if (automaton
->corresponding_automaton_decl
== NULL
)
7099 fprintf (f
, "dead_lock_%d", automaton
->automaton_order_num
);
7101 fprintf (f
, "%s_dead_lock", automaton
->corresponding_automaton_decl
->name
);
7104 /* Output name of reserved units table for AUTOMATON into file F. */
7106 output_reserved_units_table_name (f
, automaton
)
7108 automaton_t automaton
;
7110 if (automaton
->corresponding_automaton_decl
== NULL
)
7111 fprintf (f
, "reserved_units_%d", automaton
->automaton_order_num
);
7113 fprintf (f
, "%s_reserved_units",
7114 automaton
->corresponding_automaton_decl
->name
);
7117 /* Name of the PHR interface macro. */
7118 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7120 /* Name of the PHR interface macro. */
7121 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7123 /* Names of an internal functions: */
7124 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7126 /* This is external type of DFA(s) state. */
7127 #define STATE_TYPE_NAME "state_t"
7129 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7131 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7133 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7135 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7137 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7139 /* Name of cache of insn dfa codes. */
7140 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7142 /* Name of length of cache of insn dfa codes. */
7143 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7145 /* Names of the PHR interface functions: */
7146 #define SIZE_FUNC_NAME "state_size"
7148 #define TRANSITION_FUNC_NAME "state_transition"
7150 #define STATE_ALTS_FUNC_NAME "state_alts"
7152 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7154 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7156 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7158 #define RESET_FUNC_NAME "state_reset"
7160 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7162 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7164 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7166 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7168 #define DFA_START_FUNC_NAME "dfa_start"
7170 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7172 /* Names of parameters of the PHR interface functions. */
7173 #define STATE_NAME "state"
7175 #define INSN_PARAMETER_NAME "insn"
7177 #define INSN2_PARAMETER_NAME "insn2"
7179 #define CHIP_PARAMETER_NAME "chip"
7181 #define FILE_PARAMETER_NAME "f"
7183 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7185 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7187 /* Names of the variables whose values are internal insn code of rtx
7189 #define INTERNAL_INSN_CODE_NAME "insn_code"
7191 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7193 /* Names of temporary variables in some functions. */
7194 #define TEMPORARY_VARIABLE_NAME "temp"
7196 #define I_VARIABLE_NAME "i"
7198 /* Name of result variable in some functions. */
7199 #define RESULT_VARIABLE_NAME "res"
7201 /* Name of function (attribute) to translate insn into number of insn
7202 alternatives reservation. */
7203 #define INSN_ALTS_FUNC_NAME "insn_alts"
7205 /* Name of function (attribute) to translate insn into internal insn
7207 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7209 /* Name of function (attribute) to translate insn into internal insn
7210 code with caching. */
7211 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7213 /* Name of function (attribute) to translate insn into internal insn
7215 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7217 /* Name of function (attribute) to translate insn into internal insn
7219 #define BYPASS_P_FUNC_NAME "bypass_p"
7221 /* Output C type which is used for representation of codes of states
7224 output_state_member_type (f
, automaton
)
7226 automaton_t automaton
;
7228 output_range_type (f
, 0, automaton
->achieved_states_num
);
7231 /* Output definition of the structure representing current DFA(s)
7234 output_chip_definitions ()
7236 automaton_t automaton
;
7238 fprintf (output_file
, "struct %s\n{\n", CHIP_NAME
);
7239 for (automaton
= description
->first_automaton
;
7241 automaton
= automaton
->next_automaton
)
7243 fprintf (output_file
, " ");
7244 output_state_member_type (output_file
, automaton
);
7245 fprintf (output_file
, " ");
7246 output_chip_member_name (output_file
, automaton
);
7247 fprintf (output_file
, ";\n");
7249 fprintf (output_file
, "};\n\n");
7251 fprintf (output_file
, "static struct %s %s;\n\n", CHIP_NAME
, CHIP_NAME
);
7256 /* The function outputs translate vector of internal insn code into
7257 insn equivalence class number. The equivalence class number is
7258 used to access to table and vectors reprewsenting DFA(s). */
7260 output_translate_vect (automaton
)
7261 automaton_t automaton
;
7265 vla_hwint_t translate_vect
;
7267 VLA_HWINT_CREATE (translate_vect
, 250, "translate vector");
7268 VLA_HWINT_EXPAND (translate_vect
, description
->insns_num
);
7269 for (insn_value
= 0; insn_value
<= description
->insns_num
; insn_value
++)
7270 /* Undefined value */
7271 VLA_HWINT (translate_vect
, insn_value
) = automaton
->insn_equiv_classes_num
;
7272 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7273 VLA_HWINT (translate_vect
, ainsn
->insn_reserv_decl
->insn_num
)
7274 = ainsn
->insn_equiv_class_num
;
7275 fprintf (output_file
,
7276 "/* Vector translating external insn codes to internal ones.*/\n");
7277 fprintf (output_file
, "static const ");
7278 output_range_type (output_file
, 0, automaton
->insn_equiv_classes_num
);
7279 fprintf (output_file
, " ");
7280 output_translate_vect_name (output_file
, automaton
);
7281 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7282 output_vect (VLA_HWINT_BEGIN (translate_vect
),
7283 VLA_HWINT_LENGTH (translate_vect
));
7284 fprintf (output_file
, "};\n\n");
7285 VLA_HWINT_DELETE (translate_vect
);
7288 /* The value in a table state x ainsn -> something which represents
7290 static int undefined_vect_el_value
;
7292 /* The following function returns nonzero value if the best
7293 representation of the table is comb vector. */
7296 state_ainsn_table_t tab
;
7298 return (2 * VLA_HWINT_LENGTH (tab
->full_vect
)
7299 > 5 * VLA_HWINT_LENGTH (tab
->comb_vect
));
7302 /* The following function creates new table for AUTOMATON. */
7303 static state_ainsn_table_t
7304 create_state_ainsn_table (automaton
)
7305 automaton_t automaton
;
7307 state_ainsn_table_t tab
;
7308 int full_vect_length
;
7311 tab
= create_node (sizeof (struct state_ainsn_table
));
7312 tab
->automaton
= automaton
;
7313 VLA_HWINT_CREATE (tab
->comb_vect
, 10000, "comb vector");
7314 VLA_HWINT_CREATE (tab
->check_vect
, 10000, "check vector");
7315 VLA_HWINT_CREATE (tab
->base_vect
, 1000, "base vector");
7316 VLA_HWINT_EXPAND (tab
->base_vect
, automaton
->achieved_states_num
);
7317 VLA_HWINT_CREATE (tab
->full_vect
, 10000, "full vector");
7318 full_vect_length
= (automaton
->insn_equiv_classes_num
7319 * automaton
->achieved_states_num
);
7320 VLA_HWINT_EXPAND (tab
->full_vect
, full_vect_length
);
7321 for (i
= 0; i
< full_vect_length
; i
++)
7322 VLA_HWINT (tab
->full_vect
, i
) = undefined_vect_el_value
;
7323 tab
->min_base_vect_el_value
= 0;
7324 tab
->max_base_vect_el_value
= 0;
7325 tab
->min_comb_vect_el_value
= 0;
7326 tab
->max_comb_vect_el_value
= 0;
7330 /* The following function outputs the best C representation of the
7331 table TAB of given TABLE_NAME. */
7333 output_state_ainsn_table (tab
, table_name
, output_full_vect_name_func
,
7334 output_comb_vect_name_func
,
7335 output_check_vect_name_func
,
7336 output_base_vect_name_func
)
7337 state_ainsn_table_t tab
;
7339 void (*output_full_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7340 void (*output_comb_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7341 void (*output_check_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7342 void (*output_base_vect_name_func
) PARAMS ((FILE *, automaton_t
));
7344 if (!comb_vect_p (tab
))
7346 fprintf (output_file
, "/* Vector for %s. */\n", table_name
);
7347 fprintf (output_file
, "static const ");
7348 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7349 tab
->max_comb_vect_el_value
);
7350 fprintf (output_file
, " ");
7351 (*output_full_vect_name_func
) (output_file
, tab
->automaton
);
7352 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7353 output_vect (VLA_HWINT_BEGIN (tab
->full_vect
),
7354 VLA_HWINT_LENGTH (tab
->full_vect
));
7355 fprintf (output_file
, "};\n\n");
7359 fprintf (output_file
, "/* Comb vector for %s. */\n", table_name
);
7360 fprintf (output_file
, "static const ");
7361 output_range_type (output_file
, tab
->min_comb_vect_el_value
,
7362 tab
->max_comb_vect_el_value
);
7363 fprintf (output_file
, " ");
7364 (*output_comb_vect_name_func
) (output_file
, tab
->automaton
);
7365 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7366 output_vect (VLA_HWINT_BEGIN (tab
->comb_vect
),
7367 VLA_HWINT_LENGTH (tab
->comb_vect
));
7368 fprintf (output_file
, "};\n\n");
7369 fprintf (output_file
, "/* Check vector for %s. */\n", table_name
);
7370 fprintf (output_file
, "static const ");
7371 output_range_type (output_file
, 0, tab
->automaton
->achieved_states_num
);
7372 fprintf (output_file
, " ");
7373 (*output_check_vect_name_func
) (output_file
, tab
->automaton
);
7374 fprintf (output_file
, "[] = {\n");
7375 output_vect (VLA_HWINT_BEGIN (tab
->check_vect
),
7376 VLA_HWINT_LENGTH (tab
->check_vect
));
7377 fprintf (output_file
, "};\n\n");
7378 fprintf (output_file
, "/* Base vector for %s. */\n", table_name
);
7379 fprintf (output_file
, "static const ");
7380 output_range_type (output_file
, tab
->min_base_vect_el_value
,
7381 tab
->max_base_vect_el_value
);
7382 fprintf (output_file
, " ");
7383 (*output_base_vect_name_func
) (output_file
, tab
->automaton
);
7384 fprintf (output_file
, "[] = {\n");
7385 output_vect (VLA_HWINT_BEGIN (tab
->base_vect
),
7386 VLA_HWINT_LENGTH (tab
->base_vect
));
7387 fprintf (output_file
, "};\n\n");
7391 /* The following function adds vector with length VECT_LENGTH and
7392 elements pointed by VECT to table TAB as its line with number
7395 add_vect (tab
, vect_num
, vect
, vect_length
)
7396 state_ainsn_table_t tab
;
7401 int real_vect_length
;
7402 vect_el_t
*comb_vect_start
;
7403 vect_el_t
*check_vect_start
;
7404 int comb_vect_index
;
7405 int comb_vect_els_num
;
7407 int first_unempty_vect_index
;
7408 int additional_els_num
;
7413 if (vect_length
== 0)
7415 real_vect_length
= tab
->automaton
->insn_equiv_classes_num
;
7416 if (vect
[vect_length
- 1] == undefined_vect_el_value
)
7418 /* Form full vector in the table: */
7419 for (i
= 0; i
< vect_length
; i
++)
7420 VLA_HWINT (tab
->full_vect
,
7421 i
+ tab
->automaton
->insn_equiv_classes_num
* vect_num
)
7423 /* Form comb vector in the table: */
7424 if (VLA_HWINT_LENGTH (tab
->comb_vect
) != VLA_HWINT_LENGTH (tab
->check_vect
))
7426 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7427 comb_vect_els_num
= VLA_HWINT_LENGTH (tab
->comb_vect
);
7428 for (first_unempty_vect_index
= 0;
7429 first_unempty_vect_index
< vect_length
;
7430 first_unempty_vect_index
++)
7431 if (vect
[first_unempty_vect_index
] != undefined_vect_el_value
)
7433 /* Search for the place in comb vect for the inserted vect. */
7434 for (comb_vect_index
= 0;
7435 comb_vect_index
< comb_vect_els_num
;
7438 for (vect_index
= first_unempty_vect_index
;
7439 vect_index
< vect_length
7440 && vect_index
+ comb_vect_index
< comb_vect_els_num
;
7442 if (vect
[vect_index
] != undefined_vect_el_value
7443 && (comb_vect_start
[vect_index
+ comb_vect_index
]
7444 != undefined_vect_el_value
))
7446 if (vect_index
>= vect_length
7447 || vect_index
+ comb_vect_index
>= comb_vect_els_num
)
7450 /* Slot was found. */
7451 additional_els_num
= comb_vect_index
+ real_vect_length
- comb_vect_els_num
;
7452 if (additional_els_num
< 0)
7453 additional_els_num
= 0;
7454 /* Expand comb and check vectors. */
7455 vect_el
= undefined_vect_el_value
;
7456 no_state_value
= tab
->automaton
->achieved_states_num
;
7457 while (additional_els_num
> 0)
7459 VLA_HWINT_ADD (tab
->comb_vect
, vect_el
);
7460 VLA_HWINT_ADD (tab
->check_vect
, no_state_value
);
7461 additional_els_num
--;
7463 comb_vect_start
= VLA_HWINT_BEGIN (tab
->comb_vect
);
7464 check_vect_start
= VLA_HWINT_BEGIN (tab
->check_vect
);
7465 if (VLA_HWINT_LENGTH (tab
->comb_vect
)
7466 < (size_t) (comb_vect_index
+ real_vect_length
))
7468 /* Fill comb and check vectors. */
7469 for (vect_index
= 0; vect_index
< vect_length
; vect_index
++)
7470 if (vect
[vect_index
] != undefined_vect_el_value
)
7472 if (comb_vect_start
[comb_vect_index
+ vect_index
]
7473 != undefined_vect_el_value
)
7475 comb_vect_start
[comb_vect_index
+ vect_index
] = vect
[vect_index
];
7476 if (vect
[vect_index
] < 0)
7478 if (tab
->max_comb_vect_el_value
< vect
[vect_index
])
7479 tab
->max_comb_vect_el_value
= vect
[vect_index
];
7480 if (tab
->min_comb_vect_el_value
> vect
[vect_index
])
7481 tab
->min_comb_vect_el_value
= vect
[vect_index
];
7482 check_vect_start
[comb_vect_index
+ vect_index
] = vect_num
;
7484 if (tab
->max_base_vect_el_value
< comb_vect_index
)
7485 tab
->max_base_vect_el_value
= comb_vect_index
;
7486 if (tab
->min_base_vect_el_value
> comb_vect_index
)
7487 tab
->min_base_vect_el_value
= comb_vect_index
;
7488 VLA_HWINT (tab
->base_vect
, vect_num
) = comb_vect_index
;
7491 /* Return number of out arcs of STATE. */
7493 out_state_arcs_num (state
)
7500 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7502 if (arc
->insn
== NULL
)
7504 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7510 /* Compare number of possible transitions from the states. */
7512 compare_transition_els_num (state_ptr_1
, state_ptr_2
)
7513 const void *state_ptr_1
;
7514 const void *state_ptr_2
;
7516 int transition_els_num_1
;
7517 int transition_els_num_2
;
7519 transition_els_num_1
= out_state_arcs_num (*(state_t
*) state_ptr_1
);
7520 transition_els_num_2
= out_state_arcs_num (*(state_t
*) state_ptr_2
);
7521 if (transition_els_num_1
< transition_els_num_2
)
7523 else if (transition_els_num_1
== transition_els_num_2
)
7529 /* The function adds element EL_VALUE to vector VECT for a table state
7532 add_vect_el (vect
, ainsn
, el_value
)
7537 int equiv_class_num
;
7542 equiv_class_num
= ainsn
->insn_equiv_class_num
;
7543 for (vect_index
= VLA_HWINT_LENGTH (*vect
);
7544 vect_index
<= equiv_class_num
;
7546 VLA_HWINT_ADD (*vect
, undefined_vect_el_value
);
7547 VLA_HWINT (*vect
, equiv_class_num
) = el_value
;
7550 /* This is for forming vector of states of an automaton. */
7551 static vla_ptr_t output_states_vect
;
7553 /* The function is called by function pass_states. The function adds
7554 STATE to `output_states_vect'. */
7556 add_states_vect_el (state
)
7559 VLA_PTR_ADD (output_states_vect
, state
);
7562 /* Form and output vectors (comb, check, base or full vector)
7563 representing transition table of AUTOMATON. */
7565 output_trans_table (automaton
)
7566 automaton_t automaton
;
7570 vla_hwint_t transition_vect
;
7572 undefined_vect_el_value
= automaton
->achieved_states_num
;
7573 automaton
->trans_table
= create_state_ainsn_table (automaton
);
7574 /* Create vect of pointers to states ordered by num of transitions
7575 from the state (state with the maximum num is the first). */
7576 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7577 pass_states (automaton
, add_states_vect_el
);
7578 qsort (VLA_PTR_BEGIN (output_states_vect
),
7579 VLA_PTR_LENGTH (output_states_vect
),
7580 sizeof (state_t
), compare_transition_els_num
);
7581 VLA_HWINT_CREATE (transition_vect
, 500, "transition vector");
7582 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7583 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7586 VLA_HWINT_NULLIFY (transition_vect
);
7587 for (arc
= first_out_arc (*state_ptr
);
7589 arc
= next_out_arc (arc
))
7591 if (arc
->insn
== NULL
)
7593 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7594 add_vect_el (&transition_vect
, arc
->insn
,
7595 arc
->to_state
->order_state_num
);
7597 add_vect (automaton
->trans_table
, (*state_ptr
)->order_state_num
,
7598 VLA_HWINT_BEGIN (transition_vect
),
7599 VLA_HWINT_LENGTH (transition_vect
));
7601 output_state_ainsn_table
7602 (automaton
->trans_table
, (char *) "state transitions",
7603 output_trans_full_vect_name
, output_trans_comb_vect_name
,
7604 output_trans_check_vect_name
, output_trans_base_vect_name
);
7605 VLA_PTR_DELETE (output_states_vect
);
7606 VLA_HWINT_DELETE (transition_vect
);
7609 /* Form and output vectors (comb, check, base or simple vect)
7610 representing alts number table of AUTOMATON. The table is state x
7611 ainsn -> number of possible alternative reservations by the
7614 output_state_alts_table (automaton
)
7615 automaton_t automaton
;
7619 vla_hwint_t state_alts_vect
;
7621 undefined_vect_el_value
= 0; /* no alts when transition is not possible */
7622 automaton
->state_alts_table
= create_state_ainsn_table (automaton
);
7623 /* Create vect of pointers to states ordered by num of transitions
7624 from the state (state with the maximum num is the first). */
7625 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7626 pass_states (automaton
, add_states_vect_el
);
7627 qsort (VLA_PTR_BEGIN (output_states_vect
),
7628 VLA_PTR_LENGTH (output_states_vect
),
7629 sizeof (state_t
), compare_transition_els_num
);
7630 /* Create base, comb, and check vectors. */
7631 VLA_HWINT_CREATE (state_alts_vect
, 500, "state alts vector");
7632 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7633 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7636 VLA_HWINT_NULLIFY (state_alts_vect
);
7637 for (arc
= first_out_arc (*state_ptr
);
7639 arc
= next_out_arc (arc
))
7641 if (arc
->insn
== NULL
)
7643 if (arc
->insn
->first_ainsn_with_given_equialence_num
)
7644 add_vect_el (&state_alts_vect
, arc
->insn
, arc
->state_alts
);
7646 add_vect (automaton
->state_alts_table
, (*state_ptr
)->order_state_num
,
7647 VLA_HWINT_BEGIN (state_alts_vect
),
7648 VLA_HWINT_LENGTH (state_alts_vect
));
7650 output_state_ainsn_table
7651 (automaton
->state_alts_table
, (char *) "state insn alternatives",
7652 output_state_alts_full_vect_name
, output_state_alts_comb_vect_name
,
7653 output_state_alts_check_vect_name
, output_state_alts_base_vect_name
);
7654 VLA_PTR_DELETE (output_states_vect
);
7655 VLA_HWINT_DELETE (state_alts_vect
);
7658 /* The current number of passing states to find minimal issue delay
7659 value for an ainsn and state. */
7660 static int curr_state_pass_num
;
7663 /* This recursive function passes states to find minimal issue delay
7664 value for AINSN. The state being visited is STATE. The function
7665 returns minimal issue delay value for AINSN in STATE or -1 if we
7666 enter into a loop. */
7668 min_issue_delay_pass_states (state
, ainsn
)
7673 int min_insn_issue_delay
, insn_issue_delay
;
7675 if (state
->state_pass_num
== curr_state_pass_num
7676 || state
->min_insn_issue_delay
!= -1)
7677 /* We've entered into a loop or already have the correct value for
7678 given state and ainsn. */
7679 return state
->min_insn_issue_delay
;
7680 state
->state_pass_num
= curr_state_pass_num
;
7681 min_insn_issue_delay
= -1;
7682 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
7683 if (arc
->insn
== ainsn
)
7685 min_insn_issue_delay
= 0;
7690 insn_issue_delay
= min_issue_delay_pass_states (arc
->to_state
, ainsn
);
7691 if (insn_issue_delay
!= -1)
7693 if (arc
->insn
->insn_reserv_decl
7694 == DECL_INSN_RESERV (advance_cycle_insn_decl
))
7696 if (min_insn_issue_delay
== -1
7697 || min_insn_issue_delay
> insn_issue_delay
)
7699 min_insn_issue_delay
= insn_issue_delay
;
7700 if (insn_issue_delay
== 0)
7705 return min_insn_issue_delay
;
7708 /* The function searches minimal issue delay value for AINSN in STATE.
7709 The function can return negative value if we can not issue AINSN. We
7710 will report about it later. */
7712 min_issue_delay (state
, ainsn
)
7716 curr_state_pass_num
++;
7717 state
->min_insn_issue_delay
= min_issue_delay_pass_states (state
, ainsn
);
7718 return state
->min_insn_issue_delay
;
7721 /* The function initiates code for finding minimal issue delay values.
7722 It should be called only once. */
7724 initiate_min_issue_delay_pass_states ()
7726 curr_state_pass_num
= 0;
7729 /* Form and output vectors representing minimal issue delay table of
7730 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7733 output_min_issue_delay_table (automaton
)
7734 automaton_t automaton
;
7736 vla_hwint_t min_issue_delay_vect
;
7737 vla_hwint_t compressed_min_issue_delay_vect
;
7738 vect_el_t min_delay
;
7743 /* Create vect of pointers to states ordered by num of transitions
7744 from the state (state with the maximum num is the first). */
7745 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7746 pass_states (automaton
, add_states_vect_el
);
7747 VLA_HWINT_CREATE (min_issue_delay_vect
, 1500, "min issue delay vector");
7748 VLA_HWINT_EXPAND (min_issue_delay_vect
,
7749 VLA_HWINT_LENGTH (output_states_vect
)
7750 * automaton
->insn_equiv_classes_num
);
7752 i
< ((int) VLA_HWINT_LENGTH (output_states_vect
)
7753 * automaton
->insn_equiv_classes_num
);
7755 VLA_HWINT (min_issue_delay_vect
, i
) = 0;
7756 automaton
->max_min_delay
= 0;
7757 for (ainsn
= automaton
->ainsn_list
; ainsn
!= NULL
; ainsn
= ainsn
->next_ainsn
)
7758 if (ainsn
->first_ainsn_with_given_equialence_num
)
7760 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7761 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7763 (*state_ptr
)->min_insn_issue_delay
= -1;
7764 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7765 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7768 min_delay
= min_issue_delay (*state_ptr
, ainsn
);
7769 if (automaton
->max_min_delay
< min_delay
)
7770 automaton
->max_min_delay
= min_delay
;
7771 VLA_HWINT (min_issue_delay_vect
,
7772 (*state_ptr
)->order_state_num
7773 * automaton
->insn_equiv_classes_num
7774 + ainsn
->insn_equiv_class_num
) = min_delay
;
7777 fprintf (output_file
, "/* Vector of min issue delay of insns.*/\n");
7778 fprintf (output_file
, "static const ");
7779 output_range_type (output_file
, 0, automaton
->max_min_delay
);
7780 fprintf (output_file
, " ");
7781 output_min_issue_delay_vect_name (output_file
, automaton
);
7782 fprintf (output_file
, "[] ATTRIBUTE_UNUSED = {\n");
7783 /* Compress the vector */
7784 if (automaton
->max_min_delay
< 2)
7785 automaton
->min_issue_delay_table_compression_factor
= 8;
7786 else if (automaton
->max_min_delay
< 4)
7787 automaton
->min_issue_delay_table_compression_factor
= 4;
7788 else if (automaton
->max_min_delay
< 16)
7789 automaton
->min_issue_delay_table_compression_factor
= 2;
7791 automaton
->min_issue_delay_table_compression_factor
= 1;
7792 VLA_HWINT_CREATE (compressed_min_issue_delay_vect
, 1500,
7793 "compressed min issue delay vector");
7794 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect
,
7795 (VLA_HWINT_LENGTH (min_issue_delay_vect
)
7796 + automaton
->min_issue_delay_table_compression_factor
7798 / automaton
->min_issue_delay_table_compression_factor
);
7800 i
< (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
);
7802 VLA_HWINT (compressed_min_issue_delay_vect
, i
) = 0;
7803 for (i
= 0; i
< (int) VLA_HWINT_LENGTH (min_issue_delay_vect
); i
++)
7804 VLA_HWINT (compressed_min_issue_delay_vect
,
7805 i
/ automaton
->min_issue_delay_table_compression_factor
)
7806 |= (VLA_HWINT (min_issue_delay_vect
, i
)
7807 << (8 - (i
% automaton
->min_issue_delay_table_compression_factor
7809 * (8 / automaton
->min_issue_delay_table_compression_factor
)));
7810 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect
),
7811 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect
));
7812 fprintf (output_file
, "};\n\n");
7813 VLA_PTR_DELETE (output_states_vect
);
7814 VLA_HWINT_DELETE (min_issue_delay_vect
);
7815 VLA_HWINT_DELETE (compressed_min_issue_delay_vect
);
7819 /* Number of states which contains transition only by advancing cpu
7821 static int locked_states_num
;
7824 /* Form and output vector representing the locked states of
7827 output_dead_lock_vect (automaton
)
7828 automaton_t automaton
;
7832 vla_hwint_t dead_lock_vect
;
7834 /* Create vect of pointers to states ordered by num of
7835 transitions from the state (state with the maximum num is the
7837 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7838 pass_states (automaton
, add_states_vect_el
);
7839 VLA_HWINT_CREATE (dead_lock_vect
, 1500, "is dead locked vector");
7840 VLA_HWINT_EXPAND (dead_lock_vect
, VLA_HWINT_LENGTH (output_states_vect
));
7841 for (state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7842 state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7845 arc
= first_out_arc (*state_ptr
);
7848 VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
)
7849 = (next_out_arc (arc
) == NULL
7850 && (arc
->insn
->insn_reserv_decl
7851 == DECL_INSN_RESERV (advance_cycle_insn_decl
)) ? 1 : 0);
7853 if (VLA_HWINT (dead_lock_vect
, (*state_ptr
)->order_state_num
))
7854 locked_states_num
++;
7857 fprintf (output_file
, "/* Vector for locked state flags. */\n");
7858 fprintf (output_file
, "static const ");
7859 output_range_type (output_file
, 0, 1);
7860 fprintf (output_file
, " ");
7861 output_dead_lock_vect_name (output_file
, automaton
);
7862 fprintf (output_file
, "[] = {\n");
7863 output_vect (VLA_HWINT_BEGIN (dead_lock_vect
),
7864 VLA_HWINT_LENGTH (dead_lock_vect
));
7865 fprintf (output_file
, "};\n\n");
7866 VLA_HWINT_DELETE (dead_lock_vect
);
7867 VLA_PTR_DELETE (output_states_vect
);
7870 /* Form and output vector representing reserved units of the states of
7873 output_reserved_units_table (automaton
)
7874 automaton_t automaton
;
7876 state_t
*curr_state_ptr
;
7877 vla_hwint_t reserved_units_table
;
7878 size_t state_byte_size
;
7881 /* Create vect of pointers to states. */
7882 VLA_PTR_CREATE (output_states_vect
, 1500, "output states vector");
7883 pass_states (automaton
, add_states_vect_el
);
7884 /* Create vector. */
7885 VLA_HWINT_CREATE (reserved_units_table
, 1500, "reserved units vector");
7886 state_byte_size
= (description
->query_units_num
+ 7) / 8;
7887 VLA_HWINT_EXPAND (reserved_units_table
,
7888 VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7890 i
< (int) (VLA_HWINT_LENGTH (output_states_vect
) * state_byte_size
);
7892 VLA_HWINT (reserved_units_table
, i
) = 0;
7893 for (curr_state_ptr
= VLA_PTR_BEGIN (output_states_vect
);
7894 curr_state_ptr
<= (state_t
*) VLA_PTR_LAST (output_states_vect
);
7897 for (i
= 0; i
< description
->units_num
; i
++)
7898 if (units_array
[i
]->query_p
)
7900 if (test_unit_reserv ((*curr_state_ptr
)->reservs
, 0, i
))
7901 VLA_HWINT (reserved_units_table
,
7902 (*curr_state_ptr
)->order_state_num
* state_byte_size
7903 + units_array
[i
]->query_num
/ 8)
7904 += (1 << (units_array
[i
]->query_num
% 8));
7907 fprintf (output_file
, "/* Vector for reserved units of states. */\n");
7908 fprintf (output_file
, "static const ");
7909 output_range_type (output_file
, 0, 255);
7910 fprintf (output_file
, " ");
7911 output_reserved_units_table_name (output_file
, automaton
);
7912 fprintf (output_file
, "[] = {\n");
7913 output_vect (VLA_HWINT_BEGIN (reserved_units_table
),
7914 VLA_HWINT_LENGTH (reserved_units_table
));
7915 fprintf (output_file
, "};\n\n");
7916 VLA_HWINT_DELETE (reserved_units_table
);
7917 VLA_PTR_DELETE (output_states_vect
);
7920 /* The function outputs all tables representing DFA(s) used for fast
7921 pipeline hazards recognition. */
7925 automaton_t automaton
;
7928 locked_states_num
= 0;
7930 initiate_min_issue_delay_pass_states ();
7931 for (automaton
= description
->first_automaton
;
7933 automaton
= automaton
->next_automaton
)
7935 output_translate_vect (automaton
);
7936 output_trans_table (automaton
);
7937 fprintf (output_file
, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
7938 output_state_alts_table (automaton
);
7939 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7940 AUTOMATON_STATE_ALTS_MACRO_NAME
);
7941 output_min_issue_delay_table (automaton
);
7942 output_dead_lock_vect (automaton
);
7943 if (no_minimization_flag
)
7945 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
7946 output_reserved_units_table (automaton
);
7947 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
7948 CPU_UNITS_QUERY_MACRO_NAME
);
7951 fprintf (output_file
, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME
,
7952 DECL_INSN_RESERV (advance_cycle_insn_decl
)->insn_num
);
7955 /* The function outputs definition and value of PHR interface variable
7956 `max_insn_queue_index'. Its value is not less than maximal queue
7957 length needed for the insn scheduler. */
7959 output_max_insn_queue_index_def ()
7961 int i
, max
, latency
;
7964 max
= description
->max_insn_reserv_cycles
;
7965 for (i
= 0; i
< description
->decls_num
; i
++)
7967 decl
= description
->decls
[i
];
7968 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
7970 latency
= DECL_INSN_RESERV (decl
)->default_latency
;
7974 else if (decl
->mode
== dm_bypass
)
7976 latency
= DECL_BYPASS (decl
)->latency
;
7981 for (i
= 0; (1 << i
) <= max
; i
++)
7985 fprintf (output_file
, "\nint max_insn_queue_index = %d;\n\n", (1 << i
) - 1);
7989 /* The function outputs switch cases for insn reseravtions using
7990 function *output_automata_list_code. */
7992 output_insn_code_cases (output_automata_list_code
)
7993 void (*output_automata_list_code
) (automata_list_el_t
);
7998 for (i
= 0; i
< description
->decls_num
; i
++)
8000 decl
= description
->decls
[i
];
8001 if (decl
->mode
== dm_insn_reserv
)
8002 DECL_INSN_RESERV (decl
)->processed_p
= FALSE
;
8004 for (i
= 0; i
< description
->decls_num
; i
++)
8006 decl
= description
->decls
[i
];
8007 if (decl
->mode
== dm_insn_reserv
8008 && !DECL_INSN_RESERV (decl
)->processed_p
)
8010 for (j
= i
; j
< description
->decls_num
; j
++)
8012 decl2
= description
->decls
[j
];
8013 if (decl2
->mode
== dm_insn_reserv
8014 && (DECL_INSN_RESERV (decl2
)->important_automata_list
8015 == DECL_INSN_RESERV (decl
)->important_automata_list
))
8017 DECL_INSN_RESERV (decl2
)->processed_p
= TRUE
;
8018 fprintf (output_file
, " case %d: /* %s */\n",
8019 DECL_INSN_RESERV (decl2
)->insn_num
,
8020 DECL_INSN_RESERV (decl2
)->name
);
8023 (*output_automata_list_code
)
8024 (DECL_INSN_RESERV (decl
)->important_automata_list
);
8030 /* The function outputs a code for evaluation of a minimal delay of
8031 issue of insns which have reservations in given AUTOMATA_LIST. */
8033 output_automata_list_min_issue_delay_code (automata_list
)
8034 automata_list_el_t automata_list
;
8036 automata_list_el_t el
;
8037 automaton_t automaton
;
8039 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8041 automaton
= el
->automaton
;
8042 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8043 output_min_issue_delay_vect_name (output_file
, automaton
);
8044 fprintf (output_file
,
8045 (automaton
->min_issue_delay_table_compression_factor
!= 1
8047 output_translate_vect_name (output_file
, automaton
);
8048 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8049 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8050 output_chip_member_name (output_file
, automaton
);
8051 fprintf (output_file
, " * %d", automaton
->insn_equiv_classes_num
);
8052 if (automaton
->min_issue_delay_table_compression_factor
== 1)
8053 fprintf (output_file
, "];\n");
8056 fprintf (output_file
, ") / %d];\n",
8057 automaton
->min_issue_delay_table_compression_factor
);
8058 fprintf (output_file
, " %s = (%s >> (8 - (",
8059 TEMPORARY_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8060 output_translate_vect_name (output_file
, automaton
);
8062 (output_file
, " [%s] %% %d + 1) * %d)) & %d;\n",
8063 INTERNAL_INSN_CODE_NAME
,
8064 automaton
->min_issue_delay_table_compression_factor
,
8065 8 / automaton
->min_issue_delay_table_compression_factor
,
8066 (1 << (8 / automaton
->min_issue_delay_table_compression_factor
))
8069 if (el
== automata_list
)
8070 fprintf (output_file
, " %s = %s;\n",
8071 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8074 fprintf (output_file
, " if (%s > %s)\n",
8075 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8076 fprintf (output_file
, " %s = %s;\n",
8077 RESULT_VARIABLE_NAME
, TEMPORARY_VARIABLE_NAME
);
8080 fprintf (output_file
, " break;\n\n");
8083 /* Output function `internal_min_issue_delay'. */
8085 output_internal_min_issue_delay_func ()
8087 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8088 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, CHIP_NAME
);
8089 fprintf (output_file
,
8090 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8091 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8092 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8093 CHIP_PARAMETER_NAME
);
8094 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8095 TEMPORARY_VARIABLE_NAME
, RESULT_VARIABLE_NAME
);
8096 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8097 output_insn_code_cases (output_automata_list_min_issue_delay_code
);
8098 fprintf (output_file
,
8099 "\n default:\n %s = -1;\n break;\n }\n",
8100 RESULT_VARIABLE_NAME
);
8101 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8102 fprintf (output_file
, "}\n\n");
8105 /* The function outputs a code changing state after issue of insns
8106 which have reservations in given AUTOMATA_LIST. */
8108 output_automata_list_transition_code (automata_list
)
8109 automata_list_el_t automata_list
;
8111 automata_list_el_t el
, next_el
;
8113 fprintf (output_file
, " {\n");
8114 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8115 for (el
= automata_list
;; el
= next_el
)
8117 next_el
= el
->next_automata_list_el
;
8118 if (next_el
== NULL
)
8120 fprintf (output_file
, " ");
8121 output_state_member_type (output_file
, el
->automaton
);
8122 fprintf (output_file
, " ");
8123 output_temp_chip_member_name (output_file
, el
->automaton
);
8124 fprintf (output_file
, ";\n");
8126 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8127 if (comb_vect_p (el
->automaton
->trans_table
))
8129 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8130 output_trans_base_vect_name (output_file
, el
->automaton
);
8131 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8132 output_chip_member_name (output_file
, el
->automaton
);
8133 fprintf (output_file
, "] + ");
8134 output_translate_vect_name (output_file
, el
->automaton
);
8135 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8136 fprintf (output_file
, " if (");
8137 output_trans_check_vect_name (output_file
, el
->automaton
);
8138 fprintf (output_file
, " [%s] != %s->",
8139 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8140 output_chip_member_name (output_file
, el
->automaton
);
8141 fprintf (output_file
, ")\n");
8142 fprintf (output_file
, " return %s (%s, %s);\n",
8143 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8144 CHIP_PARAMETER_NAME
);
8145 fprintf (output_file
, " else\n");
8146 fprintf (output_file
, " ");
8147 if (el
->next_automata_list_el
!= NULL
)
8148 output_temp_chip_member_name (output_file
, el
->automaton
);
8151 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8152 output_chip_member_name (output_file
, el
->automaton
);
8154 fprintf (output_file
, " = ");
8155 output_trans_comb_vect_name (output_file
, el
->automaton
);
8156 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8160 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8161 output_trans_full_vect_name (output_file
, el
->automaton
);
8162 fprintf (output_file
, " [");
8163 output_translate_vect_name (output_file
, el
->automaton
);
8164 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8165 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8166 output_chip_member_name (output_file
, el
->automaton
);
8167 fprintf (output_file
, " * %d];\n",
8168 el
->automaton
->insn_equiv_classes_num
);
8169 fprintf (output_file
, " if (%s >= %d)\n",
8170 TEMPORARY_VARIABLE_NAME
, el
->automaton
->achieved_states_num
);
8171 fprintf (output_file
, " return %s (%s, %s);\n",
8172 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8173 CHIP_PARAMETER_NAME
);
8174 fprintf (output_file
, " else\n ");
8175 if (el
->next_automata_list_el
!= NULL
)
8176 output_temp_chip_member_name (output_file
, el
->automaton
);
8179 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8180 output_chip_member_name (output_file
, el
->automaton
);
8182 fprintf (output_file
, " = %s;\n", TEMPORARY_VARIABLE_NAME
);
8184 if (automata_list
!= NULL
&& automata_list
->next_automata_list_el
!= NULL
)
8185 for (el
= automata_list
;; el
= next_el
)
8187 next_el
= el
->next_automata_list_el
;
8188 if (next_el
== NULL
)
8190 fprintf (output_file
, " %s->", CHIP_PARAMETER_NAME
);
8191 output_chip_member_name (output_file
, el
->automaton
);
8192 fprintf (output_file
, " = ");
8193 output_temp_chip_member_name (output_file
, el
->automaton
);
8194 fprintf (output_file
, ";\n");
8196 fprintf (output_file
, " return -1;\n");
8197 fprintf (output_file
, " }\n");
8200 /* Output function `internal_state_transition'. */
8202 output_internal_trans_func ()
8204 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8205 INTERNAL_TRANSITION_FUNC_NAME
, CHIP_NAME
);
8206 fprintf (output_file
,
8207 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8208 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8209 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
,
8210 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8211 fprintf (output_file
, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME
);
8212 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8213 output_insn_code_cases (output_automata_list_transition_code
);
8214 fprintf (output_file
, "\n default:\n return -1;\n }\n");
8215 fprintf (output_file
, "}\n\n");
8222 insn_code = dfa_insn_code (insn);
8223 if (insn_code > DFA__ADVANCE_CYCLE)
8227 insn_code = DFA__ADVANCE_CYCLE;
8229 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8230 code denotes CODE. */
8232 output_internal_insn_code_evaluation (insn_name
, insn_code_name
, code
)
8233 const char *insn_name
;
8234 const char *insn_code_name
;
8237 fprintf (output_file
, "\n if (%s != 0)\n {\n", insn_name
);
8238 fprintf (output_file
, " %s = %s (%s);\n", insn_code_name
,
8239 DFA_INSN_CODE_FUNC_NAME
, insn_name
);
8240 fprintf (output_file
, " if (%s > %s)\n return %d;\n",
8241 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
, code
);
8242 fprintf (output_file
, " }\n else\n %s = %s;\n\n",
8243 insn_code_name
, ADVANCE_CYCLE_VALUE_NAME
);
8247 /* The function outputs function `dfa_insn_code'. */
8249 output_dfa_insn_code_func ()
8251 fprintf (output_file
, "#ifdef __GNUC__\n__inline__\n#endif\n");
8252 fprintf (output_file
, "static int %s PARAMS ((rtx));\n",
8253 DFA_INSN_CODE_FUNC_NAME
);
8254 fprintf (output_file
, "static int\n%s (%s)\n\trtx %s;\n",
8255 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN_PARAMETER_NAME
);
8256 fprintf (output_file
, "{\n int %s;\n int %s;\n\n",
8257 INTERNAL_INSN_CODE_NAME
, TEMPORARY_VARIABLE_NAME
);
8258 fprintf (output_file
, " if (INSN_UID (%s) >= %s)\n {\n",
8259 INSN_PARAMETER_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8260 fprintf (output_file
, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
8261 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8262 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, INSN_PARAMETER_NAME
);
8263 fprintf (output_file
, " %s = xrealloc (%s, %s * sizeof (int));\n",
8264 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8265 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8266 fprintf (output_file
,
8267 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
8268 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
,
8269 TEMPORARY_VARIABLE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8270 TEMPORARY_VARIABLE_NAME
);
8271 fprintf (output_file
, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
8272 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODES_VARIABLE_NAME
,
8273 INSN_PARAMETER_NAME
);
8274 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8275 INTERNAL_DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8276 fprintf (output_file
, " %s [INSN_UID (%s)] = %s;\n",
8277 DFA_INSN_CODES_VARIABLE_NAME
, INSN_PARAMETER_NAME
,
8278 INTERNAL_INSN_CODE_NAME
);
8279 fprintf (output_file
, " }\n return %s;\n}\n\n",
8280 INTERNAL_INSN_CODE_NAME
);
8283 /* The function outputs PHR interface function `state_transition'. */
8285 output_trans_func ()
8287 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8288 TRANSITION_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8289 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8290 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8291 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8292 INTERNAL_INSN_CODE_NAME
, -1);
8293 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8294 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8297 /* The function outputs a code for evaluation of alternative states
8298 number for insns which have reservations in given AUTOMATA_LIST. */
8300 output_automata_list_state_alts_code (automata_list
)
8301 automata_list_el_t automata_list
;
8303 automata_list_el_t el
;
8304 automaton_t automaton
;
8306 fprintf (output_file
, " {\n");
8307 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8308 if (comb_vect_p (el
->automaton
->state_alts_table
))
8310 fprintf (output_file
, " int %s;\n", TEMPORARY_VARIABLE_NAME
);
8313 for (el
= automata_list
; el
!= NULL
; el
= el
->next_automata_list_el
)
8315 automaton
= el
->automaton
;
8316 if (comb_vect_p (automaton
->state_alts_table
))
8318 fprintf (output_file
, "\n %s = ", TEMPORARY_VARIABLE_NAME
);
8319 output_state_alts_base_vect_name (output_file
, automaton
);
8320 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8321 output_chip_member_name (output_file
, automaton
);
8322 fprintf (output_file
, "] + ");
8323 output_translate_vect_name (output_file
, automaton
);
8324 fprintf (output_file
, " [%s];\n", INTERNAL_INSN_CODE_NAME
);
8325 fprintf (output_file
, " if (");
8326 output_state_alts_check_vect_name (output_file
, automaton
);
8327 fprintf (output_file
, " [%s] != %s->",
8328 TEMPORARY_VARIABLE_NAME
, CHIP_PARAMETER_NAME
);
8329 output_chip_member_name (output_file
, automaton
);
8330 fprintf (output_file
, ")\n");
8331 fprintf (output_file
, " return 0;\n");
8332 fprintf (output_file
, " else\n");
8333 fprintf (output_file
,
8334 (el
== automata_list
8335 ? " %s = " : " %s += "),
8336 RESULT_VARIABLE_NAME
);
8337 output_state_alts_comb_vect_name (output_file
, automaton
);
8338 fprintf (output_file
, " [%s];\n", TEMPORARY_VARIABLE_NAME
);
8342 fprintf (output_file
,
8343 (el
== automata_list
8344 ? "\n %s = " : " %s += "),
8345 RESULT_VARIABLE_NAME
);
8346 output_state_alts_full_vect_name (output_file
, automaton
);
8347 fprintf (output_file
, " [");
8348 output_translate_vect_name (output_file
, automaton
);
8349 fprintf (output_file
, " [%s] + ", INTERNAL_INSN_CODE_NAME
);
8350 fprintf (output_file
, "%s->", CHIP_PARAMETER_NAME
);
8351 output_chip_member_name (output_file
, automaton
);
8352 fprintf (output_file
, " * %d];\n",
8353 automaton
->insn_equiv_classes_num
);
8356 fprintf (output_file
, " break;\n }\n\n");
8359 /* Output function `internal_state_alts'. */
8361 output_internal_state_alts_func ()
8363 fprintf (output_file
, "static int %s PARAMS ((int, struct %s *));\n",
8364 INTERNAL_STATE_ALTS_FUNC_NAME
, CHIP_NAME
);
8365 fprintf (output_file
,
8366 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8367 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8368 CHIP_PARAMETER_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
,
8369 CHIP_PARAMETER_NAME
);
8370 fprintf (output_file
, "{\n int %s;\n", RESULT_VARIABLE_NAME
);
8371 fprintf (output_file
, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8372 output_insn_code_cases (output_automata_list_state_alts_code
);
8373 fprintf (output_file
,
8374 "\n default:\n %s = 0;\n break;\n }\n",
8375 RESULT_VARIABLE_NAME
);
8376 fprintf (output_file
, " return %s;\n", RESULT_VARIABLE_NAME
);
8377 fprintf (output_file
, "}\n\n");
8380 /* The function outputs PHR interface function `state_alts'. */
8382 output_state_alts_func ()
8384 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8385 STATE_ALTS_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8386 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8387 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8388 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8389 INTERNAL_INSN_CODE_NAME
, 0);
8390 fprintf (output_file
, " return %s (%s, %s);\n}\n\n",
8391 INTERNAL_STATE_ALTS_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, STATE_NAME
);
8394 /* Output function `min_issue_delay'. */
8396 output_min_issue_delay_func ()
8398 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8399 MIN_ISSUE_DELAY_FUNC_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
,
8400 STATE_TYPE_NAME
, STATE_NAME
, INSN_PARAMETER_NAME
);
8401 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8402 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8403 fprintf (output_file
, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME
,
8404 DFA_INSN_CODE_FUNC_NAME
, INSN_PARAMETER_NAME
);
8405 fprintf (output_file
, " if (%s > %s)\n return 0;\n",
8406 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8407 fprintf (output_file
, " }\n else\n %s = %s;\n",
8408 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8409 fprintf (output_file
, "\n return %s (%s, %s);\n",
8410 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8412 fprintf (output_file
, "}\n\n");
8415 /* Output function `internal_dead_lock'. */
8417 output_internal_dead_lock_func ()
8419 automaton_t automaton
;
8421 fprintf (output_file
, "static int %s PARAMS ((struct %s *));\n",
8422 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_NAME
);
8423 fprintf (output_file
, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8424 INTERNAL_DEAD_LOCK_FUNC_NAME
, CHIP_PARAMETER_NAME
, CHIP_NAME
,
8425 CHIP_PARAMETER_NAME
);
8426 fprintf (output_file
, "{\n");
8427 for (automaton
= description
->first_automaton
;
8429 automaton
= automaton
->next_automaton
)
8431 fprintf (output_file
, " if (");
8432 output_dead_lock_vect_name (output_file
, automaton
);
8433 fprintf (output_file
, " [%s->", CHIP_PARAMETER_NAME
);
8434 output_chip_member_name (output_file
, automaton
);
8435 fprintf (output_file
, "])\n return 1/* TRUE */;\n");
8437 fprintf (output_file
, " return 0/* FALSE */;\n}\n\n");
8440 /* The function outputs PHR interface function `state_dead_lock_p'. */
8442 output_dead_lock_func ()
8444 fprintf (output_file
, "int\n%s (%s)\n\t%s %s;\n",
8445 DEAD_LOCK_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8446 fprintf (output_file
, "{\n return %s (%s);\n}\n\n",
8447 INTERNAL_DEAD_LOCK_FUNC_NAME
, STATE_NAME
);
8450 /* Output function `internal_reset'. */
8452 output_internal_reset_func ()
8454 fprintf (output_file
, "static void %s PARAMS ((struct %s *));\n",
8455 INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8456 fprintf (output_file
, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8457 INTERNAL_RESET_FUNC_NAME
, CHIP_PARAMETER_NAME
,
8458 CHIP_NAME
, CHIP_PARAMETER_NAME
);
8459 fprintf (output_file
, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8460 CHIP_PARAMETER_NAME
, CHIP_NAME
);
8463 /* The function outputs PHR interface function `state_size'. */
8467 fprintf (output_file
, "int\n%s ()\n", SIZE_FUNC_NAME
);
8468 fprintf (output_file
, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME
);
8471 /* The function outputs PHR interface function `state_reset'. */
8473 output_reset_func ()
8475 fprintf (output_file
, "void\n%s (%s)\n\t %s %s;\n",
8476 RESET_FUNC_NAME
, STATE_NAME
, STATE_TYPE_NAME
, STATE_NAME
);
8477 fprintf (output_file
, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME
,
8481 /* Output function `min_insn_conflict_delay'. */
8483 output_min_insn_conflict_delay_func ()
8485 fprintf (output_file
,
8486 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8487 MIN_INSN_CONFLICT_DELAY_FUNC_NAME
,
8488 STATE_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8489 STATE_TYPE_NAME
, STATE_NAME
,
8490 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8491 fprintf (output_file
, "{\n struct %s %s;\n int %s, %s;\n",
8492 CHIP_NAME
, CHIP_NAME
, INTERNAL_INSN_CODE_NAME
,
8493 INTERNAL_INSN2_CODE_NAME
);
8494 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8495 INTERNAL_INSN_CODE_NAME
, 0);
8496 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8497 INTERNAL_INSN2_CODE_NAME
, 0);
8498 fprintf (output_file
, " memcpy (&%s, %s, sizeof (%s));\n",
8499 CHIP_NAME
, STATE_NAME
, CHIP_NAME
);
8500 fprintf (output_file
, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME
, CHIP_NAME
);
8501 fprintf (output_file
, " if (%s (%s, &%s) > 0)\n abort ();\n",
8502 INTERNAL_TRANSITION_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
, CHIP_NAME
);
8503 fprintf (output_file
, " return %s (%s, &%s);\n",
8504 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME
, INTERNAL_INSN2_CODE_NAME
,
8506 fprintf (output_file
, "}\n\n");
8509 /* Output function `internal_insn_latency'. */
8511 output_internal_insn_latency_func ()
8514 struct bypass_decl
*bypass
;
8517 fprintf (output_file
, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8518 INTERNAL_INSN_LATENCY_FUNC_NAME
);
8519 fprintf (output_file
, "static int\n%s (%s, %s, %s, %s)",
8520 INTERNAL_INSN_LATENCY_FUNC_NAME
, INTERNAL_INSN_CODE_NAME
,
8521 INTERNAL_INSN2_CODE_NAME
, INSN_PARAMETER_NAME
,
8522 INSN2_PARAMETER_NAME
);
8523 fprintf (output_file
, "\n\tint %s;\n\tint %s;\n",
8524 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8525 fprintf (output_file
,
8526 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8527 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8528 fprintf (output_file
, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8529 for (i
= 0; i
< description
->decls_num
; i
++)
8531 decl
= description
->decls
[i
];
8532 if (decl
->mode
== dm_insn_reserv
)
8534 fprintf (output_file
, " case %d:\n",
8535 DECL_INSN_RESERV (decl
)->insn_num
);
8536 if (DECL_INSN_RESERV (decl
)->bypass_list
== NULL
)
8537 fprintf (output_file
, " return (%s != %s ? %d : 0);\n",
8538 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8539 DECL_INSN_RESERV (decl
)->default_latency
);
8542 fprintf (output_file
, " switch (%s)\n {\n",
8543 INTERNAL_INSN2_CODE_NAME
);
8544 for (bypass
= DECL_INSN_RESERV (decl
)->bypass_list
;
8546 bypass
= bypass
->next
)
8548 fprintf (output_file
, " case %d:\n",
8549 bypass
->in_insn_reserv
->insn_num
);
8550 if (bypass
->bypass_guard_name
== NULL
)
8551 fprintf (output_file
, " return %d;\n",
8554 fprintf (output_file
,
8555 " return (%s (%s, %s) ? %d : %d);\n",
8556 bypass
->bypass_guard_name
, INSN_PARAMETER_NAME
,
8557 INSN2_PARAMETER_NAME
, bypass
->latency
,
8558 DECL_INSN_RESERV (decl
)->default_latency
);
8560 fprintf (output_file
, " default:\n");
8561 fprintf (output_file
,
8562 " return (%s != %s ? %d : 0);\n }\n",
8563 INTERNAL_INSN2_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
,
8564 DECL_INSN_RESERV (decl
)->default_latency
);
8569 fprintf (output_file
, " default:\n return 0;\n }\n}\n\n");
8572 /* The function outputs PHR interface function `insn_latency'. */
8574 output_insn_latency_func ()
8576 fprintf (output_file
, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8577 INSN_LATENCY_FUNC_NAME
, INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
,
8578 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8579 fprintf (output_file
, "{\n int %s, %s;\n",
8580 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
);
8581 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME
,
8582 INTERNAL_INSN_CODE_NAME
, 0);
8583 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME
,
8584 INTERNAL_INSN2_CODE_NAME
, 0);
8585 fprintf (output_file
, " return %s (%s, %s, %s, %s);\n}\n\n",
8586 INTERNAL_INSN_LATENCY_FUNC_NAME
,
8587 INTERNAL_INSN_CODE_NAME
, INTERNAL_INSN2_CODE_NAME
,
8588 INSN_PARAMETER_NAME
, INSN2_PARAMETER_NAME
);
8591 /* The function outputs PHR interface function `print_reservation'. */
8593 output_print_reservation_func ()
8598 fprintf (output_file
, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8599 PRINT_RESERVATION_FUNC_NAME
, FILE_PARAMETER_NAME
,
8600 INSN_PARAMETER_NAME
, FILE_PARAMETER_NAME
,
8601 INSN_PARAMETER_NAME
);
8602 fprintf (output_file
, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME
);
8603 fprintf (output_file
, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME
);
8604 fprintf (output_file
, " %s = %s (%s);\n",
8605 INTERNAL_INSN_CODE_NAME
, DFA_INSN_CODE_FUNC_NAME
,
8606 INSN_PARAMETER_NAME
);
8607 fprintf (output_file
, " if (%s > %s)\n",
8608 INTERNAL_INSN_CODE_NAME
, ADVANCE_CYCLE_VALUE_NAME
);
8609 fprintf (output_file
, " {\n fprintf (%s, \"%s\");\n",
8610 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8611 fprintf (output_file
, " return;\n }\n");
8612 fprintf (output_file
, " }\n else\n");
8613 fprintf (output_file
,
8614 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8615 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8616 fprintf (output_file
, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME
);
8617 for (i
= 0; i
< description
->decls_num
; i
++)
8619 decl
= description
->decls
[i
];
8620 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8622 fprintf (output_file
,
8623 " case %d:\n", DECL_INSN_RESERV (decl
)->insn_num
);
8624 fprintf (output_file
,
8625 " fprintf (%s, \"%s\");\n break;\n",
8626 FILE_PARAMETER_NAME
,
8627 regexp_representation (DECL_INSN_RESERV (decl
)->regexp
));
8628 finish_regexp_representation ();
8631 fprintf (output_file
, " default:\n fprintf (%s, \"%s\");\n }\n",
8632 FILE_PARAMETER_NAME
, NOTHING_NAME
);
8633 fprintf (output_file
, "}\n\n");
8636 /* The following function is used to sort unit declaration by their
8639 units_cmp (unit1
, unit2
)
8640 const void *unit1
, *unit2
;
8642 const unit_decl_t u1
= *(unit_decl_t
*) unit1
;
8643 const unit_decl_t u2
= *(unit_decl_t
*) unit2
;
8645 return strcmp (u1
->name
, u2
->name
);
8648 /* The following macro value is name of struct containing unit name
8650 #define NAME_CODE_STRUCT_NAME "name_code"
8652 /* The following macro value is name of table of struct name_code. */
8653 #define NAME_CODE_TABLE_NAME "name_code_table"
8655 /* The following macro values are member names for struct name_code. */
8656 #define NAME_MEMBER_NAME "name"
8657 #define CODE_MEMBER_NAME "code"
8659 /* The following macro values are local variable names for function
8660 `get_cpu_unit_code'. */
8661 #define CMP_VARIABLE_NAME "cmp"
8662 #define LOW_VARIABLE_NAME "l"
8663 #define MIDDLE_VARIABLE_NAME "m"
8664 #define HIGH_VARIABLE_NAME "h"
8666 /* The following function outputs function to obtain internal cpu unit
8667 code by the cpu unit name. */
8669 output_get_cpu_unit_code_func ()
8674 fprintf (output_file
, "int\n%s (%s)\n\tconst char *%s;\n",
8675 GET_CPU_UNIT_CODE_FUNC_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8676 CPU_UNIT_NAME_PARAMETER_NAME
);
8677 fprintf (output_file
, "{\n struct %s {const char *%s; int %s;};\n",
8678 NAME_CODE_STRUCT_NAME
, NAME_MEMBER_NAME
, CODE_MEMBER_NAME
);
8679 fprintf (output_file
, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME
,
8680 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8681 fprintf (output_file
, " static struct %s %s [] =\n {\n",
8682 NAME_CODE_STRUCT_NAME
, NAME_CODE_TABLE_NAME
);
8683 units
= (unit_decl_t
*) xmalloc (sizeof (unit_decl_t
)
8684 * description
->units_num
);
8685 memcpy (units
, units_array
, sizeof (unit_decl_t
) * description
->units_num
);
8686 qsort (units
, description
->units_num
, sizeof (unit_decl_t
), units_cmp
);
8687 for (i
= 0; i
< description
->units_num
; i
++)
8688 if (units
[i
]->query_p
)
8689 fprintf (output_file
, " {\"%s\", %d},\n",
8690 units
[i
]->name
, units
[i
]->query_num
);
8691 fprintf (output_file
, " };\n\n");
8692 fprintf (output_file
, " /* The following is binary search: */\n");
8693 fprintf (output_file
, " %s = 0;\n", LOW_VARIABLE_NAME
);
8694 fprintf (output_file
, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8695 HIGH_VARIABLE_NAME
, NAME_CODE_TABLE_NAME
, NAME_CODE_STRUCT_NAME
);
8696 fprintf (output_file
, " while (%s <= %s)\n {\n",
8697 LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8698 fprintf (output_file
, " %s = (%s + %s) / 2;\n",
8699 MIDDLE_VARIABLE_NAME
, LOW_VARIABLE_NAME
, HIGH_VARIABLE_NAME
);
8700 fprintf (output_file
, " %s = strcmp (%s, %s [%s].%s);\n",
8701 CMP_VARIABLE_NAME
, CPU_UNIT_NAME_PARAMETER_NAME
,
8702 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, NAME_MEMBER_NAME
);
8703 fprintf (output_file
, " if (%s < 0)\n", CMP_VARIABLE_NAME
);
8704 fprintf (output_file
, " %s = %s - 1;\n",
8705 HIGH_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8706 fprintf (output_file
, " else if (%s > 0)\n", CMP_VARIABLE_NAME
);
8707 fprintf (output_file
, " %s = %s + 1;\n",
8708 LOW_VARIABLE_NAME
, MIDDLE_VARIABLE_NAME
);
8709 fprintf (output_file
, " else\n");
8710 fprintf (output_file
, " return %s [%s].%s;\n }\n",
8711 NAME_CODE_TABLE_NAME
, MIDDLE_VARIABLE_NAME
, CODE_MEMBER_NAME
);
8712 fprintf (output_file
, " return -1;\n}\n\n");
8716 /* The following function outputs function to check reservation of cpu
8717 unit (its internal code will be passed as the function argument) in
8720 output_cpu_unit_reservation_p ()
8722 automaton_t automaton
;
8724 fprintf (output_file
, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8725 CPU_UNIT_RESERVATION_P_FUNC_NAME
, STATE_NAME
,
8726 CPU_CODE_PARAMETER_NAME
, STATE_TYPE_NAME
, STATE_NAME
,
8727 CPU_CODE_PARAMETER_NAME
);
8728 fprintf (output_file
, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
8729 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
,
8730 description
->query_units_num
);
8731 for (automaton
= description
->first_automaton
;
8733 automaton
= automaton
->next_automaton
)
8735 fprintf (output_file
, " if ((");
8736 output_reserved_units_table_name (output_file
, automaton
);
8737 fprintf (output_file
, " [((struct %s *) %s)->", CHIP_NAME
, STATE_NAME
);
8738 output_chip_member_name (output_file
, automaton
);
8739 fprintf (output_file
, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8740 (description
->query_units_num
+ 7) / 8,
8741 CPU_CODE_PARAMETER_NAME
, CPU_CODE_PARAMETER_NAME
);
8742 fprintf (output_file
, " return 1;\n");
8744 fprintf (output_file
, " return 0;\n}\n\n");
8747 /* The function outputs PHR interface function `dfa_start'. */
8749 output_dfa_start_func ()
8751 fprintf (output_file
,
8752 "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
8753 DFA_START_FUNC_NAME
, I_VARIABLE_NAME
,
8754 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8755 fprintf (output_file
, " %s = (int *) xmalloc (%s * sizeof (int));\n",
8756 DFA_INSN_CODES_VARIABLE_NAME
, DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
8757 fprintf (output_file
,
8758 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8759 I_VARIABLE_NAME
, I_VARIABLE_NAME
,
8760 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
, I_VARIABLE_NAME
,
8761 DFA_INSN_CODES_VARIABLE_NAME
, I_VARIABLE_NAME
);
8764 /* The function outputs PHR interface function `dfa_finish'. */
8766 output_dfa_finish_func ()
8768 fprintf (output_file
, "void\n%s ()\n{\n free (%s);\n}\n\n",
8769 DFA_FINISH_FUNC_NAME
, DFA_INSN_CODES_VARIABLE_NAME
);
8774 /* The page contains code for output description file (readable
8775 representation of original description and generated DFA(s). */
8777 /* The function outputs string representation of IR reservation. */
8779 output_regexp (regexp
)
8782 fprintf (output_description_file
, "%s", regexp_representation (regexp
));
8783 finish_regexp_representation ();
8786 /* Output names of units in LIST separated by comma. */
8788 output_unit_set_el_list (list
)
8793 for (el
= list
; el
!= NULL
; el
= el
->next_unit_set_el
)
8796 fprintf (output_description_file
, ",");
8797 fprintf (output_description_file
, "%s", el
->unit_decl
->name
);
8801 /* The function outputs string representation of IR define_reservation
8802 and define_insn_reservation. */
8804 output_description ()
8809 for (i
= 0; i
< description
->decls_num
; i
++)
8811 decl
= description
->decls
[i
];
8812 if (decl
->mode
== dm_unit
)
8814 if (DECL_UNIT (decl
)->excl_list
!= NULL
)
8816 fprintf (output_description_file
, "unit %s exlusion_set: ",
8817 DECL_UNIT (decl
)->name
);
8818 output_unit_set_el_list (DECL_UNIT (decl
)->excl_list
);
8819 fprintf (output_description_file
, "\n");
8821 if (DECL_UNIT (decl
)->presence_list
!= NULL
)
8823 fprintf (output_description_file
, "unit %s presence_set: ",
8824 DECL_UNIT (decl
)->name
);
8825 output_unit_set_el_list (DECL_UNIT (decl
)->presence_list
);
8826 fprintf (output_description_file
, "\n");
8828 if (DECL_UNIT (decl
)->absence_list
!= NULL
)
8830 fprintf (output_description_file
, "unit %s absence_set: ",
8831 DECL_UNIT (decl
)->name
);
8832 output_unit_set_el_list (DECL_UNIT (decl
)->absence_list
);
8833 fprintf (output_description_file
, "\n");
8837 fprintf (output_description_file
, "\n");
8838 for (i
= 0; i
< description
->decls_num
; i
++)
8840 decl
= description
->decls
[i
];
8841 if (decl
->mode
== dm_reserv
)
8843 fprintf (output_description_file
, "reservation ");
8844 fprintf (output_description_file
, DECL_RESERV (decl
)->name
);
8845 fprintf (output_description_file
, ": ");
8846 output_regexp (DECL_RESERV (decl
)->regexp
);
8847 fprintf (output_description_file
, "\n");
8849 else if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
8851 fprintf (output_description_file
, "insn reservation %s ",
8852 DECL_INSN_RESERV (decl
)->name
);
8853 print_rtl (output_description_file
,
8854 DECL_INSN_RESERV (decl
)->condexp
);
8855 fprintf (output_description_file
, ": ");
8856 output_regexp (DECL_INSN_RESERV (decl
)->regexp
);
8857 fprintf (output_description_file
, "\n");
8859 else if (decl
->mode
== dm_bypass
)
8860 fprintf (output_description_file
, "bypass %d %s %s\n",
8861 DECL_BYPASS (decl
)->latency
,
8862 DECL_BYPASS (decl
)->out_insn_name
,
8863 DECL_BYPASS (decl
)->in_insn_name
);
8865 fprintf (output_description_file
, "\n\f\n");
8868 /* The function outputs name of AUTOMATON. */
8870 output_automaton_name (f
, automaton
)
8872 automaton_t automaton
;
8874 if (automaton
->corresponding_automaton_decl
== NULL
)
8875 fprintf (f
, "#%d", automaton
->automaton_order_num
);
8877 fprintf (f
, "`%s'", automaton
->corresponding_automaton_decl
->name
);
8880 /* Maximal length of line for pretty printing into description
8882 #define MAX_LINE_LENGTH 70
8884 /* The function outputs units name belonging to AUTOMATON. */
8886 output_automaton_units (automaton
)
8887 automaton_t automaton
;
8891 int curr_line_length
;
8892 int there_is_an_automaton_unit
;
8895 fprintf (output_description_file
, "\n Coresponding units:\n");
8896 fprintf (output_description_file
, " ");
8897 curr_line_length
= 4;
8898 there_is_an_automaton_unit
= 0;
8899 for (i
= 0; i
< description
->decls_num
; i
++)
8901 decl
= description
->decls
[i
];
8902 if (decl
->mode
== dm_unit
8903 && (DECL_UNIT (decl
)->corresponding_automaton_num
8904 == automaton
->automaton_order_num
))
8906 there_is_an_automaton_unit
= 1;
8907 name
= DECL_UNIT (decl
)->name
;
8908 if (curr_line_length
+ strlen (name
) + 1 > MAX_LINE_LENGTH
)
8910 curr_line_length
= strlen (name
) + 4;
8911 fprintf (output_description_file
, "\n ");
8915 curr_line_length
+= strlen (name
) + 1;
8916 fprintf (output_description_file
, " ");
8918 fprintf (output_description_file
, name
);
8921 if (!there_is_an_automaton_unit
)
8922 fprintf (output_description_file
, "<None>");
8923 fprintf (output_description_file
, "\n\n");
8926 /* The following variable is used for forming array of all possible cpu unit
8927 reservations described by the current DFA state. */
8928 static vla_ptr_t state_reservs
;
8930 /* The function forms `state_reservs' for STATE. */
8932 add_state_reservs (state
)
8935 alt_state_t curr_alt_state
;
8936 reserv_sets_t reservs
;
8938 if (state
->component_states
!= NULL
)
8939 for (curr_alt_state
= state
->component_states
;
8940 curr_alt_state
!= NULL
;
8941 curr_alt_state
= curr_alt_state
->next_sorted_alt_state
)
8942 add_state_reservs (curr_alt_state
->state
);
8945 reservs
= state
->reservs
;
8946 VLA_PTR_ADD (state_reservs
, reservs
);
8950 /* The function outputs readable represenatation of all out arcs of
8953 output_state_arcs (state
)
8959 int curr_line_length
;
8961 for (arc
= first_out_arc (state
); arc
!= NULL
; arc
= next_out_arc (arc
))
8964 if (!ainsn
->first_insn_with_same_reservs
)
8966 fprintf (output_description_file
, " ");
8967 curr_line_length
= 7;
8968 fprintf (output_description_file
, "%2d: ", ainsn
->insn_equiv_class_num
);
8971 insn_name
= ainsn
->insn_reserv_decl
->name
;
8972 if (curr_line_length
+ strlen (insn_name
) > MAX_LINE_LENGTH
)
8974 if (ainsn
!= arc
->insn
)
8976 fprintf (output_description_file
, ",\n ");
8977 curr_line_length
= strlen (insn_name
) + 6;
8980 curr_line_length
+= strlen (insn_name
);
8984 curr_line_length
+= strlen (insn_name
);
8985 if (ainsn
!= arc
->insn
)
8987 curr_line_length
+= 2;
8988 fprintf (output_description_file
, ", ");
8991 fprintf (output_description_file
, insn_name
);
8992 ainsn
= ainsn
->next_same_reservs_insn
;
8994 while (ainsn
!= NULL
);
8995 fprintf (output_description_file
, " %d (%d)\n",
8996 arc
->to_state
->order_state_num
, arc
->state_alts
);
8998 fprintf (output_description_file
, "\n");
9001 /* The following function is used for sorting possible cpu unit
9002 reservation of a DFA state. */
9004 state_reservs_cmp (reservs_ptr_1
, reservs_ptr_2
)
9005 const void *reservs_ptr_1
;
9006 const void *reservs_ptr_2
;
9008 return reserv_sets_cmp (*(reserv_sets_t
*) reservs_ptr_1
,
9009 *(reserv_sets_t
*) reservs_ptr_2
);
9012 /* The following function is used for sorting possible cpu unit
9013 reservation of a DFA state. */
9015 remove_state_duplicate_reservs ()
9017 reserv_sets_t
*reservs_ptr
;
9018 reserv_sets_t
*last_formed_reservs_ptr
;
9020 last_formed_reservs_ptr
= NULL
;
9021 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9022 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9024 if (last_formed_reservs_ptr
== NULL
)
9025 last_formed_reservs_ptr
= reservs_ptr
;
9026 else if (reserv_sets_cmp (*last_formed_reservs_ptr
, *reservs_ptr
) != 0)
9028 ++last_formed_reservs_ptr
;
9029 *last_formed_reservs_ptr
= *reservs_ptr
;
9031 VLA_PTR_SHORTEN (state_reservs
, reservs_ptr
- last_formed_reservs_ptr
- 1);
9034 /* The following function output readable representation of DFA(s)
9035 state used for fast recognition of pipeline hazards. State is
9036 described by possible (current and scehduled) cpu unit
9039 output_state (state
)
9042 reserv_sets_t
*reservs_ptr
;
9044 VLA_PTR_CREATE (state_reservs
, 150, "state reservations");
9045 fprintf (output_description_file
, " State #%d", state
->order_state_num
);
9046 fprintf (output_description_file
,
9047 state
->new_cycle_p
? " (new cycle)\n" : "\n");
9048 add_state_reservs (state
);
9049 qsort (VLA_PTR_BEGIN (state_reservs
), VLA_PTR_LENGTH (state_reservs
),
9050 sizeof (reserv_sets_t
), state_reservs_cmp
);
9051 remove_state_duplicate_reservs ();
9052 for (reservs_ptr
= VLA_PTR_BEGIN (state_reservs
);
9053 reservs_ptr
<= (reserv_sets_t
*) VLA_PTR_LAST (state_reservs
);
9056 fprintf (output_description_file
, " ");
9057 output_reserv_sets (output_description_file
, *reservs_ptr
);
9058 fprintf (output_description_file
, "\n");
9060 fprintf (output_description_file
, "\n");
9061 output_state_arcs (state
);
9062 VLA_PTR_DELETE (state_reservs
);
9065 /* The following function output readable representation of
9066 DFAs used for fast recognition of pipeline hazards. */
9068 output_automaton_descriptions ()
9070 automaton_t automaton
;
9072 for (automaton
= description
->first_automaton
;
9074 automaton
= automaton
->next_automaton
)
9076 fprintf (output_description_file
, "\nAutomaton ");
9077 output_automaton_name (output_description_file
, automaton
);
9078 fprintf (output_description_file
, "\n");
9079 output_automaton_units (automaton
);
9080 pass_states (automaton
, output_state
);
9086 /* The page contains top level function for generation DFA(s) used for
9089 /* The function outputs statistics about work of different phases of
9092 output_statistics (f
)
9095 automaton_t automaton
;
9097 int transition_comb_vect_els
= 0;
9098 int transition_full_vect_els
= 0;
9099 int state_alts_comb_vect_els
= 0;
9100 int state_alts_full_vect_els
= 0;
9101 int min_issue_delay_vect_els
= 0;
9104 for (automaton
= description
->first_automaton
;
9106 automaton
= automaton
->next_automaton
)
9108 fprintf (f
, "\nAutomaton ");
9109 output_automaton_name (f
, automaton
);
9110 fprintf (f
, "\n %5d NDFA states, %5d NDFA arcs\n",
9111 automaton
->NDFA_states_num
, automaton
->NDFA_arcs_num
);
9112 fprintf (f
, " %5d DFA states, %5d DFA arcs\n",
9113 automaton
->DFA_states_num
, automaton
->DFA_arcs_num
);
9114 if (!no_minimization_flag
)
9115 fprintf (f
, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9116 automaton
->minimal_DFA_states_num
,
9117 automaton
->minimal_DFA_arcs_num
);
9118 fprintf (f
, " %5d all insns %5d insn equivalence classes\n",
9119 description
->insns_num
, automaton
->insn_equiv_classes_num
);
9122 (f
, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9123 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
),
9124 (long) VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
),
9125 (comb_vect_p (automaton
->trans_table
)
9126 ? "use comb vect" : "use simple vect"));
9128 (f
, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9129 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
),
9130 (long) VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
),
9131 (comb_vect_p (automaton
->state_alts_table
)
9132 ? "use comb vect" : "use simple vect"));
9134 (f
, "%5ld min delay table els, compression factor %d\n",
9135 (long) automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
,
9136 automaton
->min_issue_delay_table_compression_factor
);
9137 transition_comb_vect_els
9138 += VLA_HWINT_LENGTH (automaton
->trans_table
->comb_vect
);
9139 transition_full_vect_els
9140 += VLA_HWINT_LENGTH (automaton
->trans_table
->full_vect
);
9141 state_alts_comb_vect_els
9142 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->comb_vect
);
9143 state_alts_full_vect_els
9144 += VLA_HWINT_LENGTH (automaton
->state_alts_table
->full_vect
);
9145 min_issue_delay_vect_els
9146 += automaton
->DFA_states_num
* automaton
->insn_equiv_classes_num
;
9150 fprintf (f
, "\n%5d all allocated states, %5d all allocated arcs\n",
9151 allocated_states_num
, allocated_arcs_num
);
9152 fprintf (f
, "%5d all allocated alternative states\n",
9153 allocated_alt_states_num
);
9154 fprintf (f
, "%5d all transition comb vector els, %5d all trans table els\n",
9155 transition_comb_vect_els
, transition_full_vect_els
);
9157 (f
, "%5d all state alts comb vector els, %5d all state alts table els\n",
9158 state_alts_comb_vect_els
, state_alts_full_vect_els
);
9159 fprintf (f
, "%5d all min delay table els\n", min_issue_delay_vect_els
);
9160 fprintf (f
, "%5d locked states num\n", locked_states_num
);
9164 /* The function output times of work of different phases of DFA
9167 output_time_statistics (f
)
9170 fprintf (f
, "\n transformation: ");
9171 print_active_time (f
, transform_time
);
9172 fprintf (f
, (!ndfa_flag
? ", building DFA: " : ", building NDFA: "));
9173 print_active_time (f
, NDFA_time
);
9176 fprintf (f
, ", NDFA -> DFA: ");
9177 print_active_time (f
, NDFA_to_DFA_time
);
9179 fprintf (f
, "\n DFA minimization: ");
9180 print_active_time (f
, minimize_time
);
9181 fprintf (f
, ", making insn equivalence: ");
9182 print_active_time (f
, equiv_time
);
9183 fprintf (f
, "\n all automaton generation: ");
9184 print_active_time (f
, automaton_generation_time
);
9185 fprintf (f
, ", output: ");
9186 print_active_time (f
, output_time
);
9190 /* The function generates DFA (deterministic finate state automaton)
9191 for fast recognition of pipeline hazards. No errors during
9192 checking must be fixed before this function call. */
9196 automata_num
= split_argument
;
9197 if (description
->units_num
< automata_num
)
9198 automata_num
= description
->units_num
;
9201 initiate_automata_lists ();
9202 initiate_pass_states ();
9203 initiate_excl_sets ();
9204 initiate_presence_absence_sets ();
9205 automaton_generation_time
= create_ticker ();
9207 ticker_off (&automaton_generation_time
);
9212 /* The following function creates insn attribute whose values are
9213 number alternatives in insn reservations. */
9215 make_insn_alts_attr ()
9221 condexp
= rtx_alloc (COND
);
9222 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9223 XEXP (condexp
, 1) = make_numeric_value (0);
9224 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9226 decl
= description
->decls
[i
];
9227 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9229 XVECEXP (condexp
, 0, 2 * insn_num
)
9230 = DECL_INSN_RESERV (decl
)->condexp
;
9231 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9232 = make_numeric_value
9233 (DECL_INSN_RESERV (decl
)->transformed_regexp
->mode
!= rm_oneof
9234 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl
)
9235 ->transformed_regexp
)->regexps_num
);
9239 if (description
->insns_num
!= insn_num
+ 1)
9241 make_internal_attr (attr_printf (sizeof ("*")
9242 + strlen (INSN_ALTS_FUNC_NAME
) + 1,
9243 "*%s", INSN_ALTS_FUNC_NAME
),
9249 /* The following function creates attribute which is order number of
9250 insn in pipeline hazard description translator. */
9252 make_internal_dfa_insn_code_attr ()
9258 condexp
= rtx_alloc (COND
);
9259 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9261 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl
)
9263 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9265 decl
= description
->decls
[i
];
9266 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9268 XVECEXP (condexp
, 0, 2 * insn_num
)
9269 = DECL_INSN_RESERV (decl
)->condexp
;
9270 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9271 = make_numeric_value (DECL_INSN_RESERV (decl
)->insn_num
);
9275 if (description
->insns_num
!= insn_num
+ 1)
9278 (attr_printf (sizeof ("*")
9279 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME
) + 1,
9280 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME
),
9286 /* The following function creates attribute which order number of insn
9287 in pipeline hazard description translator. */
9289 make_default_insn_latency_attr ()
9295 condexp
= rtx_alloc (COND
);
9296 XVEC (condexp
, 0) = rtvec_alloc ((description
->insns_num
- 1) * 2);
9297 XEXP (condexp
, 1) = make_numeric_value (0);
9298 for (i
= insn_num
= 0; i
< description
->decls_num
; i
++)
9300 decl
= description
->decls
[i
];
9301 if (decl
->mode
== dm_insn_reserv
&& decl
!= advance_cycle_insn_decl
)
9303 XVECEXP (condexp
, 0, 2 * insn_num
)
9304 = DECL_INSN_RESERV (decl
)->condexp
;
9305 XVECEXP (condexp
, 0, 2 * insn_num
+ 1)
9306 = make_numeric_value (DECL_INSN_RESERV (decl
)->default_latency
);
9310 if (description
->insns_num
!= insn_num
+ 1)
9312 make_internal_attr (attr_printf (sizeof ("*")
9313 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME
)
9314 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME
),
9320 /* The following function creates attribute which returns 1 if given
9321 output insn has bypassing and 0 otherwise. */
9326 int bypass_insns_num
= 0;
9330 for (i
= 0; i
< description
->decls_num
; i
++)
9332 decl
= description
->decls
[i
];
9333 if (decl
->mode
== dm_insn_reserv
9334 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9335 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9338 if (bypass_insns_num
== 0)
9339 result_rtx
= make_numeric_value (0);
9342 result_rtx
= rtx_alloc (COND
);
9343 XVEC (result_rtx
, 0) = rtvec_alloc (bypass_insns_num
* 2);
9344 XEXP (result_rtx
, 1) = make_numeric_value (0);
9346 for (i
= bypass_insn
= 0; i
< description
->decls_num
; i
++)
9348 decl
= description
->decls
[i
];
9349 if (decl
->mode
== dm_insn_reserv
9350 && DECL_INSN_RESERV (decl
)->condexp
!= NULL
9351 && DECL_INSN_RESERV (decl
)->bypass_list
!= NULL
)
9353 XVECEXP (result_rtx
, 0, 2 * bypass_insn
)
9354 = DECL_INSN_RESERV (decl
)->condexp
;
9355 XVECEXP (result_rtx
, 0, 2 * bypass_insn
+ 1)
9356 = make_numeric_value (1);
9361 make_internal_attr (attr_printf (sizeof ("*")
9362 + strlen (BYPASS_P_FUNC_NAME
) + 1,
9363 "*%s", BYPASS_P_FUNC_NAME
),
9369 /* This page mainly contains top level functions of pipeline hazards
9370 description translator. */
9372 /* The following macro value is suffix of name of description file of
9373 pipeline hazards description translator. */
9374 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9376 /* The function returns suffix of given file name. The returned
9377 string can not be changed. */
9379 file_name_suffix (file_name
)
9380 const char *file_name
;
9382 const char *last_period
;
9384 for (last_period
= NULL
; *file_name
!= '\0'; file_name
++)
9385 if (*file_name
== '.')
9386 last_period
= file_name
;
9387 return (last_period
== NULL
? file_name
: last_period
);
9390 /* The function returns base name of given file name, i.e. pointer to
9391 first char after last `/' (or `\' for WIN32) in given file name,
9392 given file name itself if the directory name is absent. The
9393 returned string can not be changed. */
9395 base_file_name (file_name
)
9396 const char *file_name
;
9398 int directory_name_length
;
9400 directory_name_length
= strlen (file_name
);
9402 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/'
9403 && file_name
[directory_name_length
] != '\\')
9405 while (directory_name_length
>= 0 && file_name
[directory_name_length
] != '/')
9407 directory_name_length
--;
9408 return file_name
+ directory_name_length
+ 1;
9411 /* The following is top level function to initialize the work of
9412 pipeline hazards description translator. */
9414 initiate_automaton_gen (argc
, argv
)
9418 const char *base_name
;
9422 split_argument
= 0; /* default value */
9423 no_minimization_flag
= 0;
9427 for (i
= 2; i
< argc
; i
++)
9428 if (strcmp (argv
[i
], NO_MINIMIZATION_OPTION
) == 0)
9429 no_minimization_flag
= 1;
9430 else if (strcmp (argv
[i
], TIME_OPTION
) == 0)
9432 else if (strcmp (argv
[i
], V_OPTION
) == 0)
9434 else if (strcmp (argv
[i
], W_OPTION
) == 0)
9436 else if (strcmp (argv
[i
], NDFA_OPTION
) == 0)
9438 else if (strcmp (argv
[i
], "-split") == 0)
9441 fatal ("-split has no argument.");
9442 fatal ("option `-split' has not been implemented yet\n");
9443 /* split_argument = atoi (argument_vect [i + 1]); */
9445 VLA_PTR_CREATE (decls
, 150, "decls");
9446 /* Initialize IR storage. */
9447 obstack_init (&irp
);
9448 initiate_automaton_decl_table ();
9449 initiate_insn_decl_table ();
9450 initiate_decl_table ();
9451 output_file
= stdout
;
9452 output_description_file
= NULL
;
9453 base_name
= base_file_name (argv
[1]);
9454 obstack_grow (&irp
, base_name
,
9455 strlen (base_name
) - strlen (file_name_suffix (base_name
)));
9456 obstack_grow (&irp
, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
,
9457 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX
) + 1);
9458 obstack_1grow (&irp
, '\0');
9459 output_description_file_name
= obstack_base (&irp
);
9460 obstack_finish (&irp
);
9463 /* The following function checks existence at least one arc marked by
9466 check_automata_insn_issues ()
9468 automaton_t automaton
;
9469 ainsn_t ainsn
, reserv_ainsn
;
9471 for (automaton
= description
->first_automaton
;
9473 automaton
= automaton
->next_automaton
)
9475 for (ainsn
= automaton
->ainsn_list
;
9477 ainsn
= ainsn
->next_ainsn
)
9478 if (ainsn
->first_insn_with_same_reservs
&& !ainsn
->arc_exists_p
)
9480 for (reserv_ainsn
= ainsn
;
9481 reserv_ainsn
!= NULL
;
9482 reserv_ainsn
= reserv_ainsn
->next_same_reservs_insn
)
9483 if (automaton
->corresponding_automaton_decl
!= NULL
)
9486 error ("Automaton `%s': Insn `%s' will never be issued",
9487 automaton
->corresponding_automaton_decl
->name
,
9488 reserv_ainsn
->insn_reserv_decl
->name
);
9491 ("Automaton `%s': Insn `%s' will never be issued",
9492 automaton
->corresponding_automaton_decl
->name
,
9493 reserv_ainsn
->insn_reserv_decl
->name
);
9498 error ("Insn `%s' will never be issued",
9499 reserv_ainsn
->insn_reserv_decl
->name
);
9501 warning ("Insn `%s' will never be issued",
9502 reserv_ainsn
->insn_reserv_decl
->name
);
9508 /* The following vla is used for storing pointers to all achieved
9510 static vla_ptr_t automaton_states
;
9512 /* This function is called by function pass_states to add an achieved
9515 add_automaton_state (state
)
9518 VLA_PTR_ADD (automaton_states
, state
);
9521 /* The following function forms list of important automata (whose
9522 states may be changed after the insn issue) for each insn. */
9524 form_important_insn_automata_lists ()
9526 automaton_t automaton
;
9533 VLA_PTR_CREATE (automaton_states
, 1500,
9534 "automaton states for forming important insn automata sets");
9535 /* Mark important ainsns. */
9536 for (automaton
= description
->first_automaton
;
9538 automaton
= automaton
->next_automaton
)
9540 VLA_PTR_NULLIFY (automaton_states
);
9541 pass_states (automaton
, add_automaton_state
);
9542 for (state_ptr
= VLA_PTR_BEGIN (automaton_states
);
9543 state_ptr
<= (state_t
*) VLA_PTR_LAST (automaton_states
);
9546 for (arc
= first_out_arc (*state_ptr
);
9548 arc
= next_out_arc (arc
))
9549 if (arc
->to_state
!= *state_ptr
)
9551 if (!arc
->insn
->first_insn_with_same_reservs
)
9553 for (ainsn
= arc
->insn
;
9555 ainsn
= ainsn
->next_same_reservs_insn
)
9556 ainsn
->important_p
= TRUE
;
9560 VLA_PTR_DELETE (automaton_states
);
9561 /* Create automata sets for the insns. */
9562 for (i
= 0; i
< description
->decls_num
; i
++)
9564 decl
= description
->decls
[i
];
9565 if (decl
->mode
== dm_insn_reserv
)
9567 automata_list_start ();
9568 for (automaton
= description
->first_automaton
;
9570 automaton
= automaton
->next_automaton
)
9571 for (ainsn
= automaton
->ainsn_list
;
9573 ainsn
= ainsn
->next_ainsn
)
9574 if (ainsn
->important_p
9575 && ainsn
->insn_reserv_decl
== DECL_INSN_RESERV (decl
))
9577 automata_list_add (automaton
);
9580 DECL_INSN_RESERV (decl
)->important_automata_list
9581 = automata_list_finish ();
9587 /* The following is top level function to generate automat(a,on) for
9588 fast recognition of pipeline hazards. */
9594 description
= create_node (sizeof (struct description
)
9595 /* One entry for cycle advancing insn. */
9596 + sizeof (decl_t
) * VLA_PTR_LENGTH (decls
));
9597 description
->decls_num
= VLA_PTR_LENGTH (decls
);
9598 description
->query_units_num
= 0;
9599 for (i
= 0; i
< description
->decls_num
; i
++)
9601 description
->decls
[i
] = VLA_PTR (decls
, i
);
9602 if (description
->decls
[i
]->mode
== dm_unit
9603 && DECL_UNIT (description
->decls
[i
])->query_p
)
9604 DECL_UNIT (description
->decls
[i
])->query_num
9605 = description
->query_units_num
++;
9607 all_time
= create_ticker ();
9608 check_time
= create_ticker ();
9609 fprintf (stderr
, "Check description...");
9611 check_all_description ();
9612 fprintf (stderr
, "done\n");
9613 ticker_off (&check_time
);
9614 generation_time
= create_ticker ();
9617 transform_insn_regexps ();
9618 check_unit_distributions_to_automata ();
9623 check_automata_insn_issues ();
9627 form_important_insn_automata_lists ();
9628 fprintf (stderr
, "Generation of attributes...");
9630 make_internal_dfa_insn_code_attr ();
9631 make_insn_alts_attr ();
9632 make_default_insn_latency_attr ();
9633 make_bypass_attr ();
9634 fprintf (stderr
, "done\n");
9636 ticker_off (&generation_time
);
9637 ticker_off (&all_time
);
9638 fprintf (stderr
, "All other genattrtab stuff...");
9642 /* The following is top level function to output PHR and to finish
9643 work with pipeline description translator. */
9647 fprintf (stderr
, "done\n");
9649 fatal ("Errors in DFA description");
9650 ticker_on (&all_time
);
9651 output_time
= create_ticker ();
9652 fprintf (stderr
, "Forming and outputing automata tables...");
9654 output_dfa_max_issue_rate ();
9656 fprintf (stderr
, "done\n");
9657 fprintf (stderr
, "Output functions to work with automata...");
9659 output_chip_definitions ();
9660 output_max_insn_queue_index_def ();
9661 output_internal_min_issue_delay_func ();
9662 output_internal_trans_func ();
9663 /* Cache of insn dfa codes: */
9664 fprintf (output_file
, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME
);
9665 fprintf (output_file
, "\nstatic int %s;\n\n",
9666 DFA_INSN_CODES_LENGTH_VARIABLE_NAME
);
9667 output_dfa_insn_code_func ();
9668 output_trans_func ();
9669 fprintf (output_file
, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME
);
9670 output_internal_state_alts_func ();
9671 output_state_alts_func ();
9672 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9673 AUTOMATON_STATE_ALTS_MACRO_NAME
);
9674 output_min_issue_delay_func ();
9675 output_internal_dead_lock_func ();
9676 output_dead_lock_func ();
9677 output_size_func ();
9678 output_internal_reset_func ();
9679 output_reset_func ();
9680 output_min_insn_conflict_delay_func ();
9681 output_internal_insn_latency_func ();
9682 output_insn_latency_func ();
9683 output_print_reservation_func ();
9684 if (no_minimization_flag
)
9686 fprintf (output_file
, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME
);
9687 output_get_cpu_unit_code_func ();
9688 output_cpu_unit_reservation_p ();
9689 fprintf (output_file
, "\n#endif /* #if %s */\n\n",
9690 CPU_UNITS_QUERY_MACRO_NAME
);
9692 output_dfa_start_func ();
9693 output_dfa_finish_func ();
9694 fprintf (stderr
, "done\n");
9697 output_description_file
= fopen (output_description_file_name
, "w");
9698 if (output_description_file
== NULL
)
9700 perror (output_description_file_name
);
9701 exit (FATAL_EXIT_CODE
);
9703 fprintf (stderr
, "Output automata description...");
9705 output_description ();
9706 output_automaton_descriptions ();
9707 fprintf (stderr
, "done\n");
9708 output_statistics (output_description_file
);
9710 output_statistics (stderr
);
9711 ticker_off (&output_time
);
9712 output_time_statistics (stderr
);
9715 finish_automata_lists ();
9718 fprintf (stderr
, "Summary:\n");
9719 fprintf (stderr
, " check time ");
9720 print_active_time (stderr
, check_time
);
9721 fprintf (stderr
, ", generation time ");
9722 print_active_time (stderr
, generation_time
);
9723 fprintf (stderr
, ", all time ");
9724 print_active_time (stderr
, all_time
);
9725 fprintf (stderr
, "\n");
9727 /* Finish all work. */
9728 if (output_description_file
!= NULL
)
9730 fflush (output_description_file
);
9731 if (ferror (stdout
) != 0)
9732 fatal ("Error in writing DFA description file %s",
9733 output_description_file_name
);
9734 fclose (output_description_file
);
9736 finish_automaton_decl_table ();
9737 finish_insn_decl_table ();
9738 finish_decl_table ();
9739 obstack_free (&irp
, NULL
);
9740 if (have_error
&& output_description_file
!= NULL
)
9741 remove (output_description_file_name
);