aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog40
-rw-r--r--gcc/doc/md.texi10
-rw-r--r--gcc/genautomata.c170
3 files changed, 174 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d7e75a..25547664 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,43 @@
+2011-08-25 Bernd Schmidt <bernds@codesourcery.com>
+
+ * doc/md.texi (automata_option): Document collapse-ndfa.
+ * genautomata.c (COLLAPSE_OPTION): New macro.
+ (collapse_flag): New static variable.
+ (struct description): New member normal_decls_num.
+ (struct automaton): New members advance_ainsn and collapse_ainsn.
+ (gen_automata_option): Check for COLLAPSE_OPTION.
+ (collapse_ndfa_insn_decl): New static variable.
+ (add_collapse_ndfa_insn_decl, special_decl_p): New functions.
+ (find_arc): If insn is the collapse-ndfa insn, accept any arc we
+ find.
+ (transform_insn_regexps): Call add_collapse_ndfa_insn_decl if
+ necessary. Use normal_decls_num rather than decls_num, remove
+ test for special decls.
+ (create_alt_states, form_ainsn_with_same_reservs): Use
+ special_decl_p.
+ (make_automaton); Likewise. Use the new advance_cycle_insn member
+ of struct automaton.
+ (create_composed_state): Disallow advance-cycle arcs if collapse_flag
+ is set.
+ (NDFA_to_DFA): Don't create composed states for the collapse-ndfa
+ transition. Create the necessary transitions for it.
+ (create_ainsns): Return void. Take an automaton_t argument, and
+ update its ainsn_list, advance_ainsn and collapse_ainsn members. All
+ callers changed.
+ (COLLAPSE_NDFA_VALUE_NAME): New macro.
+ (output_tables): Output code to define it.
+ (output_internal_insn_code_evaluation): Output code to accept
+ const0_rtx as collapse-ndfa transition.
+ (output_default_latencies, output_print_reservation_func,
+ output_print_description): Reorganize loops to use normal_decls_num
+ as loop bound; remove special case for advance_cycle_insn_decl.
+ (initiate_automaton_gen): Handle COLLAPSE_OPTION.
+ (check_automata_insn_issues): Check for collapse_ainsn.
+ (expand_automate): Allocate sufficient space. Initialize
+ normal_decls_num.
+
2011-08-25 Georg-Johann Lay <avr@gjlay.de>
-
+
* config/avr/avr.md: Fix indentation from r177991.
2011-08-25 Bernd Schmidt <bernds@codesourcery.com>
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 0bd9ecd..da5b799 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7962,6 +7962,16 @@ nondeterministic treatment means trying all alternatives, some of them
may be rejected by reservations in the subsequent insns.
@item
+@dfn{collapse-ndfa} modifies the behaviour of the generator when
+producing an automaton. An additional state transition to collapse a
+nondeterministic @acronym{NDFA} state to a deterministic @acronym{DFA}
+state is generated. It can be triggered by passing @code{const0_rtx} to
+state_transition. In such an automaton, cycle advance transitions are
+available only for these collapsed states. This option is useful for
+ports that want to use the @code{ndfa} option, but also want to use
+@code{define_query_cpu_unit} to assign units to insns issued in a cycle.
+
+@item
@dfn{progress} means output of a progress bar showing how many states
were generated so far for automaton being processed. This is useful
during debugging a @acronym{DFA} description. If you see too many
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index e5260fa..d614e3a 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -252,6 +252,7 @@ static arc_t next_out_arc (arc_t);
#define V_OPTION "-v"
#define W_OPTION "-w"
#define NDFA_OPTION "-ndfa"
+#define COLLAPSE_OPTION "-collapse-ndfa"
#define PROGRESS_OPTION "-progress"
/* The following flags are set up by function `initiate_automaton_gen'. */
@@ -259,6 +260,11 @@ static arc_t next_out_arc (arc_t);
/* Make automata with nondeterministic reservation by insns (`-ndfa'). */
static int ndfa_flag;
+/* When making an NDFA, produce additional transitions that collapse
+ NDFA state into a deterministic one suitable for querying CPU units.
+ Provide avance-state transitions only for deterministic states. */
+static int collapse_flag;
+
/* Do not make minimization of DFA (`-no-minimization'). */
static int no_minimization_flag;
@@ -604,7 +610,7 @@ struct regexp
NDFA. */
struct description
{
- int decls_num;
+ int decls_num, normal_decls_num;
/* The following fields are defined by checker. */
@@ -624,9 +630,8 @@ struct description
automaton_t first_automaton;
/* The following field is created by pipeline hazard parser and
- contains all declarations. We allocate additional entry for
- special insn "cycle advancing" which is added by the automaton
- generator. */
+ contains all declarations. We allocate additional entries for
+ two special insns which are added by the automaton generator. */
decl_t decls [1];
};
@@ -811,6 +816,9 @@ struct automaton
/* The following field value is the list of insn declarations for
given automaton. */
ainsn_t ainsn_list;
+ /* Pointers to the ainsns corresponding to the special reservations. */
+ ainsn_t advance_ainsn, collapse_ainsn;
+
/* The following field value is the corresponding automaton
declaration. This field is not NULL only if the automatic
partition on automata is not used. */
@@ -1529,6 +1537,8 @@ gen_automata_option (rtx def)
w_flag = 1;
else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
ndfa_flag = 1;
+ else if (strcmp (XSTR (def, 0), COLLAPSE_OPTION + 1) == 0)
+ collapse_flag = 1;
else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
progress_flag = 1;
else
@@ -3202,6 +3212,10 @@ static ticker_t all_time;
/* Pseudo insn decl which denotes advancing cycle. */
static decl_t advance_cycle_insn_decl;
+/* Pseudo insn decl which denotes collapsing the NDFA state. */
+static decl_t collapse_ndfa_insn_decl;
+
+/* Create and record a decl for the special advance-cycle transition. */
static void
add_advance_cycle_insn_decl (void)
{
@@ -3217,6 +3231,31 @@ add_advance_cycle_insn_decl (void)
description->insns_num++;
}
+/* Create and record a decl for the special collapse-NDFA transition. */
+static void
+add_collapse_ndfa_insn_decl (void)
+{
+ collapse_ndfa_insn_decl = XCREATENODE (struct decl);
+ collapse_ndfa_insn_decl->mode = dm_insn_reserv;
+ collapse_ndfa_insn_decl->pos = no_pos;
+ DECL_INSN_RESERV (collapse_ndfa_insn_decl)->regexp = NULL;
+ DECL_INSN_RESERV (collapse_ndfa_insn_decl)->name = "$collapse_ndfa";
+ DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num
+ = description->insns_num;
+ description->decls [description->decls_num] = collapse_ndfa_insn_decl;
+ description->decls_num++;
+ description->insns_num++;
+}
+
+/* True if DECL is either of the two special decls we created. */
+static bool
+special_decl_p (struct insn_reserv_decl *decl)
+{
+ return (decl == DECL_INSN_RESERV (advance_cycle_insn_decl)
+ || (collapse_flag
+ && decl == DECL_INSN_RESERV (collapse_ndfa_insn_decl)));
+}
+
/* Abstract data `alternative states' which represents
nondeterministic nature of the description (see comments for
@@ -3971,7 +4010,12 @@ find_arc (state_t from_state, state_t to_state, ainsn_t insn)
arc_t arc;
for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
- if (arc->to_state == to_state && arc->insn == insn)
+ if (arc->insn == insn
+ && (arc->to_state == to_state
+ || (collapse_flag
+ /* Any arc is good enough for a collapse-ndfa transition. */
+ && (insn->insn_reserv_decl
+ == DECL_INSN_RESERV (collapse_ndfa_insn_decl)))))
return arc;
return NULL;
}
@@ -4956,12 +5000,14 @@ transform_insn_regexps (void)
transform_time = create_ticker ();
add_advance_cycle_insn_decl ();
+ if (collapse_flag)
+ add_collapse_ndfa_insn_decl ();
if (progress_flag)
fprintf (stderr, "Reservation transformation...");
- for (i = 0; i < description->decls_num; i++)
+ for (i = 0; i < description->normal_decls_num; i++)
{
decl = description->decls [i];
- if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+ if (decl->mode == dm_insn_reserv)
DECL_INSN_RESERV (decl)->transformed_regexp
= transform_regexp (copy_insn_regexp
(DECL_INSN_RESERV (decl)->regexp));
@@ -5432,7 +5478,7 @@ create_alt_states (automaton_t automaton)
curr_ainsn = curr_ainsn->next_ainsn)
{
reserv_decl = curr_ainsn->insn_reserv_decl;
- if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
+ if (!special_decl_p (reserv_decl))
{
curr_ainsn->alt_states = NULL;
process_alts_for_forming_states (reserv_decl->transformed_regexp,
@@ -5461,8 +5507,7 @@ form_ainsn_with_same_reservs (automaton_t automaton)
for (curr_ainsn = automaton->ainsn_list;
curr_ainsn != NULL;
curr_ainsn = curr_ainsn->next_ainsn)
- if (curr_ainsn->insn_reserv_decl
- == DECL_INSN_RESERV (advance_cycle_insn_decl))
+ if (special_decl_p (curr_ainsn->insn_reserv_decl))
{
curr_ainsn->next_same_reservs_insn = NULL;
curr_ainsn->first_insn_with_same_reservs = 1;
@@ -5530,7 +5575,6 @@ make_automaton (automaton_t automaton)
state_t state;
state_t start_state;
state_t state2;
- ainsn_t advance_cycle_ainsn;
VEC(state_t, heap) *state_stack = VEC_alloc(state_t, heap, 150);
int states_n;
reserv_sets_t reservs_matter = form_reservs_matter (automaton);
@@ -5544,14 +5588,13 @@ make_automaton (automaton_t automaton)
while (VEC_length (state_t, state_stack) != 0)
{
state = VEC_pop (state_t, state_stack);
- advance_cycle_ainsn = NULL;
for (ainsn = automaton->ainsn_list;
ainsn != NULL;
ainsn = ainsn->next_ainsn)
if (ainsn->first_insn_with_same_reservs)
{
insn_reserv_decl = ainsn->insn_reserv_decl;
- if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
+ if (!special_decl_p (insn_reserv_decl))
{
/* We process alt_states in the same order as they are
present in the description. */
@@ -5578,8 +5621,6 @@ make_automaton (automaton_t automaton)
}
}
}
- else
- advance_cycle_ainsn = ainsn;
}
/* Add transition to advance cycle. */
state2 = state_shift (state, reservs_matter);
@@ -5591,8 +5632,7 @@ make_automaton (automaton_t automaton)
if (progress_flag && states_n % 100 == 0)
fprintf (stderr, ".");
}
- gcc_assert (advance_cycle_ainsn);
- add_arc (state, state2, advance_cycle_ainsn);
+ add_arc (state, state2, automaton->advance_ainsn);
}
VEC_free (state_t, heap, state_stack);
}
@@ -5700,7 +5740,13 @@ create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
for (curr_arc = first_out_arc (curr_alt_state->state);
curr_arc != NULL;
curr_arc = next_out_arc (curr_arc))
- add_arc (state, curr_arc->to_state, curr_arc->insn);
+ if (!collapse_flag
+ /* When producing collapse-NDFA transitions, we
+ only add advance-cycle transitions to the
+ collapsed states. */
+ || (curr_arc->insn->insn_reserv_decl
+ != DECL_INSN_RESERV (advance_cycle_insn_decl)))
+ add_arc (state, curr_arc->to_state, curr_arc->insn);
}
arcs_marked_by_insn->to_state = state;
for (alts_number = 0,
@@ -5750,6 +5796,7 @@ NDFA_to_DFA (automaton_t automaton)
{
decl = description->decls [i];
if (decl->mode == dm_insn_reserv
+ && decl != collapse_ndfa_insn_decl
&& create_composed_state
(state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
&state_stack))
@@ -5759,6 +5806,22 @@ NDFA_to_DFA (automaton_t automaton)
fprintf (stderr, ".");
}
}
+ /* Add a transition to collapse the NDFA. */
+ if (collapse_flag)
+ {
+ if (state->component_states != NULL)
+ {
+ state_t state2 = state->component_states->state;
+ if (!state2->it_was_placed_in_stack_for_DFA_forming)
+ {
+ state2->it_was_placed_in_stack_for_DFA_forming = 1;
+ VEC_safe_push (state_t, heap, state_stack, state2);
+ }
+ add_arc (state, state2, automaton->collapse_ainsn);
+ }
+ else
+ add_arc (state, state, automaton->collapse_ainsn);
+ }
}
VEC_free (state_t, heap, state_stack);
}
@@ -5814,8 +5877,7 @@ add_achieved_state (state_t state)
/* The function sets up equivalence numbers of insns which mark all
out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
- nonzero value) or by equiv_class_num_2 of the destination state.
- The function returns number of out arcs of STATE. */
+ nonzero value) or by equiv_class_num_2 of the destination state. */
static void
set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
{
@@ -6583,8 +6645,8 @@ units_to_automata_heuristic_distr (void)
/* The functions creates automaton insns for each automata. Automaton
insn is simply insn for given automaton which makes reservation
only of units of the automaton. */
-static ainsn_t
-create_ainsns (void)
+static void
+create_ainsns (automaton_t automaton)
{
decl_t decl;
ainsn_t first_ainsn;
@@ -6607,10 +6669,14 @@ create_ainsns (void)
first_ainsn = curr_ainsn;
else
prev_ainsn->next_ainsn = curr_ainsn;
+ if (decl == advance_cycle_insn_decl)
+ automaton->advance_ainsn = curr_ainsn;
+ else if (decl == collapse_ndfa_insn_decl)
+ automaton->collapse_ainsn = curr_ainsn;
prev_ainsn = curr_ainsn;
}
}
- return first_ainsn;
+ automaton->ainsn_list = first_ainsn;
}
/* The function assigns automata to units according to constructions
@@ -6658,7 +6724,7 @@ create_automata (void)
curr_automaton_num++, prev_automaton = curr_automaton)
{
curr_automaton = XCREATENODE (struct automaton);
- curr_automaton->ainsn_list = create_ainsns ();
+ create_ainsns (curr_automaton);
curr_automaton->corresponding_automaton_decl = NULL;
curr_automaton->next_automaton = NULL;
curr_automaton->automaton_order_num = curr_automaton_num;
@@ -6679,7 +6745,7 @@ create_automata (void)
&& DECL_AUTOMATON (decl)->automaton_is_used)
{
curr_automaton = XCREATENODE (struct automaton);
- curr_automaton->ainsn_list = create_ainsns ();
+ create_ainsns (curr_automaton);
curr_automaton->corresponding_automaton_decl
= DECL_AUTOMATON (decl);
curr_automaton->next_automaton = NULL;
@@ -6696,7 +6762,7 @@ create_automata (void)
if (curr_automaton_num == 0)
{
curr_automaton = XCREATENODE (struct automaton);
- curr_automaton->ainsn_list = create_ainsns ();
+ create_ainsns (curr_automaton);
curr_automaton->corresponding_automaton_decl = NULL;
curr_automaton->next_automaton = NULL;
description->first_automaton = curr_automaton;
@@ -6925,10 +6991,11 @@ output_temp_chip_member_name (FILE *f, automaton_t automaton)
output_chip_member_name (f, automaton);
}
-/* This is name of macro value which is code of pseudo_insn
- representing advancing cpu cycle. Its value is used as internal
- code unknown insn. */
+/* This is name of macro value which is code of pseudo_insns
+ representing advancing cpu cycle and collapsing the NDFA.
+ Its value is used as internal code unknown insn. */
#define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
+#define COLLAPSE_NDFA_VALUE_NAME "NDFA__COLLAPSE"
/* Output name of translate vector for given automaton. */
static void
@@ -7803,6 +7870,9 @@ output_tables (void)
}
fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+ if (collapse_flag)
+ fprintf (output_file, "\n#define %s %d\n\n", COLLAPSE_NDFA_VALUE_NAME,
+ DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num);
}
/* The function outputs definition and value of PHR interface variable
@@ -8080,13 +8150,20 @@ output_internal_insn_code_evaluation (const char *insn_name,
const char *insn_code_name,
int code)
{
- fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
+ fprintf (output_file, "\n if (%s == 0)\n", insn_name);
+ fprintf (output_file, " %s = %s;\n\n",
+ insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
+ if (collapse_flag)
+ {
+ fprintf (output_file, "\n else if (%s == const0_rtx)\n", insn_name);
+ fprintf (output_file, " %s = %s;\n\n",
+ insn_code_name, COLLAPSE_NDFA_VALUE_NAME);
+ }
+ fprintf (output_file, "\n else\n {\n");
fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
DFA_INSN_CODE_FUNC_NAME, insn_name);
- fprintf (output_file, " if (%s > %s)\n return %d;\n",
+ fprintf (output_file, " if (%s > %s)\n return %d;\n }\n",
insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
- fprintf (output_file, " }\n else\n %s = %s;\n\n",
- insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
}
@@ -8287,9 +8364,8 @@ output_default_latencies (void)
fprintf (output_file, " static const %s default_latencies[] =\n {",
tabletype);
- for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
- if (description->decls[i]->mode == dm_insn_reserv
- && description->decls[i] != advance_cycle_insn_decl)
+ for (i = 0, j = 0, col = 7; i < description->normal_decls_num; i++)
+ if (description->decls[i]->mode == dm_insn_reserv)
{
if ((col = (col+1) % 8) == 0)
fputs ("\n ", output_file);
@@ -8298,7 +8374,7 @@ output_default_latencies (void)
fprintf (output_file, "% 4d,",
DECL_INSN_RESERV (decl)->default_latency);
}
- gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+ gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
fputs ("\n };\n", output_file);
}
@@ -8479,10 +8555,10 @@ output_print_reservation_func (void)
fputs (" static const char *const reservation_names[] =\n {",
output_file);
- for (i = 0, j = 0; i < description->decls_num; i++)
+ for (i = 0, j = 0; i < description->normal_decls_num; i++)
{
decl = description->decls [i];
- if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+ if (decl->mode == dm_insn_reserv)
{
gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
j++;
@@ -8492,7 +8568,7 @@ output_print_reservation_func (void)
finish_regexp_representation ();
}
}
- gcc_assert (j == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
+ gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
@@ -8802,7 +8878,7 @@ output_description (void)
}
}
fprintf (output_description_file, "\n");
- for (i = 0; i < description->decls_num; i++)
+ for (i = 0; i < description->normal_decls_num; i++)
{
decl = description->decls [i];
if (decl->mode == dm_reserv)
@@ -8812,7 +8888,7 @@ output_description (void)
output_regexp (DECL_RESERV (decl)->regexp);
fprintf (output_description_file, "\n");
}
- else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
+ else if (decl->mode == dm_insn_reserv)
{
fprintf (output_description_file, "insn reservation %s ",
DECL_INSN_RESERV (decl)->name);
@@ -9218,6 +9294,8 @@ initiate_automaton_gen (int argc, char **argv)
w_flag = 1;
else if (strcmp (argv [i], NDFA_OPTION) == 0)
ndfa_flag = 1;
+ else if (strcmp (argv [i], COLLAPSE_OPTION) == 0)
+ collapse_flag = 1;
else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
progress_flag = 1;
else if (strcmp (argv [i], "-split") == 0)
@@ -9260,7 +9338,8 @@ check_automata_insn_issues (void)
for (ainsn = automaton->ainsn_list;
ainsn != NULL;
ainsn = ainsn->next_ainsn)
- if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
+ if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p
+ && ainsn != automaton->collapse_ainsn)
{
for (reserv_ainsn = ainsn;
reserv_ainsn != NULL;
@@ -9374,9 +9453,10 @@ expand_automata (void)
description = XCREATENODEVAR (struct description,
sizeof (struct description)
- /* One entry for cycle advancing insn. */
- + sizeof (decl_t) * VEC_length (decl_t, decls));
+ /* Two entries for special insns. */
+ + sizeof (decl_t) * (VEC_length (decl_t, decls) + 1));
description->decls_num = VEC_length (decl_t, decls);
+ description->normal_decls_num = description->decls_num;
description->query_units_num = 0;
for (i = 0; i < description->decls_num; i++)
{