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;