This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 4/5] Cache recog_op_alt by insn code: main patch
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Jeff Law <law at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 31 May 2014 10:17:04 +0100
- Subject: [PATCH 4/5] Cache recog_op_alt by insn code: main patch
- Authentication-results: sourceware.org; auth=none
- References: <87egzokglh dot fsf at talisman dot default> <537B9911 dot 7070604 at redhat dot com> <87mwdyfhhg dot fsf_-_ at talisman dot default>
This is the refreshed main patch. I've rearranged the preprocess_constraints
code into three functions so that LRA can use it in patch 5.
Thanks,
Richard
gcc/
* recog.h (operand_alternative): Convert reg_class, reject,
matched and matches into bitfields.
(preprocess_constraints): New overload.
(preprocess_insn_constraints): New function.
(preprocess_constraints): Take the insn as parameter.
(recog_op_alt): Change into a pointer.
(target_recog): Add x_op_alt.
* recog.c (asm_op_alt): New variable.
(recog_op_alt): Change into a pointer.
(preprocess_constraints): New overload, replacing the old function
definition with one that doesn't use global state.
(preprocess_insn_constraints): New function.
(preprocess_constraints): Use them. Take the insn as parameter.
Use asm_op_alt for asms.
(recog_init): Free existing x_op_alt entries.
* ira-lives.c (check_and_make_def_conflict): Make operand_alternative
pointer const.
(make_early_clobber_and_input_conflicts): Likewise.
(process_bb_node_lives): Pass the insn to process_constraints.
* reg-stack.c (check_asm_stack_operands): Likewise.
(subst_asm_stack_regs): Likewise.
* regcprop.c (copyprop_hardreg_forward_1): Likewise.
* regrename.c (build_def_use): Likewise.
* sched-deps.c (sched_analyze_insn): Likewise.
* sel-sched.c (get_reg_class, implicit_clobber_conflict_p): Likewise.
* config/arm/arm.c (xscale_sched_adjust_cost): Likewise.
(note_invalid_constants): Likewise.
* config/i386/i386.c (ix86_legitimate_combined_insn): Likewise.
(ix86_legitimate_combined_insn): Make operand_alternative pointer
const.
Index: gcc/recog.h
===================================================================
--- gcc/recog.h 2014-05-31 09:02:35.956369716 +0100
+++ gcc/recog.h 2014-05-31 09:10:16.596150618 +0100
@@ -46,18 +46,18 @@ struct operand_alternative
const char *constraint;
/* The register class valid for this alternative (possibly NO_REGS). */
- enum reg_class cl;
+ ENUM_BITFIELD (reg_class) cl : 16;
/* "Badness" of this alternative, computed from number of '?' and '!'
characters in the constraint string. */
- unsigned int reject;
+ unsigned int reject : 16;
/* -1 if no matching constraint was found, or an operand number. */
- int matches;
+ int matches : 8;
/* The same information, but reversed: -1 if this operand is not
matched by any other, or the operand number of the operand that
matches this one. */
- int matched;
+ int matched : 8;
/* Nonzero if '&' was found in the constraint string. */
unsigned int earlyclobber:1;
@@ -77,6 +77,8 @@ struct operand_alternative
/* Nonzero if 'X' was found in the constraint string, or if the constraint
string for this alternative was empty. */
unsigned int anything_ok:1;
+
+ unsigned int unused : 8;
};
/* Return the class for operand I of alternative ALT, taking matching
@@ -142,7 +144,10 @@ extern void insn_extract (rtx);
extern void extract_insn (rtx);
extern void extract_constrain_insn_cached (rtx);
extern void extract_insn_cached (rtx);
-extern void preprocess_constraints (void);
+extern void preprocess_constraints (int, int, const char **,
+ operand_alternative *);
+extern const operand_alternative *preprocess_insn_constraints (int);
+extern void preprocess_constraints (rtx);
extern rtx peep2_next_insn (int);
extern int peep2_regno_dead_p (int, int);
extern int peep2_reg_dead_p (int, rtx);
@@ -264,8 +269,7 @@ struct recog_data_d
extern struct recog_data_d recog_data;
-extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS
- * MAX_RECOG_ALTERNATIVES];
+extern const operand_alternative *recog_op_alt;
/* Return a pointer to an array in which index OP describes the constraints
on operand OP of the current instruction alternative (which_alternative).
@@ -396,6 +400,7 @@ struct insn_data_d
struct target_recog {
bool x_initialized;
alternative_mask x_enabled_alternatives[LAST_INSN_CODE];
+ operand_alternative *x_op_alt[LAST_INSN_CODE];
};
extern struct target_recog default_target_recog;
Index: gcc/recog.c
===================================================================
--- gcc/recog.c 2014-05-31 09:07:21.669714878 +0100
+++ gcc/recog.c 2014-05-31 09:15:38.746800685 +0100
@@ -81,8 +81,11 @@ struct recog_data_d recog_data;
/* Contains a vector of operand_alternative structures, such that
operand OP of alternative A is at index A * n_operands + OP.
Set up by preprocess_constraints. */
-struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS
- * MAX_RECOG_ALTERNATIVES];
+const operand_alternative *recog_op_alt;
+
+/* Used to provide recog_op_alt for asms. */
+static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
+ * MAX_RECOG_ALTERNATIVES];
/* On return from `constrain_operands', indicate which alternative
was satisfied. */
@@ -2324,26 +2327,23 @@ extract_insn (rtx insn)
which_alternative = -1;
}
-/* After calling extract_insn, you can use this function to extract some
- information from the constraint strings into a more usable form.
- The collected data is stored in recog_op_alt. */
+/* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands,
+ N_ALTERNATIVES alternatives and constraint strings CONSTRAINTS.
+ OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries and CONSTRAINTS
+ has N_OPERANDS entries. */
+
void
-preprocess_constraints (void)
+preprocess_constraints (int n_operands, int n_alternatives,
+ const char **constraints,
+ operand_alternative *op_alt_base)
{
- int i;
-
- int n_operands = recog_data.n_operands;
- int n_alternatives = recog_data.n_alternatives;
- int n_entries = n_operands * n_alternatives;
- memset (recog_op_alt, 0, n_entries * sizeof (struct operand_alternative));
-
- for (i = 0; i < n_operands; i++)
+ for (int i = 0; i < n_operands; i++)
{
int j;
struct operand_alternative *op_alt;
- const char *p = recog_data.constraints[i];
+ const char *p = constraints[i];
- op_alt = recog_op_alt;
+ op_alt = op_alt_base;
for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
{
@@ -2462,6 +2462,59 @@ preprocess_constraints (void)
}
}
+/* Return an array of operand_alternative instructions for
+ instruction ICODE. */
+
+const operand_alternative *
+preprocess_insn_constraints (int icode)
+{
+ gcc_checking_assert (IN_RANGE (icode, 0, LAST_INSN_CODE));
+ if (this_target_recog->x_op_alt[icode])
+ return this_target_recog->x_op_alt[icode];
+
+ int n_operands = insn_data[icode].n_operands;
+ if (n_operands == 0)
+ return 0;
+ /* Always provide at least one alternative so that which_op_alt ()
+ works correctly. If the instruction has 0 alternatives (i.e. all
+ constraint strings are empty) then each operand in this alternative
+ will have anything_ok set. */
+ int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
+ int n_entries = n_operands * n_alternatives;
+
+ operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
+ const char **constraints = XALLOCAVEC (const char *, n_operands);
+
+ for (int i = 0; i < n_operands; ++i)
+ constraints[i] = insn_data[icode].operand[i].constraint;
+ preprocess_constraints (n_operands, n_alternatives, constraints, op_alt);
+
+ this_target_recog->x_op_alt[icode] = op_alt;
+ return op_alt;
+}
+
+/* After calling extract_insn, you can use this function to extract some
+ information from the constraint strings into a more usable form.
+ The collected data is stored in recog_op_alt. */
+
+void
+preprocess_constraints (rtx insn)
+{
+ int icode = INSN_CODE (insn);
+ if (icode >= 0)
+ recog_op_alt = preprocess_insn_constraints (icode);
+ else
+ {
+ int n_operands = recog_data.n_operands;
+ int n_alternatives = recog_data.n_alternatives;
+ int n_entries = n_operands * n_alternatives;
+ memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
+ preprocess_constraints (n_operands, n_alternatives,
+ recog_data.constraints, asm_op_alt);
+ recog_op_alt = asm_op_alt;
+ }
+}
+
/* Check the operands of an insn against the insn's operand constraints
and return 1 if they are valid.
The information about the insn's operands, constraints, operand modes
@@ -4211,4 +4264,10 @@ recog_init ()
}
memset (this_target_recog->x_enabled_alternatives, 0,
sizeof (this_target_recog->x_enabled_alternatives));
+ for (int i = 0; i < LAST_INSN_CODE; ++i)
+ if (this_target_recog->x_op_alt[i])
+ {
+ free (this_target_recog->x_op_alt[i]);
+ this_target_recog->x_op_alt[i] = 0;
+ }
}
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c 2014-05-31 09:07:21.670714886 +0100
+++ gcc/ira-lives.c 2014-05-31 09:10:16.598150634 +0100
@@ -625,7 +625,7 @@ check_and_make_def_conflict (int alt, in
advance_p = true;
int n_operands = recog_data.n_operands;
- operand_alternative *op_alt = &recog_op_alt[alt * n_operands];
+ const operand_alternative *op_alt = &recog_op_alt[alt * n_operands];
for (use = 0; use < n_operands; use++)
{
int alt1;
@@ -646,7 +646,8 @@ check_and_make_def_conflict (int alt, in
{
if (!TEST_BIT (enabled, alt1))
continue;
- operand_alternative *op_alt1 = &recog_op_alt[alt1 * n_operands];
+ const operand_alternative *op_alt1
+ = &recog_op_alt[alt1 * n_operands];
if (op_alt1[use].matches == def
|| (use < n_operands - 1
&& recog_data.constraints[use][0] == '%'
@@ -692,7 +693,7 @@ make_early_clobber_and_input_conflicts (
int n_alternatives = recog_data.n_alternatives;
int n_operands = recog_data.n_operands;
alternative_mask enabled = recog_data.enabled_alternatives;
- operand_alternative *op_alt = recog_op_alt;
+ const operand_alternative *op_alt = recog_op_alt;
for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands)
if (TEST_BIT (enabled, alt))
for (def = 0; def < n_operands; def++)
@@ -1251,7 +1252,7 @@ process_bb_node_lives (ira_loop_tree_nod
}
extract_insn (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
process_single_reg_class_operands (false, freq);
/* See which defined values die here. */
Index: gcc/reg-stack.c
===================================================================
--- gcc/reg-stack.c 2014-05-31 09:02:35.968369814 +0100
+++ gcc/reg-stack.c 2014-05-31 09:10:16.601150659 +0100
@@ -471,7 +471,7 @@ check_asm_stack_operands (rtx insn)
extract_insn (insn);
constrain_operands (1);
- preprocess_constraints ();
+ preprocess_constraints (insn);
get_asm_operands_in_out (body, &n_outputs, &n_inputs);
@@ -2029,7 +2029,7 @@ subst_asm_stack_regs (rtx insn, stack_pt
extract_insn (insn);
constrain_operands (1);
- preprocess_constraints ();
+ preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt ();
get_asm_operands_in_out (body, &n_outputs, &n_inputs);
Index: gcc/regcprop.c
===================================================================
--- gcc/regcprop.c 2014-05-31 09:02:35.957369724 +0100
+++ gcc/regcprop.c 2014-05-31 09:10:16.601150659 +0100
@@ -774,7 +774,7 @@ copyprop_hardreg_forward_1 (basic_block
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt ();
n_ops = recog_data.n_operands;
is_asm = asm_noperands (PATTERN (insn)) >= 0;
@@ -877,7 +877,7 @@ copyprop_hardreg_forward_1 (basic_block
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
}
/* Otherwise, try all valid registers and see if its valid. */
@@ -905,7 +905,7 @@ copyprop_hardreg_forward_1 (basic_block
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
}
}
}
Index: gcc/regrename.c
===================================================================
--- gcc/regrename.c 2014-05-31 09:02:35.958369732 +0100
+++ gcc/regrename.c 2014-05-31 09:10:16.602150667 +0100
@@ -1570,7 +1570,7 @@ build_def_use (basic_block bb)
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt ();
n_ops = recog_data.n_operands;
untracked_operands = 0;
Index: gcc/sched-deps.c
===================================================================
--- gcc/sched-deps.c 2014-05-31 08:54:09.086208879 +0100
+++ gcc/sched-deps.c 2014-05-31 09:10:16.615150774 +0100
@@ -2865,7 +2865,7 @@ sched_analyze_insn (struct deps_desc *de
HARD_REG_SET temp;
extract_insn (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
ira_implicitly_set_insn_hard_regs (&temp);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp);
Index: gcc/sel-sched.c
===================================================================
--- gcc/sel-sched.c 2014-05-31 09:02:35.970369830 +0100
+++ gcc/sel-sched.c 2014-05-31 09:10:16.617150790 +0100
@@ -1019,7 +1019,7 @@ get_reg_class (rtx insn)
extract_insn (insn);
if (! constrain_operands (1))
fatal_insn_not_found (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
n_ops = recog_data.n_operands;
const operand_alternative *op_alt = which_op_alt ();
@@ -2134,7 +2134,7 @@ implicit_clobber_conflict_p (insn_t thro
/* Calculate implicit clobbers. */
extract_insn (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
ira_implicitly_set_insn_hard_regs (&temp);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c 2014-05-31 09:02:35.966369798 +0100
+++ gcc/config/arm/arm.c 2014-05-31 09:10:16.626150864 +0100
@@ -11335,7 +11335,7 @@ xscale_sched_adjust_cost (rtx insn, rtx
that overlaps with SHIFTED_OPERAND, then we have increase the
cost of this dependency. */
extract_insn (dep);
- preprocess_constraints ();
+ preprocess_constraints (dep);
for (opno = 0; opno < recog_data.n_operands; opno++)
{
/* We can ignore strict inputs. */
@@ -16870,7 +16870,7 @@ note_invalid_constants (rtx insn, HOST_W
/* Fill in recog_op_alt with information about the constraints of
this insn. */
- preprocess_constraints ();
+ preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt ();
for (opno = 0; opno < recog_data.n_operands; opno++)
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c 2014-05-31 09:07:21.682714985 +0100
+++ gcc/config/i386/i386.c 2014-05-31 09:10:16.638150962 +0100
@@ -5826,7 +5826,7 @@ ix86_legitimate_combined_insn (rtx insn)
int i;
extract_insn (insn);
- preprocess_constraints ();
+ preprocess_constraints (insn);
int n_operands = recog_data.n_operands;
int n_alternatives = recog_data.n_alternatives;
@@ -5834,7 +5834,7 @@ ix86_legitimate_combined_insn (rtx insn)
{
rtx op = recog_data.operand[i];
enum machine_mode mode = GET_MODE (op);
- operand_alternative *op_alt;
+ const operand_alternative *op_alt;
int offset = 0;
bool win;
int j;