From b35eefd94da934283ed01242569976919aa3a6ee Mon Sep 17 00:00:00 2001 From: vmakarov Date: Sun, 5 May 2002 17:40:16 +0000 Subject: [PATCH] 2002-05-05 Vladimir Makarov * genautomata.c (form_the_same_automaton_unit_lists_from_regexp, process_unit_to_form_the_same_automaton_unit_lists, form_the_same_automaton_unit_lists check_unit_distributions_to_automata): New prototypes and functions. (check_automata): Rename it into `check_automata_insn_issues'. (unit_decl): New fields `the_same_automaton_unit' and `the_same_automaton_message_reported_p'. (unit_decl_t): New typedef. (the_same_automaton_lists): New gloval variable. (unit_regexp, unit_set_el, units_array, units_cmp, output_get_cpu_unit_code_func): Use the typedef. (evaluate_max_reserv_cycles): Increment `description->max_insn_reserv_cycles'. (initiate_states): Don't increment `max_cycles_num'. (transform_insn_regexps): Move code around transformation of regexps from `generate'. (generate): Remove call of `transform_insn_regexps'. (expand_automata): Call `transform_insn_regexps' and `check_unit_distributions_to_automata'. Check errors before `generate'. * config/sparc/ultra3.md (us3_a0, us3_a1): Move the units into automaton `ultrasparc3_1'. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53187 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 27 ++++ gcc/config/sparc/ultra3.md | 5 +- gcc/genautomata.c | 307 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 291 insertions(+), 48 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5fc92e18f91..e6f4b898630 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2002-05-05 Vladimir Makarov + + * genautomata.c (form_the_same_automaton_unit_lists_from_regexp, + process_unit_to_form_the_same_automaton_unit_lists, + form_the_same_automaton_unit_lists + check_unit_distributions_to_automata): New prototypes and + functions. + (check_automata): Rename it into `check_automata_insn_issues'. + (unit_decl): New fields `the_same_automaton_unit' and + `the_same_automaton_message_reported_p'. + (unit_decl_t): New typedef. + (the_same_automaton_lists): New gloval variable. + (unit_regexp, unit_set_el, units_array, units_cmp, + output_get_cpu_unit_code_func): Use the typedef. + (evaluate_max_reserv_cycles): Increment + `description->max_insn_reserv_cycles'. + (initiate_states): Don't increment `max_cycles_num'. + (transform_insn_regexps): Move code around transformation of + regexps from `generate'. + (generate): Remove call of `transform_insn_regexps'. + (expand_automata): Call `transform_insn_regexps' and + `check_unit_distributions_to_automata'. Check errors before + `generate'. + + * config/sparc/ultra3.md (us3_a0, us3_a1): Move the units into + automaton `ultrasparc3_1'. + 2002-05-05 Neil Booth * c-common.c (c_common_init): Set up CPP arithmetic. diff --git a/gcc/config/sparc/ultra3.md b/gcc/config/sparc/ultra3.md index 72cd33eafa4..c835096391a 100644 --- a/gcc/config/sparc/ultra3.md +++ b/gcc/config/sparc/ultra3.md @@ -26,8 +26,9 @@ (define_automaton "ultrasparc3_0,ultrasparc3_1") -(define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0") -(define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1") +(define_cpu_unit "us3_ms,us3_br,us3_fpm" "ultrasparc3_0") +(define_cpu_unit "us3_a0,us3_a1,us3_slot0,\ + us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1") (define_cpu_unit "us3_load_writeback" "ultrasparc3_1") (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)") diff --git a/gcc/genautomata.c b/gcc/genautomata.c index f39aab3df4a..3c7de309814 100644 --- a/gcc/genautomata.c +++ b/gcc/genautomata.c @@ -195,6 +195,7 @@ struct automaton; struct state_ainsn_table; /* The following typedefs are for brevity. */ +typedef struct unit_decl *unit_decl_t; typedef struct decl *decl_t; typedef struct regexp *regexp_t; typedef struct unit_set_el *unit_set_el_t; @@ -355,6 +356,12 @@ static regexp_t regexp_transform_func static regexp_t transform_regexp PARAMS ((regexp_t)); static void transform_insn_regexps PARAMS ((void)); +static void process_unit_to_form_the_same_automaton_unit_lists + PARAMS ((regexp_t, regexp_t, int)); +static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t)); +static void form_the_same_automaton_unit_lists PARAMS ((void)); +static void check_unit_distributions_to_automata PARAMS ((void)); + static int process_seq_for_forming_states PARAMS ((regexp_t, automaton_t, int)); static void finish_forming_alt_state PARAMS ((alt_state_t, @@ -507,7 +514,7 @@ static void make_default_insn_latency_attr PARAMS ((void)); static void make_bypass_attr PARAMS ((void)); static const char *file_name_suffix PARAMS ((const char *)); static const char *base_file_name PARAMS ((const char *)); -static void check_automata PARAMS ((void)); +static void check_automata_insn_issues PARAMS ((void)); static void add_automaton_state PARAMS ((state_t)); static void form_important_insn_automata_lists PARAMS ((void)); @@ -714,6 +721,15 @@ struct unit_decl /* The following field value is nonzero if the unit is used in an regexp. */ char unit_is_used; + + /* The following field value is used to form cyclic lists of units + which should be in the same automaton because the unit is + reserved not on all alternatives of a regexp on a cycle. */ + unit_decl_t the_same_automaton_unit; + /* The following field is TRUE if we already reported that the unit + is not in the same automaton. */ + int the_same_automaton_message_reported_p; + /* The following field value is order number (0, 1, ...) of given unit. */ int unit_num; @@ -847,7 +863,7 @@ struct insn_reserv_decl enters. */ int state_alts; /* The following member value is the list to automata which can be - changed by the insn issue. */ + changed by the insn issue. */ automata_list_el_t important_automata_list; /* The following member is used to process insn once for output. */ int processed_p; @@ -888,7 +904,7 @@ enum regexp_mode struct unit_regexp { char *name; - struct unit_decl *unit_decl; + unit_decl_t unit_decl; }; /* Define_reservation in a reservation. */ @@ -993,7 +1009,7 @@ struct description presence_list, absence_list. */ struct unit_set_el { - struct unit_decl *unit_decl; + unit_decl_t unit_decl; unit_set_el_t next_unit_set_el; }; @@ -1063,7 +1079,7 @@ struct state }; /* The following macro is an initial value of member - `longest_path_length' of a state. */ + `longest_path_length' of a state. */ #define UNDEFINED_LONGEST_PATH_LENGTH -1 /* Automaton arc. */ @@ -2988,6 +3004,7 @@ evaluate_max_reserv_cycles () description->max_insn_reserv_cycles = max_insn_cycles_num; } } + description->max_insn_reserv_cycles++; } /* The following function calls functions for checking all @@ -3317,7 +3334,7 @@ finish_alt_states () /* This page contains abstract data `state'. */ -/* Maximal length of reservations in cycles (> 1). */ +/* Maximal length of reservations in cycles (>= 1). */ static int max_cycles_num; /* Number of set elements (see type set_el_t) needed for @@ -3336,7 +3353,7 @@ static int els_in_reservs; static vla_ptr_t units_container; /* The start address of the array. */ -static struct unit_decl **units_array; +static unit_decl_t *units_array; /* Empty reservation of maximal length. */ static reserv_sets_t empty_reserv; @@ -3884,8 +3901,6 @@ initiate_states () units_array [decl->decl.unit.unit_num] = &decl->decl.unit; } max_cycles_num = description->max_insn_reserv_cycles; - if (max_cycles_num == 0) - max_cycles_num++; els_in_cycle_reserv = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1) / (sizeof (set_el_t) * CHAR_BIT)); @@ -4781,6 +4796,10 @@ transform_insn_regexps () decl_t decl; int i; + transform_time = create_ticker (); + add_advance_cycle_insn_decl (); + fprintf (stderr, "Reservation transformation..."); + fflush (stderr); for (i = 0; i < description->decls_num; i++) { decl = description->decls [i]; @@ -4789,6 +4808,207 @@ transform_insn_regexps () = transform_regexp (copy_insn_regexp (decl->decl.insn_reserv.regexp)); } + fprintf (stderr, "done\n"); + ticker_off (&transform_time); + fflush (stderr); +} + + + +/* The following variable is an array indexed by cycle. Each element + contains cyclic list of units which should be in the same cycle. */ +static unit_decl_t *the_same_automaton_lists; + +/* The function processes all alternative reservations on CYCLE in + given REGEXP to check the UNIT is not reserved on the all + alternatives. If it is true, the unit should be in the same + automaton with other analogous units reserved on CYCLE in given + REGEXP. */ +static void +process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle) + regexp_t unit; + regexp_t regexp; + int cycle; +{ + int i, k; + regexp_t seq, allof; + unit_decl_t unit_decl, last; + + if (regexp == NULL || regexp->mode != rm_oneof) + abort (); + unit_decl = unit->regexp.unit.unit_decl; + for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--) + { + seq = regexp->regexp.oneof.regexps [i]; + if (seq->mode == rm_sequence) + { + if (cycle >= seq->regexp.sequence.regexps_num) + break; + allof = seq->regexp.sequence.regexps [cycle]; + if (allof->mode == rm_allof) + { + for (k = 0; k < allof->regexp.allof.regexps_num; k++) + if (allof->regexp.allof.regexps [k]->mode == rm_unit + && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl + == unit_decl)) + break; + if (k >= allof->regexp.allof.regexps_num) + break; + } + else if (allof->mode == rm_unit + && allof->regexp.unit.unit_decl != unit_decl) + break; + } + else if (cycle != 0) + break; + else if (seq->mode == rm_allof) + { + for (k = 0; k < seq->regexp.allof.regexps_num; k++) + if (seq->regexp.allof.regexps [k]->mode == rm_unit + && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl + == unit_decl)) + break; + if (k >= seq->regexp.allof.regexps_num) + break; + } + else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl) + break; + } + if (i >= 0) + { + if (the_same_automaton_lists [cycle] == NULL) + the_same_automaton_lists [cycle] = unit_decl; + else + { + for (last = the_same_automaton_lists [cycle];;) + { + if (last == unit_decl) + return; + if (last->the_same_automaton_unit + == the_same_automaton_lists [cycle]) + break; + last = last->the_same_automaton_unit; + } + last->the_same_automaton_unit = unit_decl->the_same_automaton_unit; + unit_decl->the_same_automaton_unit + = the_same_automaton_lists [cycle]; + } + } +} + +/* The function processes given REGEXP to find units which should be + in the same automaton. */ +static void +form_the_same_automaton_unit_lists_from_regexp (regexp) + regexp_t regexp; +{ + int i, j, k; + regexp_t seq, allof, unit; + + if (regexp == NULL || regexp->mode != rm_oneof) + return; + for (i = 0; i < description->max_insn_reserv_cycles; i++) + the_same_automaton_lists [i] = NULL; + for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--) + { + seq = regexp->regexp.oneof.regexps [i]; + if (seq->mode == rm_sequence) + for (j = 0; j < seq->regexp.sequence.regexps_num; j++) + { + allof = seq->regexp.sequence.regexps [j]; + if (allof->mode == rm_allof) + for (k = 0; k < allof->regexp.allof.regexps_num; k++) + { + unit = allof->regexp.allof.regexps [k]; + if (unit->mode == rm_unit) + process_unit_to_form_the_same_automaton_unit_lists + (unit, regexp, j); + else if (allof->mode != rm_nothing) + abort (); + } + else if (allof->mode == rm_unit) + process_unit_to_form_the_same_automaton_unit_lists + (allof, regexp, j); + else if (allof->mode != rm_nothing) + abort (); + } + else if (seq->mode == rm_allof) + for (k = 0; k < seq->regexp.allof.regexps_num; k++) + { + unit = seq->regexp.allof.regexps [k]; + if (unit->mode == rm_unit) + process_unit_to_form_the_same_automaton_unit_lists + (unit, regexp, 0); + else if (unit->mode != rm_nothing) + abort (); + } + else if (seq->mode == rm_unit) + process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0); + else if (seq->mode != rm_nothing) + abort (); + } +} + +/* The function initializes data to search for units which should be + in the same automaton and call function + `form_the_same_automaton_unit_lists_from_regexp' for each insn + reservation regexp. */ +static void +form_the_same_automaton_unit_lists () +{ + decl_t decl; + int i; + + the_same_automaton_lists + = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles + * sizeof (unit_decl_t)); + for (i = 0; i < description->decls_num; i++) + { + decl = description->decls [i]; + if (decl->mode == dm_unit) + { + decl->decl.unit.the_same_automaton_message_reported_p = FALSE; + decl->decl.unit.the_same_automaton_unit = &decl->decl.unit; + } + } + for (i = 0; i < description->decls_num; i++) + { + decl = description->decls [i]; + if (decl->mode == dm_insn_reserv) + form_the_same_automaton_unit_lists_from_regexp + (decl->decl.insn_reserv.transformed_regexp); + } + free (the_same_automaton_lists); +} + +/* The function finds units which should be in the same automaton and, + if they are not, reports about it. */ +static void +check_unit_distributions_to_automata () +{ + decl_t decl; + unit_decl_t start_unit_decl, unit_decl; + int i; + + form_the_same_automaton_unit_lists (); + for (i = 0; i < description->decls_num; i++) + { + decl = description->decls [i]; + if (decl->mode == dm_unit) + { + start_unit_decl = &decl->decl.unit; + if (!start_unit_decl->the_same_automaton_message_reported_p) + for (unit_decl = start_unit_decl->the_same_automaton_unit; + unit_decl != start_unit_decl; + unit_decl = unit_decl->the_same_automaton_unit) + if (start_unit_decl->automaton_decl != unit_decl->automaton_decl) + { + error ("Units `%s' and `%s' should be in the same automaton", + start_unit_decl->name, unit_decl->name); + unit_decl->the_same_automaton_message_reported_p = TRUE; + } + } + } } @@ -5400,7 +5620,7 @@ init_equiv_class (states, states_num) removing nonequivalent states and placing them in *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans assigns it to the state equivalence number. If the class has been - partitioned, the function returns nonzero value. */ + partitioned, the function returns nonzero value. */ static int partition_equiv_class (equiv_class_ptr, odd_iteration_flag, next_iteration_classes, new_equiv_class_num_ptr) @@ -6286,7 +6506,7 @@ longest_path_length (state) result = 0; for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - /* Ignore cycles containing one state and `cycle advance' arcs. */ + /* Ignore cycles containing one state and `cycle advance' arcs. */ if (arc->to_state != state && (arc->insn->insn_reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)) @@ -6305,7 +6525,7 @@ longest_path_length (state) static int max_dfa_issue_rate; /* The following function processes the longest path length staring - from STATE to find MAX_DFA_ISSUE_RATE. */ + from STATE to find MAX_DFA_ISSUE_RATE. */ static void process_state_longest_path_length (state) @@ -6592,7 +6812,7 @@ output_reserved_units_table_name (f, automaton) /* Name of cache of insn dfa codes. */ #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes" -/* Name of length of cache of insn dfa codes. */ +/* Name of length of cache of insn dfa codes. */ #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length" /* Names of the PHR interface functions: */ @@ -7128,7 +7348,7 @@ min_issue_delay_pass_states (state, ainsn) if (state->state_pass_num == curr_state_pass_num || state->min_insn_issue_delay != -1) /* We've entered into a loop or already have the correct value for - given state and ainsn. */ + given state and ainsn. */ return state->min_insn_issue_delay; state->state_pass_num = curr_state_pass_num; min_insn_issue_delay = -1; @@ -8072,8 +8292,8 @@ static int units_cmp (unit1, unit2) const void *unit1, *unit2; { - const struct unit_decl *u1 = *(struct unit_decl **) unit1; - const struct unit_decl *u2 = *(struct unit_decl **) unit2; + const unit_decl_t u1 = *(unit_decl_t *) unit1; + const unit_decl_t u2 = *(unit_decl_t *) unit2; return strcmp (u1->name, u2->name); } @@ -8102,7 +8322,7 @@ static void output_get_cpu_unit_code_func () { int i; - struct unit_decl **units; + unit_decl_t *units; fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n", GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME, @@ -8113,12 +8333,10 @@ output_get_cpu_unit_code_func () LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME); fprintf (output_file, " static struct %s %s [] =\n {\n", NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME); - units = (struct unit_decl **) xmalloc (sizeof (struct unit_decl *) - * description->units_num); - memcpy (units, units_array, - sizeof (struct unit_decl *) * description->units_num); - qsort (units, description->units_num, - sizeof (struct unit_decl *), units_cmp); + units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t) + * description->units_num); + memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num); + qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp); for (i = 0; i < description->units_num; i++) if (units [i]->query_p) fprintf (output_file, " {\"%s\", %d},\n", @@ -8636,14 +8854,6 @@ generate () initiate_excl_sets (); initiate_presence_absence_sets (); automaton_generation_time = create_ticker (); - transform_time = create_ticker (); - add_advance_cycle_insn_decl (); - fprintf (stderr, "Reservation transformation..."); - fflush (stderr); - transform_insn_regexps (); - fprintf (stderr, "done\n"); - ticker_off (&transform_time); - fflush (stderr); create_automata (); ticker_off (&automaton_generation_time); } @@ -8898,7 +9108,7 @@ initiate_automaton_gen (argc, argv) /* The following function checks existence at least one arc marked by each insn. */ static void -check_automata () +check_automata_insn_issues () { automaton_t automaton; ainsn_t ainsn, reserv_ainsn; @@ -8967,7 +9177,7 @@ form_important_insn_automata_lists () VLA_PTR_CREATE (automaton_states, 1500, "automaton states for forming important insn automata sets"); - /* Mark important ainsns. */ + /* Mark important ainsns. */ for (automaton = description->first_automaton; automaton != NULL; automaton = automaton->next_automaton) @@ -8993,7 +9203,7 @@ form_important_insn_automata_lists () } } VLA_PTR_DELETE (automaton_states); - /* Create automata sets for the insns. */ + /* Create automata sets for the insns. */ for (i = 0; i < description->decls_num; i++) { decl = description->decls [i]; @@ -9049,19 +9259,24 @@ expand_automata () generation_time = create_ticker (); if (!have_error) { + transform_insn_regexps (); + check_unit_distributions_to_automata (); + } + if (!have_error) + { generate (); - check_automata (); - if (!have_error) - { - form_important_insn_automata_lists (); - fprintf (stderr, "Generation of attributes..."); - fflush (stderr); - make_internal_dfa_insn_code_attr (); - make_insn_alts_attr (); - make_default_insn_latency_attr (); - make_bypass_attr (); - fprintf (stderr, "done\n"); - } + check_automata_insn_issues (); + } + if (!have_error) + { + form_important_insn_automata_lists (); + fprintf (stderr, "Generation of attributes..."); + fflush (stderr); + make_internal_dfa_insn_code_attr (); + make_insn_alts_attr (); + make_default_insn_latency_attr (); + make_bypass_attr (); + fprintf (stderr, "done\n"); } ticker_off (&generation_time); ticker_off (&all_time); -- 2.11.4.GIT