00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include "bconfig.h"
00106 #include "system.h"
00107 #include "coretypes.h"
00108 #include "tm.h"
00109 #include "rtl.h"
00110 #include "obstack.h"
00111 #include "errors.h"
00112
00113 #include <math.h>
00114 #include "hashtab.h"
00115 #include "varray.h"
00116
00117 #ifndef CHAR_BIT
00118 #define CHAR_BIT 8
00119 #endif
00120
00121 #include "genattrtab.h"
00122
00123
00124
00125 typedef int pos_t;
00126
00127
00128
00129 typedef unsigned HOST_WIDE_INT set_el_t;
00130
00131
00132
00133 typedef set_el_t *reserv_sets_t;
00134
00135
00136
00137
00138
00139 typedef struct {
00140 size_t length;
00141 varray_type varray;
00142 } vla_ptr_t;
00143
00144 typedef vla_ptr_t vla_hwint_t;
00145
00146
00147 struct ticker
00148 {
00149
00150
00151
00152 int modified_creation_time;
00153
00154
00155 int incremented_off_time;
00156 };
00157
00158
00159 typedef struct ticker ticker_t;
00160
00161
00162 typedef HOST_WIDE_INT vect_el_t;
00163
00164
00165
00166
00167 struct unit_decl;
00168 struct bypass_decl;
00169 struct result_decl;
00170 struct automaton_decl;
00171 struct unit_pattern_rel_decl;
00172 struct reserv_decl;
00173 struct insn_reserv_decl;
00174 struct decl;
00175 struct unit_regexp;
00176 struct result_regexp;
00177 struct reserv_regexp;
00178 struct nothing_regexp;
00179 struct sequence_regexp;
00180 struct repeat_regexp;
00181 struct allof_regexp;
00182 struct oneof_regexp;
00183 struct regexp;
00184 struct description;
00185 struct unit_set_el;
00186 struct pattern_set_el;
00187 struct pattern_reserv;
00188 struct state;
00189 struct alt_state;
00190 struct arc;
00191 struct ainsn;
00192 struct automaton;
00193 struct state_ainsn_table;
00194
00195
00196 typedef struct unit_decl *unit_decl_t;
00197 typedef struct decl *decl_t;
00198 typedef struct regexp *regexp_t;
00199 typedef struct unit_set_el *unit_set_el_t;
00200 typedef struct pattern_set_el *pattern_set_el_t;
00201 typedef struct pattern_reserv *pattern_reserv_t;
00202 typedef struct alt_state *alt_state_t;
00203 typedef struct state *state_t;
00204 typedef struct arc *arc_t;
00205 typedef struct ainsn *ainsn_t;
00206 typedef struct automaton *automaton_t;
00207 typedef struct automata_list_el *automata_list_el_t;
00208 typedef struct state_ainsn_table *state_ainsn_table_t;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 static void *create_node (size_t);
00220 static void *copy_node (const void *, size_t);
00221 static char *check_name (char *, pos_t);
00222 static char *next_sep_el (char **, int, int);
00223 static int n_sep_els (char *, int, int);
00224 static char **get_str_vect (char *, int *, int, int);
00225 static void gen_presence_absence_set (rtx, int, int);
00226 static regexp_t gen_regexp_el (char *);
00227 static regexp_t gen_regexp_repeat (char *);
00228 static regexp_t gen_regexp_allof (char *);
00229 static regexp_t gen_regexp_oneof (char *);
00230 static regexp_t gen_regexp_sequence (char *);
00231 static regexp_t gen_regexp (char *);
00232
00233 static unsigned string_hash (const char *);
00234 static unsigned automaton_decl_hash (const void *);
00235 static int automaton_decl_eq_p (const void *,
00236 const void *);
00237 static decl_t insert_automaton_decl (decl_t);
00238 static decl_t find_automaton_decl (char *);
00239 static void initiate_automaton_decl_table (void);
00240 static void finish_automaton_decl_table (void);
00241
00242 static hashval_t insn_decl_hash (const void *);
00243 static int insn_decl_eq_p (const void *,
00244 const void *);
00245 static decl_t insert_insn_decl (decl_t);
00246 static decl_t find_insn_decl (char *);
00247 static void initiate_insn_decl_table (void);
00248 static void finish_insn_decl_table (void);
00249
00250 static hashval_t decl_hash (const void *);
00251 static int decl_eq_p (const void *,
00252 const void *);
00253 static decl_t insert_decl (decl_t);
00254 static decl_t find_decl (char *);
00255 static void initiate_decl_table (void);
00256 static void finish_decl_table (void);
00257
00258 static unit_set_el_t process_excls (char **, int, pos_t);
00259 static void add_excls (unit_set_el_t, unit_set_el_t,
00260 pos_t);
00261 static unit_set_el_t process_presence_absence_names
00262 (char **, int, pos_t,
00263 int, int);
00264 static pattern_set_el_t process_presence_absence_patterns
00265 (char ***, int, pos_t,
00266 int, int);
00267 static void add_presence_absence (unit_set_el_t,
00268 pattern_set_el_t,
00269 pos_t, int, int);
00270 static void process_decls (void);
00271 static struct bypass_decl *find_bypass (struct bypass_decl *,
00272 struct insn_reserv_decl *);
00273 static void check_automaton_usage (void);
00274 static regexp_t process_regexp (regexp_t);
00275 static void process_regexp_decls (void);
00276 static void check_usage (void);
00277 static int loop_in_regexp (regexp_t, decl_t);
00278 static void check_loops_in_regexps (void);
00279 static void process_regexp_cycles (regexp_t, int, int,
00280 int *, int *);
00281 static void evaluate_max_reserv_cycles (void);
00282 static void check_all_description (void);
00283
00284 static ticker_t create_ticker (void);
00285 static void ticker_off (ticker_t *);
00286 static void ticker_on (ticker_t *);
00287 static int active_time (ticker_t);
00288 static void print_active_time (FILE *, ticker_t);
00289
00290 static void add_advance_cycle_insn_decl (void);
00291
00292 static alt_state_t get_free_alt_state (void);
00293 static void free_alt_state (alt_state_t);
00294 static void free_alt_states (alt_state_t);
00295 static int alt_state_cmp (const void *alt_state_ptr_1,
00296 const void *alt_state_ptr_2);
00297 static alt_state_t uniq_sort_alt_states (alt_state_t);
00298 static int alt_states_eq (alt_state_t, alt_state_t);
00299 static void initiate_alt_states (void);
00300 static void finish_alt_states (void);
00301
00302 static reserv_sets_t alloc_empty_reserv_sets (void);
00303 static unsigned reserv_sets_hash_value (reserv_sets_t);
00304 static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
00305 static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
00306 static void set_unit_reserv (reserv_sets_t, int, int);
00307 static int test_unit_reserv (reserv_sets_t, int, int);
00308 static int it_is_empty_reserv_sets (reserv_sets_t)
00309 ATTRIBUTE_UNUSED;
00310 static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
00311 static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
00312 static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
00313 reserv_sets_t);
00314 static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
00315 reserv_sets_t)
00316 ATTRIBUTE_UNUSED;
00317 static void output_cycle_reservs (FILE *, reserv_sets_t,
00318 int, int);
00319 static void output_reserv_sets (FILE *, reserv_sets_t);
00320 static state_t get_free_state (int, automaton_t);
00321 static void free_state (state_t);
00322 static hashval_t state_hash (const void *);
00323 static int state_eq_p (const void *, const void *);
00324 static state_t insert_state (state_t);
00325 static void set_state_reserv (state_t, int, int);
00326 static int intersected_state_reservs_p (state_t, state_t);
00327 static state_t states_union (state_t, state_t, reserv_sets_t);
00328 static state_t state_shift (state_t, reserv_sets_t);
00329 static void initiate_states (void);
00330 static void finish_states (void);
00331
00332 static void free_arc (arc_t);
00333 static void remove_arc (state_t, arc_t);
00334 static arc_t find_arc (state_t, state_t, ainsn_t);
00335 static arc_t add_arc (state_t, state_t, ainsn_t, int);
00336 static arc_t first_out_arc (state_t);
00337 static arc_t next_out_arc (arc_t);
00338 static void initiate_arcs (void);
00339 static void finish_arcs (void);
00340
00341 static automata_list_el_t get_free_automata_list_el (void);
00342 static void free_automata_list_el (automata_list_el_t);
00343 static void free_automata_list (automata_list_el_t);
00344 static hashval_t automata_list_hash (const void *);
00345 static int automata_list_eq_p (const void *, const void *);
00346 static void initiate_automata_lists (void);
00347 static void automata_list_start (void);
00348 static void automata_list_add (automaton_t);
00349 static automata_list_el_t automata_list_finish (void);
00350 static void finish_automata_lists (void);
00351
00352 static void initiate_excl_sets (void);
00353 static reserv_sets_t get_excl_set (reserv_sets_t);
00354
00355 static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
00356 static void initiate_presence_absence_pattern_sets (void);
00357 static int check_presence_pattern_sets (reserv_sets_t,
00358 reserv_sets_t, int);
00359 static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
00360 int);
00361
00362 static regexp_t copy_insn_regexp (regexp_t);
00363 static regexp_t transform_1 (regexp_t);
00364 static regexp_t transform_2 (regexp_t);
00365 static regexp_t transform_3 (regexp_t);
00366 static regexp_t regexp_transform_func
00367 (regexp_t, regexp_t (*) (regexp_t));
00368 static regexp_t transform_regexp (regexp_t);
00369 static void transform_insn_regexps (void);
00370
00371 static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
00372 static void check_regexp_units_distribution (const char *, regexp_t);
00373 static void check_unit_distributions_to_automata (void);
00374
00375 static int process_seq_for_forming_states (regexp_t, automaton_t,
00376 int);
00377 static void finish_forming_alt_state (alt_state_t,
00378 automaton_t);
00379 static void process_alts_for_forming_states (regexp_t,
00380 automaton_t, int);
00381 static void create_alt_states (automaton_t);
00382
00383 static void form_ainsn_with_same_reservs (automaton_t);
00384
00385 static reserv_sets_t form_reservs_matter (automaton_t);
00386 static void make_automaton (automaton_t);
00387 static void form_arcs_marked_by_insn (state_t);
00388 static int create_composed_state (state_t, arc_t, vla_ptr_t *);
00389 static void NDFA_to_DFA (automaton_t);
00390 static void pass_state_graph (state_t, void (*) (state_t));
00391 static void pass_states (automaton_t,
00392 void (*) (state_t));
00393 static void initiate_pass_states (void);
00394 static void add_achieved_state (state_t);
00395 static int set_out_arc_insns_equiv_num (state_t, int);
00396 static void clear_arc_insns_equiv_num (state_t);
00397 static void copy_equiv_class (vla_ptr_t *to,
00398 const vla_ptr_t *from);
00399 static int first_cycle_unit_presence (state_t, int);
00400 static int state_is_differed (state_t, state_t, int, int);
00401 static state_t init_equiv_class (state_t *states, int);
00402 static int partition_equiv_class (state_t *, int,
00403 vla_ptr_t *, int *);
00404 static void evaluate_equiv_classes (automaton_t, vla_ptr_t *);
00405 static void merge_states (automaton_t, vla_ptr_t *);
00406 static void set_new_cycle_flags (state_t);
00407 static void minimize_DFA (automaton_t);
00408 static void incr_states_and_arcs_nums (state_t);
00409 static void count_states_and_arcs (automaton_t, int *, int *);
00410 static void build_automaton (automaton_t);
00411
00412 static void set_order_state_num (state_t);
00413 static void enumerate_states (automaton_t);
00414
00415 static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
00416 static void delete_ainsn_from_equiv_class (ainsn_t);
00417 static void process_insn_equiv_class (ainsn_t, arc_t *);
00418 static void process_state_for_insn_equiv_partition (state_t);
00419 static void set_insn_equiv_classes (automaton_t);
00420
00421 static double estimate_one_automaton_bound (void);
00422 static int compare_max_occ_cycle_nums (const void *,
00423 const void *);
00424 static void units_to_automata_heuristic_distr (void);
00425 static ainsn_t create_ainsns (void);
00426 static void units_to_automata_distr (void);
00427 static void create_automata (void);
00428
00429 static void form_regexp (regexp_t);
00430 static const char *regexp_representation (regexp_t);
00431 static void finish_regexp_representation (void);
00432
00433 static void output_range_type (FILE *, long int, long int);
00434 static int longest_path_length (state_t);
00435 static void process_state_longest_path_length (state_t);
00436 static void output_dfa_max_issue_rate (void);
00437 static void output_vect (vect_el_t *, int);
00438 static void output_chip_member_name (FILE *, automaton_t);
00439 static void output_temp_chip_member_name (FILE *, automaton_t);
00440 static void output_translate_vect_name (FILE *, automaton_t);
00441 static void output_trans_full_vect_name (FILE *, automaton_t);
00442 static void output_trans_comb_vect_name (FILE *, automaton_t);
00443 static void output_trans_check_vect_name (FILE *, automaton_t);
00444 static void output_trans_base_vect_name (FILE *, automaton_t);
00445 static void output_state_alts_full_vect_name (FILE *, automaton_t);
00446 static void output_state_alts_comb_vect_name (FILE *, automaton_t);
00447 static void output_state_alts_check_vect_name (FILE *, automaton_t);
00448 static void output_state_alts_base_vect_name (FILE *, automaton_t);
00449 static void output_min_issue_delay_vect_name (FILE *, automaton_t);
00450 static void output_dead_lock_vect_name (FILE *, automaton_t);
00451 static void output_reserved_units_table_name (FILE *, automaton_t);
00452 static void output_state_member_type (FILE *, automaton_t);
00453 static void output_chip_definitions (void);
00454 static void output_translate_vect (automaton_t);
00455 static int comb_vect_p (state_ainsn_table_t);
00456 static state_ainsn_table_t create_state_ainsn_table (automaton_t);
00457 static void output_state_ainsn_table
00458 (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
00459 void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
00460 void (*) (FILE *, automaton_t));
00461 static void add_vect (state_ainsn_table_t,
00462 int, vect_el_t *, int);
00463 static int out_state_arcs_num (state_t);
00464 static int compare_transition_els_num (const void *, const void *);
00465 static void add_vect_el (vla_hwint_t *,
00466 ainsn_t, int);
00467 static void add_states_vect_el (state_t);
00468 static void output_trans_table (automaton_t);
00469 static void output_state_alts_table (automaton_t);
00470 static int min_issue_delay_pass_states (state_t, ainsn_t);
00471 static int min_issue_delay (state_t, ainsn_t);
00472 static void initiate_min_issue_delay_pass_states (void);
00473 static void output_min_issue_delay_table (automaton_t);
00474 static void output_dead_lock_vect (automaton_t);
00475 static void output_reserved_units_table (automaton_t);
00476 static void output_tables (void);
00477 static void output_max_insn_queue_index_def (void);
00478 static void output_insn_code_cases (void (*) (automata_list_el_t));
00479 static void output_automata_list_min_issue_delay_code (automata_list_el_t);
00480 static void output_internal_min_issue_delay_func (void);
00481 static void output_automata_list_transition_code (automata_list_el_t);
00482 static void output_internal_trans_func (void);
00483 static void output_internal_insn_code_evaluation (const char *,
00484 const char *, int);
00485 static void output_dfa_insn_code_func (void);
00486 static void output_trans_func (void);
00487 static void output_automata_list_state_alts_code (automata_list_el_t);
00488 static void output_internal_state_alts_func (void);
00489 static void output_state_alts_func (void);
00490 static void output_min_issue_delay_func (void);
00491 static void output_internal_dead_lock_func (void);
00492 static void output_dead_lock_func (void);
00493 static void output_internal_reset_func (void);
00494 static void output_size_func (void);
00495 static void output_reset_func (void);
00496 static void output_min_insn_conflict_delay_func (void);
00497 static void output_internal_insn_latency_func (void);
00498 static void output_insn_latency_func (void);
00499 static void output_print_reservation_func (void);
00500 static int units_cmp (const void *,
00501 const void *);
00502 static void output_get_cpu_unit_code_func (void);
00503 static void output_cpu_unit_reservation_p (void);
00504 static void output_dfa_clean_insn_cache_func (void);
00505 static void output_dfa_start_func (void);
00506 static void output_dfa_finish_func (void);
00507
00508 static void output_regexp (regexp_t );
00509 static void output_unit_set_el_list (unit_set_el_t);
00510 static void output_pattern_set_el_list (pattern_set_el_t);
00511 static void output_description (void);
00512 static void output_automaton_name (FILE *, automaton_t);
00513 static void output_automaton_units (automaton_t);
00514 static void add_state_reservs (state_t);
00515 static void output_state_arcs (state_t);
00516 static int state_reservs_cmp (const void *,
00517 const void *);
00518 static void remove_state_duplicate_reservs (void);
00519 static void output_state (state_t);
00520 static void output_automaton_descriptions (void);
00521 static void output_statistics (FILE *);
00522 static void output_time_statistics (FILE *);
00523 static void generate (void);
00524
00525 static void make_insn_alts_attr (void);
00526 static void make_internal_dfa_insn_code_attr (void);
00527 static void make_default_insn_latency_attr (void);
00528 static void make_bypass_attr (void);
00529 static const char *file_name_suffix (const char *);
00530 static const char *base_file_name (const char *);
00531 static void check_automata_insn_issues (void);
00532 static void add_automaton_state (state_t);
00533 static void form_important_insn_automata_lists (void);
00534
00535
00536 static pos_t no_pos = 0;
00537
00538
00539 static struct obstack irp;
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 #define VLA_PTR_CREATE(vla, allocated_length, name) \
00550 do \
00551 { \
00552 vla_ptr_t *const _vla_ptr = &(vla); \
00553 \
00554 VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
00555 _vla_ptr->length = 0; \
00556 } \
00557 while (0)
00558
00559
00560 #define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
00561
00562
00563 #define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
00564
00565
00566
00567 #define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray, \
00568 (vla).length - 1))
00569
00570 #define VLA_PTR_NULLIFY(vla) ((vla).length = 0)
00571
00572
00573 #define VLA_PTR_SHORTEN(vla, n) ((vla).length -= (n))
00574
00575
00576
00577 #define VLA_PTR_EXPAND(vla, n) \
00578 do { \
00579 vla_ptr_t *const _expand_vla_ptr = &(vla); \
00580 const size_t _new_length = (n) + _expand_vla_ptr->length; \
00581 \
00582 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
00583 VARRAY_GROW (_expand_vla_ptr->varray, \
00584 (_new_length - _expand_vla_ptr->length < 128 \
00585 ? _expand_vla_ptr->length + 128 : _new_length)); \
00586 _expand_vla_ptr->length = _new_length; \
00587 } while (0)
00588
00589
00590 #define VLA_PTR_ADD(vla, ptr) \
00591 do { \
00592 vla_ptr_t *const _vla_ptr = &(vla); \
00593 \
00594 VLA_PTR_EXPAND (*_vla_ptr, 1); \
00595 VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
00596 } while (0)
00597
00598
00599 #define VLA_PTR_LENGTH(vla) ((vla).length)
00600
00601
00602 #define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
00603
00604
00605
00606
00607
00608 #define VLA_HWINT_CREATE(vla, allocated_length, name) \
00609 do { \
00610 vla_hwint_t *const _vla_ptr = &(vla); \
00611 \
00612 VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
00613 _vla_ptr->length = 0; \
00614 } while (0)
00615
00616 #define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
00617
00618 #define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
00619
00620 #define VLA_HWINT_NULLIFY(vla) ((vla).length = 0)
00621
00622 #define VLA_HWINT_EXPAND(vla, n) \
00623 do { \
00624 vla_hwint_t *const _expand_vla_ptr = &(vla); \
00625 const size_t _new_length = (n) + _expand_vla_ptr->length; \
00626 \
00627 if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
00628 VARRAY_GROW (_expand_vla_ptr->varray, \
00629 (_new_length - _expand_vla_ptr->length < 128 \
00630 ? _expand_vla_ptr->length + 128 : _new_length)); \
00631 _expand_vla_ptr->length = _new_length; \
00632 } while (0)
00633
00634 #define VLA_HWINT_ADD(vla, ptr) \
00635 do { \
00636 vla_hwint_t *const _vla_ptr = &(vla); \
00637 \
00638 VLA_HWINT_EXPAND (*_vla_ptr, 1); \
00639 VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
00640 } while (0)
00641
00642 #define VLA_HWINT_LENGTH(vla) ((vla).length)
00643
00644 #define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
00645
00646
00647
00648
00649
00650
00651
00652 #define NO_MINIMIZATION_OPTION "-no-minimization"
00653
00654 #define TIME_OPTION "-time"
00655
00656 #define V_OPTION "-v"
00657
00658 #define W_OPTION "-w"
00659
00660 #define NDFA_OPTION "-ndfa"
00661
00662 #define PROGRESS_OPTION "-progress"
00663
00664
00665
00666
00667 static int ndfa_flag;
00668
00669
00670 static int no_minimization_flag;
00671
00672
00673
00674
00675
00676
00677 static int split_argument;
00678
00679
00680 static int time_flag;
00681
00682
00683
00684 static int v_flag;
00685
00686
00687
00688 static int progress_flag;
00689
00690
00691
00692 static int w_flag;
00693
00694
00695
00696
00697 static FILE *output_file;
00698
00699
00700
00701 static FILE *output_description_file;
00702
00703
00704 static char *output_description_file_name;
00705
00706
00707
00708 static struct description *description;
00709
00710
00711
00712
00713
00714 enum decl_mode
00715 {
00716 dm_unit,
00717 dm_bypass,
00718 dm_automaton,
00719 dm_excl,
00720 dm_presence,
00721 dm_absence,
00722 dm_reserv,
00723 dm_insn_reserv
00724 };
00725
00726
00727
00728 struct unit_decl
00729 {
00730 char *name;
00731
00732 char *automaton_name;
00733
00734
00735 char query_p;
00736
00737
00738
00739
00740
00741 char unit_is_used;
00742
00743
00744
00745 int unit_num;
00746
00747
00748
00749 struct automaton_decl *automaton_decl;
00750
00751
00752
00753 int max_occ_cycle_num;
00754
00755
00756
00757 int min_occ_cycle_num;
00758
00759
00760 unit_set_el_t excl_list;
00761
00762
00763 pattern_set_el_t presence_list;
00764 pattern_set_el_t final_presence_list;
00765
00766
00767 pattern_set_el_t absence_list;
00768 pattern_set_el_t final_absence_list;
00769
00770
00771 int query_num;
00772
00773
00774 int last_distribution_check_cycle;
00775
00776
00777
00778
00779
00780 int corresponding_automaton_num;
00781
00782
00783
00784
00785 char in_set_p;
00786 };
00787
00788
00789 struct bypass_decl
00790 {
00791 int latency;
00792 char *out_insn_name;
00793 char *in_insn_name;
00794 char *bypass_guard_name;
00795
00796
00797
00798
00799 struct insn_reserv_decl *out_insn_reserv;
00800 struct insn_reserv_decl *in_insn_reserv;
00801
00802 struct bypass_decl *next;
00803 };
00804
00805
00806 struct automaton_decl
00807 {
00808 char *name;
00809
00810
00811
00812
00813
00814 char automaton_is_used;
00815
00816
00817
00818
00819
00820
00821
00822 automaton_t corresponding_automaton;
00823 };
00824
00825
00826
00827 struct excl_rel_decl
00828 {
00829 int all_names_num;
00830 int first_list_length;
00831 char *names [1];
00832 };
00833
00834
00835
00836 struct unit_pattern_rel_decl
00837 {
00838 int final_p;
00839 int names_num;
00840 int patterns_num;
00841 char **names;
00842 char ***patterns;
00843 };
00844
00845
00846 struct reserv_decl
00847 {
00848 char *name;
00849 regexp_t regexp;
00850
00851
00852
00853
00854
00855 char reserv_is_used;
00856
00857
00858 int loop_pass_num;
00859 };
00860
00861
00862 struct insn_reserv_decl
00863 {
00864 rtx condexp;
00865 int default_latency;
00866 regexp_t regexp;
00867 char *name;
00868
00869
00870
00871
00872
00873 int insn_num;
00874
00875
00876 struct bypass_decl *bypass_list;
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 regexp_t transformed_regexp;
00887
00888
00889 arc_t arcs_marked_by_insn;
00890
00891
00892
00893
00894
00895 int equiv_class_num;
00896
00897
00898
00899 int state_alts;
00900
00901
00902 automata_list_el_t important_automata_list;
00903
00904 int processed_p;
00905 };
00906
00907
00908 struct decl
00909 {
00910
00911 enum decl_mode mode;
00912 pos_t pos;
00913 union
00914 {
00915 struct unit_decl unit;
00916 struct bypass_decl bypass;
00917 struct automaton_decl automaton;
00918 struct excl_rel_decl excl;
00919 struct unit_pattern_rel_decl presence;
00920 struct unit_pattern_rel_decl absence;
00921 struct reserv_decl reserv;
00922 struct insn_reserv_decl insn_reserv;
00923 } decl;
00924 };
00925
00926
00927 enum regexp_mode
00928 {
00929 rm_unit,
00930 rm_reserv,
00931 rm_nothing,
00932 rm_sequence,
00933 rm_repeat,
00934 rm_allof,
00935 rm_oneof
00936 };
00937
00938
00939 struct unit_regexp
00940 {
00941 char *name;
00942 unit_decl_t unit_decl;
00943 };
00944
00945
00946 struct reserv_regexp
00947 {
00948 char *name;
00949 struct reserv_decl *reserv_decl;
00950 };
00951
00952
00953 struct nothing_regexp
00954 {
00955
00956 char unused;
00957 };
00958
00959
00960
00961 struct sequence_regexp
00962 {
00963 int regexps_num;
00964 regexp_t regexps [1];
00965 };
00966
00967
00968 struct repeat_regexp
00969 {
00970 int repeat_num;
00971 regexp_t regexp;
00972 };
00973
00974
00975
00976 struct allof_regexp
00977 {
00978 int regexps_num;
00979 regexp_t regexps [1];
00980 };
00981
00982
00983
00984 struct oneof_regexp
00985 {
00986 int regexps_num;
00987 regexp_t regexps [1];
00988 };
00989
00990
00991 struct regexp
00992 {
00993
00994 enum regexp_mode mode;
00995 pos_t pos;
00996 union
00997 {
00998 struct unit_regexp unit;
00999 struct reserv_regexp reserv;
01000 struct nothing_regexp nothing;
01001 struct sequence_regexp sequence;
01002 struct repeat_regexp repeat;
01003 struct allof_regexp allof;
01004 struct oneof_regexp oneof;
01005 } regexp;
01006 };
01007
01008
01009
01010 struct description
01011 {
01012 int decls_num;
01013
01014
01015
01016
01017
01018 int units_num;
01019 int query_units_num;
01020 int insns_num;
01021
01022
01023
01024 int max_insn_reserv_cycles;
01025
01026
01027
01028
01029 automaton_t first_automaton;
01030
01031
01032
01033
01034
01035 decl_t decls [1];
01036 };
01037
01038
01039
01040
01041
01042
01043 struct unit_set_el
01044 {
01045 unit_decl_t unit_decl;
01046 unit_set_el_t next_unit_set_el;
01047 };
01048
01049
01050
01051
01052 struct pattern_set_el
01053 {
01054
01055 int units_num;
01056
01057 struct unit_decl **unit_decls;
01058 pattern_set_el_t next_pattern_set_el;
01059 };
01060
01061
01062
01063
01064
01065
01066
01067
01068 struct pattern_reserv
01069 {
01070 reserv_sets_t reserv;
01071 pattern_reserv_t next_pattern_reserv;
01072 };
01073
01074
01075
01076
01077
01078
01079 struct state
01080 {
01081
01082
01083 int new_cycle_p;
01084
01085
01086 reserv_sets_t reservs;
01087
01088
01089 int unique_num;
01090
01091
01092 automaton_t automaton;
01093
01094
01095 arc_t first_out_arc;
01096
01097 char it_was_placed_in_stack_for_NDFA_forming;
01098
01099 char it_was_placed_in_stack_for_DFA_forming;
01100
01101
01102
01103
01104
01105
01106 alt_state_t component_states;
01107
01108 int pass_num;
01109
01110
01111 state_t next_equiv_class_state;
01112
01113
01114 int equiv_class_num_1, equiv_class_num_2;
01115
01116
01117
01118 state_t equiv_class_state;
01119
01120
01121
01122 int order_state_num;
01123
01124
01125 int state_pass_num;
01126
01127
01128 int min_insn_issue_delay;
01129
01130
01131
01132
01133 int longest_path_length;
01134 };
01135
01136
01137
01138 #define UNDEFINED_LONGEST_PATH_LENGTH -1
01139
01140
01141 struct arc
01142 {
01143
01144
01145 state_t to_state;
01146
01147
01148
01149
01150 ainsn_t insn;
01151
01152
01153 arc_t next_out_arc;
01154
01155
01156 arc_t next_arc_marked_by_insn;
01157
01158
01159
01160 int state_alts;
01161 };
01162
01163
01164
01165
01166 struct alt_state
01167 {
01168
01169
01170 state_t state;
01171
01172
01173 alt_state_t next_alt_state;
01174
01175 alt_state_t next_sorted_alt_state;
01176 };
01177
01178
01179
01180 struct ainsn
01181 {
01182
01183
01184 struct insn_reserv_decl *insn_reserv_decl;
01185
01186
01187 ainsn_t next_ainsn;
01188
01189
01190
01191 alt_state_t alt_states;
01192
01193
01194
01195 alt_state_t sorted_alt_states;
01196
01197
01198 ainsn_t next_same_reservs_insn;
01199
01200
01201
01202
01203
01204 char first_insn_with_same_reservs;
01205
01206
01207 char arc_exists_p;
01208
01209
01210 ainsn_t next_equiv_class_insn;
01211
01212
01213 char first_ainsn_with_given_equivalence_num;
01214
01215
01216
01217 int insn_equiv_class_num;
01218
01219
01220
01221 int important_p;
01222 };
01223
01224
01225 struct automaton
01226 {
01227
01228
01229 ainsn_t ainsn_list;
01230
01231
01232
01233 struct automaton_decl *corresponding_automaton_decl;
01234
01235 automaton_t next_automaton;
01236
01237
01238 state_t start_state;
01239
01240
01241
01242 int insn_equiv_classes_num;
01243
01244 int achieved_states_num;
01245
01246
01247 int automaton_order_num;
01248
01249
01250 int NDFA_states_num, DFA_states_num;
01251
01252
01253 int minimal_DFA_states_num;
01254 int NDFA_arcs_num, DFA_arcs_num;
01255
01256
01257 int minimal_DFA_arcs_num;
01258
01259
01260 state_ainsn_table_t trans_table;
01261 state_ainsn_table_t state_alts_table;
01262
01263
01264 int max_min_delay;
01265
01266
01267
01268 int min_issue_delay_table_compression_factor;
01269 };
01270
01271
01272 struct automata_list_el
01273 {
01274
01275 automaton_t automaton;
01276
01277 automata_list_el_t next_automata_list_el;
01278 };
01279
01280
01281 struct state_ainsn_table
01282 {
01283
01284 automaton_t automaton;
01285
01286
01287 vla_hwint_t comb_vect;
01288 vla_hwint_t check_vect;
01289 vla_hwint_t base_vect;
01290
01291 vla_hwint_t full_vect;
01292
01293 int min_comb_vect_el_value, max_comb_vect_el_value;
01294 int min_base_vect_el_value, max_base_vect_el_value;
01295 };
01296
01297
01298
01299
01300 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
01301
01302 #define DECL_UNIT(d) __extension__ \
01303 (({ struct decl *const _decl = (d); \
01304 if (_decl->mode != dm_unit) \
01305 decl_mode_check_failed (_decl->mode, "dm_unit", \
01306 __FILE__, __LINE__, __FUNCTION__); \
01307 &(_decl)->decl.unit; }))
01308
01309 #define DECL_BYPASS(d) __extension__ \
01310 (({ struct decl *const _decl = (d); \
01311 if (_decl->mode != dm_bypass) \
01312 decl_mode_check_failed (_decl->mode, "dm_bypass", \
01313 __FILE__, __LINE__, __FUNCTION__); \
01314 &(_decl)->decl.bypass; }))
01315
01316 #define DECL_AUTOMATON(d) __extension__ \
01317 (({ struct decl *const _decl = (d); \
01318 if (_decl->mode != dm_automaton) \
01319 decl_mode_check_failed (_decl->mode, "dm_automaton", \
01320 __FILE__, __LINE__, __FUNCTION__); \
01321 &(_decl)->decl.automaton; }))
01322
01323 #define DECL_EXCL(d) __extension__ \
01324 (({ struct decl *const _decl = (d); \
01325 if (_decl->mode != dm_excl) \
01326 decl_mode_check_failed (_decl->mode, "dm_excl", \
01327 __FILE__, __LINE__, __FUNCTION__); \
01328 &(_decl)->decl.excl; }))
01329
01330 #define DECL_PRESENCE(d) __extension__ \
01331 (({ struct decl *const _decl = (d); \
01332 if (_decl->mode != dm_presence) \
01333 decl_mode_check_failed (_decl->mode, "dm_presence", \
01334 __FILE__, __LINE__, __FUNCTION__); \
01335 &(_decl)->decl.presence; }))
01336
01337 #define DECL_ABSENCE(d) __extension__ \
01338 (({ struct decl *const _decl = (d); \
01339 if (_decl->mode != dm_absence) \
01340 decl_mode_check_failed (_decl->mode, "dm_absence", \
01341 __FILE__, __LINE__, __FUNCTION__); \
01342 &(_decl)->decl.absence; }))
01343
01344 #define DECL_RESERV(d) __extension__ \
01345 (({ struct decl *const _decl = (d); \
01346 if (_decl->mode != dm_reserv) \
01347 decl_mode_check_failed (_decl->mode, "dm_reserv", \
01348 __FILE__, __LINE__, __FUNCTION__); \
01349 &(_decl)->decl.reserv; }))
01350
01351 #define DECL_INSN_RESERV(d) __extension__ \
01352 (({ struct decl *const _decl = (d); \
01353 if (_decl->mode != dm_insn_reserv) \
01354 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
01355 __FILE__, __LINE__, __FUNCTION__); \
01356 &(_decl)->decl.insn_reserv; }))
01357
01358 static const char *decl_name (enum decl_mode);
01359 static void decl_mode_check_failed (enum decl_mode, const char *,
01360 const char *, int, const char *);
01361
01362
01363 static const char *
01364 decl_name (enum decl_mode mode)
01365 {
01366 static char str [100];
01367
01368 if (mode == dm_unit)
01369 return "dm_unit";
01370 else if (mode == dm_bypass)
01371 return "dm_bypass";
01372 else if (mode == dm_automaton)
01373 return "dm_automaton";
01374 else if (mode == dm_excl)
01375 return "dm_excl";
01376 else if (mode == dm_presence)
01377 return "dm_presence";
01378 else if (mode == dm_absence)
01379 return "dm_absence";
01380 else if (mode == dm_reserv)
01381 return "dm_reserv";
01382 else if (mode == dm_insn_reserv)
01383 return "dm_insn_reserv";
01384 else
01385 sprintf (str, "unknown (%d)", (int) mode);
01386 return str;
01387 }
01388
01389
01390
01391 static void
01392 decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
01393 const char *file, int line, const char *func)
01394 {
01395 fprintf
01396 (stderr,
01397 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
01398 file, line, func, expected_mode_str, decl_name (mode));
01399 exit (1);
01400 }
01401
01402
01403 #define REGEXP_UNIT(r) __extension__ \
01404 (({ struct regexp *const _regexp = (r); \
01405 if (_regexp->mode != rm_unit) \
01406 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
01407 __FILE__, __LINE__, __FUNCTION__); \
01408 &(_regexp)->regexp.unit; }))
01409
01410 #define REGEXP_RESERV(r) __extension__ \
01411 (({ struct regexp *const _regexp = (r); \
01412 if (_regexp->mode != rm_reserv) \
01413 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
01414 __FILE__, __LINE__, __FUNCTION__); \
01415 &(_regexp)->regexp.reserv; }))
01416
01417 #define REGEXP_SEQUENCE(r) __extension__ \
01418 (({ struct regexp *const _regexp = (r); \
01419 if (_regexp->mode != rm_sequence) \
01420 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
01421 __FILE__, __LINE__, __FUNCTION__); \
01422 &(_regexp)->regexp.sequence; }))
01423
01424 #define REGEXP_REPEAT(r) __extension__ \
01425 (({ struct regexp *const _regexp = (r); \
01426 if (_regexp->mode != rm_repeat) \
01427 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
01428 __FILE__, __LINE__, __FUNCTION__); \
01429 &(_regexp)->regexp.repeat; }))
01430
01431 #define REGEXP_ALLOF(r) __extension__ \
01432 (({ struct regexp *const _regexp = (r); \
01433 if (_regexp->mode != rm_allof) \
01434 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
01435 __FILE__, __LINE__, __FUNCTION__); \
01436 &(_regexp)->regexp.allof; }))
01437
01438 #define REGEXP_ONEOF(r) __extension__ \
01439 (({ struct regexp *const _regexp = (r); \
01440 if (_regexp->mode != rm_oneof) \
01441 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
01442 __FILE__, __LINE__, __FUNCTION__); \
01443 &(_regexp)->regexp.oneof; }))
01444
01445 static const char *regexp_name (enum regexp_mode);
01446 static void regexp_mode_check_failed (enum regexp_mode, const char *,
01447 const char *, int,
01448 const char *);
01449
01450
01451
01452 static const char *
01453 regexp_name (enum regexp_mode mode)
01454 {
01455 switch (mode)
01456 {
01457 case rm_unit:
01458 return "rm_unit";
01459 case rm_reserv:
01460 return "rm_reserv";
01461 case rm_nothing:
01462 return "rm_nothing";
01463 case rm_sequence:
01464 return "rm_sequence";
01465 case rm_repeat:
01466 return "rm_repeat";
01467 case rm_allof:
01468 return "rm_allof";
01469 case rm_oneof:
01470 return "rm_oneof";
01471 default:
01472 gcc_unreachable ();
01473 }
01474 }
01475
01476
01477
01478 static void
01479 regexp_mode_check_failed (enum regexp_mode mode,
01480 const char *expected_mode_str,
01481 const char *file, int line, const char *func)
01482 {
01483 fprintf
01484 (stderr,
01485 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
01486 file, line, func, expected_mode_str, regexp_name (mode));
01487 exit (1);
01488 }
01489
01490 #else
01491
01492 #define DECL_UNIT(d) (&(d)->decl.unit)
01493 #define DECL_BYPASS(d) (&(d)->decl.bypass)
01494 #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
01495 #define DECL_EXCL(d) (&(d)->decl.excl)
01496 #define DECL_PRESENCE(d) (&(d)->decl.presence)
01497 #define DECL_ABSENCE(d) (&(d)->decl.absence)
01498 #define DECL_RESERV(d) (&(d)->decl.reserv)
01499 #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
01500
01501 #define REGEXP_UNIT(r) (&(r)->regexp.unit)
01502 #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
01503 #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
01504 #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
01505 #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
01506 #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
01507
01508 #endif
01509
01510
01511 static void *
01512 create_node (size_t size)
01513 {
01514 void *result;
01515
01516 obstack_blank (&irp, size);
01517 result = obstack_base (&irp);
01518 obstack_finish (&irp);
01519
01520 memset (result, 0, size);
01521 return result;
01522 }
01523
01524
01525 static void *
01526 copy_node (const void *from, size_t size)
01527 {
01528 void *const result = create_node (size);
01529 memcpy (result, from, size);
01530 return result;
01531 }
01532
01533
01534 static char *
01535 check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
01536 {
01537 const char *str;
01538
01539 for (str = name; *str != '\0'; str++)
01540 if (*str == '\"')
01541 error ("Name `%s' contains quotes", name);
01542 return name;
01543 }
01544
01545
01546
01547 static vla_ptr_t decls;
01548
01549
01550
01551
01552
01553
01554 static char *
01555 next_sep_el (char **pstr, int sep, int par_flag)
01556 {
01557 char *out_str;
01558 char *p;
01559 int pars_num;
01560 int n_spaces;
01561
01562
01563 while (ISSPACE ((int) **pstr))
01564 (*pstr)++;
01565
01566 if (**pstr == '\0')
01567 return NULL;
01568
01569 n_spaces = 0;
01570 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
01571 {
01572 if (par_flag && *p == '(')
01573 pars_num++;
01574 else if (par_flag && *p == ')')
01575 pars_num--;
01576 else if (pars_num == 0 && *p == sep)
01577 break;
01578 if (pars_num == 0 && ISSPACE ((int) *p))
01579 n_spaces++;
01580 else
01581 {
01582 for (; n_spaces != 0; n_spaces--)
01583 obstack_1grow (&irp, p [-n_spaces]);
01584 obstack_1grow (&irp, *p);
01585 }
01586 }
01587 obstack_1grow (&irp, '\0');
01588 out_str = obstack_base (&irp);
01589 obstack_finish (&irp);
01590
01591 *pstr = p;
01592 if (**pstr == sep)
01593 (*pstr)++;
01594
01595 return out_str;
01596 }
01597
01598
01599
01600
01601
01602 static int
01603 n_sep_els (char *s, int sep, int par_flag)
01604 {
01605 int n;
01606 int pars_num;
01607
01608 if (*s == '\0')
01609 return 0;
01610
01611 for (pars_num = 0, n = 1; *s; s++)
01612 if (par_flag && *s == '(')
01613 pars_num++;
01614 else if (par_flag && *s == ')')
01615 pars_num--;
01616 else if (pars_num == 0 && *s == sep)
01617 n++;
01618
01619 return (pars_num != 0 ? -1 : n);
01620 }
01621
01622
01623
01624
01625
01626
01627 static char **
01628 get_str_vect (char *str, int *els_num, int sep, int paren_p)
01629 {
01630 int i;
01631 char **vect;
01632 char **pstr;
01633 char *trail;
01634
01635 *els_num = n_sep_els (str, sep, paren_p);
01636 if (*els_num <= 0)
01637 return NULL;
01638 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
01639 vect = (char **) obstack_base (&irp);
01640 obstack_finish (&irp);
01641 pstr = &str;
01642 for (i = 0; i < *els_num; i++)
01643 vect [i] = next_sep_el (pstr, sep, paren_p);
01644 trail = next_sep_el (pstr, sep, paren_p);
01645 gcc_assert (!trail);
01646 vect [i] = NULL;
01647 return vect;
01648 }
01649
01650
01651
01652
01653
01654 void
01655 gen_cpu_unit (rtx def)
01656 {
01657 decl_t decl;
01658 char **str_cpu_units;
01659 int vect_length;
01660 int i;
01661
01662 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
01663 FALSE);
01664 if (str_cpu_units == NULL)
01665 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
01666 for (i = 0; i < vect_length; i++)
01667 {
01668 decl = create_node (sizeof (struct decl));
01669 decl->mode = dm_unit;
01670 decl->pos = 0;
01671 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
01672 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
01673 DECL_UNIT (decl)->query_p = 0;
01674 DECL_UNIT (decl)->min_occ_cycle_num = -1;
01675 DECL_UNIT (decl)->in_set_p = 0;
01676 VLA_PTR_ADD (decls, decl);
01677 num_dfa_decls++;
01678 }
01679 }
01680
01681
01682
01683
01684
01685 void
01686 gen_query_cpu_unit (rtx def)
01687 {
01688 decl_t decl;
01689 char **str_cpu_units;
01690 int vect_length;
01691 int i;
01692
01693 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
01694 FALSE);
01695 if (str_cpu_units == NULL)
01696 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
01697 for (i = 0; i < vect_length; i++)
01698 {
01699 decl = create_node (sizeof (struct decl));
01700 decl->mode = dm_unit;
01701 decl->pos = 0;
01702 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
01703 DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
01704 DECL_UNIT (decl)->query_p = 1;
01705 VLA_PTR_ADD (decls, decl);
01706 num_dfa_decls++;
01707 }
01708 }
01709
01710
01711
01712
01713
01714
01715 void
01716 gen_bypass (rtx def)
01717 {
01718 decl_t decl;
01719 char **out_insns;
01720 int out_length;
01721 char **in_insns;
01722 int in_length;
01723 int i, j;
01724
01725 out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
01726 if (out_insns == NULL)
01727 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
01728 in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
01729 if (in_insns == NULL)
01730 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
01731 for (i = 0; i < out_length; i++)
01732 for (j = 0; j < in_length; j++)
01733 {
01734 decl = create_node (sizeof (struct decl));
01735 decl->mode = dm_bypass;
01736 decl->pos = 0;
01737 DECL_BYPASS (decl)->latency = XINT (def, 0);
01738 DECL_BYPASS (decl)->out_insn_name = out_insns [i];
01739 DECL_BYPASS (decl)->in_insn_name = in_insns [j];
01740 DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
01741 VLA_PTR_ADD (decls, decl);
01742 num_dfa_decls++;
01743 }
01744 }
01745
01746
01747
01748
01749
01750
01751 void
01752 gen_excl_set (rtx def)
01753 {
01754 decl_t decl;
01755 char **first_str_cpu_units;
01756 char **second_str_cpu_units;
01757 int first_vect_length;
01758 int length;
01759 int i;
01760
01761 first_str_cpu_units
01762 = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
01763 if (first_str_cpu_units == NULL)
01764 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
01765 second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
01766 FALSE);
01767 if (second_str_cpu_units == NULL)
01768 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
01769 length += first_vect_length;
01770 decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
01771 decl->mode = dm_excl;
01772 decl->pos = 0;
01773 DECL_EXCL (decl)->all_names_num = length;
01774 DECL_EXCL (decl)->first_list_length = first_vect_length;
01775 for (i = 0; i < length; i++)
01776 if (i < first_vect_length)
01777 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
01778 else
01779 DECL_EXCL (decl)->names [i]
01780 = second_str_cpu_units [i - first_vect_length];
01781 VLA_PTR_ADD (decls, decl);
01782 num_dfa_decls++;
01783 }
01784
01785
01786
01787
01788
01789
01790
01791 static void
01792 gen_presence_absence_set (rtx def, int presence_p, int final_p)
01793 {
01794 decl_t decl;
01795 char **str_cpu_units;
01796 char ***str_patterns;
01797 int cpu_units_length;
01798 int length;
01799 int patterns_length;
01800 int i;
01801
01802 str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
01803 FALSE);
01804 if (str_cpu_units == NULL)
01805 fatal ((presence_p
01806 ? (final_p
01807 ? "invalid first string `%s' in final_presence_set"
01808 : "invalid first string `%s' in presence_set")
01809 : (final_p
01810 ? "invalid first string `%s' in final_absence_set"
01811 : "invalid first string `%s' in absence_set")),
01812 XSTR (def, 0));
01813 str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
01814 &patterns_length, ',', FALSE);
01815 if (str_patterns == NULL)
01816 fatal ((presence_p
01817 ? (final_p
01818 ? "invalid second string `%s' in final_presence_set"
01819 : "invalid second string `%s' in presence_set")
01820 : (final_p
01821 ? "invalid second string `%s' in final_absence_set"
01822 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
01823 for (i = 0; i < patterns_length; i++)
01824 {
01825 str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
01826 FALSE);
01827 gcc_assert (str_patterns [i]);
01828 }
01829 decl = create_node (sizeof (struct decl));
01830 decl->pos = 0;
01831 if (presence_p)
01832 {
01833 decl->mode = dm_presence;
01834 DECL_PRESENCE (decl)->names_num = cpu_units_length;
01835 DECL_PRESENCE (decl)->names = str_cpu_units;
01836 DECL_PRESENCE (decl)->patterns = str_patterns;
01837 DECL_PRESENCE (decl)->patterns_num = patterns_length;
01838 DECL_PRESENCE (decl)->final_p = final_p;
01839 }
01840 else
01841 {
01842 decl->mode = dm_absence;
01843 DECL_ABSENCE (decl)->names_num = cpu_units_length;
01844 DECL_ABSENCE (decl)->names = str_cpu_units;
01845 DECL_ABSENCE (decl)->patterns = str_patterns;
01846 DECL_ABSENCE (decl)->patterns_num = patterns_length;
01847 DECL_ABSENCE (decl)->final_p = final_p;
01848 }
01849 VLA_PTR_ADD (decls, decl);
01850 num_dfa_decls++;
01851 }
01852
01853
01854
01855
01856
01857
01858 void
01859 gen_presence_set (rtx def)
01860 {
01861 gen_presence_absence_set (def, TRUE, FALSE);
01862 }
01863
01864
01865
01866
01867
01868
01869 void
01870 gen_final_presence_set (rtx def)
01871 {
01872 gen_presence_absence_set (def, TRUE, TRUE);
01873 }
01874
01875
01876
01877
01878
01879
01880 void
01881 gen_absence_set (rtx def)
01882 {
01883 gen_presence_absence_set (def, FALSE, FALSE);
01884 }
01885
01886
01887
01888
01889
01890
01891 void
01892 gen_final_absence_set (rtx def)
01893 {
01894 gen_presence_absence_set (def, FALSE, TRUE);
01895 }
01896
01897
01898
01899
01900
01901
01902 void
01903 gen_automaton (rtx def)
01904 {
01905 decl_t decl;
01906 char **str_automata;
01907 int vect_length;
01908 int i;
01909
01910 str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
01911 FALSE);
01912 if (str_automata == NULL)
01913 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
01914 for (i = 0; i < vect_length; i++)
01915 {
01916 decl = create_node (sizeof (struct decl));
01917 decl->mode = dm_automaton;
01918 decl->pos = 0;
01919 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
01920 VLA_PTR_ADD (decls, decl);
01921 num_dfa_decls++;
01922 }
01923 }
01924
01925
01926
01927
01928
01929 void
01930 gen_automata_option (rtx def)
01931 {
01932 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
01933 no_minimization_flag = 1;
01934 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
01935 time_flag = 1;
01936 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
01937 v_flag = 1;
01938 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
01939 w_flag = 1;
01940 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
01941 ndfa_flag = 1;
01942 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
01943 progress_flag = 1;
01944 else
01945 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
01946 }
01947
01948
01949 #define NOTHING_NAME "nothing"
01950
01951
01952
01953 static char *reserv_str;
01954
01955
01956 static regexp_t
01957 gen_regexp_el (char *str)
01958 {
01959 regexp_t regexp;
01960 int len;
01961
01962 if (*str == '(')
01963 {
01964 len = strlen (str);
01965 if (str [len - 1] != ')')
01966 fatal ("garbage after ) in reservation `%s'", reserv_str);
01967 str [len - 1] = '\0';
01968 regexp = gen_regexp_sequence (str + 1);
01969 }
01970 else if (strcmp (str, NOTHING_NAME) == 0)
01971 {
01972 regexp = create_node (sizeof (struct decl));
01973 regexp->mode = rm_nothing;
01974 }
01975 else
01976 {
01977 regexp = create_node (sizeof (struct decl));
01978 regexp->mode = rm_unit;
01979 REGEXP_UNIT (regexp)->name = str;
01980 }
01981 return regexp;
01982 }
01983
01984
01985 static regexp_t
01986 gen_regexp_repeat (char *str)
01987 {
01988 regexp_t regexp;
01989 regexp_t repeat;
01990 char **repeat_vect;
01991 int els_num;
01992 int i;
01993
01994 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
01995 if (repeat_vect == NULL)
01996 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
01997 if (els_num > 1)
01998 {
01999 regexp = gen_regexp_el (repeat_vect [0]);
02000 for (i = 1; i < els_num; i++)
02001 {
02002 repeat = create_node (sizeof (struct regexp));
02003 repeat->mode = rm_repeat;
02004 REGEXP_REPEAT (repeat)->regexp = regexp;
02005 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
02006 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
02007 fatal ("repetition `%s' <= 1 in reservation `%s'",
02008 str, reserv_str);
02009 regexp = repeat;
02010 }
02011 return regexp;
02012 }
02013 else
02014 return gen_regexp_el (str);
02015 }
02016
02017
02018 static regexp_t
02019 gen_regexp_allof (char *str)
02020 {
02021 regexp_t allof;
02022 char **allof_vect;
02023 int els_num;
02024 int i;
02025
02026 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
02027 if (allof_vect == NULL)
02028 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
02029 if (els_num > 1)
02030 {
02031 allof = create_node (sizeof (struct regexp)
02032 + sizeof (regexp_t) * (els_num - 1));
02033 allof->mode = rm_allof;
02034 REGEXP_ALLOF (allof)->regexps_num = els_num;
02035 for (i = 0; i < els_num; i++)
02036 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
02037 return allof;
02038 }
02039 else
02040 return gen_regexp_repeat (str);
02041 }
02042
02043
02044 static regexp_t
02045 gen_regexp_oneof (char *str)
02046 {
02047 regexp_t oneof;
02048 char **oneof_vect;
02049 int els_num;
02050 int i;
02051
02052 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
02053 if (oneof_vect == NULL)
02054 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
02055 if (els_num > 1)
02056 {
02057 oneof = create_node (sizeof (struct regexp)
02058 + sizeof (regexp_t) * (els_num - 1));
02059 oneof->mode = rm_oneof;
02060 REGEXP_ONEOF (oneof)->regexps_num = els_num;
02061 for (i = 0; i < els_num; i++)
02062 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
02063 return oneof;
02064 }
02065 else
02066 return gen_regexp_allof (str);
02067 }
02068
02069
02070 static regexp_t
02071 gen_regexp_sequence (char *str)
02072 {
02073 regexp_t sequence;
02074 char **sequence_vect;
02075 int els_num;
02076 int i;
02077
02078 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
02079 if (els_num > 1)
02080 {
02081 sequence = create_node (sizeof (struct regexp)
02082 + sizeof (regexp_t) * (els_num - 1));
02083 sequence->mode = rm_sequence;
02084 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
02085 for (i = 0; i < els_num; i++)
02086 REGEXP_SEQUENCE (sequence)->regexps [i]
02087 = gen_regexp_oneof (sequence_vect [i]);
02088 return sequence;
02089 }
02090 else
02091 return gen_regexp_oneof (str);
02092 }
02093
02094
02095 static regexp_t
02096 gen_regexp (char *str)
02097 {
02098 reserv_str = str;
02099 return gen_regexp_sequence (str);;
02100 }
02101
02102
02103
02104
02105
02106
02107 void
02108 gen_reserv (rtx def)
02109 {
02110 decl_t decl;
02111
02112 decl = create_node (sizeof (struct decl));
02113 decl->mode = dm_reserv;
02114 decl->pos = 0;
02115 DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
02116 DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
02117 VLA_PTR_ADD (decls, decl);
02118 num_dfa_decls++;
02119 }
02120
02121
02122
02123
02124
02125
02126 void
02127 gen_insn_reserv (rtx def)
02128 {
02129 decl_t decl;
02130
02131 decl = create_node (sizeof (struct decl));
02132 decl->mode = dm_insn_reserv;
02133 decl->pos = 0;
02134 DECL_INSN_RESERV (decl)->name
02135 = check_name ((char *) XSTR (def, 0), decl->pos);
02136 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
02137 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
02138 DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
02139 VLA_PTR_ADD (decls, decl);
02140 num_dfa_decls++;
02141 }
02142
02143
02144
02145
02146 static unsigned
02147 string_hash (const char *string)
02148 {
02149 unsigned result, i;
02150
02151 for (result = i = 0;*string++ != '\0'; i++)
02152 result += ((unsigned char) *string << (i % CHAR_BIT));
02153 return result;
02154 }
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166 static hashval_t
02167 automaton_decl_hash (const void *automaton_decl)
02168 {
02169 const decl_t decl = (decl_t) automaton_decl;
02170
02171 gcc_assert (decl->mode != dm_automaton
02172 || DECL_AUTOMATON (decl)->name);
02173 return string_hash (DECL_AUTOMATON (decl)->name);
02174 }
02175
02176
02177
02178
02179
02180 static int
02181 automaton_decl_eq_p (const void* automaton_decl_1,
02182 const void* automaton_decl_2)
02183 {
02184 const decl_t decl1 = (decl_t) automaton_decl_1;
02185 const decl_t decl2 = (decl_t) automaton_decl_2;
02186
02187 gcc_assert (decl1->mode == dm_automaton
02188 && DECL_AUTOMATON (decl1)->name
02189 && decl2->mode == dm_automaton
02190 && DECL_AUTOMATON (decl2)->name);
02191 return strcmp (DECL_AUTOMATON (decl1)->name,
02192 DECL_AUTOMATON (decl2)->name) == 0;
02193 }
02194
02195
02196
02197 static htab_t automaton_decl_table;
02198
02199
02200
02201
02202
02203
02204 static decl_t
02205 insert_automaton_decl (decl_t automaton_decl)
02206 {
02207 void **entry_ptr;
02208
02209 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
02210 if (*entry_ptr == NULL)
02211 *entry_ptr = (void *) automaton_decl;
02212 return (decl_t) *entry_ptr;
02213 }
02214
02215
02216
02217
02218 static struct decl work_automaton_decl;
02219
02220
02221
02222
02223
02224 static decl_t
02225 find_automaton_decl (char *name)
02226 {
02227 void *entry;
02228
02229 work_automaton_decl.mode = dm_automaton;
02230 DECL_AUTOMATON (&work_automaton_decl)->name = name;
02231 entry = htab_find (automaton_decl_table, &work_automaton_decl);
02232 return (decl_t) entry;
02233 }
02234
02235
02236
02237
02238
02239 static void
02240 initiate_automaton_decl_table (void)
02241 {
02242 work_automaton_decl.mode = dm_automaton;
02243 automaton_decl_table = htab_create (10, automaton_decl_hash,
02244 automaton_decl_eq_p, (htab_del) 0);
02245 }
02246
02247
02248
02249
02250 static void
02251 finish_automaton_decl_table (void)
02252 {
02253 htab_delete (automaton_decl_table);
02254 }
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267 static hashval_t
02268 insn_decl_hash (const void *insn_decl)
02269 {
02270 const decl_t decl = (decl_t) insn_decl;
02271
02272 gcc_assert (decl->mode == dm_insn_reserv
02273 && DECL_INSN_RESERV (decl)->name);
02274 return string_hash (DECL_INSN_RESERV (decl)->name);
02275 }
02276
02277
02278
02279
02280 static int
02281 insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
02282 {
02283 const decl_t decl1 = (decl_t) insn_decl_1;
02284 const decl_t decl2 = (decl_t) insn_decl_2;
02285
02286 gcc_assert (decl1->mode == dm_insn_reserv
02287 && DECL_INSN_RESERV (decl1)->name
02288 && decl2->mode == dm_insn_reserv
02289 && DECL_INSN_RESERV (decl2)->name);
02290 return strcmp (DECL_INSN_RESERV (decl1)->name,
02291 DECL_INSN_RESERV (decl2)->name) == 0;
02292 }
02293
02294
02295
02296
02297 static htab_t insn_decl_table;
02298
02299
02300
02301
02302
02303 static decl_t
02304 insert_insn_decl (decl_t insn_decl)
02305 {
02306 void **entry_ptr;
02307
02308 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
02309 if (*entry_ptr == NULL)
02310 *entry_ptr = (void *) insn_decl;
02311 return (decl_t) *entry_ptr;
02312 }
02313
02314
02315
02316
02317 static struct decl work_insn_decl;
02318
02319
02320
02321
02322
02323 static decl_t
02324 find_insn_decl (char *name)
02325 {
02326 void *entry;
02327
02328 work_insn_decl.mode = dm_insn_reserv;
02329 DECL_INSN_RESERV (&work_insn_decl)->name = name;
02330 entry = htab_find (insn_decl_table, &work_insn_decl);
02331 return (decl_t) entry;
02332 }
02333
02334
02335
02336
02337
02338 static void
02339 initiate_insn_decl_table (void)
02340 {
02341 work_insn_decl.mode = dm_insn_reserv;
02342 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
02343 (htab_del) 0);
02344 }
02345
02346
02347
02348
02349 static void
02350 finish_insn_decl_table (void)
02351 {
02352 htab_delete (insn_decl_table);
02353 }
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365 static hashval_t
02366 decl_hash (const void *decl)
02367 {
02368 const decl_t d = (const decl_t) decl;
02369
02370 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
02371 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
02372 return string_hash (d->mode == dm_unit
02373 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
02374 }
02375
02376
02377
02378
02379 static int
02380 decl_eq_p (const void *decl_1, const void *decl_2)
02381 {
02382 const decl_t d1 = (const decl_t) decl_1;
02383 const decl_t d2 = (const decl_t) decl_2;
02384
02385 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
02386 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
02387 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
02388 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
02389 return strcmp ((d1->mode == dm_unit
02390 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
02391 (d2->mode == dm_unit
02392 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
02393 }
02394
02395
02396
02397 static htab_t decl_table;
02398
02399
02400
02401
02402
02403
02404 static decl_t
02405 insert_decl (decl_t decl)
02406 {
02407 void **entry_ptr;
02408
02409 entry_ptr = htab_find_slot (decl_table, decl, 1);
02410 if (*entry_ptr == NULL)
02411 *entry_ptr = (void *) decl;
02412 return (decl_t) *entry_ptr;
02413 }
02414
02415
02416
02417 static struct decl work_decl;
02418
02419
02420
02421
02422
02423 static decl_t
02424 find_decl (char *name)
02425 {
02426 void *entry;
02427
02428 work_decl.mode = dm_unit;
02429 DECL_UNIT (&work_decl)->name = name;
02430 entry = htab_find (decl_table, &work_decl);
02431 return (decl_t) entry;
02432 }
02433
02434
02435
02436
02437
02438 static void
02439 initiate_decl_table (void)
02440 {
02441 work_decl.mode = dm_unit;
02442 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
02443 }
02444
02445
02446
02447
02448 static void
02449 finish_decl_table (void)
02450 {
02451 htab_delete (decl_table);
02452 }
02453
02454
02455
02456
02457
02458
02459
02460 static unit_set_el_t
02461 process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
02462 {
02463 unit_set_el_t el_list;
02464 unit_set_el_t last_el;
02465 unit_set_el_t new_el;
02466 decl_t decl_in_table;
02467 int i;
02468
02469 el_list = NULL;
02470 last_el = NULL;
02471 for (i = 0; i < num; i++)
02472 {
02473 decl_in_table = find_decl (names [i]);
02474 if (decl_in_table == NULL)
02475 error ("unit `%s' in exclusion is not declared", names [i]);
02476 else if (decl_in_table->mode != dm_unit)
02477 error ("`%s' in exclusion is not unit", names [i]);
02478 else
02479 {
02480 new_el = create_node (sizeof (struct unit_set_el));
02481 new_el->unit_decl = DECL_UNIT (decl_in_table);
02482 new_el->next_unit_set_el = NULL;
02483 if (last_el == NULL)
02484 el_list = last_el = new_el;
02485 else
02486 {
02487 last_el->next_unit_set_el = new_el;
02488 last_el = last_el->next_unit_set_el;
02489 }
02490 }
02491 }
02492 return el_list;
02493 }
02494
02495
02496
02497
02498 static void
02499 add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
02500 pos_t excl_pos ATTRIBUTE_UNUSED)
02501 {
02502 unit_set_el_t dst;
02503 unit_set_el_t src;
02504 unit_set_el_t curr_el;
02505 unit_set_el_t prev_el;
02506 unit_set_el_t copy;
02507
02508 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
02509 for (src = source_list; src != NULL; src = src->next_unit_set_el)
02510 {
02511 if (dst->unit_decl == src->unit_decl)
02512 {
02513 error ("unit `%s' excludes itself", src->unit_decl->name);
02514 continue;
02515 }
02516 if (dst->unit_decl->automaton_name != NULL
02517 && src->unit_decl->automaton_name != NULL
02518 && strcmp (dst->unit_decl->automaton_name,
02519 src->unit_decl->automaton_name) != 0)
02520 {
02521 error ("units `%s' and `%s' in exclusion set belong to different automata",
02522 src->unit_decl->name, dst->unit_decl->name);
02523 continue;
02524 }
02525 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
02526 curr_el != NULL;
02527 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
02528 if (curr_el->unit_decl == src->unit_decl)
02529 break;
02530 if (curr_el == NULL)
02531 {
02532
02533 copy = copy_node (src, sizeof (*src));
02534 copy->next_unit_set_el = NULL;
02535 if (prev_el == NULL)
02536 dst->unit_decl->excl_list = copy;
02537 else
02538 prev_el->next_unit_set_el = copy;
02539 }
02540 }
02541 }
02542
02543
02544
02545
02546 static unit_set_el_t
02547 process_presence_absence_names (char **names, int num,
02548 pos_t req_pos ATTRIBUTE_UNUSED,
02549 int presence_p, int final_p)
02550 {
02551 unit_set_el_t el_list;
02552 unit_set_el_t last_el;
02553 unit_set_el_t new_el;
02554 decl_t decl_in_table;
02555 int i;
02556
02557 el_list = NULL;
02558 last_el = NULL;
02559 for (i = 0; i < num; i++)
02560 {
02561 decl_in_table = find_decl (names [i]);
02562 if (decl_in_table == NULL)
02563 error ((presence_p
02564 ? (final_p
02565 ? "unit `%s' in final presence set is not declared"
02566 : "unit `%s' in presence set is not declared")
02567 : (final_p
02568 ? "unit `%s' in final absence set is not declared"
02569 : "unit `%s' in absence set is not declared")), names [i]);
02570 else if (decl_in_table->mode != dm_unit)
02571 error ((presence_p
02572 ? (final_p
02573 ? "`%s' in final presence set is not unit"
02574 : "`%s' in presence set is not unit")
02575 : (final_p
02576 ? "`%s' in final absence set is not unit"
02577 : "`%s' in absence set is not unit")), names [i]);
02578 else
02579 {
02580 new_el = create_node (sizeof (struct unit_set_el));
02581 new_el->unit_decl = DECL_UNIT (decl_in_table);
02582 new_el->next_unit_set_el = NULL;
02583 if (last_el == NULL)
02584 el_list = last_el = new_el;
02585 else
02586 {
02587 last_el->next_unit_set_el = new_el;
02588 last_el = last_el->next_unit_set_el;
02589 }
02590 }
02591 }
02592 return el_list;
02593 }
02594
02595
02596
02597
02598 static pattern_set_el_t
02599 process_presence_absence_patterns (char ***patterns, int num,
02600 pos_t req_pos ATTRIBUTE_UNUSED,
02601 int presence_p, int final_p)
02602 {
02603 pattern_set_el_t el_list;
02604 pattern_set_el_t last_el;
02605 pattern_set_el_t new_el;
02606 decl_t decl_in_table;
02607 int i, j;
02608
02609 el_list = NULL;
02610 last_el = NULL;
02611 for (i = 0; i < num; i++)
02612 {
02613 for (j = 0; patterns [i] [j] != NULL; j++)
02614 ;
02615 new_el = create_node (sizeof (struct pattern_set_el)
02616 + sizeof (struct unit_decl *) * j);
02617 new_el->unit_decls
02618 = (struct unit_decl **) ((char *) new_el
02619 + sizeof (struct pattern_set_el));
02620 new_el->next_pattern_set_el = NULL;
02621 if (last_el == NULL)
02622 el_list = last_el = new_el;
02623 else
02624 {
02625 last_el->next_pattern_set_el = new_el;
02626 last_el = last_el->next_pattern_set_el;
02627 }
02628 new_el->units_num = 0;
02629 for (j = 0; patterns [i] [j] != NULL; j++)
02630 {
02631 decl_in_table = find_decl (patterns [i] [j]);
02632 if (decl_in_table == NULL)
02633 error ((presence_p
02634 ? (final_p
02635 ? "unit `%s' in final presence set is not declared"
02636 : "unit `%s' in presence set is not declared")
02637 : (final_p
02638 ? "unit `%s' in final absence set is not declared"
02639 : "unit `%s' in absence set is not declared")),
02640 patterns [i] [j]);
02641 else if (decl_in_table->mode != dm_unit)
02642 error ((presence_p
02643 ? (final_p
02644 ? "`%s' in final presence set is not unit"
02645 : "`%s' in presence set is not unit")
02646 : (final_p
02647 ? "`%s' in final absence set is not unit"
02648 : "`%s' in absence set is not unit")),
02649 patterns [i] [j]);
02650 else
02651 {
02652 new_el->unit_decls [new_el->units_num]
02653 = DECL_UNIT (decl_in_table);
02654 new_el->units_num++;
02655 }
02656 }
02657 }
02658 return el_list;
02659 }
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669 static void
02670 add_presence_absence (unit_set_el_t dest_list,
02671 pattern_set_el_t pattern_list,
02672 pos_t req_pos ATTRIBUTE_UNUSED,
02673 int presence_p, int final_p)
02674 {
02675 unit_set_el_t dst;
02676 pattern_set_el_t pat;
02677 struct unit_decl *unit;
02678 unit_set_el_t curr_excl_el;
02679 pattern_set_el_t curr_pat_el;
02680 pattern_set_el_t prev_el;
02681 pattern_set_el_t copy;
02682 int i;
02683 int no_error_flag;
02684
02685 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
02686 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
02687 {
02688 for (i = 0; i < pat->units_num; i++)
02689 {
02690 unit = pat->unit_decls [i];
02691 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
02692 {
02693 error ("unit `%s' requires own absence", unit->name);
02694 continue;
02695 }
02696 if (dst->unit_decl->automaton_name != NULL
02697 && unit->automaton_name != NULL
02698 && strcmp (dst->unit_decl->automaton_name,
02699 unit->automaton_name) != 0)
02700 {
02701 error ((presence_p
02702 ? (final_p
02703 ? "units `%s' and `%s' in final presence set belong to different automata"
02704 : "units `%s' and `%s' in presence set belong to different automata")
02705 : (final_p
02706 ? "units `%s' and `%s' in final absence set belong to different automata"
02707 : "units `%s' and `%s' in absence set belong to different automata")),
02708 unit->name, dst->unit_decl->name);
02709 continue;
02710 }
02711 no_error_flag = 1;
02712 if (presence_p)
02713 for (curr_excl_el = dst->unit_decl->excl_list;
02714 curr_excl_el != NULL;
02715 curr_excl_el = curr_excl_el->next_unit_set_el)
02716 {
02717 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
02718 {
02719 if (!w_flag)
02720 {
02721 error ("unit `%s' excludes and requires presence of `%s'",
02722 dst->unit_decl->name, unit->name);
02723 no_error_flag = 0;
02724 }
02725 else
02726 warning
02727 ("unit `%s' excludes and requires presence of `%s'",
02728 dst->unit_decl->name, unit->name);
02729 }
02730 }
02731 else if (pat->units_num == 1)
02732 for (curr_pat_el = dst->unit_decl->presence_list;
02733 curr_pat_el != NULL;
02734 curr_pat_el = curr_pat_el->next_pattern_set_el)
02735 if (curr_pat_el->units_num == 1
02736 && unit == curr_pat_el->unit_decls [0])
02737 {
02738 if (!w_flag)
02739 {
02740 error
02741 ("unit `%s' requires absence and presence of `%s'",
02742 dst->unit_decl->name, unit->name);
02743 no_error_flag = 0;
02744 }
02745 else
02746 warning
02747 ("unit `%s' requires absence and presence of `%s'",
02748 dst->unit_decl->name, unit->name);
02749 }
02750 if (no_error_flag)
02751 {
02752 for (prev_el = (presence_p
02753 ? (final_p
02754 ? dst->unit_decl->final_presence_list
02755 : dst->unit_decl->final_presence_list)
02756 : (final_p
02757 ? dst->unit_decl->final_absence_list
02758 : dst->unit_decl->absence_list));
02759 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
02760 prev_el = prev_el->next_pattern_set_el)
02761 ;
02762 copy = copy_node (pat, sizeof (*pat));
02763 copy->next_pattern_set_el = NULL;
02764 if (prev_el == NULL)
02765 {
02766 if (presence_p)
02767 {
02768 if (final_p)
02769 dst->unit_decl->final_presence_list = copy;
02770 else
02771 dst->unit_decl->presence_list = copy;
02772 }
02773 else if (final_p)
02774 dst->unit_decl->final_absence_list = copy;
02775 else
02776 dst->unit_decl->absence_list = copy;
02777 }
02778 else
02779 prev_el->next_pattern_set_el = copy;
02780 }
02781 }
02782 }
02783 }
02784
02785
02786
02787
02788 static struct bypass_decl *
02789 find_bypass (struct bypass_decl *bypass_list,
02790 struct insn_reserv_decl *in_insn_reserv)
02791 {
02792 struct bypass_decl *bypass;
02793
02794 for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
02795 if (bypass->in_insn_reserv == in_insn_reserv)
02796 break;
02797 return bypass;
02798 }
02799
02800
02801
02802 static void
02803 process_decls (void)
02804 {
02805 decl_t decl;
02806 decl_t automaton_decl;
02807 decl_t decl_in_table;
02808 decl_t out_insn_reserv;
02809 decl_t in_insn_reserv;
02810 struct bypass_decl *bypass;
02811 int automaton_presence;
02812 int i;
02813
02814
02815 automaton_presence = 0;
02816 for (i = 0; i < description->decls_num; i++)
02817 {
02818 decl = description->decls [i];
02819 if (decl->mode == dm_automaton)
02820 {
02821 automaton_presence = 1;
02822 decl_in_table = insert_automaton_decl (decl);
02823 if (decl_in_table != decl)
02824 {
02825 if (!w_flag)
02826 error ("repeated declaration of automaton `%s'",
02827 DECL_AUTOMATON (decl)->name);
02828 else
02829 warning ("repeated declaration of automaton `%s'",
02830 DECL_AUTOMATON (decl)->name);
02831 }
02832 }
02833 }
02834
02835
02836
02837 for (i = 0; i < description->decls_num; i++)
02838 {
02839 decl = description->decls [i];
02840 if (decl->mode == dm_insn_reserv)
02841 {
02842 DECL_INSN_RESERV (decl)->condexp
02843 = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
02844 if (DECL_INSN_RESERV (decl)->default_latency < 0)
02845 error ("define_insn_reservation `%s' has negative latency time",
02846 DECL_INSN_RESERV (decl)->name);
02847 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
02848 description->insns_num++;
02849 decl_in_table = insert_insn_decl (decl);
02850 if (decl_in_table != decl)
02851 error ("`%s' is already used as insn reservation name",
02852 DECL_INSN_RESERV (decl)->name);
02853 }
02854 else if (decl->mode == dm_bypass)
02855 {
02856 if (DECL_BYPASS (decl)->latency < 0)
02857 error ("define_bypass `%s - %s' has negative latency time",
02858 DECL_BYPASS (decl)->out_insn_name,
02859 DECL_BYPASS (decl)->in_insn_name);
02860 }
02861 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
02862 {
02863 if (decl->mode == dm_unit)
02864 {
02865 DECL_UNIT (decl)->automaton_decl = NULL;
02866 if (DECL_UNIT (decl)->automaton_name != NULL)
02867 {
02868 automaton_decl
02869 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
02870 if (automaton_decl == NULL)
02871 error ("automaton `%s' is not declared",
02872 DECL_UNIT (decl)->automaton_name);
02873 else
02874 {
02875 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
02876 DECL_UNIT (decl)->automaton_decl
02877 = DECL_AUTOMATON (automaton_decl);
02878 }
02879 }
02880 else if (automaton_presence)
02881 error ("define_unit `%s' without automaton when one defined",
02882 DECL_UNIT (decl)->name);
02883 DECL_UNIT (decl)->unit_num = description->units_num;
02884 description->units_num++;
02885 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
02886 {
02887 error ("`%s' is declared as cpu unit", NOTHING_NAME);
02888 continue;
02889 }
02890 decl_in_table = find_decl (DECL_UNIT (decl)->name);
02891 }
02892 else
02893 {
02894 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
02895 {
02896 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
02897 continue;
02898 }
02899 decl_in_table = find_decl (DECL_RESERV (decl)->name);
02900 }
02901 if (decl_in_table == NULL)
02902 decl_in_table = insert_decl (decl);
02903 else
02904 {
02905 if (decl->mode == dm_unit)
02906 error ("repeated declaration of unit `%s'",
02907 DECL_UNIT (decl)->name);
02908 else
02909 error ("repeated declaration of reservation `%s'",
02910 DECL_RESERV (decl)->name);
02911 }
02912 }
02913 }
02914
02915
02916 for (i = 0; i < description->decls_num; i++)
02917 {
02918 decl = description->decls [i];
02919 if (decl->mode == dm_bypass)
02920 {
02921 out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
02922 in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
02923 if (out_insn_reserv == NULL)
02924 error ("there is no insn reservation `%s'",
02925 DECL_BYPASS (decl)->out_insn_name);
02926 else if (in_insn_reserv == NULL)
02927 error ("there is no insn reservation `%s'",
02928 DECL_BYPASS (decl)->in_insn_name);
02929 else
02930 {
02931 DECL_BYPASS (decl)->out_insn_reserv
02932 = DECL_INSN_RESERV (out_insn_reserv);
02933 DECL_BYPASS (decl)->in_insn_reserv
02934 = DECL_INSN_RESERV (in_insn_reserv);
02935 bypass
02936 = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
02937 DECL_BYPASS (decl)->in_insn_reserv);
02938 if (bypass != NULL)
02939 {
02940 if (DECL_BYPASS (decl)->latency == bypass->latency)
02941 {
02942 if (!w_flag)
02943 error
02944 ("the same bypass `%s - %s' is already defined",
02945 DECL_BYPASS (decl)->out_insn_name,
02946 DECL_BYPASS (decl)->in_insn_name);
02947 else
02948 warning
02949 ("the same bypass `%s - %s' is already defined",
02950 DECL_BYPASS (decl)->out_insn_name,
02951 DECL_BYPASS (decl)->in_insn_name);
02952 }
02953 else
02954 error ("bypass `%s - %s' is already defined",
02955 DECL_BYPASS (decl)->out_insn_name,
02956 DECL_BYPASS (decl)->in_insn_name);
02957 }
02958 else
02959 {
02960 DECL_BYPASS (decl)->next
02961 = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
02962 DECL_INSN_RESERV (out_insn_reserv)->bypass_list
02963 = DECL_BYPASS (decl);
02964 }
02965 }
02966 }
02967 }
02968
02969
02970 for (i = 0; i < description->decls_num; i++)
02971 {
02972 decl = description->decls [i];
02973 if (decl->mode == dm_excl)
02974 {
02975 unit_set_el_t unit_set_el_list;
02976 unit_set_el_t unit_set_el_list_2;
02977
02978 unit_set_el_list
02979 = process_excls (DECL_EXCL (decl)->names,
02980 DECL_EXCL (decl)->first_list_length, decl->pos);
02981 unit_set_el_list_2
02982 = process_excls (&DECL_EXCL (decl)->names
02983 [DECL_EXCL (decl)->first_list_length],
02984 DECL_EXCL (decl)->all_names_num
02985 - DECL_EXCL (decl)->first_list_length,
02986 decl->pos);
02987 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
02988 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
02989 }
02990 }
02991
02992
02993 for (i = 0; i < description->decls_num; i++)
02994 {
02995 decl = description->decls [i];
02996 if (decl->mode == dm_presence)
02997 {
02998 unit_set_el_t unit_set_el_list;
02999 pattern_set_el_t pattern_set_el_list;
03000
03001 unit_set_el_list
03002 = process_presence_absence_names
03003 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
03004 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
03005 pattern_set_el_list
03006 = process_presence_absence_patterns
03007 (DECL_PRESENCE (decl)->patterns,
03008 DECL_PRESENCE (decl)->patterns_num,
03009 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
03010 add_presence_absence (unit_set_el_list, pattern_set_el_list,
03011 decl->pos, TRUE,
03012 DECL_PRESENCE (decl)->final_p);
03013 }
03014 }
03015
03016
03017 for (i = 0; i < description->decls_num; i++)
03018 {
03019 decl = description->decls [i];
03020 if (decl->mode == dm_absence)
03021 {
03022 unit_set_el_t unit_set_el_list;
03023 pattern_set_el_t pattern_set_el_list;
03024
03025 unit_set_el_list
03026 = process_presence_absence_names
03027 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
03028 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
03029 pattern_set_el_list
03030 = process_presence_absence_patterns
03031 (DECL_ABSENCE (decl)->patterns,
03032 DECL_ABSENCE (decl)->patterns_num,
03033 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
03034 add_presence_absence (unit_set_el_list, pattern_set_el_list,
03035 decl->pos, FALSE,
03036 DECL_ABSENCE (decl)->final_p);
03037 }
03038 }
03039 }
03040
03041
03042
03043
03044 static void
03045 check_automaton_usage (void)
03046 {
03047 decl_t decl;
03048 int i;
03049
03050 for (i = 0; i < description->decls_num; i++)
03051 {
03052 decl = description->decls [i];
03053 if (decl->mode == dm_automaton
03054 && !DECL_AUTOMATON (decl)->automaton_is_used)
03055 {
03056 if (!w_flag)
03057 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
03058 else
03059 warning ("automaton `%s' is not used",
03060 DECL_AUTOMATON (decl)->name);
03061 }
03062 }
03063 }
03064
03065
03066
03067
03068
03069
03070 static regexp_t
03071 process_regexp (regexp_t regexp)
03072 {
03073 decl_t decl_in_table;
03074 regexp_t new_regexp;
03075 int i;
03076
03077 switch (regexp->mode)
03078 {
03079 case rm_unit:
03080 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
03081 if (decl_in_table == NULL)
03082 error ("undeclared unit or reservation `%s'",
03083 REGEXP_UNIT (regexp)->name);
03084 else
03085 switch (decl_in_table->mode)
03086 {
03087 case dm_unit:
03088 DECL_UNIT (decl_in_table)->unit_is_used = 1;
03089 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
03090 break;
03091
03092 case dm_reserv:
03093 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
03094 new_regexp = create_node (sizeof (struct regexp));
03095 new_regexp->mode = rm_reserv;
03096 new_regexp->pos = regexp->pos;
03097 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
03098 REGEXP_RESERV (new_regexp)->reserv_decl
03099 = DECL_RESERV (decl_in_table);
03100 regexp = new_regexp;
03101 break;
03102
03103 default:
03104 gcc_unreachable ();
03105 }
03106 break;
03107 case rm_sequence:
03108 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
03109 REGEXP_SEQUENCE (regexp)->regexps [i]
03110 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
03111 break;
03112 case rm_allof:
03113 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
03114 REGEXP_ALLOF (regexp)->regexps [i]
03115 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
03116 break;
03117 case rm_oneof:
03118 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
03119 REGEXP_ONEOF (regexp)->regexps [i]
03120 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
03121 break;
03122 case rm_repeat:
03123 REGEXP_REPEAT (regexp)->regexp
03124 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
03125 break;
03126 case rm_nothing:
03127 break;
03128 default:
03129 gcc_unreachable ();
03130 }
03131 return regexp;
03132 }
03133
03134
03135
03136
03137 static void
03138 process_regexp_decls (void)
03139 {
03140 decl_t decl;
03141 int i;
03142
03143 for (i = 0; i < description->decls_num; i++)
03144 {
03145 decl = description->decls [i];
03146 if (decl->mode == dm_reserv)
03147 DECL_RESERV (decl)->regexp
03148 = process_regexp (DECL_RESERV (decl)->regexp);
03149 else if (decl->mode == dm_insn_reserv)
03150 DECL_INSN_RESERV (decl)->regexp
03151 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
03152 }
03153 }
03154
03155
03156
03157
03158
03159 static void
03160 check_usage (void)
03161 {
03162 decl_t decl;
03163 int i;
03164
03165 for (i = 0; i < description->decls_num; i++)
03166 {
03167 decl = description->decls [i];
03168 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
03169 {
03170 if (!w_flag)
03171 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
03172 else
03173 warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
03174 }
03175 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
03176 {
03177 if (!w_flag)
03178 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
03179 else
03180 warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
03181 }
03182 }
03183 }
03184
03185
03186
03187 static int curr_loop_pass_num;
03188
03189
03190
03191
03192 static int
03193 loop_in_regexp (regexp_t regexp, decl_t start_decl)
03194 {
03195 int i;
03196
03197 if (regexp == NULL)
03198 return 0;
03199 switch (regexp->mode)
03200 {
03201 case rm_unit:
03202 return 0;
03203
03204 case rm_reserv:
03205 if (start_decl->mode == dm_reserv
03206 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
03207 return 1;
03208 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
03209 == curr_loop_pass_num)
03210
03211 return 0;
03212 else
03213 {
03214 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
03215 = curr_loop_pass_num;
03216 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
03217 start_decl);
03218 }
03219
03220 case rm_sequence:
03221 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
03222 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
03223 return 1;
03224 return 0;
03225
03226 case rm_allof:
03227 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
03228 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
03229 return 1;
03230 return 0;
03231
03232 case rm_oneof:
03233 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
03234 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
03235 return 1;
03236 return 0;
03237
03238 case rm_repeat:
03239 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
03240
03241 case rm_nothing:
03242 return 0;
03243
03244 default:
03245 gcc_unreachable ();
03246 }
03247 }
03248
03249
03250
03251 static void
03252 check_loops_in_regexps (void)
03253 {
03254 decl_t decl;
03255 int i;
03256
03257 for (i = 0; i < description->decls_num; i++)
03258 {
03259 decl = description->decls [i];
03260 if (decl->mode == dm_reserv)
03261 DECL_RESERV (decl)->loop_pass_num = 0;
03262 }
03263 for (i = 0; i < description->decls_num; i++)
03264 {
03265 decl = description->decls [i];
03266 curr_loop_pass_num = i;
03267
03268 if (decl->mode == dm_reserv)
03269 {
03270 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
03271 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
03272 {
03273 gcc_assert (DECL_RESERV (decl)->regexp);
03274 error ("cycle in definition of reservation `%s'",
03275 DECL_RESERV (decl)->name);
03276 }
03277 }
03278 }
03279 }
03280
03281
03282
03283 static void
03284 process_regexp_cycles (regexp_t regexp, int max_start_cycle,
03285 int min_start_cycle, int *max_finish_cycle,
03286 int *min_finish_cycle)
03287 {
03288 int i;
03289
03290 switch (regexp->mode)
03291 {
03292 case rm_unit:
03293 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
03294 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
03295 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
03296 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
03297 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
03298 *max_finish_cycle = max_start_cycle;
03299 *min_finish_cycle = min_start_cycle;
03300 break;
03301
03302 case rm_reserv:
03303 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
03304 max_start_cycle, min_start_cycle,
03305 max_finish_cycle, min_finish_cycle);
03306 break;
03307
03308 case rm_repeat:
03309 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
03310 {
03311 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
03312 max_start_cycle, min_start_cycle,
03313 max_finish_cycle, min_finish_cycle);
03314 max_start_cycle = *max_finish_cycle + 1;
03315 min_start_cycle = *min_finish_cycle + 1;
03316 }
03317 break;
03318
03319 case rm_sequence:
03320 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
03321 {
03322 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
03323 max_start_cycle, min_start_cycle,
03324 max_finish_cycle, min_finish_cycle);
03325 max_start_cycle = *max_finish_cycle + 1;
03326 min_start_cycle = *min_finish_cycle + 1;
03327 }
03328 break;
03329
03330 case rm_allof:
03331 {
03332 int max_cycle = 0;
03333 int min_cycle = 0;
03334
03335 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
03336 {
03337 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
03338 max_start_cycle, min_start_cycle,
03339 max_finish_cycle, min_finish_cycle);
03340 if (max_cycle < *max_finish_cycle)
03341 max_cycle = *max_finish_cycle;
03342 if (i == 0 || min_cycle > *min_finish_cycle)
03343 min_cycle = *min_finish_cycle;
03344 }
03345 *max_finish_cycle = max_cycle;
03346 *min_finish_cycle = min_cycle;
03347 }
03348 break;
03349
03350 case rm_oneof:
03351 {
03352 int max_cycle = 0;
03353 int min_cycle = 0;
03354
03355 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
03356 {
03357 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
03358 max_start_cycle, min_start_cycle,
03359 max_finish_cycle, min_finish_cycle);
03360 if (max_cycle < *max_finish_cycle)
03361 max_cycle = *max_finish_cycle;
03362 if (i == 0 || min_cycle > *min_finish_cycle)
03363 min_cycle = *min_finish_cycle;
03364 }
03365 *max_finish_cycle = max_cycle;
03366 *min_finish_cycle = min_cycle;
03367 }
03368 break;
03369
03370 case rm_nothing:
03371 *max_finish_cycle = max_start_cycle;
03372 *min_finish_cycle = min_start_cycle;
03373 break;
03374
03375 default:
03376 gcc_unreachable ();
03377 }
03378 }
03379
03380
03381
03382 static void
03383 evaluate_max_reserv_cycles (void)
03384 {
03385 int max_insn_cycles_num;
03386 int min_insn_cycles_num;
03387 decl_t decl;
03388 int i;
03389
03390 description->max_insn_reserv_cycles = 0;
03391 for (i = 0; i < description->decls_num; i++)
03392 {
03393 decl = description->decls [i];
03394 if (decl->mode == dm_insn_reserv)
03395 {
03396 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
03397 &max_insn_cycles_num, &min_insn_cycles_num);
03398 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
03399 description->max_insn_reserv_cycles = max_insn_cycles_num;
03400 }
03401 }
03402 description->max_insn_reserv_cycles++;
03403 }
03404
03405
03406
03407 static void
03408 check_all_description (void)
03409 {
03410 process_decls ();
03411 check_automaton_usage ();
03412 process_regexp_decls ();
03413 check_usage ();
03414 check_loops_in_regexps ();
03415 if (!have_error)
03416 evaluate_max_reserv_cycles ();
03417 }
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427 static ticker_t
03428 create_ticker (void)
03429 {
03430 ticker_t ticker;
03431
03432 ticker.modified_creation_time = get_run_time ();
03433 ticker.incremented_off_time = 0;
03434 return ticker;
03435 }
03436
03437
03438 static void
03439 ticker_off (ticker_t *ticker)
03440 {
03441 if (ticker->incremented_off_time == 0)
03442 ticker->incremented_off_time = get_run_time () + 1;
03443 }
03444
03445
03446 static void
03447 ticker_on (ticker_t *ticker)
03448 {
03449 if (ticker->incremented_off_time != 0)
03450 {
03451 ticker->modified_creation_time
03452 += get_run_time () - ticker->incremented_off_time + 1;
03453 ticker->incremented_off_time = 0;
03454 }
03455 }
03456
03457
03458
03459 static int
03460 active_time (ticker_t ticker)
03461 {
03462 if (ticker.incremented_off_time != 0)
03463 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
03464 else
03465 return get_run_time () - ticker.modified_creation_time;
03466 }
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484 static void
03485 print_active_time (FILE *f, ticker_t ticker)
03486 {
03487 int msecs;
03488
03489 msecs = active_time (ticker);
03490 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
03491 }
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502 static int automata_num;
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512 static ticker_t transform_time;
03513 static ticker_t NDFA_time;
03514 static ticker_t NDFA_to_DFA_time;
03515 static ticker_t minimize_time;
03516 static ticker_t equiv_time;
03517 static ticker_t automaton_generation_time;
03518 static ticker_t output_time;
03519
03520
03521
03522
03523
03524 static ticker_t check_time;
03525 static ticker_t generation_time;
03526 static ticker_t all_time;
03527
03528
03529
03530
03531 static decl_t advance_cycle_insn_decl;
03532 static void
03533 add_advance_cycle_insn_decl (void)
03534 {
03535 advance_cycle_insn_decl = create_node (sizeof (struct decl));
03536 advance_cycle_insn_decl->mode = dm_insn_reserv;
03537 advance_cycle_insn_decl->pos = no_pos;
03538 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
03539 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
03540 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
03541 = description->insns_num;
03542 description->decls [description->decls_num] = advance_cycle_insn_decl;
03543 description->decls_num++;
03544 description->insns_num++;
03545 num_dfa_decls++;
03546 }
03547
03548
03549
03550
03551
03552
03553
03554 static alt_state_t first_free_alt_state;
03555
03556 #ifndef NDEBUG
03557
03558
03559 static int allocated_alt_states_num = 0;
03560 #endif
03561
03562
03563
03564 static alt_state_t
03565 get_free_alt_state (void)
03566 {
03567 alt_state_t result;
03568
03569 if (first_free_alt_state != NULL)
03570 {
03571 result = first_free_alt_state;
03572 first_free_alt_state = first_free_alt_state->next_alt_state;
03573 }
03574 else
03575 {
03576 #ifndef NDEBUG
03577 allocated_alt_states_num++;
03578 #endif
03579 result = create_node (sizeof (struct alt_state));
03580 }
03581 result->state = NULL;
03582 result->next_alt_state = NULL;
03583 result->next_sorted_alt_state = NULL;
03584 return result;
03585 }
03586
03587
03588 static void
03589 free_alt_state (alt_state_t alt_state)
03590 {
03591 if (alt_state == NULL)
03592 return;
03593 alt_state->next_alt_state = first_free_alt_state;
03594 first_free_alt_state = alt_state;
03595 }
03596
03597
03598 static void
03599 free_alt_states (alt_state_t alt_states_list)
03600 {
03601 alt_state_t curr_alt_state;
03602 alt_state_t next_alt_state;
03603
03604 for (curr_alt_state = alt_states_list;
03605 curr_alt_state != NULL;
03606 curr_alt_state = next_alt_state)
03607 {
03608 next_alt_state = curr_alt_state->next_alt_state;
03609 free_alt_state (curr_alt_state);
03610 }
03611 }
03612
03613
03614 static int
03615 alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
03616 {
03617 if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
03618 == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
03619 return 0;
03620 else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
03621 < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
03622 return -1;
03623 else
03624 return 1;
03625 }
03626
03627
03628
03629
03630 static alt_state_t
03631 uniq_sort_alt_states (alt_state_t alt_states_list)
03632 {
03633 alt_state_t curr_alt_state;
03634 vla_ptr_t alt_states;
03635 size_t i;
03636 size_t prev_unique_state_ind;
03637 alt_state_t result;
03638 alt_state_t *result_ptr;
03639
03640 VLA_PTR_CREATE (alt_states, 150, "alt_states");
03641 for (curr_alt_state = alt_states_list;
03642 curr_alt_state != NULL;
03643 curr_alt_state = curr_alt_state->next_alt_state)
03644 VLA_PTR_ADD (alt_states, curr_alt_state);
03645 qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
03646 sizeof (alt_state_t), alt_state_cmp);
03647 if (VLA_PTR_LENGTH (alt_states) == 0)
03648 result = NULL;
03649 else
03650 {
03651 result_ptr = VLA_PTR_BEGIN (alt_states);
03652 prev_unique_state_ind = 0;
03653 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
03654 if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
03655 {
03656 prev_unique_state_ind++;
03657 result_ptr [prev_unique_state_ind] = result_ptr [i];
03658 }
03659 #if 0
03660 for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
03661 free_alt_state (result_ptr [i]);
03662 #endif
03663 VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
03664 result_ptr = VLA_PTR_BEGIN (alt_states);
03665 for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
03666 result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
03667 result_ptr [i - 1]->next_sorted_alt_state = NULL;
03668 result = *result_ptr;
03669 }
03670 VLA_PTR_DELETE (alt_states);
03671 return result;
03672 }
03673
03674
03675
03676 static int
03677 alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
03678 {
03679 while (alt_states_1 != NULL && alt_states_2 != NULL
03680 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
03681 {
03682 alt_states_1 = alt_states_1->next_sorted_alt_state;
03683 alt_states_2 = alt_states_2->next_sorted_alt_state;
03684 }
03685 return alt_states_1 == alt_states_2;
03686 }
03687
03688
03689 static void
03690 initiate_alt_states (void)
03691 {
03692 first_free_alt_state = NULL;
03693 }
03694
03695
03696 static void
03697 finish_alt_states (void)
03698 {
03699 }
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709 #define SET_BIT(bitstring, bitno) \
03710 (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
03711
03712 #define CLEAR_BIT(bitstring, bitno) \
03713 (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
03714
03715
03716
03717 #define TEST_BIT(bitstring, bitno) \
03718 (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
03719
03720
03721
03722
03723
03724
03725 static int max_cycles_num;
03726
03727
03728
03729
03730 static int els_in_cycle_reserv;
03731
03732
03733
03734
03735
03736 static int els_in_reservs;
03737
03738
03739
03740 static vla_ptr_t units_container;
03741
03742
03743 static unit_decl_t *units_array;
03744
03745
03746 static reserv_sets_t temp_reserv;
03747
03748
03749 static htab_t state_table;
03750
03751
03752
03753 static vla_ptr_t free_states;
03754
03755 static int curr_unique_state_num;
03756
03757 #ifndef NDEBUG
03758
03759
03760 static int allocated_states_num = 0;
03761 #endif
03762
03763
03764 static reserv_sets_t
03765 alloc_empty_reserv_sets (void)
03766 {
03767 reserv_sets_t result;
03768
03769 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
03770 result = (reserv_sets_t) obstack_base (&irp);
03771 obstack_finish (&irp);
03772 memset (result, 0, els_in_reservs * sizeof (set_el_t));
03773 return result;
03774 }
03775
03776
03777 static unsigned
03778 reserv_sets_hash_value (reserv_sets_t reservs)
03779 {
03780 set_el_t hash_value;
03781 unsigned result;
03782 int reservs_num, i;
03783 set_el_t *reserv_ptr;
03784
03785 hash_value = 0;
03786 reservs_num = els_in_reservs;
03787 reserv_ptr = reservs;
03788 i = 0;
03789 while (reservs_num != 0)
03790 {
03791 reservs_num--;
03792 hash_value += ((*reserv_ptr >> i)
03793 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
03794 i++;
03795 if (i == sizeof (set_el_t) * CHAR_BIT)
03796 i = 0;
03797 reserv_ptr++;
03798 }
03799 if (sizeof (set_el_t) <= sizeof (unsigned))
03800 return hash_value;
03801 result = 0;
03802 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
03803 {
03804 result += (unsigned) hash_value;
03805 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
03806 }
03807 return result;
03808 }
03809
03810
03811 static int
03812 reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
03813 {
03814 int reservs_num;
03815 set_el_t *reserv_ptr_1;
03816 set_el_t *reserv_ptr_2;
03817
03818 gcc_assert (reservs_1 && reservs_2);
03819 reservs_num = els_in_reservs;
03820 reserv_ptr_1 = reservs_1;
03821 reserv_ptr_2 = reservs_2;
03822 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
03823 {
03824 reservs_num--;
03825 reserv_ptr_1++;
03826 reserv_ptr_2++;
03827 }
03828 if (reservs_num == 0)
03829 return 0;
03830 else if (*reserv_ptr_1 < *reserv_ptr_2)
03831 return -1;
03832 else
03833 return 1;
03834 }
03835
03836
03837 static int
03838 reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
03839 {
03840 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
03841 }
03842
03843
03844
03845 static void
03846 set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
03847 {
03848 gcc_assert (cycle_num < max_cycles_num);
03849 SET_BIT (reservs, cycle_num * els_in_cycle_reserv
03850 * sizeof (set_el_t) * CHAR_BIT + unit_num);
03851 }
03852
03853
03854
03855 static int
03856 test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
03857 {
03858 gcc_assert (cycle_num < max_cycles_num);
03859 return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
03860 * sizeof (set_el_t) * CHAR_BIT + unit_num);
03861 }
03862
03863
03864
03865 static int
03866 it_is_empty_reserv_sets (reserv_sets_t operand)
03867 {
03868 set_el_t *reserv_ptr;
03869 int reservs_num;
03870
03871 gcc_assert (operand);
03872 for (reservs_num = els_in_reservs, reserv_ptr = operand;
03873 reservs_num != 0;
03874 reserv_ptr++, reservs_num--)
03875 if (*reserv_ptr != 0)
03876 return 0;
03877 return 1;
03878 }
03879
03880
03881
03882
03883 static int
03884 reserv_sets_are_intersected (reserv_sets_t operand_1,
03885 reserv_sets_t operand_2)
03886 {
03887 set_el_t *el_ptr_1;
03888 set_el_t *el_ptr_2;
03889 set_el_t *cycle_ptr_1;
03890 set_el_t *cycle_ptr_2;
03891
03892 gcc_assert (operand_1 && operand_2);
03893 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
03894 el_ptr_1 < operand_1 + els_in_reservs;
03895 el_ptr_1++, el_ptr_2++)
03896 if (*el_ptr_1 & *el_ptr_2)
03897 return 1;
03898 reserv_sets_or (temp_reserv, operand_1, operand_2);
03899 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
03900 cycle_ptr_1 < operand_1 + els_in_reservs;
03901 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
03902 {
03903 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
03904 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
03905 el_ptr_1++, el_ptr_2++)
03906 if (*el_ptr_1 & *el_ptr_2)
03907 return 1;
03908 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
03909 return 1;
03910 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
03911 - operand_2),
03912 cycle_ptr_2, TRUE))
03913 return 1;
03914 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
03915 return 1;
03916 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
03917 cycle_ptr_2, TRUE))
03918 return 1;
03919 }
03920 return 0;
03921 }
03922
03923
03924
03925
03926 static void
03927 reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
03928 {
03929 int i;
03930
03931 gcc_assert (result && operand && result != operand);
03932 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
03933 result [i - els_in_cycle_reserv] = operand [i];
03934 }
03935
03936
03937 static void
03938 reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
03939 reserv_sets_t operand_2)
03940 {
03941 set_el_t *el_ptr_1;
03942 set_el_t *el_ptr_2;
03943 set_el_t *result_set_el_ptr;
03944
03945 gcc_assert (result && operand_1 && operand_2);
03946 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
03947 el_ptr_1 < operand_1 + els_in_reservs;
03948 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
03949 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
03950 }
03951
03952
03953 static void
03954 reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
03955 reserv_sets_t operand_2)
03956 {
03957 set_el_t *el_ptr_1;
03958 set_el_t *el_ptr_2;
03959 set_el_t *result_set_el_ptr;
03960
03961 gcc_assert (result && operand_1 && operand_2);
03962 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
03963 el_ptr_1 < operand_1 + els_in_reservs;
03964 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
03965 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
03966 }
03967
03968
03969
03970
03971 static void
03972 output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
03973 int repetition_num)
03974 {
03975 int unit_num;
03976 int reserved_units_num;
03977
03978 reserved_units_num = 0;
03979 for (unit_num = 0; unit_num < description->units_num; unit_num++)
03980 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
03981 * sizeof (set_el_t) * CHAR_BIT + unit_num))
03982 reserved_units_num++;
03983 gcc_assert (repetition_num > 0);
03984 if (repetition_num != 1 && reserved_units_num > 1)
03985 fprintf (f, "(");
03986 reserved_units_num = 0;
03987 for (unit_num = 0;
03988 unit_num < description->units_num;
03989 unit_num++)
03990 if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
03991 * sizeof (set_el_t) * CHAR_BIT + unit_num))
03992 {
03993 if (reserved_units_num != 0)
03994 fprintf (f, "+");
03995 reserved_units_num++;
03996 fprintf (f, "%s", units_array [unit_num]->name);
03997 }
03998 if (reserved_units_num == 0)
03999 fprintf (f, NOTHING_NAME);
04000 gcc_assert (repetition_num > 0);
04001 if (repetition_num != 1 && reserved_units_num > 1)
04002 fprintf (f, ")");
04003 if (repetition_num != 1)
04004 fprintf (f, "*%d", repetition_num);
04005 }
04006
04007
04008
04009 static void
04010 output_reserv_sets (FILE *f, reserv_sets_t reservs)
04011 {
04012 int start_cycle = 0;
04013 int cycle;
04014 int repetition_num;
04015
04016 repetition_num = 0;
04017 for (cycle = 0; cycle < max_cycles_num; cycle++)
04018 if (repetition_num == 0)
04019 {
04020 repetition_num++;
04021 start_cycle = cycle;
04022 }
04023 else if (memcmp
04024 ((char *) reservs + start_cycle * els_in_cycle_reserv
04025 * sizeof (set_el_t),
04026 (char *) reservs + cycle * els_in_cycle_reserv
04027 * sizeof (set_el_t),
04028 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
04029 repetition_num++;
04030 else
04031 {
04032 if (start_cycle != 0)
04033 fprintf (f, ", ");
04034 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
04035 repetition_num = 1;
04036 start_cycle = cycle;
04037 }
04038 if (start_cycle < max_cycles_num)
04039 {
04040 if (start_cycle != 0)
04041 fprintf (f, ", ");
04042 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
04043 }
04044 }
04045
04046
04047
04048
04049 static state_t
04050 get_free_state (int with_reservs, automaton_t automaton)
04051 {
04052 state_t result;
04053
04054 gcc_assert (max_cycles_num > 0 && automaton);
04055 if (VLA_PTR_LENGTH (free_states) != 0)
04056 {
04057 result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
04058 VLA_PTR_SHORTEN (free_states, 1);
04059 result->automaton = automaton;
04060 result->first_out_arc = NULL;
04061 result->it_was_placed_in_stack_for_NDFA_forming = 0;
04062 result->it_was_placed_in_stack_for_DFA_forming = 0;
04063 result->component_states = NULL;
04064 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
04065 }
04066 else
04067 {
04068 #ifndef NDEBUG
04069 allocated_states_num++;
04070 #endif
04071 result = create_node (sizeof (struct state));
04072 result->automaton = automaton;
04073 result->first_out_arc = NULL;
04074 result->unique_num = curr_unique_state_num;
04075 result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
04076 curr_unique_state_num++;
04077 }
04078 if (with_reservs)
04079 {
04080 if (result->reservs == NULL)
04081 result->reservs = alloc_empty_reserv_sets ();
04082 else
04083 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
04084 }
04085 return result;
04086 }
04087
04088
04089 static void
04090 free_state (state_t state)
04091 {
04092 free_alt_states (state->component_states);
04093 VLA_PTR_ADD (free_states, state);
04094 }
04095
04096
04097
04098
04099
04100 static hashval_t
04101 state_hash (const void *state)
04102 {
04103 unsigned int hash_value;
04104 alt_state_t alt_state;
04105
04106 if (((state_t) state)->component_states == NULL)
04107 hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
04108 else
04109 {
04110 hash_value = 0;
04111 for (alt_state = ((state_t) state)->component_states;
04112 alt_state != NULL;
04113 alt_state = alt_state->next_sorted_alt_state)
04114 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
04115 | (hash_value << CHAR_BIT))
04116 + alt_state->state->unique_num);
04117 }
04118 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
04119 | (hash_value << CHAR_BIT))
04120 + ((state_t) state)->automaton->automaton_order_num);
04121 return hash_value;
04122 }
04123
04124
04125 static int
04126 state_eq_p (const void *state_1, const void *state_2)
04127 {
04128 alt_state_t alt_state_1;
04129 alt_state_t alt_state_2;
04130
04131 if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
04132 return 0;
04133 else if (((state_t) state_1)->component_states == NULL
04134 && ((state_t) state_2)->component_states == NULL)
04135 return reserv_sets_eq (((state_t) state_1)->reservs,
04136 ((state_t) state_2)->reservs);
04137 else if (((state_t) state_1)->component_states != NULL
04138 && ((state_t) state_2)->component_states != NULL)
04139 {
04140 for (alt_state_1 = ((state_t) state_1)->component_states,
04141 alt_state_2 = ((state_t) state_2)->component_states;
04142 alt_state_1 != NULL && alt_state_2 != NULL;
04143 alt_state_1 = alt_state_1->next_sorted_alt_state,
04144 alt_state_2 = alt_state_2->next_sorted_alt_state)
04145
04146
04147 if (alt_state_1->state != alt_state_2->state)
04148 return 0;
04149 return alt_state_1 == alt_state_2;
04150 }
04151 else
04152 return 0;
04153 }
04154
04155
04156 static state_t
04157 insert_state (state_t state)
04158 {
04159 void **entry_ptr;
04160
04161 entry_ptr = htab_find_slot (state_table, (void *) state, 1);
04162 if (*entry_ptr == NULL)
04163 *entry_ptr = (void *) state;
04164 return (state_t) *entry_ptr;
04165 }
04166
04167
04168
04169 static void
04170 set_state_reserv (state_t state, int cycle_num, int unit_num)
04171 {
04172 set_unit_reserv (state->reservs, cycle_num, unit_num);
04173 }
04174
04175
04176
04177 static int
04178 intersected_state_reservs_p (state_t state1, state_t state2)
04179 {
04180 gcc_assert (state1->automaton == state2->automaton);
04181 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
04182 }
04183
04184
04185
04186
04187 static state_t
04188 states_union (state_t state1, state_t state2, reserv_sets_t reservs)
04189 {
04190 state_t result;
04191 state_t state_in_table;
04192
04193 gcc_assert (state1->automaton == state2->automaton);
04194 result = get_free_state (1, state1->automaton);
04195 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
04196 reserv_sets_and (result->reservs, result->reservs, reservs);
04197 state_in_table = insert_state (result);
04198 if (result != state_in_table)
04199 {
04200 free_state (result);
04201 result = state_in_table;
04202 }
04203 return result;
04204 }
04205
04206
04207
04208
04209 static state_t
04210 state_shift (state_t state, reserv_sets_t reservs)
04211 {
04212 state_t result;
04213 state_t state_in_table;
04214
04215 result = get_free_state (1, state->automaton);
04216 reserv_sets_shift (result->reservs, state->reservs);
04217 reserv_sets_and (result->reservs, result->reservs, reservs);
04218 state_in_table = insert_state (result);
04219 if (result != state_in_table)
04220 {
04221 free_state (result);
04222 result = state_in_table;
04223 }
04224 return result;
04225 }
04226
04227
04228 static void
04229 initiate_states (void)
04230 {
04231 decl_t decl;
04232 int i;
04233
04234 VLA_PTR_CREATE (units_container, description->units_num, "units_container");
04235 units_array
04236 = (description->decls_num && description->units_num
04237 ? VLA_PTR_BEGIN (units_container) : NULL);
04238 for (i = 0; i < description->decls_num; i++)
04239 {
04240 decl = description->decls [i];
04241 if (decl->mode == dm_unit)
04242 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
04243 }
04244 max_cycles_num = description->max_insn_reserv_cycles;
04245 els_in_cycle_reserv
04246 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
04247 / (sizeof (set_el_t) * CHAR_BIT));
04248 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
04249 curr_unique_state_num = 0;
04250 initiate_alt_states ();
04251 VLA_PTR_CREATE (free_states, 1500, "free states");
04252 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
04253 temp_reserv = alloc_empty_reserv_sets ();
04254 }
04255
04256
04257 static void
04258 finish_states (void)
04259 {
04260 VLA_PTR_DELETE (units_container);
04261 htab_delete (state_table);
04262 VLA_PTR_DELETE (free_states);
04263 finish_alt_states ();
04264 }
04265
04266
04267
04268
04269
04270
04271 static arc_t first_free_arc;
04272
04273 #ifndef NDEBUG
04274
04275
04276 static int allocated_arcs_num = 0;
04277 #endif
04278
04279
04280 static void
04281 free_arc (arc_t arc)
04282 {
04283 arc->next_out_arc = first_free_arc;
04284 first_free_arc = arc;
04285 }
04286
04287
04288 static void
04289 remove_arc (state_t from_state, arc_t arc)
04290 {
04291 arc_t prev_arc;
04292 arc_t curr_arc;
04293
04294 gcc_assert (arc);
04295 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
04296 curr_arc != NULL;
04297 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
04298 if (curr_arc == arc)
04299 break;
04300 gcc_assert (curr_arc);
04301 if (prev_arc == NULL)
04302 from_state->first_out_arc = arc->next_out_arc;
04303 else
04304 prev_arc->next_out_arc = arc->next_out_arc;
04305 free_arc (arc);
04306 }
04307
04308
04309
04310 static arc_t
04311 find_arc (state_t from_state, state_t to_state, ainsn_t insn)
04312 {
04313 arc_t arc;
04314
04315 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
04316 if (arc->to_state == to_state && arc->insn == insn)
04317 return arc;
04318 return NULL;
04319 }
04320
04321
04322
04323
04324 static arc_t
04325 add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
04326 int state_alts)
04327 {
04328 arc_t new_arc;
04329
04330 new_arc = find_arc (from_state, to_state, ainsn);
04331 if (new_arc != NULL)
04332 return new_arc;
04333 if (first_free_arc == NULL)
04334 {
04335 #ifndef NDEBUG
04336 allocated_arcs_num++;
04337 #endif
04338 new_arc = create_node (sizeof (struct arc));
04339 new_arc->to_state = NULL;
04340 new_arc->insn = NULL;
04341 new_arc->next_out_arc = NULL;
04342 }
04343 else
04344 {
04345 new_arc = first_free_arc;
04346 first_free_arc = first_free_arc->next_out_arc;
04347 }
04348 new_arc->to_state = to_state;
04349 new_arc->insn = ainsn;
04350 ainsn->arc_exists_p = 1;
04351 new_arc->next_out_arc = from_state->first_out_arc;
04352 from_state->first_out_arc = new_arc;
04353 new_arc->next_arc_marked_by_insn = NULL;
04354 new_arc->state_alts = state_alts;
04355 return new_arc;
04356 }
04357
04358
04359 static arc_t
04360 first_out_arc (state_t state)
04361 {
04362 return state->first_out_arc;
04363 }
04364
04365
04366 static arc_t
04367 next_out_arc (arc_t arc)
04368 {
04369 return arc->next_out_arc;
04370 }
04371
04372
04373 static void
04374 initiate_arcs (void)
04375 {
04376 first_free_arc = NULL;
04377 }
04378
04379
04380 static void
04381 finish_arcs (void)
04382 {
04383 }
04384
04385
04386
04387
04388
04389
04390 static automata_list_el_t first_free_automata_list_el;
04391
04392
04393 static automata_list_el_t current_automata_list;
04394
04395
04396 static htab_t automata_list_table;
04397
04398
04399
04400 static automata_list_el_t
04401 get_free_automata_list_el (void)
04402 {
04403 automata_list_el_t result;
04404
04405 if (first_free_automata_list_el != NULL)
04406 {
04407 result = first_free_automata_list_el;
04408 first_free_automata_list_el
04409 = first_free_automata_list_el->next_automata_list_el;
04410 }
04411 else
04412 result = create_node (sizeof (struct automata_list_el));
04413 result->automaton = NULL;
04414 result->next_automata_list_el = NULL;
04415 return result;
04416 }
04417
04418
04419 static void
04420 free_automata_list_el (automata_list_el_t automata_list_el)
04421 {
04422 if (automata_list_el == NULL)
04423 return;
04424 automata_list_el->next_automata_list_el = first_free_automata_list_el;
04425 first_free_automata_list_el = automata_list_el;
04426 }
04427
04428
04429 static void
04430 free_automata_list (automata_list_el_t automata_list)
04431 {
04432 automata_list_el_t curr_automata_list_el;
04433 automata_list_el_t next_automata_list_el;
04434
04435 for (curr_automata_list_el = automata_list;
04436 curr_automata_list_el != NULL;
04437 curr_automata_list_el = next_automata_list_el)
04438 {
04439 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
04440 free_automata_list_el (curr_automata_list_el);
04441 }
04442 }
04443
04444
04445 static hashval_t
04446 automata_list_hash (const void *automata_list)
04447 {
04448 unsigned int hash_value;
04449 automata_list_el_t curr_automata_list_el;
04450
04451 hash_value = 0;
04452 for (curr_automata_list_el = (automata_list_el_t) automata_list;
04453 curr_automata_list_el != NULL;
04454 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
04455 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
04456 | (hash_value << CHAR_BIT))
04457 + curr_automata_list_el->automaton->automaton_order_num);
04458 return hash_value;
04459 }
04460
04461
04462 static int
04463 automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
04464 {
04465 automata_list_el_t automata_list_el_1;
04466 automata_list_el_t automata_list_el_2;
04467
04468 for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
04469 automata_list_el_2 = (automata_list_el_t) automata_list_2;
04470 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
04471 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
04472 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
04473 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
04474 return 0;
04475 return automata_list_el_1 == automata_list_el_2;
04476 }
04477
04478
04479 static void
04480 initiate_automata_lists (void)
04481 {
04482 first_free_automata_list_el = NULL;
04483 automata_list_table = htab_create (1500, automata_list_hash,
04484 automata_list_eq_p, (htab_del) 0);
04485 }
04486
04487
04488
04489 static void
04490 automata_list_start (void)
04491 {
04492 current_automata_list = NULL;
04493 }
04494
04495
04496 static void
04497 automata_list_add (automaton_t automaton)
04498 {
04499 automata_list_el_t el;
04500
04501 el = get_free_automata_list_el ();
04502 el->automaton = automaton;
04503 el->next_automata_list_el = current_automata_list;
04504 current_automata_list = el;
04505 }
04506
04507
04508
04509 static automata_list_el_t
04510 automata_list_finish (void)
04511 {
04512 void **entry_ptr;
04513
04514 if (current_automata_list == NULL)
04515 return NULL;
04516 entry_ptr = htab_find_slot (automata_list_table,
04517 (void *) current_automata_list, 1);
04518 if (*entry_ptr == NULL)
04519 *entry_ptr = (void *) current_automata_list;
04520 else
04521 free_automata_list (current_automata_list);
04522 current_automata_list = NULL;
04523 return (automata_list_el_t) *entry_ptr;
04524 }
04525
04526
04527 static void
04528 finish_automata_lists (void)
04529 {
04530 htab_delete (automata_list_table);
04531 }
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542 static reserv_sets_t excl_set;
04543
04544
04545 static reserv_sets_t *unit_excl_set_table;
04546
04547
04548
04549 static void
04550 initiate_excl_sets (void)
04551 {
04552 decl_t decl;
04553 reserv_sets_t unit_excl_set;
04554 unit_set_el_t el;
04555 int i;
04556
04557 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
04558 excl_set = (reserv_sets_t) obstack_base (&irp);
04559 obstack_finish (&irp);
04560 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
04561 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
04562 obstack_finish (&irp);
04563
04564 for (i = 0; i < description->decls_num; i++)
04565 {
04566 decl = description->decls [i];
04567 if (decl->mode == dm_unit)
04568 {
04569 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
04570 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
04571 obstack_finish (&irp);
04572 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
04573 for (el = DECL_UNIT (decl)->excl_list;
04574 el != NULL;
04575 el = el->next_unit_set_el)
04576 {
04577 SET_BIT (unit_excl_set, el->unit_decl->unit_num);
04578 el->unit_decl->in_set_p = TRUE;
04579 }
04580 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
04581 }
04582 }
04583 }
04584
04585
04586
04587 static reserv_sets_t
04588 get_excl_set (reserv_sets_t in_set)
04589 {
04590 int excl_char_num;
04591 int chars_num;
04592 int i;
04593 int start_unit_num;
04594 int unit_num;
04595
04596 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04597 memset (excl_set, 0, chars_num);
04598 for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
04599 if (((unsigned char *) in_set) [excl_char_num])
04600 for (i = CHAR_BIT - 1; i >= 0; i--)
04601 if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
04602 {
04603 start_unit_num = excl_char_num * CHAR_BIT + i;
04604 if (start_unit_num >= description->units_num)
04605 return excl_set;
04606 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04607 {
04608 excl_set [unit_num]
04609 |= unit_excl_set_table [start_unit_num] [unit_num];
04610 }
04611 }
04612 return excl_set;
04613 }
04614
04615
04616
04617
04618
04619
04620
04621
04622 static pattern_reserv_t *unit_presence_set_table;
04623 static pattern_reserv_t *unit_final_presence_set_table;
04624 static pattern_reserv_t *unit_absence_set_table;
04625 static pattern_reserv_t *unit_final_absence_set_table;
04626
04627
04628
04629 static pattern_reserv_t
04630 form_reserv_sets_list (pattern_set_el_t pattern_list)
04631 {
04632 pattern_set_el_t el;
04633 pattern_reserv_t first, curr, prev;
04634 int i;
04635
04636 prev = first = NULL;
04637 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
04638 {
04639 curr = create_node (sizeof (struct pattern_reserv));
04640 curr->reserv = alloc_empty_reserv_sets ();
04641 curr->next_pattern_reserv = NULL;
04642 for (i = 0; i < el->units_num; i++)
04643 {
04644 SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
04645 el->unit_decls [i]->in_set_p = TRUE;
04646 }
04647 if (prev != NULL)
04648 prev->next_pattern_reserv = curr;
04649 else
04650 first = curr;
04651 prev = curr;
04652 }
04653 return first;
04654 }
04655
04656
04657
04658 static void
04659 initiate_presence_absence_pattern_sets (void)
04660 {
04661 decl_t decl;
04662 int i;
04663
04664 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04665 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04666 obstack_finish (&irp);
04667 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04668 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04669 obstack_finish (&irp);
04670 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04671 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04672 obstack_finish (&irp);
04673 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
04674 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
04675 obstack_finish (&irp);
04676
04677 for (i = 0; i < description->decls_num; i++)
04678 {
04679 decl = description->decls [i];
04680 if (decl->mode == dm_unit)
04681 {
04682 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
04683 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
04684 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
04685 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
04686 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
04687 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
04688 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
04689 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
04690 }
04691 }
04692 }
04693
04694
04695
04696
04697 static int
04698 check_presence_pattern_sets (reserv_sets_t checked_set,
04699 reserv_sets_t origional_set,
04700 int final_p)
04701 {
04702 int char_num;
04703 int chars_num;
04704 int i;
04705 int start_unit_num;
04706 int unit_num;
04707 int presence_p;
04708 pattern_reserv_t pat_reserv;
04709
04710 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04711 for (char_num = 0; char_num < chars_num; char_num++)
04712 if (((unsigned char *) origional_set) [char_num])
04713 for (i = CHAR_BIT - 1; i >= 0; i--)
04714 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
04715 {
04716 start_unit_num = char_num * CHAR_BIT + i;
04717 if (start_unit_num >= description->units_num)
04718 break;
04719 if ((final_p
04720 && unit_final_presence_set_table [start_unit_num] == NULL)
04721 || (!final_p
04722 && unit_presence_set_table [start_unit_num] == NULL))
04723 continue;
04724 presence_p = FALSE;
04725 for (pat_reserv = (final_p
04726 ? unit_final_presence_set_table [start_unit_num]
04727 : unit_presence_set_table [start_unit_num]);
04728 pat_reserv != NULL;
04729 pat_reserv = pat_reserv->next_pattern_reserv)
04730 {
04731 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04732 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
04733 != pat_reserv->reserv [unit_num])
04734 break;
04735 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
04736 }
04737 if (!presence_p)
04738 return FALSE;
04739 }
04740 return TRUE;
04741 }
04742
04743
04744
04745
04746 static int
04747 check_absence_pattern_sets (reserv_sets_t checked_set,
04748 reserv_sets_t origional_set,
04749 int final_p)
04750 {
04751 int char_num;
04752 int chars_num;
04753 int i;
04754 int start_unit_num;
04755 int unit_num;
04756 pattern_reserv_t pat_reserv;
04757
04758 chars_num = els_in_cycle_reserv * sizeof (set_el_t);
04759 for (char_num = 0; char_num < chars_num; char_num++)
04760 if (((unsigned char *) origional_set) [char_num])
04761 for (i = CHAR_BIT - 1; i >= 0; i--)
04762 if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
04763 {
04764 start_unit_num = char_num * CHAR_BIT + i;
04765 if (start_unit_num >= description->units_num)
04766 break;
04767 for (pat_reserv = (final_p
04768 ? unit_final_absence_set_table [start_unit_num]
04769 : unit_absence_set_table [start_unit_num]);
04770 pat_reserv != NULL;
04771 pat_reserv = pat_reserv->next_pattern_reserv)
04772 {
04773 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
04774 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
04775 != pat_reserv->reserv [unit_num]
04776 && pat_reserv->reserv [unit_num])
04777 break;
04778 if (unit_num >= els_in_cycle_reserv)
04779 return FALSE;
04780 }
04781 }
04782 return TRUE;
04783 }
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797 static regexp_t
04798 copy_insn_regexp (regexp_t regexp)
04799 {
04800 regexp_t result;
04801 int i;
04802
04803 switch (regexp->mode)
04804 {
04805 case rm_reserv:
04806 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
04807 break;
04808
04809 case rm_unit:
04810 result = copy_node (regexp, sizeof (struct regexp));
04811 break;
04812
04813 case rm_repeat:
04814 result = copy_node (regexp, sizeof (struct regexp));
04815 REGEXP_REPEAT (result)->regexp
04816 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
04817 break;
04818
04819 case rm_sequence:
04820 result = copy_node (regexp,
04821 sizeof (struct regexp) + sizeof (regexp_t)
04822 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
04823 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04824 REGEXP_SEQUENCE (result)->regexps [i]
04825 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04826 break;
04827
04828 case rm_allof:
04829 result = copy_node (regexp,
04830 sizeof (struct regexp) + sizeof (regexp_t)
04831 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
04832 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04833 REGEXP_ALLOF (result)->regexps [i]
04834 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04835 break;
04836
04837 case rm_oneof:
04838 result = copy_node (regexp,
04839 sizeof (struct regexp) + sizeof (regexp_t)
04840 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
04841 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04842 REGEXP_ONEOF (result)->regexps [i]
04843 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
04844 break;
04845
04846 case rm_nothing:
04847 result = copy_node (regexp, sizeof (struct regexp));
04848 break;
04849
04850 default:
04851 gcc_unreachable ();
04852 }
04853 return result;
04854 }
04855
04856
04857
04858 static int regexp_transformed_p;
04859
04860
04861
04862 static regexp_t
04863 transform_1 (regexp_t regexp)
04864 {
04865 int i;
04866 int repeat_num;
04867 regexp_t operand;
04868 pos_t pos;
04869
04870 if (regexp->mode == rm_repeat)
04871 {
04872 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
04873 gcc_assert (repeat_num > 1);
04874 operand = REGEXP_REPEAT (regexp)->regexp;
04875 pos = regexp->mode;
04876 regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
04877 * (repeat_num - 1));
04878 regexp->mode = rm_sequence;
04879 regexp->pos = pos;
04880 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
04881 for (i = 0; i < repeat_num; i++)
04882 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
04883 regexp_transformed_p = 1;
04884 }
04885 return regexp;
04886 }
04887
04888
04889
04890
04891
04892 static regexp_t
04893 transform_2 (regexp_t regexp)
04894 {
04895 if (regexp->mode == rm_sequence)
04896 {
04897 regexp_t sequence = NULL;
04898 regexp_t result;
04899 int sequence_index = 0;
04900 int i, j;
04901
04902 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04903 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
04904 {
04905 sequence_index = i;
04906 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
04907 break;
04908 }
04909 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
04910 {
04911 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
04912 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
04913 result = create_node (sizeof (struct regexp)
04914 + sizeof (regexp_t)
04915 * (REGEXP_SEQUENCE (regexp)->regexps_num
04916 + REGEXP_SEQUENCE (sequence)->regexps_num
04917 - 2));
04918 result->mode = rm_sequence;
04919 result->pos = regexp->pos;
04920 REGEXP_SEQUENCE (result)->regexps_num
04921 = (REGEXP_SEQUENCE (regexp)->regexps_num
04922 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
04923 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
04924 if (i < sequence_index)
04925 REGEXP_SEQUENCE (result)->regexps [i]
04926 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04927 else if (i > sequence_index)
04928 REGEXP_SEQUENCE (result)->regexps
04929 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
04930 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
04931 else
04932 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
04933 REGEXP_SEQUENCE (result)->regexps [i + j]
04934 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
04935 regexp_transformed_p = 1;
04936 regexp = result;
04937 }
04938 }
04939 else if (regexp->mode == rm_allof)
04940 {
04941 regexp_t allof = NULL;
04942 regexp_t result;
04943 int allof_index = 0;
04944 int i, j;
04945
04946 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04947 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
04948 {
04949 allof_index = i;
04950 allof = REGEXP_ALLOF (regexp)->regexps [i];
04951 break;
04952 }
04953 if (i < REGEXP_ALLOF (regexp)->regexps_num)
04954 {
04955 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
04956 && REGEXP_ALLOF (regexp)->regexps_num > 1);
04957 result = create_node (sizeof (struct regexp)
04958 + sizeof (regexp_t)
04959 * (REGEXP_ALLOF (regexp)->regexps_num
04960 + REGEXP_ALLOF (allof)->regexps_num - 2));
04961 result->mode = rm_allof;
04962 result->pos = regexp->pos;
04963 REGEXP_ALLOF (result)->regexps_num
04964 = (REGEXP_ALLOF (regexp)->regexps_num
04965 + REGEXP_ALLOF (allof)->regexps_num - 1);
04966 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
04967 if (i < allof_index)
04968 REGEXP_ALLOF (result)->regexps [i]
04969 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04970 else if (i > allof_index)
04971 REGEXP_ALLOF (result)->regexps
04972 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
04973 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
04974 else
04975 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
04976 REGEXP_ALLOF (result)->regexps [i + j]
04977 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
04978 regexp_transformed_p = 1;
04979 regexp = result;
04980 }
04981 }
04982 else if (regexp->mode == rm_oneof)
04983 {
04984 regexp_t oneof = NULL;
04985 regexp_t result;
04986 int oneof_index = 0;
04987 int i, j;
04988
04989 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
04990 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
04991 {
04992 oneof_index = i;
04993 oneof = REGEXP_ONEOF (regexp)->regexps [i];
04994 break;
04995 }
04996 if (i < REGEXP_ONEOF (regexp)->regexps_num)
04997 {
04998 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
04999 && REGEXP_ONEOF (regexp)->regexps_num > 1);
05000 result = create_node (sizeof (struct regexp)
05001 + sizeof (regexp_t)
05002 * (REGEXP_ONEOF (regexp)->regexps_num
05003 + REGEXP_ONEOF (oneof)->regexps_num - 2));
05004 result->mode = rm_oneof;
05005 result->pos = regexp->pos;
05006 REGEXP_ONEOF (result)->regexps_num
05007 = (REGEXP_ONEOF (regexp)->regexps_num
05008 + REGEXP_ONEOF (oneof)->regexps_num - 1);
05009 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
05010 if (i < oneof_index)
05011 REGEXP_ONEOF (result)->regexps [i]
05012 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
05013 else if (i > oneof_index)
05014 REGEXP_ONEOF (result)->regexps
05015 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
05016 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
05017 else
05018 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
05019 REGEXP_ONEOF (result)->regexps [i + j]
05020 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
05021 regexp_transformed_p = 1;
05022 regexp = result;
05023 }
05024 }
05025 return regexp;
05026 }
05027
05028
05029
05030
05031
05032
05033 static regexp_t
05034 transform_3 (regexp_t regexp)
05035 {
05036 if (regexp->mode == rm_sequence)
05037 {
05038 regexp_t oneof = NULL;
05039 int oneof_index = 0;
05040 regexp_t result;
05041 regexp_t sequence;
05042 int i, j;
05043
05044 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
05045 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
05046 {
05047 oneof_index = i;
05048 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
05049 break;
05050 }
05051 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
05052 {
05053 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
05054 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
05055 result = create_node (sizeof (struct regexp)
05056 + sizeof (regexp_t)
05057 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
05058 result->mode = rm_oneof;
05059 result->pos = regexp->pos;
05060 REGEXP_ONEOF (result)->regexps_num
05061 = REGEXP_ONEOF (oneof)->regexps_num;
05062 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
05063 {
05064 sequence
05065 = create_node (sizeof (struct regexp)
05066 + sizeof (regexp_t)
05067 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
05068 sequence->mode = rm_sequence;
05069 sequence->pos = regexp->pos;
05070 REGEXP_SEQUENCE (sequence)->regexps_num
05071 = REGEXP_SEQUENCE (regexp)->regexps_num;
05072 REGEXP_ONEOF (result)->regexps [i] = sequence;
05073 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
05074 if (j != oneof_index)
05075 REGEXP_SEQUENCE (sequence)->regexps [j]
05076 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
05077 else
05078 REGEXP_SEQUENCE (sequence)->regexps [j]
05079 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
05080 }
05081 regexp_transformed_p = 1;
05082 regexp = result;
05083 }
05084 }
05085 else if (regexp->mode == rm_allof)
05086 {
05087 regexp_t oneof = NULL;
05088 regexp_t seq;
05089 int oneof_index = 0;
05090 int max_seq_length, allof_length;
05091 regexp_t result;
05092 regexp_t allof = NULL;
05093 regexp_t allof_op = NULL;
05094 int i, j;
05095
05096 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
05097 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
05098 {
05099 oneof_index = i;
05100 oneof = REGEXP_ALLOF (regexp)->regexps [i];
05101 break;
05102 }
05103 if (i < REGEXP_ALLOF (regexp)->regexps_num)
05104 {
05105 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
05106 && REGEXP_ALLOF (regexp)->regexps_num > 1);
05107 result = create_node (sizeof (struct regexp)
05108 + sizeof (regexp_t)
05109 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
05110 result->mode = rm_oneof;
05111 result->pos = regexp->pos;
05112 REGEXP_ONEOF (result)->regexps_num
05113 = REGEXP_ONEOF (oneof)->regexps_num;
05114 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
05115 {
05116 allof
05117 = create_node (sizeof (struct regexp)
05118 + sizeof (regexp_t)
05119 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
05120 allof->mode = rm_allof;
05121 allof->pos = regexp->pos;
05122 REGEXP_ALLOF (allof)->regexps_num
05123 = REGEXP_ALLOF (regexp)->regexps_num;
05124 REGEXP_ONEOF (result)->regexps [i] = allof;
05125 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
05126 if (j != oneof_index)
05127 REGEXP_ALLOF (allof)->regexps [j]
05128 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
05129 else
05130 REGEXP_ALLOF (allof)->regexps [j]
05131 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
05132 }
05133 regexp_transformed_p = 1;
05134 regexp = result;
05135 }
05136 max_seq_length = 0;
05137 if (regexp->mode == rm_allof)
05138 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
05139 {
05140 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
05141 {
05142 case rm_sequence:
05143 seq = REGEXP_ALLOF (regexp)->regexps [i];
05144 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
05145 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
05146 break;
05147
05148 case rm_unit:
05149 case rm_nothing:
05150 break;
05151
05152 default:
05153 max_seq_length = 0;
05154 goto break_for;
05155 }
05156 }
05157 break_for:
05158 if (max_seq_length != 0)
05159 {
05160 gcc_assert (max_seq_length != 1
05161 && REGEXP_ALLOF (regexp)->regexps_num > 1);
05162 result = create_node (sizeof (struct regexp)
05163 + sizeof (regexp_t) * (max_seq_length - 1));
05164 result->mode = rm_sequence;
05165 result->pos = regexp->pos;
05166 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
05167 for (i = 0; i < max_seq_length; i++)
05168 {
05169 allof_length = 0;
05170 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
05171 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
05172 {
05173 case rm_sequence:
05174 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
05175 ->regexps [j])->regexps_num))
05176 {
05177 allof_op
05178 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
05179 ->regexps [j])
05180 ->regexps [i]);
05181 allof_length++;
05182 }
05183 break;
05184 case rm_unit:
05185 case rm_nothing:
05186 if (i == 0)
05187 {
05188 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
05189 allof_length++;
05190 }
05191 break;
05192 default:
05193 break;
05194 }
05195
05196 if (allof_length == 1)
05197 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
05198 else
05199 {
05200 allof = create_node (sizeof (struct regexp)
05201 + sizeof (regexp_t)
05202 * (allof_length - 1));
05203 allof->mode = rm_allof;
05204 allof->pos = regexp->pos;
05205 REGEXP_ALLOF (allof)->regexps_num = allof_length;
05206 REGEXP_SEQUENCE (result)->regexps [i] = allof;
05207 allof_length = 0;
05208 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
05209 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
05210 && (i <
05211 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
05212 ->regexps [j])->regexps_num)))
05213 {
05214 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
05215 ->regexps [j])
05216 ->regexps [i]);
05217 REGEXP_ALLOF (allof)->regexps [allof_length]
05218 = allof_op;
05219 allof_length++;
05220 }
05221 else if (i == 0
05222 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
05223 == rm_unit
05224 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
05225 == rm_nothing)))
05226 {
05227 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
05228 REGEXP_ALLOF (allof)->regexps [allof_length]
05229 = allof_op;
05230 allof_length++;
05231 }
05232 }
05233 }
05234 regexp_transformed_p = 1;
05235 regexp = result;
05236 }
05237 }
05238 return regexp;
05239 }
05240
05241
05242
05243 static regexp_t
05244 regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
05245 {
05246 int i;
05247
05248 switch (regexp->mode)
05249 {
05250 case rm_sequence:
05251 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
05252 REGEXP_SEQUENCE (regexp)->regexps [i]
05253 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
05254 func);
05255 break;
05256
05257 case rm_allof:
05258 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
05259 REGEXP_ALLOF (regexp)->regexps [i]
05260 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
05261 break;
05262
05263 case rm_oneof:
05264 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
05265 REGEXP_ONEOF (regexp)->regexps [i]
05266 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
05267 break;
05268
05269 case rm_repeat:
05270 REGEXP_REPEAT (regexp)->regexp
05271 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
05272 break;
05273
05274 case rm_nothing:
05275 case rm_unit:
05276 break;
05277
05278 default:
05279 gcc_unreachable ();
05280 }
05281 return (*func) (regexp);
05282 }
05283
05284
05285
05286 static regexp_t
05287 transform_regexp (regexp_t regexp)
05288 {
05289 regexp = regexp_transform_func (regexp, transform_1);
05290 do
05291 {
05292 regexp_transformed_p = 0;
05293 regexp = regexp_transform_func (regexp, transform_2);
05294 regexp = regexp_transform_func (regexp, transform_3);
05295 }
05296 while (regexp_transformed_p);
05297 return regexp;
05298 }
05299
05300
05301
05302 static void
05303 transform_insn_regexps (void)
05304 {
05305 decl_t decl;
05306 int i;
05307
05308 transform_time = create_ticker ();
05309 add_advance_cycle_insn_decl ();
05310 if (progress_flag)
05311 fprintf (stderr, "Reservation transformation...");
05312 for (i = 0; i < description->decls_num; i++)
05313 {
05314 decl = description->decls [i];
05315 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
05316 DECL_INSN_RESERV (decl)->transformed_regexp
05317 = transform_regexp (copy_insn_regexp
05318 (DECL_INSN_RESERV (decl)->regexp));
05319 }
05320 if (progress_flag)
05321 fprintf (stderr, "done\n");
05322 ticker_off (&transform_time);
05323 }
05324
05325
05326
05327
05328
05329 static int annotation_message_reported_p;
05330
05331
05332 struct unit_usage
05333 {
05334 unit_decl_t unit_decl;
05335
05336
05337 struct unit_usage *next;
05338 };
05339
05340
05341 static struct obstack unit_usages;
05342
05343
05344
05345
05346
05347
05348
05349 static vla_ptr_t cycle_alt_unit_usages;
05350
05351
05352
05353
05354 static void
05355 store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
05356 int alt_num)
05357 {
05358 size_t i, length, old_length;
05359 unit_decl_t unit_decl;
05360 struct unit_usage *unit_usage_ptr;
05361 int index;
05362
05363 gcc_assert (regexp && regexp->mode == rm_oneof
05364 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
05365 unit_decl = REGEXP_UNIT (unit)->unit_decl;
05366 old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
05367 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
05368 if (old_length < length)
05369 {
05370 VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
05371 for (i = old_length; i < length; i++)
05372 VLA_PTR (cycle_alt_unit_usages, i) = NULL;
05373 }
05374 obstack_blank (&unit_usages, sizeof (struct unit_usage));
05375 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
05376 obstack_finish (&unit_usages);
05377 unit_usage_ptr->unit_decl = unit_decl;
05378 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
05379 unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
05380 VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
05381 unit_decl->last_distribution_check_cycle = -1;
05382 }
05383
05384
05385
05386 static void
05387 check_regexp_units_distribution (const char *insn_reserv_name,
05388 regexp_t regexp)
05389 {
05390 int i, j, k, cycle;
05391 regexp_t seq, allof, unit;
05392 struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
05393
05394 if (regexp == NULL || regexp->mode != rm_oneof)
05395 return;
05396
05397 obstack_init (&unit_usages);
05398 VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
05399 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
05400 {
05401 seq = REGEXP_ONEOF (regexp)->regexps [i];
05402 switch (seq->mode)
05403 {
05404 case rm_sequence:
05405 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
05406 {
05407 allof = REGEXP_SEQUENCE (seq)->regexps [j];
05408 switch (allof->mode)
05409 {
05410 case rm_allof:
05411 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
05412 {
05413 unit = REGEXP_ALLOF (allof)->regexps [k];
05414 if (unit->mode == rm_unit)
05415 store_alt_unit_usage (regexp, unit, j, i);
05416 else
05417 gcc_assert (unit->mode == rm_nothing);
05418 }
05419 break;
05420
05421 case rm_unit:
05422 store_alt_unit_usage (regexp, allof, j, i);
05423 break;
05424
05425 case rm_nothing:
05426 break;
05427
05428 default:
05429 gcc_unreachable ();
05430 }
05431 }
05432 break;
05433
05434 case rm_allof:
05435 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
05436 {
05437 unit = REGEXP_ALLOF (seq)->regexps [k];
05438 switch (unit->mode)
05439 {
05440 case rm_unit:
05441 store_alt_unit_usage (regexp, unit, 0, i);
05442 break;
05443
05444 case rm_nothing:
05445 break;
05446
05447 default:
05448 gcc_unreachable ();
05449 }
05450 }
05451 break;
05452
05453 case rm_unit:
05454 store_alt_unit_usage (regexp, seq, 0, i);
05455 break;
05456
05457 case rm_nothing:
05458 break;
05459
05460 default:
05461 gcc_unreachable ();
05462 }
05463 }
05464
05465 for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
05466 {
05467 cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
05468 for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
05469 unit_usage_ptr != NULL;
05470 unit_usage_ptr = unit_usage_ptr->next)
05471 if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
05472 {
05473 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
05474 for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
05475 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
05476 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
05477 k++)
05478 {
05479 for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
05480 other_unit_usage_ptr != NULL;
05481 other_unit_usage_ptr = other_unit_usage_ptr->next)
05482 if (unit_usage_ptr->unit_decl->automaton_decl
05483 == other_unit_usage_ptr->unit_decl->automaton_decl)
05484 break;
05485 if (other_unit_usage_ptr == NULL
05486 && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
05487 break;
05488 }
05489 if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
05490 && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
05491 {
05492 if (!annotation_message_reported_p)
05493 {
05494 fprintf (stderr, "\n");
05495 error ("The following units do not satisfy units-automata distribution rule");
05496 error (" (A unit of given unit automaton should be on each reserv. altern.)");
05497 annotation_message_reported_p = TRUE;
05498 }
05499 error ("Unit %s, reserv. %s, cycle %d",
05500 unit_usage_ptr->unit_decl->name, insn_reserv_name,
05501 cycle);
05502 }
05503 }
05504 }
05505 VLA_PTR_DELETE (cycle_alt_unit_usages);
05506 obstack_free (&unit_usages, NULL);
05507 }
05508
05509
05510
05511 static void
05512 check_unit_distributions_to_automata (void)
05513 {
05514 decl_t decl;
05515 int i;
05516
05517 if (progress_flag)
05518 fprintf (stderr, "Check unit distributions to automata...");
05519 annotation_message_reported_p = FALSE;
05520 for (i = 0; i < description->decls_num; i++)
05521 {
05522 decl = description->decls [i];
05523 if (decl->mode == dm_insn_reserv)
05524 check_regexp_units_distribution
05525 (DECL_INSN_RESERV (decl)->name,
05526 DECL_INSN_RESERV (decl)->transformed_regexp);
05527 }
05528 if (progress_flag)
05529 fprintf (stderr, "done\n");
05530 }
05531
05532
05533
05534
05535
05536
05537
05538
05539 static state_t state_being_formed;
05540
05541
05542 static alt_state_t alt_state_being_formed;
05543
05544
05545
05546
05547 static int
05548 process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
05549 int curr_cycle)
05550 {
05551 int i;
05552
05553 if (regexp == NULL)
05554 return curr_cycle;
05555
05556 switch (regexp->mode)
05557 {
05558 case rm_unit:
05559 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
05560 == automaton->automaton_order_num)
05561 set_state_reserv (state_being_formed, curr_cycle,
05562 REGEXP_UNIT (regexp)->unit_decl->unit_num);
05563 return curr_cycle;
05564
05565 case rm_sequence:
05566 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
05567 curr_cycle
05568 = process_seq_for_forming_states
05569 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
05570 return curr_cycle;
05571
05572 case rm_allof:
05573 {
05574 int finish_cycle = 0;
05575 int cycle;
05576
05577 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
05578 {
05579 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
05580 ->regexps [i],
05581 automaton, curr_cycle);
05582 if (finish_cycle < cycle)
05583 finish_cycle = cycle;
05584 }
05585 return finish_cycle;
05586 }
05587
05588 case rm_nothing:
05589 return curr_cycle;
05590
05591 default:
05592 gcc_unreachable ();
05593 }
05594 }
05595
05596
05597
05598 static void
05599 finish_forming_alt_state (alt_state_t alt_state,
05600 automaton_t automaton ATTRIBUTE_UNUSED)
05601 {
05602 state_t state_in_table;
05603 state_t corresponding_state;
05604
05605 corresponding_state = alt_state->state;
05606 state_in_table = insert_state (corresponding_state);
05607 if (state_in_table != corresponding_state)
05608 {
05609 free_state (corresponding_state);
05610 alt_state->state = state_in_table;
05611 }
05612 }
05613
05614
05615
05616 static ainsn_t curr_ainsn;
05617
05618
05619
05620
05621 static void
05622 process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
05623 int inside_oneof_p)
05624 {
05625 int i;
05626
05627 if (regexp->mode != rm_oneof)
05628 {
05629 alt_state_being_formed = get_free_alt_state ();
05630 state_being_formed = get_free_state (1, automaton);
05631 alt_state_being_formed->state = state_being_formed;
05632
05633
05634
05635 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
05636 curr_ainsn->alt_states = alt_state_being_formed;
05637 (void) process_seq_for_forming_states (regexp, automaton, 0);
05638 finish_forming_alt_state (alt_state_being_formed, automaton);
05639 }
05640 else
05641 {
05642 gcc_assert (!inside_oneof_p);
05643
05644
05645
05646 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
05647 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
05648 automaton, 1);
05649 }
05650 }
05651
05652
05653 static void
05654 create_alt_states (automaton_t automaton)
05655 {
05656 struct insn_reserv_decl *reserv_decl;
05657
05658 for (curr_ainsn = automaton->ainsn_list;
05659 curr_ainsn != NULL;
05660 curr_ainsn = curr_ainsn->next_ainsn)
05661 {
05662 reserv_decl = curr_ainsn->insn_reserv_decl;
05663 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
05664 {
05665 curr_ainsn->alt_states = NULL;
05666 process_alts_for_forming_states (reserv_decl->transformed_regexp,
05667 automaton, 0);
05668 curr_ainsn->sorted_alt_states
05669 = uniq_sort_alt_states (curr_ainsn->alt_states);
05670 }
05671 }
05672 }
05673
05674
05675
05676
05677
05678
05679
05680
05681 static void
05682 form_ainsn_with_same_reservs (automaton_t automaton)
05683 {
05684 ainsn_t curr_ainsn;
05685 size_t i;
05686 vla_ptr_t first_insns;
05687 vla_ptr_t last_insns;
05688
05689 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
05690 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
05691 for (curr_ainsn = automaton->ainsn_list;
05692 curr_ainsn != NULL;
05693 curr_ainsn = curr_ainsn->next_ainsn)
05694 if (curr_ainsn->insn_reserv_decl
05695 == DECL_INSN_RESERV (advance_cycle_insn_decl))
05696 {
05697 curr_ainsn->next_same_reservs_insn = NULL;
05698 curr_ainsn->first_insn_with_same_reservs = 1;
05699 }
05700 else
05701 {
05702 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
05703 if (alt_states_eq
05704 (curr_ainsn->sorted_alt_states,
05705 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
05706 break;
05707 curr_ainsn->next_same_reservs_insn = NULL;
05708 if (i < VLA_PTR_LENGTH (first_insns))
05709 {
05710 curr_ainsn->first_insn_with_same_reservs = 0;
05711 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
05712 = curr_ainsn;
05713 VLA_PTR (last_insns, i) = curr_ainsn;
05714 }
05715 else
05716 {
05717 VLA_PTR_ADD (first_insns, curr_ainsn);
05718 VLA_PTR_ADD (last_insns, curr_ainsn);
05719 curr_ainsn->first_insn_with_same_reservs = 1;
05720 }
05721 }
05722 VLA_PTR_DELETE (first_insns);
05723 VLA_PTR_DELETE (last_insns);
05724 }
05725
05726
05727
05728
05729
05730
05731
05732
05733 static reserv_sets_t
05734 form_reservs_matter (automaton_t automaton)
05735 {
05736 int cycle, unit;
05737 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
05738
05739 for (cycle = 0; cycle < max_cycles_num; cycle++)
05740 for (unit = 0; unit < description->units_num; unit++)
05741 if (units_array [unit]->automaton_decl
05742 == automaton->corresponding_automaton_decl
05743 && (cycle >= units_array [unit]->min_occ_cycle_num
05744
05745 || units_array [unit]->query_p
05746
05747
05748
05749
05750 || units_array [unit]->in_set_p))
05751 set_unit_reserv (reservs_matter, cycle, unit);
05752 return reservs_matter;
05753 }
05754
05755
05756
05757 static void
05758 make_automaton (automaton_t automaton)
05759 {
05760 ainsn_t ainsn;
05761 struct insn_reserv_decl *insn_reserv_decl;
05762 alt_state_t alt_state;
05763 state_t state;
05764 state_t start_state;
05765 state_t state2;
05766 ainsn_t advance_cycle_ainsn;
05767 arc_t added_arc;
05768 vla_ptr_t state_stack;
05769 int states_n;
05770 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
05771
05772 VLA_PTR_CREATE (state_stack, 150, "state stack");
05773
05774 start_state = insert_state (get_free_state (1, automaton));
05775 automaton->start_state = start_state;
05776 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
05777 VLA_PTR_ADD (state_stack, start_state);
05778 states_n = 1;
05779 while (VLA_PTR_LENGTH (state_stack) != 0)
05780 {
05781 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
05782 VLA_PTR_SHORTEN (state_stack, 1);
05783 advance_cycle_ainsn = NULL;
05784 for (ainsn = automaton->ainsn_list;
05785 ainsn != NULL;
05786 ainsn = ainsn->next_ainsn)
05787 if (ainsn->first_insn_with_same_reservs)
05788 {
05789 insn_reserv_decl = ainsn->insn_reserv_decl;
05790 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
05791 {
05792
05793
05794 added_arc = NULL;
05795 for (alt_state = ainsn->alt_states;
05796 alt_state != NULL;
05797 alt_state = alt_state->next_alt_state)
05798 {
05799 state2 = alt_state->state;
05800 if (!intersected_state_reservs_p (state, state2))
05801 {
05802 state2 = states_union (state, state2, reservs_matter);
05803 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
05804 {
05805 state2->it_was_placed_in_stack_for_NDFA_forming
05806 = 1;
05807 VLA_PTR_ADD (state_stack, state2);
05808 states_n++;
05809 if (progress_flag && states_n % 100 == 0)
05810 fprintf (stderr, ".");
05811 }
05812 added_arc = add_arc (state, state2, ainsn, 1);
05813 if (!ndfa_flag)
05814 break;
05815 }
05816 }
05817 if (!ndfa_flag && added_arc != NULL)
05818 {
05819 added_arc->state_alts = 0;
05820 for (alt_state = ainsn->alt_states;
05821 alt_state != NULL;
05822 alt_state = alt_state->next_alt_state)
05823 {
05824 state2 = alt_state->state;
05825 if (!intersected_state_reservs_p (state, state2))
05826 added_arc->state_alts++;
05827 }
05828 }
05829 }
05830 else
05831 advance_cycle_ainsn = ainsn;
05832 }
05833
05834 state2 = state_shift (state, reservs_matter);
05835 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
05836 {
05837 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
05838 VLA_PTR_ADD (state_stack, state2);
05839 states_n++;
05840 if (progress_flag && states_n % 100 == 0)
05841 fprintf (stderr, ".");
05842 }
05843 gcc_assert (advance_cycle_ainsn);
05844 add_arc (state, state2, advance_cycle_ainsn, 1);
05845 }
05846 VLA_PTR_DELETE (state_stack);
05847 }
05848
05849
05850 static void
05851 form_arcs_marked_by_insn (state_t state)
05852 {
05853 decl_t decl;
05854 arc_t arc;
05855 int i;
05856
05857 for (i = 0; i < description->decls_num; i++)
05858 {
05859 decl = description->decls [i];
05860 if (decl->mode == dm_insn_reserv)
05861 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
05862 }
05863 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
05864 {
05865 gcc_assert (arc->insn);
05866 arc->next_arc_marked_by_insn
05867 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
05868 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
05869 }
05870 }
05871
05872
05873
05874
05875
05876 static int
05877 create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
05878 vla_ptr_t *state_stack)
05879 {
05880 state_t state;
05881 alt_state_t alt_state, curr_alt_state;
05882 alt_state_t new_alt_state;
05883 arc_t curr_arc;
05884 arc_t next_arc;
05885 state_t state_in_table;
05886 state_t temp_state;
05887 alt_state_t canonical_alt_states_list;
05888 int alts_number;
05889 int new_state_p = 0;
05890
05891 if (arcs_marked_by_insn == NULL)
05892 return new_state_p;
05893 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
05894 state = arcs_marked_by_insn->to_state;
05895 else
05896 {
05897 gcc_assert (ndfa_flag);
05898
05899 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
05900 curr_alt_state = NULL;
05901 for (curr_arc = arcs_marked_by_insn;
05902 curr_arc != NULL;
05903 curr_arc = curr_arc->next_arc_marked_by_insn)
05904 if (curr_arc->to_state->component_states == NULL)
05905 {
05906 new_alt_state = get_free_alt_state ();
05907 new_alt_state->next_alt_state = curr_alt_state;
05908 new_alt_state->state = curr_arc->to_state;
05909 curr_alt_state = new_alt_state;
05910 }
05911 else
05912 for (alt_state = curr_arc->to_state->component_states;
05913 alt_state != NULL;
05914 alt_state = alt_state->next_sorted_alt_state)
05915 {
05916 new_alt_state = get_free_alt_state ();
05917 new_alt_state->next_alt_state = curr_alt_state;
05918 new_alt_state->state = alt_state->state;
05919 gcc_assert (!alt_state->state->component_states);
05920 curr_alt_state = new_alt_state;
05921 }
05922
05923 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
05924 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
05925 {
05926 temp_state = state;
05927 state = canonical_alt_states_list->state;
05928 free_state (temp_state);
05929 }
05930 else
05931 {
05932 state->component_states = canonical_alt_states_list;
05933 state_in_table = insert_state (state);
05934 if (state_in_table != state)
05935 {
05936 gcc_assert
05937 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
05938 free_state (state);
05939 state = state_in_table;
05940 }
05941 else
05942 {
05943 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
05944 new_state_p = 1;
05945 for (curr_alt_state = state->component_states;
05946 curr_alt_state != NULL;
05947 curr_alt_state = curr_alt_state->next_sorted_alt_state)
05948 for (curr_arc = first_out_arc (curr_alt_state->state);
05949 curr_arc != NULL;
05950 curr_arc = next_out_arc (curr_arc))
05951 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
05952 }
05953 arcs_marked_by_insn->to_state = state;
05954 for (alts_number = 0,
05955 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
05956 curr_arc != NULL;
05957 curr_arc = next_arc)
05958 {
05959 next_arc = curr_arc->next_arc_marked_by_insn;
05960 remove_arc (original_state, curr_arc);
05961 alts_number++;
05962 }
05963 arcs_marked_by_insn->state_alts = alts_number;
05964 }
05965 }
05966 if (!state->it_was_placed_in_stack_for_DFA_forming)
05967 {
05968 state->it_was_placed_in_stack_for_DFA_forming = 1;
05969 VLA_PTR_ADD (*state_stack, state);
05970 }
05971 return new_state_p;
05972 }
05973
05974
05975
05976 static void
05977 NDFA_to_DFA (automaton_t automaton)
05978 {
05979 state_t start_state;
05980 state_t state;
05981 decl_t decl;
05982 vla_ptr_t state_stack;
05983 int i;
05984 int states_n;
05985
05986 VLA_PTR_CREATE (state_stack, 150, "state stack");
05987
05988 start_state = automaton->start_state;
05989 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
05990 VLA_PTR_ADD (state_stack, start_state);
05991 states_n = 1;
05992 while (VLA_PTR_LENGTH (state_stack) != 0)
05993 {
05994 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
05995 VLA_PTR_SHORTEN (state_stack, 1);
05996 form_arcs_marked_by_insn (state);
05997 for (i = 0; i < description->decls_num; i++)
05998 {
05999 decl = description->decls [i];
06000 if (decl->mode == dm_insn_reserv
06001 && create_composed_state
06002 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
06003 &state_stack))
06004 {
06005 states_n++;
06006 if (progress_flag && states_n % 100 == 0)
06007 fprintf (stderr, ".");
06008 }
06009 }
06010 }
06011 VLA_PTR_DELETE (state_stack);
06012 }
06013
06014
06015
06016 static int curr_state_graph_pass_num;
06017
06018
06019
06020 static void
06021 pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
06022 {
06023 arc_t arc;
06024
06025 if (start_state->pass_num == curr_state_graph_pass_num)
06026 return;
06027 start_state->pass_num = curr_state_graph_pass_num;
06028 (*applied_func) (start_state);
06029 for (arc = first_out_arc (start_state);
06030 arc != NULL;
06031 arc = next_out_arc (arc))
06032 pass_state_graph (arc->to_state, applied_func);
06033 }
06034
06035
06036
06037 static void
06038 pass_states (automaton_t automaton, void (*applied_func) (state_t state))
06039 {
06040 curr_state_graph_pass_num++;
06041 pass_state_graph (automaton->start_state, applied_func);
06042 }
06043
06044
06045 static void
06046 initiate_pass_states (void)
06047 {
06048 curr_state_graph_pass_num = 0;
06049 }
06050
06051
06052
06053 static vla_ptr_t all_achieved_states;
06054
06055
06056
06057 static void
06058 add_achieved_state (state_t state)
06059 {
06060 VLA_PTR_ADD (all_achieved_states, state);
06061 }
06062
06063
06064
06065
06066
06067 static int
06068 set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
06069 {
06070 int state_out_arcs_num;
06071 arc_t arc;
06072
06073 state_out_arcs_num = 0;
06074 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06075 {
06076 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num
06077 && !arc->insn->insn_reserv_decl->state_alts);
06078 state_out_arcs_num++;
06079 arc->insn->insn_reserv_decl->equiv_class_num
06080 = (odd_iteration_flag
06081 ? arc->to_state->equiv_class_num_1
06082 : arc->to_state->equiv_class_num_2);
06083 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
06084 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num
06085 && arc->insn->insn_reserv_decl->state_alts > 0);
06086 }
06087 return state_out_arcs_num;
06088 }
06089
06090
06091
06092 static void
06093 clear_arc_insns_equiv_num (state_t state)
06094 {
06095 arc_t arc;
06096
06097 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06098 {
06099 arc->insn->insn_reserv_decl->equiv_class_num = 0;
06100 arc->insn->insn_reserv_decl->state_alts = 0;
06101 }
06102 }
06103
06104
06105
06106 static void
06107 copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
06108 {
06109 state_t *class_ptr;
06110
06111 VLA_PTR_NULLIFY (*to);
06112 for (class_ptr = VLA_PTR_BEGIN (*from);
06113 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
06114 class_ptr++)
06115 VLA_PTR_ADD (*to, *class_ptr);
06116 }
06117
06118
06119
06120 static int
06121 first_cycle_unit_presence (state_t state, int unit_num)
06122 {
06123 int presence_p;
06124
06125 if (state->component_states == NULL)
06126 presence_p = test_unit_reserv (state->reservs, 0, unit_num);
06127 else
06128 presence_p
06129 = test_unit_reserv (state->component_states->state->reservs,
06130 0, unit_num);
06131 return presence_p;
06132 }
06133
06134
06135
06136
06137
06138
06139 static int
06140 state_is_differed (state_t state, state_t another_state,
06141 int another_state_out_arcs_num, int odd_iteration_flag)
06142 {
06143 arc_t arc;
06144 int state_out_arcs_num;
06145 int i, presence1_p, presence2_p;
06146
06147 state_out_arcs_num = 0;
06148 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06149 {
06150 state_out_arcs_num++;
06151 if ((odd_iteration_flag
06152 ? arc->to_state->equiv_class_num_1
06153 : arc->to_state->equiv_class_num_2)
06154 != arc->insn->insn_reserv_decl->equiv_class_num
06155 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
06156 return 1;
06157 }
06158 if (state_out_arcs_num != another_state_out_arcs_num)
06159 return 1;
06160
06161
06162 for (i = 0; i < description->units_num; i++)
06163 if (units_array [i]->query_p)
06164 {
06165 presence1_p = first_cycle_unit_presence (state, i);
06166 presence2_p = first_cycle_unit_presence (another_state, i);
06167 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
06168 return 1;
06169 }
06170 return 0;
06171 }
06172
06173
06174
06175 static state_t
06176 init_equiv_class (state_t *states, int states_num)
06177 {
06178 state_t *state_ptr;
06179 state_t result_equiv_class;
06180
06181 result_equiv_class = NULL;
06182 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
06183 {
06184 (*state_ptr)->equiv_class_num_1 = 1;
06185 (*state_ptr)->next_equiv_class_state = result_equiv_class;
06186 result_equiv_class = *state_ptr;
06187 }
06188 return result_equiv_class;
06189 }
06190
06191
06192
06193
06194
06195
06196
06197
06198 static int
06199 partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
06200 vla_ptr_t *next_iteration_classes,
06201 int *new_equiv_class_num_ptr)
06202 {
06203 state_t new_equiv_class;
06204 int partition_p;
06205 state_t first_state;
06206 state_t curr_state;
06207 state_t prev_state;
06208 state_t next_state;
06209 int out_arcs_num;
06210
06211 partition_p = 0;
06212 gcc_assert (*equiv_class_ptr);
06213 for (first_state = *equiv_class_ptr;
06214 first_state != NULL;
06215 first_state = new_equiv_class)
06216 {
06217 new_equiv_class = NULL;
06218 if (first_state->next_equiv_class_state != NULL)
06219 {
06220
06221 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
06222 odd_iteration_flag);
06223 for (prev_state = first_state,
06224 curr_state = first_state->next_equiv_class_state;
06225 curr_state != NULL;
06226 curr_state = next_state)
06227 {
06228 next_state = curr_state->next_equiv_class_state;
06229 if (state_is_differed (curr_state, first_state, out_arcs_num,
06230 odd_iteration_flag))
06231 {
06232
06233 prev_state->next_equiv_class_state = next_state;
06234
06235 curr_state->next_equiv_class_state = new_equiv_class;
06236 if (new_equiv_class == NULL)
06237 (*new_equiv_class_num_ptr)++;
06238 if (odd_iteration_flag)
06239 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
06240 else
06241 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
06242 new_equiv_class = curr_state;
06243 partition_p = 1;
06244 }
06245 else
06246 prev_state = curr_state;
06247 }
06248 clear_arc_insns_equiv_num (first_state);
06249 }
06250 if (new_equiv_class != NULL)
06251 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
06252 }
06253 return partition_p;
06254 }
06255
06256
06257 static void
06258 evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
06259 {
06260 state_t new_equiv_class;
06261 int new_equiv_class_num;
06262 int odd_iteration_flag;
06263 int finish_flag;
06264 vla_ptr_t next_iteration_classes;
06265 state_t *equiv_class_ptr;
06266 state_t *state_ptr;
06267
06268 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
06269 pass_states (automaton, add_achieved_state);
06270 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
06271 VLA_PTR_LENGTH (all_achieved_states));
06272 odd_iteration_flag = 0;
06273 new_equiv_class_num = 1;
06274 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
06275 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
06276 do
06277 {
06278 odd_iteration_flag = !odd_iteration_flag;
06279 finish_flag = 1;
06280 copy_equiv_class (equiv_classes, &next_iteration_classes);
06281
06282 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
06283 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
06284 state_ptr++)
06285 if (odd_iteration_flag)
06286 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
06287 else
06288 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
06289 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
06290 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
06291 equiv_class_ptr++)
06292 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
06293 &next_iteration_classes,
06294 &new_equiv_class_num))
06295 finish_flag = 0;
06296 }
06297 while (!finish_flag);
06298 VLA_PTR_DELETE (next_iteration_classes);
06299 VLA_PTR_DELETE (all_achieved_states);
06300 }
06301
06302
06303 static void
06304 merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
06305 {
06306 state_t *equiv_class_ptr;
06307 state_t curr_state;
06308 state_t new_state;
06309 state_t first_class_state;
06310 alt_state_t alt_states;
06311 alt_state_t alt_state, new_alt_state;
06312 arc_t curr_arc;
06313 arc_t next_arc;
06314
06315
06316
06317 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
06318 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
06319 equiv_class_ptr++)
06320 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
06321 {
06322
06323
06324 new_state = get_free_state (0, automaton);
06325 alt_states = NULL;
06326 first_class_state = *equiv_class_ptr;
06327 for (curr_state = first_class_state;
06328 curr_state != NULL;
06329 curr_state = curr_state->next_equiv_class_state)
06330 {
06331 curr_state->equiv_class_state = new_state;
06332 if (curr_state->component_states == NULL)
06333 {
06334 new_alt_state = get_free_alt_state ();
06335 new_alt_state->state = curr_state;
06336 new_alt_state->next_alt_state = alt_states;
06337 alt_states = new_alt_state;
06338 }
06339 else
06340 for (alt_state = curr_state->component_states;
06341 alt_state != NULL;
06342 alt_state = alt_state->next_sorted_alt_state)
06343 {
06344 new_alt_state = get_free_alt_state ();
06345 new_alt_state->state = alt_state->state;
06346 new_alt_state->next_alt_state = alt_states;
06347 alt_states = new_alt_state;
06348 }
06349 }
06350
06351
06352 new_state->component_states = uniq_sort_alt_states (alt_states);
06353 }
06354 else
06355 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
06356 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
06357 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
06358 equiv_class_ptr++)
06359 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
06360 {
06361 first_class_state = *equiv_class_ptr;
06362
06363
06364 for (curr_arc = first_out_arc (first_class_state);
06365 curr_arc != NULL;
06366 curr_arc = next_out_arc (curr_arc))
06367 add_arc (first_class_state->equiv_class_state,
06368 curr_arc->to_state->equiv_class_state,
06369 curr_arc->insn, curr_arc->state_alts);
06370
06371 for (curr_state = first_class_state;
06372 curr_state != NULL;
06373 curr_state = curr_state->next_equiv_class_state)
06374 {
06375 if (automaton->start_state == curr_state)
06376 automaton->start_state = curr_state->equiv_class_state;
06377
06378 for (curr_arc = first_out_arc (curr_state);
06379 curr_arc != NULL;
06380 curr_arc = next_arc)
06381 {
06382 next_arc = next_out_arc (curr_arc);
06383 free_arc (curr_arc);
06384 }
06385 }
06386 }
06387 else
06388 {
06389
06390
06391 for (curr_arc = first_out_arc (*equiv_class_ptr);
06392 curr_arc != NULL;
06393 curr_arc = next_out_arc (curr_arc))
06394 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
06395 }
06396 }
06397
06398
06399
06400 static void
06401 set_new_cycle_flags (state_t state)
06402 {
06403 arc_t arc;
06404
06405 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06406 if (arc->insn->insn_reserv_decl
06407 == DECL_INSN_RESERV (advance_cycle_insn_decl))
06408 arc->to_state->new_cycle_p = 1;
06409 }
06410
06411
06412
06413 static void
06414 minimize_DFA (automaton_t automaton)
06415 {
06416 vla_ptr_t equiv_classes;
06417
06418 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
06419 evaluate_equiv_classes (automaton, &equiv_classes);
06420 merge_states (automaton, &equiv_classes);
06421 pass_states (automaton, set_new_cycle_flags);
06422 VLA_PTR_DELETE (equiv_classes);
06423 }
06424
06425
06426
06427 static int curr_counted_states_num;
06428 static int curr_counted_arcs_num;
06429
06430
06431
06432 static void
06433 incr_states_and_arcs_nums (state_t state)
06434 {
06435 arc_t arc;
06436
06437 curr_counted_states_num++;
06438 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06439 curr_counted_arcs_num++;
06440 }
06441
06442
06443 static void
06444 count_states_and_arcs (automaton_t automaton, int *states_num,
06445 int *arcs_num)
06446 {
06447 curr_counted_states_num = 0;
06448 curr_counted_arcs_num = 0;
06449 pass_states (automaton, incr_states_and_arcs_nums);
06450 *states_num = curr_counted_states_num;
06451 *arcs_num = curr_counted_arcs_num;
06452 }
06453
06454
06455
06456
06457 static void
06458 build_automaton (automaton_t automaton)
06459 {
06460 int states_num;
06461 int arcs_num;
06462
06463 ticker_on (&NDFA_time);
06464 if (progress_flag)
06465 {
06466 if (automaton->corresponding_automaton_decl == NULL)
06467 fprintf (stderr, "Create anonymous automaton");
06468 else
06469 fprintf (stderr, "Create automaton `%s'",
06470 automaton->corresponding_automaton_decl->name);
06471 fprintf (stderr, " (1 dot is 100 new states):");
06472 }
06473 make_automaton (automaton);
06474 if (progress_flag)
06475 fprintf (stderr, " done\n");
06476 ticker_off (&NDFA_time);
06477 count_states_and_arcs (automaton, &states_num, &arcs_num);
06478 automaton->NDFA_states_num = states_num;
06479 automaton->NDFA_arcs_num = arcs_num;
06480 ticker_on (&NDFA_to_DFA_time);
06481 if (progress_flag)
06482 {
06483 if (automaton->corresponding_automaton_decl == NULL)
06484 fprintf (stderr, "Make anonymous DFA");
06485 else
06486 fprintf (stderr, "Make DFA `%s'",
06487 automaton->corresponding_automaton_decl->name);
06488 fprintf (stderr, " (1 dot is 100 new states):");
06489 }
06490 NDFA_to_DFA (automaton);
06491 if (progress_flag)
06492 fprintf (stderr, " done\n");
06493 ticker_off (&NDFA_to_DFA_time);
06494 count_states_and_arcs (automaton, &states_num, &arcs_num);
06495 automaton->DFA_states_num = states_num;
06496 automaton->DFA_arcs_num = arcs_num;
06497 if (!no_minimization_flag)
06498 {
06499 ticker_on (&minimize_time);
06500 if (progress_flag)
06501 {
06502 if (automaton->corresponding_automaton_decl == NULL)
06503 fprintf (stderr, "Minimize anonymous DFA...");
06504 else
06505 fprintf (stderr, "Minimize DFA `%s'...",
06506 automaton->corresponding_automaton_decl->name);
06507 }
06508 minimize_DFA (automaton);
06509 if (progress_flag)
06510 fprintf (stderr, "done\n");
06511 ticker_off (&minimize_time);
06512 count_states_and_arcs (automaton, &states_num, &arcs_num);
06513 automaton->minimal_DFA_states_num = states_num;
06514 automaton->minimal_DFA_arcs_num = arcs_num;
06515 }
06516 }
06517
06518
06519
06520
06521
06522
06523
06524 static int curr_state_order_num;
06525
06526
06527
06528 static void
06529 set_order_state_num (state_t state)
06530 {
06531 state->order_state_num = curr_state_order_num;
06532 curr_state_order_num++;
06533 }
06534
06535
06536 static void
06537 enumerate_states (automaton_t automaton)
06538 {
06539 curr_state_order_num = 0;
06540 pass_states (automaton, set_order_state_num);
06541 automaton->achieved_states_num = curr_state_order_num;
06542 }
06543
06544
06545
06546
06547
06548
06549
06550
06551 static ainsn_t
06552 insert_ainsn_into_equiv_class (ainsn_t ainsn,
06553 ainsn_t cyclic_equiv_class_insn_list)
06554 {
06555 if (cyclic_equiv_class_insn_list == NULL)
06556 ainsn->next_equiv_class_insn = ainsn;
06557 else
06558 {
06559 ainsn->next_equiv_class_insn
06560 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
06561 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
06562 }
06563 return ainsn;
06564 }
06565
06566
06567
06568 static void
06569 delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
06570 {
06571 ainsn_t curr_equiv_class_insn;
06572 ainsn_t prev_equiv_class_insn;
06573
06574 prev_equiv_class_insn = equiv_class_insn;
06575 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
06576 curr_equiv_class_insn != equiv_class_insn;
06577 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
06578 prev_equiv_class_insn = curr_equiv_class_insn;
06579 if (prev_equiv_class_insn != equiv_class_insn)
06580 prev_equiv_class_insn->next_equiv_class_insn
06581 = equiv_class_insn->next_equiv_class_insn;
06582 }
06583
06584
06585
06586
06587 static void
06588 process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
06589 {
06590 ainsn_t next_insn;
06591 ainsn_t curr_insn;
06592 ainsn_t cyclic_insn_list;
06593 arc_t arc;
06594
06595 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
06596 curr_insn = ainsn;
06597
06598 cyclic_insn_list = NULL;
06599 do
06600 {
06601 next_insn = curr_insn->next_equiv_class_insn;
06602 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
06603 if (arc == NULL
06604 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
06605 != arc->to_state))
06606 {
06607 delete_ainsn_from_equiv_class (curr_insn);
06608 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
06609 cyclic_insn_list);
06610 }
06611 curr_insn = next_insn;
06612 }
06613 while (curr_insn != ainsn);
06614 }
06615
06616
06617 static void
06618 process_state_for_insn_equiv_partition (state_t state)
06619 {
06620 arc_t arc;
06621 arc_t *insn_arcs_array;
06622 int i;
06623 vla_ptr_t insn_arcs_vect;
06624
06625 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
06626 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
06627 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
06628
06629 for (i = 0; i < description->insns_num; i++)
06630 insn_arcs_array [i] = NULL;
06631 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06632 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
06633 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
06634 process_insn_equiv_class (arc->insn, insn_arcs_array);
06635 VLA_PTR_DELETE (insn_arcs_vect);
06636 }
06637
06638
06639 static void
06640 set_insn_equiv_classes (automaton_t automaton)
06641 {
06642 ainsn_t ainsn;
06643 ainsn_t first_insn;
06644 ainsn_t curr_insn;
06645 ainsn_t cyclic_insn_list;
06646 ainsn_t insn_with_same_reservs;
06647 int equiv_classes_num;
06648
06649
06650 cyclic_insn_list = NULL;
06651 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06652 if (ainsn->first_insn_with_same_reservs)
06653 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
06654 cyclic_insn_list);
06655
06656 pass_states (automaton, process_state_for_insn_equiv_partition);
06657
06658 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06659
06660 ainsn->insn_equiv_class_num = -1;
06661 equiv_classes_num = 0;
06662 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
06663 if (ainsn->insn_equiv_class_num < 0)
06664 {
06665 first_insn = ainsn;
06666 gcc_assert (first_insn->first_insn_with_same_reservs);
06667 first_insn->first_ainsn_with_given_equivalence_num = 1;
06668 curr_insn = first_insn;
06669 do
06670 {
06671 for (insn_with_same_reservs = curr_insn;
06672 insn_with_same_reservs != NULL;
06673 insn_with_same_reservs
06674 = insn_with_same_reservs->next_same_reservs_insn)
06675 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
06676 curr_insn = curr_insn->next_equiv_class_insn;
06677 }
06678 while (curr_insn != first_insn);
06679 equiv_classes_num++;
06680 }
06681 automaton->insn_equiv_classes_num = equiv_classes_num;
06682 }
06683
06684
06685
06686
06687
06688
06689
06690
06691
06692
06693
06694
06695
06696 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
06697
06698
06699
06700 static double
06701 estimate_one_automaton_bound (void)
06702 {
06703 decl_t decl;
06704 double one_automaton_estimation_bound;
06705 double root_value;
06706 int i;
06707
06708 one_automaton_estimation_bound = 1.0;
06709 for (i = 0; i < description->decls_num; i++)
06710 {
06711 decl = description->decls [i];
06712 if (decl->mode == dm_unit)
06713 {
06714 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
06715 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
06716 / automata_num);
06717 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
06718 > one_automaton_estimation_bound)
06719 one_automaton_estimation_bound *= root_value;
06720 }
06721 }
06722 return one_automaton_estimation_bound;
06723 }
06724
06725
06726
06727 static int
06728 compare_max_occ_cycle_nums (const void *unit_decl_1,
06729 const void *unit_decl_2)
06730 {
06731 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
06732 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
06733 return 1;
06734 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
06735 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
06736 return 0;
06737 else
06738 return -1;
06739 }
06740
06741
06742
06743 static void
06744 units_to_automata_heuristic_distr (void)
06745 {
06746 double estimation_bound;
06747 decl_t decl;
06748 decl_t *unit_decl_ptr;
06749 int automaton_num;
06750 int rest_units_num;
06751 double bound_value;
06752 vla_ptr_t unit_decls;
06753 int i;
06754
06755 if (description->units_num == 0)
06756 return;
06757 estimation_bound = estimate_one_automaton_bound ();
06758 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
06759 for (i = 0; i < description->decls_num; i++)
06760 {
06761 decl = description->decls [i];
06762 if (decl->mode == dm_unit)
06763 VLA_PTR_ADD (unit_decls, decl);
06764 }
06765 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
06766 sizeof (decl_t), compare_max_occ_cycle_nums);
06767 automaton_num = 0;
06768 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
06769 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
06770 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
06771 for (unit_decl_ptr++;
06772 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
06773 unit_decl_ptr++)
06774 {
06775 rest_units_num
06776 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
06777 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
06778 if (automaton_num < automata_num - 1
06779 && ((automata_num - automaton_num - 1 == rest_units_num)
06780 || (bound_value
06781 > (estimation_bound
06782 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
06783 {
06784 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
06785 automaton_num++;
06786 }
06787 else
06788 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
06789 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
06790 }
06791 gcc_assert (automaton_num == automata_num - 1);
06792 VLA_PTR_DELETE (unit_decls);
06793 }
06794
06795
06796
06797
06798 static ainsn_t
06799 create_ainsns (void)
06800 {
06801 decl_t decl;
06802 ainsn_t first_ainsn;
06803 ainsn_t curr_ainsn;
06804 ainsn_t prev_ainsn;
06805 int i;
06806
06807 first_ainsn = NULL;
06808 prev_ainsn = NULL;
06809 for (i = 0; i < description->decls_num; i++)
06810 {
06811 decl = description->decls [i];
06812 if (decl->mode == dm_insn_reserv)
06813 {
06814 curr_ainsn = create_node (sizeof (struct ainsn));
06815 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
06816 curr_ainsn->important_p = FALSE;
06817 curr_ainsn->next_ainsn = NULL;
06818 if (prev_ainsn == NULL)
06819 first_ainsn = curr_ainsn;
06820 else
06821 prev_ainsn->next_ainsn = curr_ainsn;
06822 prev_ainsn = curr_ainsn;
06823 }
06824 }
06825 return first_ainsn;
06826 }
06827
06828
06829
06830 static void
06831 units_to_automata_distr (void)
06832 {
06833 decl_t decl;
06834 int i;
06835
06836 for (i = 0; i < description->decls_num; i++)
06837 {
06838 decl = description->decls [i];
06839 if (decl->mode == dm_unit)
06840 {
06841 if (DECL_UNIT (decl)->automaton_decl == NULL
06842 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
06843 == NULL))
06844
06845 DECL_UNIT (decl)->corresponding_automaton_num = 0;
06846 else
06847 DECL_UNIT (decl)->corresponding_automaton_num
06848 = (DECL_UNIT (decl)->automaton_decl
06849 ->corresponding_automaton->automaton_order_num);
06850 }
06851 }
06852 }
06853
06854
06855
06856 static void
06857 create_automata (void)
06858 {
06859 automaton_t curr_automaton;
06860 automaton_t prev_automaton;
06861 decl_t decl;
06862 int curr_automaton_num;
06863 int i;
06864
06865 if (automata_num != 0)
06866 {
06867 units_to_automata_heuristic_distr ();
06868 for (prev_automaton = NULL, curr_automaton_num = 0;
06869 curr_automaton_num < automata_num;
06870 curr_automaton_num++, prev_automaton = curr_automaton)
06871 {
06872 curr_automaton = create_node (sizeof (struct automaton));
06873 curr_automaton->ainsn_list = create_ainsns ();
06874 curr_automaton->corresponding_automaton_decl = NULL;
06875 curr_automaton->next_automaton = NULL;
06876 curr_automaton->automaton_order_num = curr_automaton_num;
06877 if (prev_automaton == NULL)
06878 description->first_automaton = curr_automaton;
06879 else
06880 prev_automaton->next_automaton = curr_automaton;
06881 }
06882 }
06883 else
06884 {
06885 curr_automaton_num = 0;
06886 prev_automaton = NULL;
06887 for (i = 0; i < description->decls_num; i++)
06888 {
06889 decl = description->decls [i];
06890 if (decl->mode == dm_automaton
06891 && DECL_AUTOMATON (decl)->automaton_is_used)
06892 {
06893 curr_automaton = create_node (sizeof (struct automaton));
06894 curr_automaton->ainsn_list = create_ainsns ();
06895 curr_automaton->corresponding_automaton_decl
06896 = DECL_AUTOMATON (decl);
06897 curr_automaton->next_automaton = NULL;
06898 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
06899 curr_automaton->automaton_order_num = curr_automaton_num;
06900 if (prev_automaton == NULL)
06901 description->first_automaton = curr_automaton;
06902 else
06903 prev_automaton->next_automaton = curr_automaton;
06904 curr_automaton_num++;
06905 prev_automaton = curr_automaton;
06906 }
06907 }
06908 if (curr_automaton_num == 0)
06909 {
06910 curr_automaton = create_node (sizeof (struct automaton));
06911 curr_automaton->ainsn_list = create_ainsns ();
06912 curr_automaton->corresponding_automaton_decl = NULL;
06913 curr_automaton->next_automaton = NULL;
06914 description->first_automaton = curr_automaton;
06915 }
06916 units_to_automata_distr ();
06917 }
06918 NDFA_time = create_ticker ();
06919 ticker_off (&NDFA_time);
06920 NDFA_to_DFA_time = create_ticker ();
06921 ticker_off (&NDFA_to_DFA_time);
06922 minimize_time = create_ticker ();
06923 ticker_off (&minimize_time);
06924 equiv_time = create_ticker ();
06925 ticker_off (&equiv_time);
06926 for (curr_automaton = description->first_automaton;
06927 curr_automaton != NULL;
06928 curr_automaton = curr_automaton->next_automaton)
06929 {
06930 if (progress_flag)
06931 {
06932 if (curr_automaton->corresponding_automaton_decl == NULL)
06933 fprintf (stderr, "Prepare anonymous automaton creation ... ");
06934 else
06935 fprintf (stderr, "Prepare automaton `%s' creation...",
06936 curr_automaton->corresponding_automaton_decl->name);
06937 }
06938 create_alt_states (curr_automaton);
06939 form_ainsn_with_same_reservs (curr_automaton);
06940 if (progress_flag)
06941 fprintf (stderr, "done\n");
06942 build_automaton (curr_automaton);
06943 enumerate_states (curr_automaton);
06944 ticker_on (&equiv_time);
06945 set_insn_equiv_classes (curr_automaton);
06946 ticker_off (&equiv_time);
06947 }
06948 }
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959 static void
06960 form_regexp (regexp_t regexp)
06961 {
06962 int i;
06963
06964 switch (regexp->mode)
06965 {
06966 case rm_unit: case rm_reserv:
06967 {
06968 const char *name = (regexp->mode == rm_unit
06969 ? REGEXP_UNIT (regexp)->name
06970 : REGEXP_RESERV (regexp)->name);
06971
06972 obstack_grow (&irp, name, strlen (name));
06973 break;
06974 }
06975
06976 case rm_sequence:
06977 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
06978 {
06979 if (i != 0)
06980 obstack_1grow (&irp, ',');
06981 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
06982 }
06983 break;
06984
06985 case rm_allof:
06986 obstack_1grow (&irp, '(');
06987 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
06988 {
06989 if (i != 0)
06990 obstack_1grow (&irp, '+');
06991 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
06992 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
06993 obstack_1grow (&irp, '(');
06994 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
06995 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
06996 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
06997 obstack_1grow (&irp, ')');
06998 }
06999 obstack_1grow (&irp, ')');
07000 break;
07001
07002 case rm_oneof:
07003 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
07004 {
07005 if (i != 0)
07006 obstack_1grow (&irp, '|');
07007 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
07008 obstack_1grow (&irp, '(');
07009 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
07010 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
07011 obstack_1grow (&irp, ')');
07012 }
07013 break;
07014
07015 case rm_repeat:
07016 {
07017 char digits [30];
07018
07019 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
07020 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
07021 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
07022 obstack_1grow (&irp, '(');
07023 form_regexp (REGEXP_REPEAT (regexp)->regexp);
07024 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
07025 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
07026 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
07027 obstack_1grow (&irp, ')');
07028 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
07029 obstack_grow (&irp, digits, strlen (digits));
07030 break;
07031 }
07032
07033 case rm_nothing:
07034 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
07035 break;
07036
07037 default:
07038 gcc_unreachable ();
07039 }
07040 }
07041
07042
07043
07044 static const char *
07045 regexp_representation (regexp_t regexp)
07046 {
07047 form_regexp (regexp);
07048 obstack_1grow (&irp, '\0');
07049 return obstack_base (&irp);
07050 }
07051
07052
07053
07054 static void
07055 finish_regexp_representation (void)
07056 {
07057 int length = obstack_object_size (&irp);
07058
07059 obstack_blank_fast (&irp, -length);
07060 }
07061
07062
07063
07064
07065
07066
07067
07068
07069
07070
07071
07072
07073 static void
07074 output_range_type (FILE *f, long int min_range_value,
07075 long int max_range_value)
07076 {
07077 if (min_range_value >= 0 && max_range_value <= 255)
07078 fprintf (f, "unsigned char");
07079 else if (min_range_value >= -127 && max_range_value <= 127)
07080 fprintf (f, "signed char");
07081 else if (min_range_value >= 0 && max_range_value <= 65535)
07082 fprintf (f, "unsigned short");
07083 else if (min_range_value >= -32767 && max_range_value <= 32767)
07084 fprintf (f, "short");
07085 else
07086 fprintf (f, "int");
07087 }
07088
07089
07090
07091
07092
07093 #define ON_THE_PATH -2
07094
07095
07096
07097
07098
07099 static int
07100 longest_path_length (state_t state)
07101 {
07102 arc_t arc;
07103 int length, result;
07104
07105 if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
07106 {
07107
07108
07109
07110 gcc_assert (state->longest_path_length != ON_THE_PATH);
07111
07112
07113 return state->longest_path_length;
07114 }
07115
07116 result = 0;
07117 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
07118
07119 if (arc->to_state != state
07120 && (arc->insn->insn_reserv_decl
07121 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
07122 {
07123 length = longest_path_length (arc->to_state);
07124 if (length > result)
07125 result = length;
07126 }
07127 state->longest_path_length = result + 1;
07128 return result;
07129 }
07130
07131
07132
07133
07134 static int max_dfa_issue_rate;
07135
07136
07137
07138
07139 static void
07140 process_state_longest_path_length (state_t state)
07141 {
07142 int value;
07143
07144 value = longest_path_length (state);
07145 if (value > max_dfa_issue_rate)
07146 max_dfa_issue_rate = value;
07147 }
07148
07149
07150
07151
07152 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
07153
07154
07155
07156
07157 static void
07158 output_dfa_max_issue_rate (void)
07159 {
07160 automaton_t automaton;
07161
07162 gcc_assert (UNDEFINED_LONGEST_PATH_LENGTH != ON_THE_PATH && ON_THE_PATH < 0);
07163 max_dfa_issue_rate = 0;
07164 for (automaton = description->first_automaton;
07165 automaton != NULL;
07166 automaton = automaton->next_automaton)
07167 pass_states (automaton, process_state_longest_path_length);
07168 fprintf (output_file, "\nint %s = %d;\n",
07169 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
07170 }
07171
07172
07173
07174 static void
07175 output_vect (vect_el_t *vect, int vect_length)
07176 {
07177 int els_on_line;
07178
07179 els_on_line = 1;
07180 if (vect_length == 0)
07181 fprintf (output_file,
07182 "0 /* This is dummy el because the vect is empty */");
07183 else
07184 {
07185 do
07186 {
07187 fprintf (output_file, "%5ld", (long) *vect);
07188 vect_length--;
07189 if (els_on_line == 10)
07190 {
07191 els_on_line = 0;
07192 fprintf (output_file, ",\n");
07193 }
07194 else if (vect_length != 0)
07195 fprintf (output_file, ", ");
07196 els_on_line++;
07197 vect++;
07198 }
07199 while (vect_length != 0);
07200 }
07201 }
07202
07203
07204
07205 #define CHIP_NAME "DFA_chip"
07206
07207
07208
07209 static void
07210 output_chip_member_name (FILE *f, automaton_t automaton)
07211 {
07212 if (automaton->corresponding_automaton_decl == NULL)
07213 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
07214 else
07215 fprintf (f, "%s_automaton_state",
07216 automaton->corresponding_automaton_decl->name);
07217 }
07218
07219
07220
07221 static void
07222 output_temp_chip_member_name (FILE *f, automaton_t automaton)
07223 {
07224 fprintf (f, "_");
07225 output_chip_member_name (f, automaton);
07226 }
07227
07228
07229
07230
07231 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
07232
07233
07234 static void
07235 output_translate_vect_name (FILE *f, automaton_t automaton)
07236 {
07237 if (automaton->corresponding_automaton_decl == NULL)
07238 fprintf (f, "translate_%d", automaton->automaton_order_num);
07239 else
07240 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
07241 }
07242
07243
07244 static void
07245 output_trans_full_vect_name (FILE *f, automaton_t automaton)
07246 {
07247 if (automaton->corresponding_automaton_decl == NULL)
07248 fprintf (f, "transitions_%d", automaton->automaton_order_num);
07249 else
07250 fprintf (f, "%s_transitions",
07251 automaton->corresponding_automaton_decl->name);
07252 }
07253
07254
07255
07256 static void
07257 output_trans_comb_vect_name (FILE *f, automaton_t automaton)
07258 {
07259 if (automaton->corresponding_automaton_decl == NULL)
07260 fprintf (f, "transitions_%d", automaton->automaton_order_num);
07261 else
07262 fprintf (f, "%s_transitions",
07263 automaton->corresponding_automaton_decl->name);
07264 }
07265
07266
07267
07268 static void
07269 output_trans_check_vect_name (FILE *f, automaton_t automaton)
07270 {
07271 if (automaton->corresponding_automaton_decl == NULL)
07272 fprintf (f, "check_%d", automaton->automaton_order_num);
07273 else
07274 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
07275 }
07276
07277
07278
07279 static void
07280 output_trans_base_vect_name (FILE *f, automaton_t automaton)
07281 {
07282 if (automaton->corresponding_automaton_decl == NULL)
07283 fprintf (f, "base_%d", automaton->automaton_order_num);
07284 else
07285 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
07286 }
07287
07288
07289 static void
07290 output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
07291 {
07292 if (automaton->corresponding_automaton_decl == NULL)
07293 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
07294 else
07295 fprintf (f, "%s_state_alts",
07296 automaton->corresponding_automaton_decl->name);
07297 }
07298
07299
07300
07301 static void
07302 output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
07303 {
07304 if (automaton->corresponding_automaton_decl == NULL)
07305 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
07306 else
07307 fprintf (f, "%s_state_alts",
07308 automaton->corresponding_automaton_decl->name);
07309 }
07310
07311
07312
07313 static void
07314 output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
07315 {
07316 if (automaton->corresponding_automaton_decl == NULL)
07317 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
07318 else
07319 fprintf (f, "%s_check_state_alts",
07320 automaton->corresponding_automaton_decl->name);
07321 }
07322
07323
07324
07325 static void
07326 output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
07327 {
07328 if (automaton->corresponding_automaton_decl == NULL)
07329 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
07330 else
07331 fprintf (f, "%s_base_state_alts",
07332 automaton->corresponding_automaton_decl->name);
07333 }
07334
07335
07336 static void
07337 output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
07338 {
07339 if (automaton->corresponding_automaton_decl == NULL)
07340 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
07341 else
07342 fprintf (f, "%s_min_issue_delay",
07343 automaton->corresponding_automaton_decl->name);
07344 }
07345
07346
07347 static void
07348 output_dead_lock_vect_name (FILE *f, automaton_t automaton)
07349 {
07350 if (automaton->corresponding_automaton_decl == NULL)
07351 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
07352 else
07353 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
07354 }
07355
07356
07357 static void
07358 output_reserved_units_table_name (FILE *f, automaton_t automaton)
07359 {
07360 if (automaton->corresponding_automaton_decl == NULL)
07361 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
07362 else
07363 fprintf (f, "%s_reserved_units",
07364 automaton->corresponding_automaton_decl->name);
07365 }
07366
07367
07368 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
07369
07370
07371 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
07372
07373
07374 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
07375
07376
07377 #define STATE_TYPE_NAME "state_t"
07378
07379 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
07380
07381 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
07382
07383 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
07384
07385 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
07386
07387 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
07388
07389
07390 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
07391
07392
07393 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
07394
07395
07396 #define SIZE_FUNC_NAME "state_size"
07397
07398 #define TRANSITION_FUNC_NAME "state_transition"
07399
07400 #define STATE_ALTS_FUNC_NAME "state_alts"
07401
07402 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
07403
07404 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
07405
07406 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
07407
07408 #define RESET_FUNC_NAME "state_reset"
07409
07410 #define INSN_LATENCY_FUNC_NAME "insn_latency"
07411
07412 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
07413
07414 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
07415
07416 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
07417
07418 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
07419
07420 #define DFA_START_FUNC_NAME "dfa_start"
07421
07422 #define DFA_FINISH_FUNC_NAME "dfa_finish"
07423
07424
07425 #define STATE_NAME "state"
07426
07427 #define INSN_PARAMETER_NAME "insn"
07428
07429 #define INSN2_PARAMETER_NAME "insn2"
07430
07431 #define CHIP_PARAMETER_NAME "chip"
07432
07433 #define FILE_PARAMETER_NAME "f"
07434
07435 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
07436
07437 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
07438
07439
07440
07441 #define INTERNAL_INSN_CODE_NAME "insn_code"
07442
07443 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
07444
07445
07446 #define TEMPORARY_VARIABLE_NAME "temp"
07447
07448 #define I_VARIABLE_NAME "i"
07449
07450
07451 #define RESULT_VARIABLE_NAME "res"
07452
07453
07454
07455 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
07456
07457
07458
07459 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
07460
07461
07462
07463 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
07464
07465
07466
07467 #define BYPASS_P_FUNC_NAME "bypass_p"
07468
07469
07470
07471 static void
07472 output_state_member_type (FILE *f, automaton_t automaton)
07473 {
07474 output_range_type (f, 0, automaton->achieved_states_num);
07475 }
07476
07477
07478
07479 static void
07480 output_chip_definitions (void)
07481 {
07482 automaton_t automaton;
07483
07484 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
07485 for (automaton = description->first_automaton;
07486 automaton != NULL;
07487 automaton = automaton->next_automaton)
07488 {
07489 fprintf (output_file, " ");
07490 output_state_member_type (output_file, automaton);
07491 fprintf (output_file, " ");
07492 output_chip_member_name (output_file, automaton);
07493 fprintf (output_file, ";\n");
07494 }
07495 fprintf (output_file, "};\n\n");
07496 #if 0
07497 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
07498 #endif
07499 }
07500
07501
07502
07503
07504
07505 static void
07506 output_translate_vect (automaton_t automaton)
07507 {
07508 ainsn_t ainsn;
07509 int insn_value;
07510 vla_hwint_t translate_vect;
07511
07512 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
07513 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
07514 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
07515
07516 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
07517 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
07518 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
07519 = ainsn->insn_equiv_class_num;
07520 fprintf (output_file,
07521 "/* Vector translating external insn codes to internal ones.*/\n");
07522 fprintf (output_file, "static const ");
07523 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
07524 fprintf (output_file, " ");
07525 output_translate_vect_name (output_file, automaton);
07526 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07527 output_vect (VLA_HWINT_BEGIN (translate_vect),
07528 VLA_HWINT_LENGTH (translate_vect));
07529 fprintf (output_file, "};\n\n");
07530 VLA_HWINT_DELETE (translate_vect);
07531 }
07532
07533
07534
07535 static int undefined_vect_el_value;
07536
07537
07538
07539 static int
07540 comb_vect_p (state_ainsn_table_t tab)
07541 {
07542 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
07543 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
07544 }
07545
07546
07547 static state_ainsn_table_t
07548 create_state_ainsn_table (automaton_t automaton)
07549 {
07550 state_ainsn_table_t tab;
07551 int full_vect_length;
07552 int i;
07553
07554 tab = create_node (sizeof (struct state_ainsn_table));
07555 tab->automaton = automaton;
07556 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
07557 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
07558 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
07559 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
07560 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
07561 full_vect_length = (automaton->insn_equiv_classes_num
07562 * automaton->achieved_states_num);
07563 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
07564 for (i = 0; i < full_vect_length; i++)
07565 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
07566 tab->min_base_vect_el_value = 0;
07567 tab->max_base_vect_el_value = 0;
07568 tab->min_comb_vect_el_value = 0;
07569 tab->max_comb_vect_el_value = 0;
07570 return tab;
07571 }
07572
07573
07574
07575 static void
07576 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
07577 void (*output_full_vect_name_func) (FILE *, automaton_t),
07578 void (*output_comb_vect_name_func) (FILE *, automaton_t),
07579 void (*output_check_vect_name_func) (FILE *, automaton_t),
07580 void (*output_base_vect_name_func) (FILE *, automaton_t))
07581 {
07582 if (!comb_vect_p (tab))
07583 {
07584 fprintf (output_file, "/* Vector for %s. */\n", table_name);
07585 fprintf (output_file, "static const ");
07586 output_range_type (output_file, tab->min_comb_vect_el_value,
07587 tab->max_comb_vect_el_value);
07588 fprintf (output_file, " ");
07589 (*output_full_vect_name_func) (output_file, tab->automaton);
07590 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07591 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
07592 VLA_HWINT_LENGTH (tab->full_vect));
07593 fprintf (output_file, "};\n\n");
07594 }
07595 else
07596 {
07597 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
07598 fprintf (output_file, "static const ");
07599 output_range_type (output_file, tab->min_comb_vect_el_value,
07600 tab->max_comb_vect_el_value);
07601 fprintf (output_file, " ");
07602 (*output_comb_vect_name_func) (output_file, tab->automaton);
07603 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
07604 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
07605 VLA_HWINT_LENGTH (tab->comb_vect));
07606 fprintf (output_file, "};\n\n");
07607 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
07608 fprintf (output_file, "static const ");
07609 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
07610 fprintf (output_file, " ");
07611 (*output_check_vect_name_func) (output_file, tab->automaton);
07612 fprintf (output_file, "[] = {\n");
07613 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
07614 VLA_HWINT_LENGTH (tab->check_vect));
07615 fprintf (output_file, "};\n\n");
07616 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
07617 fprintf (output_file, "static const ");
07618 output_range_type (output_file, tab->min_base_vect_el_value,
07619 tab->max_base_vect_el_value);
07620 fprintf (output_file, " ");
07621 (*output_base_vect_name_func) (output_file, tab->automaton);
07622 fprintf (output_file, "[] = {\n");
07623 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
07624 VLA_HWINT_LENGTH (tab->base_vect));
07625 fprintf (output_file, "};\n\n");
07626 }
07627 }
07628
07629
07630
07631
07632 static void
07633 add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
07634 int vect_length)
07635 {
07636 int real_vect_length;
07637 vect_el_t *comb_vect_start;
07638 vect_el_t *check_vect_start;
07639 int comb_vect_index;
07640 int comb_vect_els_num;
07641 int vect_index;
07642 int first_unempty_vect_index;
07643 int additional_els_num;
07644 int no_state_value;
07645 vect_el_t vect_el;
07646 int i;
07647 unsigned long vect_mask, comb_vect_mask;
07648
07649 gcc_assert (vect_length);
07650 real_vect_length = tab->automaton->insn_equiv_classes_num;
07651 gcc_assert (vect [vect_length - 1] != undefined_vect_el_value);
07652
07653 for (i = 0; i < vect_length; i++)
07654 VLA_HWINT (tab->full_vect,
07655 i + tab->automaton->insn_equiv_classes_num * vect_num)
07656 = vect [i];
07657
07658 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
07659 == VLA_HWINT_LENGTH (tab->check_vect));
07660 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
07661 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
07662 for (first_unempty_vect_index = 0;
07663 first_unempty_vect_index < vect_length;
07664 first_unempty_vect_index++)
07665 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
07666 break;
07667
07668
07669
07670
07671 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
07672 {
07673 for (comb_vect_index = 0;
07674 comb_vect_index < comb_vect_els_num;
07675 comb_vect_index++)
07676 {
07677 for (vect_index = first_unempty_vect_index;
07678 vect_index < vect_length
07679 && vect_index + comb_vect_index < comb_vect_els_num;
07680 vect_index++)
07681 if (vect [vect_index] != undefined_vect_el_value
07682 && (comb_vect_start [vect_index + comb_vect_index]
07683 != undefined_vect_el_value))
07684 break;
07685 if (vect_index >= vect_length
07686 || vect_index + comb_vect_index >= comb_vect_els_num)
07687 break;
07688 }
07689 goto found;
07690 }
07691
07692
07693 vect_mask = 0;
07694 for (vect_index = first_unempty_vect_index;
07695 vect_index < vect_length;
07696 vect_index++)
07697 {
07698 vect_mask = vect_mask << 1;
07699 if (vect [vect_index] != undefined_vect_el_value)
07700 vect_mask |= 1;
07701 }
07702
07703
07704 comb_vect_index = 0;
07705 if (comb_vect_els_num == 0)
07706 goto found;
07707
07708 comb_vect_mask = 0;
07709 for (vect_index = first_unempty_vect_index;
07710 vect_index < vect_length && vect_index < comb_vect_els_num;
07711 vect_index++)
07712 {
07713 comb_vect_mask <<= 1;
07714 if (vect_index + comb_vect_index < comb_vect_els_num
07715 && comb_vect_start [vect_index + comb_vect_index]
07716 != undefined_vect_el_value)
07717 comb_vect_mask |= 1;
07718 }
07719 if ((vect_mask & comb_vect_mask) == 0)
07720 goto found;
07721
07722 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
07723 comb_vect_index++, i++)
07724 {
07725 comb_vect_mask = (comb_vect_mask << 1) | 1;
07726 comb_vect_mask ^= comb_vect_start [i] == undefined_vect_el_value;
07727 if ((vect_mask & comb_vect_mask) == 0)
07728 goto found;
07729 }
07730 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
07731 {
07732 comb_vect_mask <<= 1;
07733 if ((vect_mask & comb_vect_mask) == 0)
07734 goto found;
07735 }
07736
07737 found:
07738
07739 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
07740 if (additional_els_num < 0)
07741 additional_els_num = 0;
07742
07743 vect_el = undefined_vect_el_value;
07744 no_state_value = tab->automaton->achieved_states_num;
07745 while (additional_els_num > 0)
07746 {
07747 VLA_HWINT_ADD (tab->comb_vect, vect_el);
07748 VLA_HWINT_ADD (tab->check_vect, no_state_value);
07749 additional_els_num--;
07750 }
07751 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
07752 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
07753 gcc_assert (VLA_HWINT_LENGTH (tab->comb_vect)
07754 >= (size_t) (comb_vect_index + real_vect_length));
07755
07756 for (vect_index = 0; vect_index < vect_length; vect_index++)
07757 if (vect [vect_index] != undefined_vect_el_value)
07758 {
07759 gcc_assert (comb_vect_start [comb_vect_index + vect_index]
07760 == undefined_vect_el_value);
07761 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
07762 gcc_assert (vect [vect_index] >= 0);
07763 if (tab->max_comb_vect_el_value < vect [vect_index])
07764 tab->max_comb_vect_el_value = vect [vect_index];
07765 if (tab->min_comb_vect_el_value > vect [vect_index])
07766 tab->min_comb_vect_el_value = vect [vect_index];
07767 check_vect_start [comb_vect_index + vect_index] = vect_num;
07768 }
07769 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
07770 tab->max_comb_vect_el_value = undefined_vect_el_value;
07771 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
07772 tab->min_comb_vect_el_value = undefined_vect_el_value;
07773 if (tab->max_base_vect_el_value < comb_vect_index)
07774 tab->max_base_vect_el_value = comb_vect_index;
07775 if (tab->min_base_vect_el_value > comb_vect_index)
07776 tab->min_base_vect_el_value = comb_vect_index;
07777 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
07778 }
07779
07780
07781 static int
07782 out_state_arcs_num (state_t state)
07783 {
07784 int result;
07785 arc_t arc;
07786
07787 result = 0;
07788 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
07789 {
07790 gcc_assert (arc->insn);
07791 if (arc->insn->first_ainsn_with_given_equivalence_num)
07792 result++;
07793 }
07794 return result;
07795 }
07796
07797
07798 static int
07799 compare_transition_els_num (const void *state_ptr_1,
07800 const void *state_ptr_2)
07801 {
07802 int transition_els_num_1;
07803 int transition_els_num_2;
07804
07805 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
07806 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
07807 if (transition_els_num_1 < transition_els_num_2)
07808 return 1;
07809 else if (transition_els_num_1 == transition_els_num_2)
07810 return 0;
07811 else
07812 return -1;
07813 }
07814
07815
07816
07817 static void
07818 add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
07819 {
07820 int equiv_class_num;
07821 int vect_index;
07822
07823 gcc_assert (ainsn);
07824 equiv_class_num = ainsn->insn_equiv_class_num;
07825 for (vect_index = VLA_HWINT_LENGTH (*vect);
07826 vect_index <= equiv_class_num;
07827 vect_index++)
07828 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
07829 VLA_HWINT (*vect, equiv_class_num) = el_value;
07830 }
07831
07832
07833 static vla_ptr_t output_states_vect;
07834
07835
07836
07837 static void
07838 add_states_vect_el (state_t state)
07839 {
07840 VLA_PTR_ADD (output_states_vect, state);
07841 }
07842
07843
07844
07845 static void
07846 output_trans_table (automaton_t automaton)
07847 {
07848 state_t *state_ptr;
07849 arc_t arc;
07850 vla_hwint_t transition_vect;
07851
07852 undefined_vect_el_value = automaton->achieved_states_num;
07853 automaton->trans_table = create_state_ainsn_table (automaton);
07854
07855
07856 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
07857 pass_states (automaton, add_states_vect_el);
07858 qsort (VLA_PTR_BEGIN (output_states_vect),
07859 VLA_PTR_LENGTH (output_states_vect),
07860 sizeof (state_t), compare_transition_els_num);
07861 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
07862 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
07863 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
07864 state_ptr++)
07865 {
07866 VLA_HWINT_NULLIFY (transition_vect);
07867 for (arc = first_out_arc (*state_ptr);
07868 arc != NULL;
07869 arc = next_out_arc (arc))
07870 {
07871 gcc_assert (arc->insn);
07872 if (arc->insn->first_ainsn_with_given_equivalence_num)
07873 add_vect_el (&transition_vect, arc->insn,
07874 arc->to_state->order_state_num);
07875 }
07876 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
07877 VLA_HWINT_BEGIN (transition_vect),
07878 VLA_HWINT_LENGTH (transition_vect));
07879 }
07880 output_state_ainsn_table
07881 (automaton->trans_table, (char *) "state transitions",
07882 output_trans_full_vect_name, output_trans_comb_vect_name,
07883 output_trans_check_vect_name, output_trans_base_vect_name);
07884 VLA_PTR_DELETE (output_states_vect);
07885 VLA_HWINT_DELETE (transition_vect);
07886 }
07887
07888
07889
07890
07891
07892 static void
07893 output_state_alts_table (automaton_t automaton)
07894 {
07895 state_t *state_ptr;
07896 arc_t arc;
07897 vla_hwint_t state_alts_vect;
07898
07899 undefined_vect_el_value = 0;
07900 automaton->state_alts_table = create_state_ainsn_table (automaton);
07901
07902
07903 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
07904 pass_states (automaton, add_states_vect_el);
07905 qsort (VLA_PTR_BEGIN (output_states_vect),
07906 VLA_PTR_LENGTH (output_states_vect),
07907 sizeof (state_t), compare_transition_els_num);
07908
07909 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
07910 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
07911 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
07912 state_ptr++)
07913 {
07914 VLA_HWINT_NULLIFY (state_alts_vect);
07915 for (arc = first_out_arc (*state_ptr);
07916 arc != NULL;
07917 arc = next_out_arc (arc))
07918 {
07919 gcc_assert (arc->insn);
07920 if (arc->insn->first_ainsn_with_given_equivalence_num)
07921 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
07922 }
07923 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
07924 VLA_HWINT_BEGIN (state_alts_vect),
07925 VLA_HWINT_LENGTH (state_alts_vect));
07926 }
07927 output_state_ainsn_table
07928 (automaton->state_alts_table, (char *) "state insn alternatives",
07929 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
07930 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
07931 VLA_PTR_DELETE (output_states_vect);
07932 VLA_HWINT_DELETE (state_alts_vect);
07933 }
07934
07935
07936
07937 static int curr_state_pass_num;
07938
07939
07940
07941
07942
07943 static int
07944 min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
07945 {
07946 arc_t arc;
07947 int min_insn_issue_delay, insn_issue_delay;
07948
07949 if (state->state_pass_num == curr_state_pass_num
07950 || state->min_insn_issue_delay != -1)
07951
07952
07953 return state->min_insn_issue_delay;
07954 state->state_pass_num = curr_state_pass_num;
07955 min_insn_issue_delay = -1;
07956 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
07957 if (arc->insn == ainsn)
07958 {
07959 min_insn_issue_delay = 0;
07960 break;
07961 }
07962 else
07963 {
07964 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
07965 if (insn_issue_delay != -1)
07966 {
07967 if (arc->insn->insn_reserv_decl
07968 == DECL_INSN_RESERV (advance_cycle_insn_decl))
07969 insn_issue_delay++;
07970 if (min_insn_issue_delay == -1
07971 || min_insn_issue_delay > insn_issue_delay)
07972 {
07973 min_insn_issue_delay = insn_issue_delay;
07974 if (insn_issue_delay == 0)
07975 break;
07976 }
07977 }
07978 }
07979 return min_insn_issue_delay;
07980 }
07981
07982
07983
07984
07985 static int
07986 min_issue_delay (state_t state, ainsn_t ainsn)
07987 {
07988 curr_state_pass_num++;
07989 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
07990 return state->min_insn_issue_delay;
07991 }
07992
07993
07994
07995 static void
07996 initiate_min_issue_delay_pass_states (void)
07997 {
07998 curr_state_pass_num = 0;
07999 }
08000
08001
08002
08003
08004 static void
08005 output_min_issue_delay_table (automaton_t automaton)
08006 {
08007 vla_hwint_t min_issue_delay_vect;
08008 vla_hwint_t compressed_min_issue_delay_vect;
08009 vect_el_t min_delay;
08010 ainsn_t ainsn;
08011 state_t *state_ptr;
08012 int i;
08013
08014
08015
08016 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
08017 pass_states (automaton, add_states_vect_el);
08018 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
08019 VLA_HWINT_EXPAND (min_issue_delay_vect,
08020 VLA_HWINT_LENGTH (output_states_vect)
08021 * automaton->insn_equiv_classes_num);
08022 for (i = 0;
08023 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
08024 * automaton->insn_equiv_classes_num);
08025 i++)
08026 VLA_HWINT (min_issue_delay_vect, i) = 0;
08027 automaton->max_min_delay = 0;
08028 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
08029 if (ainsn->first_ainsn_with_given_equivalence_num)
08030 {
08031 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
08032 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
08033 state_ptr++)
08034 (*state_ptr)->min_insn_issue_delay = -1;
08035 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
08036 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
08037 state_ptr++)
08038 {
08039 min_delay = min_issue_delay (*state_ptr, ainsn);
08040 if (automaton->max_min_delay < min_delay)
08041 automaton->max_min_delay = min_delay;
08042 VLA_HWINT (min_issue_delay_vect,
08043 (*state_ptr)->order_state_num
08044 * automaton->insn_equiv_classes_num
08045 + ainsn->insn_equiv_class_num) = min_delay;
08046 }
08047 }
08048 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
08049 fprintf (output_file, "static const ");
08050 output_range_type (output_file, 0, automaton->max_min_delay);
08051 fprintf (output_file, " ");
08052 output_min_issue_delay_vect_name (output_file, automaton);
08053 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
08054
08055 if (automaton->max_min_delay < 2)
08056 automaton->min_issue_delay_table_compression_factor = 8;
08057 else if (automaton->max_min_delay < 4)
08058 automaton->min_issue_delay_table_compression_factor = 4;
08059 else if (automaton->max_min_delay < 16)
08060 automaton->min_issue_delay_table_compression_factor = 2;
08061 else
08062 automaton->min_issue_delay_table_compression_factor = 1;
08063 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
08064 "compressed min issue delay vector");
08065 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
08066 (VLA_HWINT_LENGTH (min_issue_delay_vect)
08067 + automaton->min_issue_delay_table_compression_factor
08068 - 1)
08069 / automaton->min_issue_delay_table_compression_factor);
08070 for (i = 0;
08071 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
08072 i++)
08073 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
08074 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
08075 VLA_HWINT (compressed_min_issue_delay_vect,
08076 i / automaton->min_issue_delay_table_compression_factor)
08077 |= (VLA_HWINT (min_issue_delay_vect, i)
08078 << (8 - (i % automaton->min_issue_delay_table_compression_factor
08079 + 1)
08080 * (8 / automaton->min_issue_delay_table_compression_factor)));
08081 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
08082 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
08083 fprintf (output_file, "};\n\n");
08084 VLA_PTR_DELETE (output_states_vect);
08085 VLA_HWINT_DELETE (min_issue_delay_vect);
08086 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
08087 }
08088
08089 #ifndef NDEBUG
08090
08091
08092 static int locked_states_num;
08093 #endif
08094
08095
08096
08097 static void
08098 output_dead_lock_vect (automaton_t automaton)
08099 {
08100 state_t *state_ptr;
08101 arc_t arc;
08102 vla_hwint_t dead_lock_vect;
08103
08104
08105
08106
08107 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
08108 pass_states (automaton, add_states_vect_el);
08109 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
08110 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
08111 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
08112 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
08113 state_ptr++)
08114 {
08115 arc = first_out_arc (*state_ptr);
08116 gcc_assert (arc);
08117 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
08118 = (next_out_arc (arc) == NULL
08119 && (arc->insn->insn_reserv_decl
08120 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
08121 #ifndef NDEBUG
08122 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
08123 locked_states_num++;
08124 #endif
08125 }
08126 fprintf (output_file, "/* Vector for locked state flags. */\n");
08127 fprintf (output_file, "static const ");
08128 output_range_type (output_file, 0, 1);
08129 fprintf (output_file, " ");
08130 output_dead_lock_vect_name (output_file, automaton);
08131 fprintf (output_file, "[] = {\n");
08132 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
08133 VLA_HWINT_LENGTH (dead_lock_vect));
08134 fprintf (output_file, "};\n\n");
08135 VLA_HWINT_DELETE (dead_lock_vect);
08136 VLA_PTR_DELETE (output_states_vect);
08137 }
08138
08139
08140
08141 static void
08142 output_reserved_units_table (automaton_t automaton)
08143 {
08144 state_t *curr_state_ptr;
08145 vla_hwint_t reserved_units_table;
08146 size_t state_byte_size;
08147 int i;
08148
08149
08150 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
08151 pass_states (automaton, add_states_vect_el);
08152
08153 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
08154 state_byte_size = (description->query_units_num + 7) / 8;
08155 VLA_HWINT_EXPAND (reserved_units_table,
08156 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
08157 for (i = 0;
08158 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
08159 i++)
08160 VLA_HWINT (reserved_units_table, i) = 0;
08161 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
08162 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
08163 curr_state_ptr++)
08164 {
08165 for (i = 0; i < description->units_num; i++)
08166 if (units_array [i]->query_p
08167 && first_cycle_unit_presence (*curr_state_ptr, i))
08168 VLA_HWINT (reserved_units_table,
08169 (*curr_state_ptr)->order_state_num * state_byte_size
08170 + units_array [i]->query_num / 8)
08171 += (1 << (units_array [i]->query_num % 8));
08172 }
08173 fprintf (output_file, "/* Vector for reserved units of states. */\n");
08174 fprintf (output_file, "static const ");
08175 output_range_type (output_file, 0, 255);
08176 fprintf (output_file, " ");
08177 output_reserved_units_table_name (output_file, automaton);
08178 fprintf (output_file, "[] = {\n");
08179 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
08180 VLA_HWINT_LENGTH (reserved_units_table));
08181 fprintf (output_file, "};\n\n");
08182 VLA_HWINT_DELETE (reserved_units_table);
08183 VLA_PTR_DELETE (output_states_vect);
08184 }
08185
08186
08187
08188 static void
08189 output_tables (void)
08190 {
08191 automaton_t automaton;
08192
08193 #ifndef NDEBUG
08194 locked_states_num = 0;
08195 #endif
08196 initiate_min_issue_delay_pass_states ();
08197 for (automaton = description->first_automaton;
08198 automaton != NULL;
08199 automaton = automaton->next_automaton)
08200 {
08201 output_translate_vect (automaton);
08202 output_trans_table (automaton);
08203 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
08204 output_state_alts_table (automaton);
08205 fprintf (output_file, "\n#endif /* #if %s */\n\n",
08206 AUTOMATON_STATE_ALTS_MACRO_NAME);
08207 output_min_issue_delay_table (automaton);
08208 output_dead_lock_vect (automaton);
08209 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
08210 output_reserved_units_table (automaton);
08211 fprintf (output_file, "\n#endif /* #if %s */\n\n",
08212 CPU_UNITS_QUERY_MACRO_NAME);
08213 }
08214 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
08215 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
08216 }
08217
08218
08219
08220
08221 static void
08222 output_max_insn_queue_index_def (void)
08223 {
08224 int i, max, latency;
08225 decl_t decl;
08226
08227 max = description->max_insn_reserv_cycles;
08228 for (i = 0; i < description->decls_num; i++)
08229 {
08230 decl = description->decls [i];
08231 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
08232 {
08233 latency = DECL_INSN_RESERV (decl)->default_latency;
08234 if (latency > max)
08235 max = latency;
08236 }
08237 else if (decl->mode == dm_bypass)
08238 {
08239 latency = DECL_BYPASS (decl)->latency;
08240 if (latency > max)
08241 max = latency;
08242 }
08243 }
08244 for (i = 0; (1 << i) <= max; i++)
08245 ;
08246 gcc_assert (i >= 0);
08247 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
08248 }
08249
08250
08251
08252
08253 static void
08254 output_insn_code_cases (void (*output_automata_list_code)
08255 (automata_list_el_t))
08256 {
08257 decl_t decl, decl2;
08258 int i, j;
08259
08260 for (i = 0; i < description->decls_num; i++)
08261 {
08262 decl = description->decls [i];
08263 if (decl->mode == dm_insn_reserv)
08264 DECL_INSN_RESERV (decl)->processed_p = FALSE;
08265 }
08266 for (i = 0; i < description->decls_num; i++)
08267 {
08268 decl = description->decls [i];
08269 if (decl->mode == dm_insn_reserv
08270 && !DECL_INSN_RESERV (decl)->processed_p)
08271 {
08272 for (j = i; j < description->decls_num; j++)
08273 {
08274 decl2 = description->decls [j];
08275 if (decl2->mode == dm_insn_reserv
08276 && (DECL_INSN_RESERV (decl2)->important_automata_list
08277 == DECL_INSN_RESERV (decl)->important_automata_list))
08278 {
08279 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
08280 fprintf (output_file, " case %d: /* %s */\n",
08281 DECL_INSN_RESERV (decl2)->insn_num,
08282 DECL_INSN_RESERV (decl2)->name);
08283 }
08284 }
08285 (*output_automata_list_code)
08286 (DECL_INSN_RESERV (decl)->important_automata_list);
08287 }
08288 }
08289 }
08290
08291
08292
08293
08294 static void
08295 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
08296 {
08297 automata_list_el_t el;
08298 automaton_t automaton;
08299
08300 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
08301 {
08302 automaton = el->automaton;
08303 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
08304 output_min_issue_delay_vect_name (output_file, automaton);
08305 fprintf (output_file,
08306 (automaton->min_issue_delay_table_compression_factor != 1
08307 ? " [(" : " ["));
08308 output_translate_vect_name (output_file, automaton);
08309 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
08310 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
08311 output_chip_member_name (output_file, automaton);
08312 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
08313 if (automaton->min_issue_delay_table_compression_factor == 1)
08314 fprintf (output_file, "];\n");
08315 else
08316 {
08317 fprintf (output_file, ") / %d];\n",
08318 automaton->min_issue_delay_table_compression_factor);
08319 fprintf (output_file, " %s = (%s >> (8 - (",
08320 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
08321 output_translate_vect_name (output_file, automaton);
08322 fprintf
08323 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
08324 INTERNAL_INSN_CODE_NAME,
08325 automaton->min_issue_delay_table_compression_factor,
08326 8 / automaton->min_issue_delay_table_compression_factor,
08327 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
08328 - 1);
08329 }
08330 if (el == automata_list)
08331 fprintf (output_file, " %s = %s;\n",
08332 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
08333 else
08334 {
08335 fprintf (output_file, " if (%s > %s)\n",
08336 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
08337 fprintf (output_file, " %s = %s;\n",
08338 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
08339 }
08340 }
08341 fprintf (output_file, " break;\n\n");
08342 }
08343
08344
08345 static void
08346 output_internal_min_issue_delay_func (void)
08347 {
08348 fprintf (output_file,
08349 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
08350 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08351 CHIP_NAME, CHIP_PARAMETER_NAME);
08352 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
08353 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
08354 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
08355 output_insn_code_cases (output_automata_list_min_issue_delay_code);
08356 fprintf (output_file,
08357 "\n default:\n %s = -1;\n break;\n }\n",
08358 RESULT_VARIABLE_NAME);
08359 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
08360 fprintf (output_file, "}\n\n");
08361 }
08362
08363
08364
08365 static void
08366 output_automata_list_transition_code (automata_list_el_t automata_list)
08367 {
08368 automata_list_el_t el, next_el;
08369
08370 fprintf (output_file, " {\n");
08371 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
08372 for (el = automata_list;; el = next_el)
08373 {
08374 next_el = el->next_automata_list_el;
08375 if (next_el == NULL)
08376 break;
08377 fprintf (output_file, " ");
08378 output_state_member_type (output_file, el->automaton);
08379 fprintf (output_file, " ");
08380 output_temp_chip_member_name (output_file, el->automaton);
08381 fprintf (output_file, ";\n");
08382 }
08383 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
08384 if (comb_vect_p (el->automaton->trans_table))
08385 {
08386 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
08387 output_trans_base_vect_name (output_file, el->automaton);
08388 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
08389 output_chip_member_name (output_file, el->automaton);
08390 fprintf (output_file, "] + ");
08391 output_translate_vect_name (output_file, el->automaton);
08392 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
08393 fprintf (output_file, " if (");
08394 output_trans_check_vect_name (output_file, el->automaton);
08395 fprintf (output_file, " [%s] != %s->",
08396 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
08397 output_chip_member_name (output_file, el->automaton);
08398 fprintf (output_file, ")\n");
08399 fprintf (output_file, " return %s (%s, %s);\n",
08400 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08401 CHIP_PARAMETER_NAME);
08402 fprintf (output_file, " else\n");
08403 fprintf (output_file, " ");
08404 if (el->next_automata_list_el != NULL)
08405 output_temp_chip_member_name (output_file, el->automaton);
08406 else
08407 {
08408 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
08409 output_chip_member_name (output_file, el->automaton);
08410 }
08411 fprintf (output_file, " = ");
08412 output_trans_comb_vect_name (output_file, el->automaton);
08413 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
08414 }
08415 else
08416 {
08417 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
08418 output_trans_full_vect_name (output_file, el->automaton);
08419 fprintf (output_file, " [");
08420 output_translate_vect_name (output_file, el->automaton);
08421 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
08422 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
08423 output_chip_member_name (output_file, el->automaton);
08424 fprintf (output_file, " * %d];\n",
08425 el->automaton->insn_equiv_classes_num);
08426 fprintf (output_file, " if (%s >= %d)\n",
08427 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
08428 fprintf (output_file, " return %s (%s, %s);\n",
08429 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08430 CHIP_PARAMETER_NAME);
08431 fprintf (output_file, " else\n ");
08432 if (el->next_automata_list_el != NULL)
08433 output_temp_chip_member_name (output_file, el->automaton);
08434 else
08435 {
08436 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
08437 output_chip_member_name (output_file, el->automaton);
08438 }
08439 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
08440 }
08441 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
08442 for (el = automata_list;; el = next_el)
08443 {
08444 next_el = el->next_automata_list_el;
08445 if (next_el == NULL)
08446 break;
08447 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
08448 output_chip_member_name (output_file, el->automaton);
08449 fprintf (output_file, " = ");
08450 output_temp_chip_member_name (output_file, el->automaton);
08451 fprintf (output_file, ";\n");
08452 }
08453 fprintf (output_file, " return -1;\n");
08454 fprintf (output_file, " }\n");
08455 }
08456
08457
08458 static void
08459 output_internal_trans_func (void)
08460 {
08461 fprintf (output_file,
08462 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
08463 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08464 CHIP_NAME, CHIP_PARAMETER_NAME);
08465 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
08466 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
08467 output_insn_code_cases (output_automata_list_transition_code);
08468 fprintf (output_file, "\n default:\n return -1;\n }\n");
08469 fprintf (output_file, "}\n\n");
08470 }
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485 static void
08486 output_internal_insn_code_evaluation (const char *insn_name,
08487 const char *insn_code_name,
08488 int code)
08489 {
08490 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
08491 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
08492 DFA_INSN_CODE_FUNC_NAME, insn_name);
08493 fprintf (output_file, " if (%s > %s)\n return %d;\n",
08494 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
08495 fprintf (output_file, " }\n else\n %s = %s;\n\n",
08496 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
08497 }
08498
08499
08500
08501
08502 static void
08503 output_dfa_insn_code_func (void)
08504 {
08505
08506
08507 fprintf (output_file, "\
08508 static void\n\
08509 dfa_insn_code_enlarge (int uid)\n\
08510 {\n\
08511 int i = %s;\n\
08512 %s = 2 * uid;\n\
08513 %s = xrealloc (%s,\n\
08514 %s * sizeof(int));\n\
08515 for (; i < %s; i++)\n\
08516 %s[i] = -1;\n}\n\n",
08517 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
08518 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
08519 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
08520 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
08521 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
08522 DFA_INSN_CODES_VARIABLE_NAME);
08523 fprintf (output_file, "\
08524 static inline int\n%s (rtx %s)\n\
08525 {\n\
08526 int uid = INSN_UID (%s);\n\
08527 int %s;\n\n",
08528 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
08529 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
08530
08531 fprintf (output_file,
08532 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
08533 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
08534 fprintf (output_file, " %s = %s[uid];\n",
08535 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
08536 fprintf (output_file, "\
08537 if (%s < 0)\n\
08538 {\n\
08539 %s = %s (%s);\n\
08540 %s[uid] = %s;\n\
08541 }\n",
08542 INTERNAL_INSN_CODE_NAME,
08543 INTERNAL_INSN_CODE_NAME,
08544 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
08545 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
08546 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
08547 }
08548
08549
08550 static void
08551 output_trans_func (void)
08552 {
08553 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
08554 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
08555 INSN_PARAMETER_NAME);
08556 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
08557 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
08558 INTERNAL_INSN_CODE_NAME, -1);
08559 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
08560 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
08561 }
08562
08563
08564
08565 static void
08566 output_automata_list_state_alts_code (automata_list_el_t automata_list)
08567 {
08568 automata_list_el_t el;
08569 automaton_t automaton;
08570
08571 fprintf (output_file, " {\n");
08572 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
08573 if (comb_vect_p (el->automaton->state_alts_table))
08574 {
08575 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
08576 break;
08577 }
08578 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
08579 {
08580 automaton = el->automaton;
08581 if (comb_vect_p (automaton->state_alts_table))
08582 {
08583 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
08584 output_state_alts_base_vect_name (output_file, automaton);
08585 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
08586 output_chip_member_name (output_file, automaton);
08587 fprintf (output_file, "] + ");
08588 output_translate_vect_name (output_file, automaton);
08589 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
08590 fprintf (output_file, " if (");
08591 output_state_alts_check_vect_name (output_file, automaton);
08592 fprintf (output_file, " [%s] != %s->",
08593 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
08594 output_chip_member_name (output_file, automaton);
08595 fprintf (output_file, ")\n");
08596 fprintf (output_file, " return 0;\n");
08597 fprintf (output_file, " else\n");
08598 fprintf (output_file,
08599 (el == automata_list
08600 ? " %s = " : " %s += "),
08601 RESULT_VARIABLE_NAME);
08602 output_state_alts_comb_vect_name (output_file, automaton);
08603 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
08604 }
08605 else
08606 {
08607 fprintf (output_file,
08608 (el == automata_list
08609 ? "\n %s = " : " %s += "),
08610 RESULT_VARIABLE_NAME);
08611 output_state_alts_full_vect_name (output_file, automaton);
08612 fprintf (output_file, " [");
08613 output_translate_vect_name (output_file, automaton);
08614 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
08615 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
08616 output_chip_member_name (output_file, automaton);
08617 fprintf (output_file, " * %d];\n",
08618 automaton->insn_equiv_classes_num);
08619 }
08620 }
08621 fprintf (output_file, " break;\n }\n\n");
08622 }
08623
08624
08625 static void
08626 output_internal_state_alts_func (void)
08627 {
08628 fprintf (output_file,
08629 "static int\n%s (int %s, struct %s *%s)\n",
08630 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08631 CHIP_NAME, CHIP_PARAMETER_NAME);
08632 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
08633 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
08634 output_insn_code_cases (output_automata_list_state_alts_code);
08635 fprintf (output_file,
08636 "\n default:\n %s = 0;\n break;\n }\n",
08637 RESULT_VARIABLE_NAME);
08638 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
08639 fprintf (output_file, "}\n\n");
08640 }
08641
08642
08643 static void
08644 output_state_alts_func (void)
08645 {
08646 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
08647 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
08648 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
08649 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
08650 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
08651 INTERNAL_INSN_CODE_NAME, 0);
08652 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
08653 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
08654 }
08655
08656
08657 static void
08658 output_min_issue_delay_func (void)
08659 {
08660 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
08661 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
08662 INSN_PARAMETER_NAME);
08663 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
08664 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
08665 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
08666 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
08667 fprintf (output_file, " if (%s > %s)\n return 0;\n",
08668 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
08669 fprintf (output_file, " }\n else\n %s = %s;\n",
08670 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
08671 fprintf (output_file, "\n return %s (%s, %s);\n",
08672 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08673 STATE_NAME);
08674 fprintf (output_file, "}\n\n");
08675 }
08676
08677
08678 static void
08679 output_internal_dead_lock_func (void)
08680 {
08681 automaton_t automaton;
08682
08683 fprintf (output_file, "static int\n%s (struct %s *%s)\n",
08684 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
08685 fprintf (output_file, "{\n");
08686 for (automaton = description->first_automaton;
08687 automaton != NULL;
08688 automaton = automaton->next_automaton)
08689 {
08690 fprintf (output_file, " if (");
08691 output_dead_lock_vect_name (output_file, automaton);
08692 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
08693 output_chip_member_name (output_file, automaton);
08694 fprintf (output_file, "])\n return 1/* TRUE */;\n");
08695 }
08696 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
08697 }
08698
08699
08700 static void
08701 output_dead_lock_func (void)
08702 {
08703 fprintf (output_file, "int\n%s (%s %s)\n",
08704 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
08705 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
08706 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
08707 }
08708
08709
08710 static void
08711 output_internal_reset_func (void)
08712 {
08713 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
08714 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
08715 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
08716 CHIP_PARAMETER_NAME, CHIP_NAME);
08717 }
08718
08719
08720 static void
08721 output_size_func (void)
08722 {
08723 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
08724 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
08725 }
08726
08727
08728 static void
08729 output_reset_func (void)
08730 {
08731 fprintf (output_file, "void\n%s (%s %s)\n",
08732 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
08733 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
08734 STATE_NAME);
08735 }
08736
08737
08738 static void
08739 output_min_insn_conflict_delay_func (void)
08740 {
08741 fprintf (output_file,
08742 "int\n%s (%s %s, rtx %s, rtx %s)\n",
08743 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
08744 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
08745 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
08746 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
08747 INTERNAL_INSN2_CODE_NAME);
08748 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
08749 INTERNAL_INSN_CODE_NAME, 0);
08750 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
08751 INTERNAL_INSN2_CODE_NAME, 0);
08752 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
08753 CHIP_NAME, STATE_NAME, CHIP_NAME);
08754 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
08755 fprintf (output_file, " transition = %s (%s, &%s);\n",
08756 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
08757 fprintf (output_file, " gcc_assert (transition <= 0);\n");
08758 fprintf (output_file, " return %s (%s, &%s);\n",
08759 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
08760 CHIP_NAME);
08761 fprintf (output_file, "}\n\n");
08762 }
08763
08764
08765 static void
08766 output_internal_insn_latency_func (void)
08767 {
08768 decl_t decl;
08769 struct bypass_decl *bypass;
08770 int i, j, col;
08771 const char *tabletype = "unsigned char";
08772
08773
08774
08775 for (i = 0; i < description->decls_num; i++)
08776 if (description->decls[i]->mode == dm_insn_reserv)
08777 {
08778 decl = description->decls[i];
08779 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
08780 && tabletype[0] != 'i')
08781 tabletype = "unsigned short";
08782 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
08783 tabletype = "int";
08784 }
08785
08786 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
08787 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
08788 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
08789 INSN2_PARAMETER_NAME);
08790 fprintf (output_file, "{\n");
08791
08792 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
08793 {
08794 fputs (" return 0;\n}\n\n", output_file);
08795 return;
08796 }
08797
08798 fprintf (output_file, " static const %s default_latencies[] =\n {",
08799 tabletype);
08800
08801 for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
08802 if (description->decls[i]->mode == dm_insn_reserv
08803 && description->decls[i] != advance_cycle_insn_decl)
08804 {
08805 if ((col = (col+1) % 8) == 0)
08806 fputs ("\n ", output_file);
08807 decl = description->decls[i];
08808 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
08809 fprintf (output_file, "% 4d,",
08810 DECL_INSN_RESERV (decl)->default_latency);
08811 }
08812 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
08813 fputs ("\n };\n", output_file);
08814
08815 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
08816 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
08817 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
08818
08819 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
08820 for (i = 0; i < description->decls_num; i++)
08821 if (description->decls[i]->mode == dm_insn_reserv
08822 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
08823 {
08824 decl = description->decls [i];
08825 fprintf (output_file,
08826 " case %d:\n switch (%s)\n {\n",
08827 DECL_INSN_RESERV (decl)->insn_num,
08828 INTERNAL_INSN2_CODE_NAME);
08829 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
08830 bypass != NULL;
08831 bypass = bypass->next)
08832 {
08833 gcc_assert (bypass->in_insn_reserv->insn_num
08834 != (DECL_INSN_RESERV
08835 (advance_cycle_insn_decl)->insn_num));
08836 fprintf (output_file, " case %d:\n",
08837 bypass->in_insn_reserv->insn_num);
08838 if (bypass->bypass_guard_name == NULL)
08839 fprintf (output_file, " return %d;\n",
08840 bypass->latency);
08841 else
08842 {
08843 fprintf (output_file,
08844 " if (%s (%s, %s))\n",
08845 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
08846 INSN2_PARAMETER_NAME);
08847 fprintf (output_file,
08848 " return %d;\n break;\n",
08849 bypass->latency);
08850 }
08851 }
08852 fputs (" }\n break;\n", output_file);
08853 }
08854
08855 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
08856 INTERNAL_INSN_CODE_NAME);
08857 }
08858
08859
08860 static void
08861 output_insn_latency_func (void)
08862 {
08863 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
08864 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
08865 fprintf (output_file, "{\n int %s, %s;\n",
08866 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
08867 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
08868 INTERNAL_INSN_CODE_NAME, 0);
08869 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
08870 INTERNAL_INSN2_CODE_NAME, 0);
08871 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
08872 INTERNAL_INSN_LATENCY_FUNC_NAME,
08873 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
08874 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
08875 }
08876
08877
08878 static void
08879 output_print_reservation_func (void)
08880 {
08881 decl_t decl;
08882 int i, j;
08883
08884 fprintf (output_file,
08885 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
08886 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
08887 INSN_PARAMETER_NAME);
08888
08889 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
08890 {
08891 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
08892 NOTHING_NAME, FILE_PARAMETER_NAME);
08893 return;
08894 }
08895
08896
08897 fputs (" static const char *const reservation_names[] =\n {",
08898 output_file);
08899
08900 for (i = 0, j = 0; i < description->decls_num; i++)
08901 {
08902 decl = description->decls [i];
08903 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
08904 {
08905 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
08906 j++;
08907
08908 fprintf (output_file, "\n \"%s\",",
08909 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
08910 finish_regexp_representation ();
08911 }
08912 }
08913 gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
08914
08915 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
08916 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
08917
08918 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
08919 INSN_PARAMETER_NAME,
08920 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
08921 fprintf (output_file, " else\n\
08922 {\n\
08923 %s = %s (%s);\n\
08924 if (%s > %s)\n\
08925 %s = %s;\n\
08926 }\n",
08927 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
08928 INSN_PARAMETER_NAME,
08929 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
08930 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
08931
08932 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
08933 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
08934 }
08935
08936
08937
08938 static int
08939 units_cmp (const void *unit1, const void *unit2)
08940 {
08941 const unit_decl_t u1 = *(unit_decl_t *) unit1;
08942 const unit_decl_t u2 = *(unit_decl_t *) unit2;
08943
08944 return strcmp (u1->name, u2->name);
08945 }
08946
08947
08948
08949 #define NAME_CODE_STRUCT_NAME "name_code"
08950
08951
08952 #define NAME_CODE_TABLE_NAME "name_code_table"
08953
08954
08955 #define NAME_MEMBER_NAME "name"
08956 #define CODE_MEMBER_NAME "code"
08957
08958
08959
08960 #define CMP_VARIABLE_NAME "cmp"
08961 #define LOW_VARIABLE_NAME "l"
08962 #define MIDDLE_VARIABLE_NAME "m"
08963 #define HIGH_VARIABLE_NAME "h"
08964
08965
08966
08967 static void
08968 output_get_cpu_unit_code_func (void)
08969 {
08970 int i;
08971 unit_decl_t *units;
08972
08973 fprintf (output_file, "int\n%s (const char *%s)\n",
08974 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
08975 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
08976 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
08977 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
08978 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
08979 fprintf (output_file, " static struct %s %s [] =\n {\n",
08980 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
08981 units = xmalloc (sizeof (unit_decl_t) * description->units_num);
08982 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
08983 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
08984 for (i = 0; i < description->units_num; i++)
08985 if (units [i]->query_p)
08986 fprintf (output_file, " {\"%s\", %d},\n",
08987 units[i]->name, units[i]->query_num);
08988 fprintf (output_file, " };\n\n");
08989 fprintf (output_file, " /* The following is binary search: */\n");
08990 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
08991 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
08992 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
08993 fprintf (output_file, " while (%s <= %s)\n {\n",
08994 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
08995 fprintf (output_file, " %s = (%s + %s) / 2;\n",
08996 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
08997 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
08998 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
08999 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
09000 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
09001 fprintf (output_file, " %s = %s - 1;\n",
09002 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
09003 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
09004 fprintf (output_file, " %s = %s + 1;\n",
09005 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
09006 fprintf (output_file, " else\n");
09007 fprintf (output_file, " return %s [%s].%s;\n }\n",
09008 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
09009 fprintf (output_file, " return -1;\n}\n\n");
09010 free (units);
09011 }
09012
09013
09014
09015
09016 static void
09017 output_cpu_unit_reservation_p (void)
09018 {
09019 automaton_t automaton;
09020
09021 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
09022 CPU_UNIT_RESERVATION_P_FUNC_NAME,
09023 STATE_TYPE_NAME, STATE_NAME,
09024 CPU_CODE_PARAMETER_NAME);
09025 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
09026 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
09027 description->query_units_num);
09028 for (automaton = description->first_automaton;
09029 automaton != NULL;
09030 automaton = automaton->next_automaton)
09031 {
09032 fprintf (output_file, " if ((");
09033 output_reserved_units_table_name (output_file, automaton);
09034 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
09035 output_chip_member_name (output_file, automaton);
09036 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
09037 (description->query_units_num + 7) / 8,
09038 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
09039 fprintf (output_file, " return 1;\n");
09040 }
09041 fprintf (output_file, " return 0;\n}\n\n");
09042 }
09043
09044
09045 static void
09046 output_dfa_clean_insn_cache_func (void)
09047 {
09048 fprintf (output_file,
09049 "void\n%s (void)\n{\n int %s;\n\n",
09050 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
09051 fprintf (output_file,
09052 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
09053 I_VARIABLE_NAME, I_VARIABLE_NAME,
09054 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
09055 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
09056 }
09057
09058
09059 static void
09060 output_dfa_start_func (void)
09061 {
09062 fprintf (output_file,
09063 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
09064 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
09065 fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
09066 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
09067 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
09068 }
09069
09070
09071 static void
09072 output_dfa_finish_func (void)
09073 {
09074 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
09075 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
09076 }
09077
09078
09079
09080
09081
09082
09083
09084 static void
09085 output_regexp (regexp_t regexp)
09086 {
09087 fprintf (output_description_file, "%s", regexp_representation (regexp));
09088 finish_regexp_representation ();
09089 }
09090
09091
09092 static void
09093 output_unit_set_el_list (unit_set_el_t list)
09094 {
09095 unit_set_el_t el;
09096
09097 for (el = list; el != NULL; el = el->next_unit_set_el)
09098 {
09099 if (el != list)
09100 fprintf (output_description_file, ", ");
09101 fprintf (output_description_file, "%s", el->unit_decl->name);
09102 }
09103 }
09104
09105
09106 static void
09107 output_pattern_set_el_list (pattern_set_el_t list)
09108 {
09109 pattern_set_el_t el;
09110 int i;
09111
09112 for (el = list; el != NULL; el = el->next_pattern_set_el)
09113 {
09114 if (el != list)
09115 fprintf (output_description_file, ", ");
09116 for (i = 0; i < el->units_num; i++)
09117 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
09118 el->unit_decls [i]->name);
09119 }
09120 }
09121
09122
09123
09124 static void
09125 output_description (void)
09126 {
09127 decl_t decl;
09128 int i;
09129
09130 for (i = 0; i < description->decls_num; i++)
09131 {
09132 decl = description->decls [i];
09133 if (decl->mode == dm_unit)
09134 {
09135 if (DECL_UNIT (decl)->excl_list != NULL)
09136 {
09137 fprintf (output_description_file, "unit %s exlusion_set: ",
09138 DECL_UNIT (decl)->name);
09139 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
09140 fprintf (output_description_file, "\n");
09141 }
09142 if (DECL_UNIT (decl)->presence_list != NULL)
09143 {
09144 fprintf (output_description_file, "unit %s presence_set: ",
09145 DECL_UNIT (decl)->name);
09146 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
09147 fprintf (output_description_file, "\n");
09148 }
09149 if (DECL_UNIT (decl)->final_presence_list != NULL)
09150 {
09151 fprintf (output_description_file, "unit %s final_presence_set: ",
09152 DECL_UNIT (decl)->name);
09153 output_pattern_set_el_list
09154 (DECL_UNIT (decl)->final_presence_list);
09155 fprintf (output_description_file, "\n");
09156 }
09157 if (DECL_UNIT (decl)->absence_list != NULL)
09158 {
09159 fprintf (output_description_file, "unit %s absence_set: ",
09160 DECL_UNIT (decl)->name);
09161 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
09162 fprintf (output_description_file, "\n");
09163 }
09164 if (DECL_UNIT (decl)->final_absence_list != NULL)
09165 {
09166 fprintf (output_description_file, "unit %s final_absence_set: ",
09167 DECL_UNIT (decl)->name);
09168 output_pattern_set_el_list
09169 (DECL_UNIT (decl)->final_absence_list);
09170 fprintf (output_description_file, "\n");
09171 }
09172 }
09173 }
09174 fprintf (output_description_file, "\n");
09175 for (i = 0; i < description->decls_num; i++)
09176 {
09177 decl = description->decls [i];
09178 if (decl->mode == dm_reserv)
09179 {
09180 fprintf (output_description_file, "reservation %s: ",
09181 DECL_RESERV (decl)->name);
09182 output_regexp (DECL_RESERV (decl)->regexp);
09183 fprintf (output_description_file, "\n");
09184 }
09185 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
09186 {
09187 fprintf (output_description_file, "insn reservation %s ",
09188 DECL_INSN_RESERV (decl)->name);
09189 print_rtl (output_description_file,
09190 DECL_INSN_RESERV (decl)->condexp);
09191 fprintf (output_description_file, ": ");
09192 output_regexp (DECL_INSN_RESERV (decl)->regexp);
09193 fprintf (output_description_file, "\n");
09194 }
09195 else if (decl->mode == dm_bypass)
09196 fprintf (output_description_file, "bypass %d %s %s\n",
09197 DECL_BYPASS (decl)->latency,
09198 DECL_BYPASS (decl)->out_insn_name,
09199 DECL_BYPASS (decl)->in_insn_name);
09200 }
09201 fprintf (output_description_file, "\n\f\n");
09202 }
09203
09204
09205 static void
09206 output_automaton_name (FILE *f, automaton_t automaton)
09207 {
09208 if (automaton->corresponding_automaton_decl == NULL)
09209 fprintf (f, "#%d", automaton->automaton_order_num);
09210 else
09211 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
09212 }
09213
09214
09215
09216 #define MAX_LINE_LENGTH 70
09217
09218
09219 static void
09220 output_automaton_units (automaton_t automaton)
09221 {
09222 decl_t decl;
09223 char *name;
09224 int curr_line_length;
09225 int there_is_an_automaton_unit;
09226 int i;
09227
09228 fprintf (output_description_file, "\n Corresponding units:\n");
09229 fprintf (output_description_file, " ");
09230 curr_line_length = 4;
09231 there_is_an_automaton_unit = 0;
09232 for (i = 0; i < description->decls_num; i++)
09233 {
09234 decl = description->decls [i];
09235 if (decl->mode == dm_unit
09236 && (DECL_UNIT (decl)->corresponding_automaton_num
09237 == automaton->automaton_order_num))
09238 {
09239 there_is_an_automaton_unit = 1;
09240 name = DECL_UNIT (decl)->name;
09241 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
09242 {
09243 curr_line_length = strlen (name) + 4;
09244 fprintf (output_description_file, "\n ");
09245 }
09246 else
09247 {
09248 curr_line_length += strlen (name) + 1;
09249 fprintf (output_description_file, " ");
09250 }
09251 fprintf (output_description_file, "%s", name);
09252 }
09253 }
09254 if (!there_is_an_automaton_unit)
09255 fprintf (output_description_file, "<None>");
09256 fprintf (output_description_file, "\n\n");
09257 }
09258
09259
09260
09261 static vla_ptr_t state_reservs;
09262
09263
09264 static void
09265 add_state_reservs (state_t state)
09266 {
09267 alt_state_t curr_alt_state;
09268 reserv_sets_t reservs;
09269
09270 if (state->component_states != NULL)
09271 for (curr_alt_state = state->component_states;
09272 curr_alt_state != NULL;
09273 curr_alt_state = curr_alt_state->next_sorted_alt_state)
09274 add_state_reservs (curr_alt_state->state);
09275 else
09276 {
09277 reservs = state->reservs;
09278 VLA_PTR_ADD (state_reservs, reservs);
09279 }
09280 }
09281
09282
09283
09284 static void
09285 output_state_arcs (state_t state)
09286 {
09287 arc_t arc;
09288 ainsn_t ainsn;
09289 char *insn_name;
09290 int curr_line_length;
09291
09292 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
09293 {
09294 ainsn = arc->insn;
09295 gcc_assert (ainsn->first_insn_with_same_reservs);
09296 fprintf (output_description_file, " ");
09297 curr_line_length = 7;
09298 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
09299 do
09300 {
09301 insn_name = ainsn->insn_reserv_decl->name;
09302 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
09303 {
09304 if (ainsn != arc->insn)
09305 {
09306 fprintf (output_description_file, ",\n ");
09307 curr_line_length = strlen (insn_name) + 6;
09308 }
09309 else
09310 curr_line_length += strlen (insn_name);
09311 }
09312 else
09313 {
09314 curr_line_length += strlen (insn_name);
09315 if (ainsn != arc->insn)
09316 {
09317 curr_line_length += 2;
09318 fprintf (output_description_file, ", ");
09319 }
09320 }
09321 fprintf (output_description_file, "%s", insn_name);
09322 ainsn = ainsn->next_same_reservs_insn;
09323 }
09324 while (ainsn != NULL);
09325 fprintf (output_description_file, " %d (%d)\n",
09326 arc->to_state->order_state_num, arc->state_alts);
09327 }
09328 fprintf (output_description_file, "\n");
09329 }
09330
09331
09332
09333 static int
09334 state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
09335 {
09336 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
09337 *(reserv_sets_t *) reservs_ptr_2);
09338 }
09339
09340
09341
09342 static void
09343 remove_state_duplicate_reservs (void)
09344 {
09345 reserv_sets_t *reservs_ptr;
09346 reserv_sets_t *last_formed_reservs_ptr;
09347
09348 last_formed_reservs_ptr = NULL;
09349 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
09350 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
09351 reservs_ptr++)
09352 if (last_formed_reservs_ptr == NULL)
09353 last_formed_reservs_ptr = reservs_ptr;
09354 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
09355 {
09356 ++last_formed_reservs_ptr;
09357 *last_formed_reservs_ptr = *reservs_ptr;
09358 }
09359 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
09360 }
09361
09362
09363
09364
09365
09366 static void
09367 output_state (state_t state)
09368 {
09369 reserv_sets_t *reservs_ptr;
09370
09371 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
09372 fprintf (output_description_file, " State #%d", state->order_state_num);
09373 fprintf (output_description_file,
09374 state->new_cycle_p ? " (new cycle)\n" : "\n");
09375 add_state_reservs (state);
09376 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
09377 sizeof (reserv_sets_t), state_reservs_cmp);
09378 remove_state_duplicate_reservs ();
09379 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
09380 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
09381 reservs_ptr++)
09382 {
09383 fprintf (output_description_file, " ");
09384 output_reserv_sets (output_description_file, *reservs_ptr);
09385 fprintf (output_description_file, "\n");
09386 }
09387 fprintf (output_description_file, "\n");
09388 output_state_arcs (state);
09389 VLA_PTR_DELETE (state_reservs);
09390 }
09391
09392
09393
09394 static void
09395 output_automaton_descriptions (void)
09396 {
09397 automaton_t automaton;
09398
09399 for (automaton = description->first_automaton;
09400 automaton != NULL;
09401 automaton = automaton->next_automaton)
09402 {
09403 fprintf (output_description_file, "\nAutomaton ");
09404 output_automaton_name (output_description_file, automaton);
09405 fprintf (output_description_file, "\n");
09406 output_automaton_units (automaton);
09407 pass_states (automaton, output_state);
09408 }
09409 }
09410
09411
09412
09413
09414
09415
09416
09417
09418 static void
09419 output_statistics (FILE *f)
09420 {
09421 automaton_t automaton;
09422 int states_num;
09423 #ifndef NDEBUG
09424 int transition_comb_vect_els = 0;
09425 int transition_full_vect_els = 0;
09426 int state_alts_comb_vect_els = 0;
09427 int state_alts_full_vect_els = 0;
09428 int min_issue_delay_vect_els = 0;
09429 #endif
09430
09431 for (automaton = description->first_automaton;
09432 automaton != NULL;
09433 automaton = automaton->next_automaton)
09434 {
09435 fprintf (f, "\nAutomaton ");
09436 output_automaton_name (f, automaton);
09437 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
09438 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
09439 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
09440 automaton->DFA_states_num, automaton->DFA_arcs_num);
09441 states_num = automaton->DFA_states_num;
09442 if (!no_minimization_flag)
09443 {
09444 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
09445 automaton->minimal_DFA_states_num,
09446 automaton->minimal_DFA_arcs_num);
09447 states_num = automaton->minimal_DFA_states_num;
09448 }
09449 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
09450 description->insns_num, automaton->insn_equiv_classes_num);
09451 #ifndef NDEBUG
09452 fprintf
09453 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
09454 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
09455 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
09456 (comb_vect_p (automaton->trans_table)
09457 ? "use comb vect" : "use simple vect"));
09458 fprintf
09459 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
09460 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
09461 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
09462 (comb_vect_p (automaton->state_alts_table)
09463 ? "use comb vect" : "use simple vect"));
09464 fprintf
09465 (f, "%5ld min delay table els, compression factor %d\n",
09466 (long) states_num * automaton->insn_equiv_classes_num,
09467 automaton->min_issue_delay_table_compression_factor);
09468 transition_comb_vect_els
09469 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
09470 transition_full_vect_els
09471 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
09472 state_alts_comb_vect_els
09473 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
09474 state_alts_full_vect_els
09475 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
09476 min_issue_delay_vect_els
09477 += states_num * automaton->insn_equiv_classes_num;
09478 #endif
09479 }
09480 #ifndef NDEBUG
09481 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
09482 allocated_states_num, allocated_arcs_num);
09483 fprintf (f, "%5d all allocated alternative states\n",
09484 allocated_alt_states_num);
09485 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
09486 transition_comb_vect_els, transition_full_vect_els);
09487 fprintf
09488 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
09489 state_alts_comb_vect_els, state_alts_full_vect_els);
09490 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
09491 fprintf (f, "%5d locked states num\n", locked_states_num);
09492 #endif
09493 }
09494
09495
09496
09497 static void
09498 output_time_statistics (FILE *f)
09499 {
09500 fprintf (f, "\n transformation: ");
09501 print_active_time (f, transform_time);
09502 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
09503 print_active_time (f, NDFA_time);
09504 if (ndfa_flag)
09505 {
09506 fprintf (f, ", NDFA -> DFA: ");
09507 print_active_time (f, NDFA_to_DFA_time);
09508 }
09509 fprintf (f, "\n DFA minimization: ");
09510 print_active_time (f, minimize_time);
09511 fprintf (f, ", making insn equivalence: ");
09512 print_active_time (f, equiv_time);
09513 fprintf (f, "\n all automaton generation: ");
09514 print_active_time (f, automaton_generation_time);
09515 fprintf (f, ", output: ");
09516 print_active_time (f, output_time);
09517 fprintf (f, "\n");
09518 }
09519
09520
09521
09522
09523 static void
09524 generate (void)
09525 {
09526 automata_num = split_argument;
09527 if (description->units_num < automata_num)
09528 automata_num = description->units_num;
09529 initiate_states ();
09530 initiate_arcs ();
09531 initiate_automata_lists ();
09532 initiate_pass_states ();
09533 initiate_excl_sets ();
09534 initiate_presence_absence_pattern_sets ();
09535 automaton_generation_time = create_ticker ();
09536 create_automata ();
09537 ticker_off (&automaton_generation_time);
09538 }
09539
09540
09541
09542
09543
09544 static void
09545 make_insn_alts_attr (void)
09546 {
09547 int i, insn_num;
09548 decl_t decl;
09549 rtx condexp;
09550
09551 condexp = rtx_alloc (COND);
09552 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
09553 XEXP (condexp, 1) = make_numeric_value (0);
09554 for (i = insn_num = 0; i < description->decls_num; i++)
09555 {
09556 decl = description->decls [i];
09557 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
09558 {
09559 XVECEXP (condexp, 0, 2 * insn_num)
09560 = DECL_INSN_RESERV (decl)->condexp;
09561 XVECEXP (condexp, 0, 2 * insn_num + 1)
09562 = make_numeric_value
09563 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
09564 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
09565 ->transformed_regexp)->regexps_num);
09566 insn_num++;
09567 }
09568 }
09569 gcc_assert (description->insns_num == insn_num + 1);
09570 make_internal_attr (attr_printf (sizeof ("*")
09571 + strlen (INSN_ALTS_FUNC_NAME) + 1,
09572 "*%s", INSN_ALTS_FUNC_NAME),
09573 condexp, ATTR_NONE);
09574 }
09575
09576
09577
09578
09579
09580 static void
09581 make_internal_dfa_insn_code_attr (void)
09582 {
09583 int i, insn_num;
09584 decl_t decl;
09585 rtx condexp;
09586
09587 condexp = rtx_alloc (COND);
09588 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
09589 XEXP (condexp, 1)
09590 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
09591 ->insn_num + 1);
09592 for (i = insn_num = 0; i < description->decls_num; i++)
09593 {
09594 decl = description->decls [i];
09595 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
09596 {
09597 XVECEXP (condexp, 0, 2 * insn_num)
09598 = DECL_INSN_RESERV (decl)->condexp;
09599 XVECEXP (condexp, 0, 2 * insn_num + 1)
09600 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
09601 insn_num++;
09602 }
09603 }
09604 gcc_assert (description->insns_num == insn_num + 1);
09605 make_internal_attr
09606 (attr_printf (sizeof ("*")
09607 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
09608 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
09609 condexp, ATTR_STATIC);
09610 }
09611
09612
09613
09614
09615
09616 static void
09617 make_default_insn_latency_attr (void)
09618 {
09619 int i, insn_num;
09620 decl_t decl;
09621 rtx condexp;
09622
09623 condexp = rtx_alloc (COND);
09624 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
09625 XEXP (condexp, 1) = make_numeric_value (0);
09626 for (i = insn_num = 0; i < description->decls_num; i++)
09627 {
09628 decl = description->decls [i];
09629 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
09630 {
09631 XVECEXP (condexp, 0, 2 * insn_num)
09632 = DECL_INSN_RESERV (decl)->condexp;
09633 XVECEXP (condexp, 0, 2 * insn_num + 1)
09634 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
09635 insn_num++;
09636 }
09637 }
09638 gcc_assert (description->insns_num == insn_num + 1);
09639 make_internal_attr (attr_printf (sizeof ("*")
09640 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
09641 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
09642 condexp, ATTR_NONE);
09643 }
09644
09645
09646
09647
09648
09649 static void
09650 make_bypass_attr (void)
09651 {
09652 int i, bypass_insn;
09653 int bypass_insns_num = 0;
09654 decl_t decl;
09655 rtx result_rtx;
09656
09657 for (i = 0; i < description->decls_num; i++)
09658 {
09659 decl = description->decls [i];
09660 if (decl->mode == dm_insn_reserv
09661 && DECL_INSN_RESERV (decl)->condexp != NULL
09662 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
09663 bypass_insns_num++;
09664 }
09665 if (bypass_insns_num == 0)
09666 result_rtx = make_numeric_value (0);
09667 else
09668 {
09669 result_rtx = rtx_alloc (COND);
09670 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
09671 XEXP (result_rtx, 1) = make_numeric_value (0);
09672
09673 for (i = bypass_insn = 0; i < description->decls_num; i++)
09674 {
09675 decl = description->decls [i];
09676 if (decl->mode == dm_insn_reserv
09677 && DECL_INSN_RESERV (decl)->condexp != NULL
09678 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
09679 {
09680 XVECEXP (result_rtx, 0, 2 * bypass_insn)
09681 = DECL_INSN_RESERV (decl)->condexp;
09682 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
09683 = make_numeric_value (1);
09684 bypass_insn++;
09685 }
09686 }
09687 }
09688 make_internal_attr (attr_printf (sizeof ("*")
09689 + strlen (BYPASS_P_FUNC_NAME) + 1,
09690 "*%s", BYPASS_P_FUNC_NAME),
09691 result_rtx, ATTR_NONE);
09692 }
09693
09694
09695
09696
09697
09698
09699
09700
09701 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
09702
09703
09704
09705 static const char *
09706 file_name_suffix (const char *file_name)
09707 {
09708 const char *last_period;
09709
09710 for (last_period = NULL; *file_name != '\0'; file_name++)
09711 if (*file_name == '.')
09712 last_period = file_name;
09713 return (last_period == NULL ? file_name : last_period);
09714 }
09715
09716
09717
09718
09719
09720 static const char *
09721 base_file_name (const char *file_name)
09722 {
09723 int directory_name_length;
09724
09725 directory_name_length = strlen (file_name);
09726 #ifdef WIN32
09727 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
09728 && file_name[directory_name_length] != '\\')
09729 #else
09730 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
09731 #endif
09732 directory_name_length--;
09733 return file_name + directory_name_length + 1;
09734 }
09735
09736
09737
09738 void
09739 initiate_automaton_gen (int argc, char **argv)
09740 {
09741 const char *base_name;
09742 int i;
09743
09744 ndfa_flag = 0;
09745 split_argument = 0;
09746 no_minimization_flag = 0;
09747 time_flag = 0;
09748 v_flag = 0;
09749 w_flag = 0;
09750 progress_flag = 0;
09751 for (i = 2; i < argc; i++)
09752 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
09753 no_minimization_flag = 1;
09754 else if (strcmp (argv [i], TIME_OPTION) == 0)
09755 time_flag = 1;
09756 else if (strcmp (argv [i], V_OPTION) == 0)
09757 v_flag = 1;
09758 else if (strcmp (argv [i], W_OPTION) == 0)
09759 w_flag = 1;
09760 else if (strcmp (argv [i], NDFA_OPTION) == 0)
09761 ndfa_flag = 1;
09762 else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
09763 progress_flag = 1;
09764 else if (strcmp (argv [i], "-split") == 0)
09765 {
09766 if (i + 1 >= argc)
09767 fatal ("-split has no argument.");
09768 fatal ("option `-split' has not been implemented yet\n");
09769
09770 }
09771 VLA_PTR_CREATE (decls, 150, "decls");
09772
09773 obstack_init (&irp);
09774 initiate_automaton_decl_table ();
09775 initiate_insn_decl_table ();
09776 initiate_decl_table ();
09777 output_file = stdout;
09778 output_description_file = NULL;
09779 base_name = base_file_name (argv[1]);
09780 obstack_grow (&irp, base_name,
09781 strlen (base_name) - strlen (file_name_suffix (base_name)));
09782 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
09783 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
09784 obstack_1grow (&irp, '\0');
09785 output_description_file_name = obstack_base (&irp);
09786 obstack_finish (&irp);
09787 }
09788
09789
09790
09791 static void
09792 check_automata_insn_issues (void)
09793 {
09794 automaton_t automaton;
09795 ainsn_t ainsn, reserv_ainsn;
09796
09797 for (automaton = description->first_automaton;
09798 automaton != NULL;
09799 automaton = automaton->next_automaton)
09800 {
09801 for (ainsn = automaton->ainsn_list;
09802 ainsn != NULL;
09803 ainsn = ainsn->next_ainsn)
09804 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
09805 {
09806 for (reserv_ainsn = ainsn;
09807 reserv_ainsn != NULL;
09808 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
09809 if (automaton->corresponding_automaton_decl != NULL)
09810 {
09811 if (!w_flag)
09812 error ("Automaton `%s': Insn `%s' will never be issued",
09813 automaton->corresponding_automaton_decl->name,
09814 reserv_ainsn->insn_reserv_decl->name);
09815 else
09816 warning
09817 ("Automaton `%s': Insn `%s' will never be issued",
09818 automaton->corresponding_automaton_decl->name,
09819 reserv_ainsn->insn_reserv_decl->name);
09820 }
09821 else
09822 {
09823 if (!w_flag)
09824 error ("Insn `%s' will never be issued",
09825 reserv_ainsn->insn_reserv_decl->name);
09826 else
09827 warning ("Insn `%s' will never be issued",
09828 reserv_ainsn->insn_reserv_decl->name);
09829 }
09830 }
09831 }
09832 }
09833
09834
09835
09836 static vla_ptr_t automaton_states;
09837
09838
09839
09840 static void
09841 add_automaton_state (state_t state)
09842 {
09843 VLA_PTR_ADD (automaton_states, state);
09844 }
09845
09846
09847
09848 static void
09849 form_important_insn_automata_lists (void)
09850 {
09851 automaton_t automaton;
09852 state_t *state_ptr;
09853 decl_t decl;
09854 ainsn_t ainsn;
09855 arc_t arc;
09856 int i;
09857
09858 VLA_PTR_CREATE (automaton_states, 1500,
09859 "automaton states for forming important insn automata sets");
09860
09861 for (automaton = description->first_automaton;
09862 automaton != NULL;
09863 automaton = automaton->next_automaton)
09864 {
09865 VLA_PTR_NULLIFY (automaton_states);
09866 pass_states (automaton, add_automaton_state);
09867 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
09868 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
09869 state_ptr++)
09870 {
09871 for (arc = first_out_arc (*state_ptr);
09872 arc != NULL;
09873 arc = next_out_arc (arc))
09874 if (arc->to_state != *state_ptr)
09875 {
09876 gcc_assert (arc->insn->first_insn_with_same_reservs);
09877 for (ainsn = arc->insn;
09878 ainsn != NULL;
09879 ainsn = ainsn->next_same_reservs_insn)
09880 ainsn->important_p = TRUE;
09881 }
09882 }
09883 }
09884 VLA_PTR_DELETE (automaton_states);
09885
09886 for (i = 0; i < description->decls_num; i++)
09887 {
09888 decl = description->decls [i];
09889 if (decl->mode == dm_insn_reserv)
09890 {
09891 automata_list_start ();
09892 for (automaton = description->first_automaton;
09893 automaton != NULL;
09894 automaton = automaton->next_automaton)
09895 for (ainsn = automaton->ainsn_list;
09896 ainsn != NULL;
09897 ainsn = ainsn->next_ainsn)
09898 if (ainsn->important_p
09899 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
09900 {
09901 automata_list_add (automaton);
09902 break;
09903 }
09904 DECL_INSN_RESERV (decl)->important_automata_list
09905 = automata_list_finish ();
09906 }
09907 }
09908 }
09909
09910
09911
09912
09913 void
09914 expand_automata (void)
09915 {
09916 int i;
09917
09918 description = create_node (sizeof (struct description)
09919
09920 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
09921 description->decls_num = VLA_PTR_LENGTH (decls);
09922 description->query_units_num = 0;
09923 for (i = 0; i < description->decls_num; i++)
09924 {
09925 description->decls [i] = VLA_PTR (decls, i);
09926 if (description->decls [i]->mode == dm_unit
09927 && DECL_UNIT (description->decls [i])->query_p)
09928 DECL_UNIT (description->decls [i])->query_num
09929 = description->query_units_num++;
09930 }
09931 all_time = create_ticker ();
09932 check_time = create_ticker ();
09933 if (progress_flag)
09934 fprintf (stderr, "Check description...");
09935 check_all_description ();
09936 if (progress_flag)
09937 fprintf (stderr, "done\n");
09938 ticker_off (&check_time);
09939 generation_time = create_ticker ();
09940 if (!have_error)
09941 {
09942 transform_insn_regexps ();
09943 check_unit_distributions_to_automata ();
09944 }
09945 if (!have_error)
09946 {
09947 generate ();
09948 check_automata_insn_issues ();
09949 }
09950 if (!have_error)
09951 {
09952 form_important_insn_automata_lists ();
09953 if (progress_flag)
09954 fprintf (stderr, "Generation of attributes...");
09955 make_internal_dfa_insn_code_attr ();
09956 make_insn_alts_attr ();
09957 make_default_insn_latency_attr ();
09958 make_bypass_attr ();
09959 if (progress_flag)
09960 fprintf (stderr, "done\n");
09961 }
09962 ticker_off (&generation_time);
09963 ticker_off (&all_time);
09964 if (progress_flag)
09965 fprintf (stderr, "All other genattrtab stuff...");
09966 }
09967
09968
09969
09970 void
09971 write_automata (void)
09972 {
09973 if (progress_flag)
09974 fprintf (stderr, "done\n");
09975 if (have_error)
09976 fatal ("Errors in DFA description");
09977 ticker_on (&all_time);
09978 output_time = create_ticker ();
09979 if (progress_flag)
09980 fprintf (stderr, "Forming and outputting automata tables...");
09981 output_dfa_max_issue_rate ();
09982 output_tables ();
09983 if (progress_flag)
09984 {
09985 fprintf (stderr, "done\n");
09986 fprintf (stderr, "Output functions to work with automata...");
09987 }
09988 output_chip_definitions ();
09989 output_max_insn_queue_index_def ();
09990 output_internal_min_issue_delay_func ();
09991 output_internal_trans_func ();
09992
09993 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
09994 fprintf (output_file, "\nstatic int %s;\n\n",
09995 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
09996 output_dfa_insn_code_func ();
09997 output_trans_func ();
09998 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
09999 output_internal_state_alts_func ();
10000 output_state_alts_func ();
10001 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10002 AUTOMATON_STATE_ALTS_MACRO_NAME);
10003 output_min_issue_delay_func ();
10004 output_internal_dead_lock_func ();
10005 output_dead_lock_func ();
10006 output_size_func ();
10007 output_internal_reset_func ();
10008 output_reset_func ();
10009 output_min_insn_conflict_delay_func ();
10010 output_internal_insn_latency_func ();
10011 output_insn_latency_func ();
10012 output_print_reservation_func ();
10013
10014 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10015 output_get_cpu_unit_code_func ();
10016 output_cpu_unit_reservation_p ();
10017 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10018 CPU_UNITS_QUERY_MACRO_NAME);
10019 output_dfa_clean_insn_cache_func ();
10020 output_dfa_start_func ();
10021 output_dfa_finish_func ();
10022 if (progress_flag)
10023 fprintf (stderr, "done\n");
10024 if (v_flag)
10025 {
10026 output_description_file = fopen (output_description_file_name, "w");
10027 if (output_description_file == NULL)
10028 {
10029 perror (output_description_file_name);
10030 exit (FATAL_EXIT_CODE);
10031 }
10032 if (progress_flag)
10033 fprintf (stderr, "Output automata description...");
10034 output_description ();
10035 output_automaton_descriptions ();
10036 if (progress_flag)
10037 fprintf (stderr, "done\n");
10038 output_statistics (output_description_file);
10039 }
10040 output_statistics (stderr);
10041 ticker_off (&output_time);
10042 output_time_statistics (stderr);
10043 finish_states ();
10044 finish_arcs ();
10045 finish_automata_lists ();
10046 if (time_flag)
10047 {
10048 fprintf (stderr, "Summary:\n");
10049 fprintf (stderr, " check time ");
10050 print_active_time (stderr, check_time);
10051 fprintf (stderr, ", generation time ");
10052 print_active_time (stderr, generation_time);
10053 fprintf (stderr, ", all time ");
10054 print_active_time (stderr, all_time);
10055 fprintf (stderr, "\n");
10056 }
10057
10058 if (output_description_file != NULL)
10059 {
10060 fflush (output_description_file);
10061 if (ferror (stdout) != 0)
10062 fatal ("Error in writing DFA description file %s",
10063 output_description_file_name);
10064 fclose (output_description_file);
10065 }
10066 finish_automaton_decl_table ();
10067 finish_insn_decl_table ();
10068 finish_decl_table ();
10069 obstack_free (&irp, NULL);
10070 if (have_error && output_description_file != NULL)
10071 remove (output_description_file_name);
10072 }