recog.h (operand_alternative): Convert reg_class, reject, matched and matches into bitfields.

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.

From-SVN: r211240
This commit is contained in:
Richard Sandiford 2014-06-04 17:34:40 +00:00 committed by Richard Sandiford
parent 5f2e0797ae
commit 1145837df5
11 changed files with 138 additions and 40 deletions

View File

@ -1,3 +1,36 @@
2014-06-04 Richard Sandiford <rdsandiford@googlemail.com>
* 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.
2014-06-04 Richard Sandiford <rdsandiford@googlemail.com> 2014-06-04 Richard Sandiford <rdsandiford@googlemail.com>
* recog.c (preprocess_constraints): Don't skip disabled alternatives. * recog.c (preprocess_constraints): Don't skip disabled alternatives.

View File

@ -11341,7 +11341,7 @@ xscale_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
that overlaps with SHIFTED_OPERAND, then we have increase the that overlaps with SHIFTED_OPERAND, then we have increase the
cost of this dependency. */ cost of this dependency. */
extract_insn (dep); extract_insn (dep);
preprocess_constraints (); preprocess_constraints (dep);
for (opno = 0; opno < recog_data.n_operands; opno++) for (opno = 0; opno < recog_data.n_operands; opno++)
{ {
/* We can ignore strict inputs. */ /* We can ignore strict inputs. */
@ -16876,7 +16876,7 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
/* Fill in recog_op_alt with information about the constraints of /* Fill in recog_op_alt with information about the constraints of
this insn. */ this insn. */
preprocess_constraints (); preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt (); const operand_alternative *op_alt = which_op_alt ();
for (opno = 0; opno < recog_data.n_operands; opno++) for (opno = 0; opno < recog_data.n_operands; opno++)

View File

@ -5827,7 +5827,7 @@ ix86_legitimate_combined_insn (rtx insn)
int i; int i;
extract_insn (insn); extract_insn (insn);
preprocess_constraints (); preprocess_constraints (insn);
int n_operands = recog_data.n_operands; int n_operands = recog_data.n_operands;
int n_alternatives = recog_data.n_alternatives; int n_alternatives = recog_data.n_alternatives;
@ -5835,7 +5835,7 @@ ix86_legitimate_combined_insn (rtx insn)
{ {
rtx op = recog_data.operand[i]; rtx op = recog_data.operand[i];
enum machine_mode mode = GET_MODE (op); enum machine_mode mode = GET_MODE (op);
operand_alternative *op_alt; const operand_alternative *op_alt;
int offset = 0; int offset = 0;
bool win; bool win;
int j; int j;

View File

@ -625,7 +625,7 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
advance_p = true; advance_p = true;
int n_operands = recog_data.n_operands; 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++) for (use = 0; use < n_operands; use++)
{ {
int alt1; int alt1;
@ -646,7 +646,8 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
{ {
if (!TEST_BIT (enabled, alt1)) if (!TEST_BIT (enabled, alt1))
continue; 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 if (op_alt1[use].matches == def
|| (use < n_operands - 1 || (use < n_operands - 1
&& recog_data.constraints[use][0] == '%' && recog_data.constraints[use][0] == '%'
@ -692,7 +693,7 @@ make_early_clobber_and_input_conflicts (void)
int n_alternatives = recog_data.n_alternatives; int n_alternatives = recog_data.n_alternatives;
int n_operands = recog_data.n_operands; int n_operands = recog_data.n_operands;
alternative_mask enabled = recog_data.enabled_alternatives; 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) for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands)
if (TEST_BIT (enabled, alt)) if (TEST_BIT (enabled, alt))
for (def = 0; def < n_operands; def++) for (def = 0; def < n_operands; def++)
@ -1251,7 +1252,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
} }
extract_insn (insn); extract_insn (insn);
preprocess_constraints (); preprocess_constraints (insn);
process_single_reg_class_operands (false, freq); process_single_reg_class_operands (false, freq);
/* See which defined values die here. */ /* See which defined values die here. */

View File

@ -81,8 +81,11 @@ struct recog_data_d recog_data;
/* Contains a vector of operand_alternative structures, such that /* Contains a vector of operand_alternative structures, such that
operand OP of alternative A is at index A * n_operands + OP. operand OP of alternative A is at index A * n_operands + OP.
Set up by preprocess_constraints. */ Set up by preprocess_constraints. */
struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS const operand_alternative *recog_op_alt;
* MAX_RECOG_ALTERNATIVES];
/* 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 /* On return from `constrain_operands', indicate which alternative
was satisfied. */ was satisfied. */
@ -2324,26 +2327,23 @@ extract_insn (rtx insn)
which_alternative = -1; which_alternative = -1;
} }
/* After calling extract_insn, you can use this function to extract some /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands,
information from the constraint strings into a more usable form. N_ALTERNATIVES alternatives and constraint strings CONSTRAINTS.
The collected data is stored in recog_op_alt. */ OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries and CONSTRAINTS
has N_OPERANDS entries. */
void void
preprocess_constraints (void) preprocess_constraints (int n_operands, int n_alternatives,
const char **constraints,
operand_alternative *op_alt_base)
{ {
int i; for (int i = 0; i < n_operands; 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++)
{ {
int j; int j;
struct operand_alternative *op_alt; 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) 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 /* Check the operands of an insn against the insn's operand constraints
and return 1 if they are valid. and return 1 if they are valid.
The information about the insn's operands, constraints, operand modes The information about the insn's operands, constraints, operand modes
@ -4212,4 +4265,10 @@ recog_init ()
} }
memset (this_target_recog->x_enabled_alternatives, 0, memset (this_target_recog->x_enabled_alternatives, 0,
sizeof (this_target_recog->x_enabled_alternatives)); 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;
}
} }

View File

@ -46,18 +46,18 @@ struct operand_alternative
const char *constraint; const char *constraint;
/* The register class valid for this alternative (possibly NO_REGS). */ /* 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 '!' /* "Badness" of this alternative, computed from number of '?' and '!'
characters in the constraint string. */ characters in the constraint string. */
unsigned int reject; unsigned int reject : 16;
/* -1 if no matching constraint was found, or an operand number. */ /* -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 /* The same information, but reversed: -1 if this operand is not
matched by any other, or the operand number of the operand that matched by any other, or the operand number of the operand that
matches this one. */ matches this one. */
int matched; int matched : 8;
/* Nonzero if '&' was found in the constraint string. */ /* Nonzero if '&' was found in the constraint string. */
unsigned int earlyclobber:1; unsigned int earlyclobber:1;
@ -77,6 +77,8 @@ struct operand_alternative
/* Nonzero if 'X' was found in the constraint string, or if the constraint /* Nonzero if 'X' was found in the constraint string, or if the constraint
string for this alternative was empty. */ string for this alternative was empty. */
unsigned int anything_ok:1; unsigned int anything_ok:1;
unsigned int unused : 8;
}; };
/* Return the class for operand I of alternative ALT, taking matching /* 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_insn (rtx);
extern void extract_constrain_insn_cached (rtx); extern void extract_constrain_insn_cached (rtx);
extern void extract_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 rtx peep2_next_insn (int);
extern int peep2_regno_dead_p (int, int); extern int peep2_regno_dead_p (int, int);
extern int peep2_reg_dead_p (int, rtx); 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 recog_data_d recog_data;
extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS extern const operand_alternative *recog_op_alt;
* MAX_RECOG_ALTERNATIVES];
/* Return a pointer to an array in which index OP describes the constraints /* Return a pointer to an array in which index OP describes the constraints
on operand OP of the current instruction alternative (which_alternative). on operand OP of the current instruction alternative (which_alternative).
@ -396,6 +400,7 @@ extern int peep2_current_count;
struct target_recog { struct target_recog {
bool x_initialized; bool x_initialized;
alternative_mask x_enabled_alternatives[LAST_INSN_CODE]; alternative_mask x_enabled_alternatives[LAST_INSN_CODE];
operand_alternative *x_op_alt[LAST_INSN_CODE];
}; };
extern struct target_recog default_target_recog; extern struct target_recog default_target_recog;

View File

@ -471,7 +471,7 @@ check_asm_stack_operands (rtx insn)
extract_insn (insn); extract_insn (insn);
constrain_operands (1); constrain_operands (1);
preprocess_constraints (); preprocess_constraints (insn);
get_asm_operands_in_out (body, &n_outputs, &n_inputs); get_asm_operands_in_out (body, &n_outputs, &n_inputs);
@ -2029,7 +2029,7 @@ subst_asm_stack_regs (rtx insn, stack_ptr regstack)
extract_insn (insn); extract_insn (insn);
constrain_operands (1); constrain_operands (1);
preprocess_constraints (); preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt (); const operand_alternative *op_alt = which_op_alt ();
get_asm_operands_in_out (body, &n_outputs, &n_inputs); get_asm_operands_in_out (body, &n_outputs, &n_inputs);

View File

@ -774,7 +774,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
preprocess_constraints (); preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt (); const operand_alternative *op_alt = which_op_alt ();
n_ops = recog_data.n_operands; n_ops = recog_data.n_operands;
is_asm = asm_noperands (PATTERN (insn)) >= 0; is_asm = asm_noperands (PATTERN (insn)) >= 0;
@ -877,7 +877,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
preprocess_constraints (); preprocess_constraints (insn);
} }
/* Otherwise, try all valid registers and see if its valid. */ /* Otherwise, try all valid registers and see if its valid. */
@ -905,7 +905,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
preprocess_constraints (); preprocess_constraints (insn);
} }
} }
} }

View File

@ -1570,7 +1570,7 @@ build_def_use (basic_block bb)
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
preprocess_constraints (); preprocess_constraints (insn);
const operand_alternative *op_alt = which_op_alt (); const operand_alternative *op_alt = which_op_alt ();
n_ops = recog_data.n_operands; n_ops = recog_data.n_operands;
untracked_operands = 0; untracked_operands = 0;

View File

@ -2865,7 +2865,7 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
HARD_REG_SET temp; HARD_REG_SET temp;
extract_insn (insn); extract_insn (insn);
preprocess_constraints (); preprocess_constraints (insn);
ira_implicitly_set_insn_hard_regs (&temp); ira_implicitly_set_insn_hard_regs (&temp);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp); IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp);

View File

@ -1019,7 +1019,7 @@ get_reg_class (rtx insn)
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (1)) if (! constrain_operands (1))
fatal_insn_not_found (insn); fatal_insn_not_found (insn);
preprocess_constraints (); preprocess_constraints (insn);
n_ops = recog_data.n_operands; n_ops = recog_data.n_operands;
const operand_alternative *op_alt = which_op_alt (); const operand_alternative *op_alt = which_op_alt ();
@ -2134,7 +2134,7 @@ implicit_clobber_conflict_p (insn_t through_insn, expr_t expr)
/* Calculate implicit clobbers. */ /* Calculate implicit clobbers. */
extract_insn (insn); extract_insn (insn);
preprocess_constraints (); preprocess_constraints (insn);
ira_implicitly_set_insn_hard_regs (&temp); ira_implicitly_set_insn_hard_regs (&temp);
AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);