aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2014-06-04 17:34:40 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2014-06-04 17:34:40 +0000
commit1145837df5c8c6c7664551878d216671ecf8ef6e (patch)
treed9fb5507a542d8ccc1d218346a802396dd5c276c /gcc/recog.c
parent5f2e0797aeb67a52d1b71859e054f55d1cd24ec7 (diff)
downloadgcc-1145837df5c8c6c7664551878d216671ecf8ef6e.zip
gcc-1145837df5c8c6c7664551878d216671ecf8ef6e.tar.gz
gcc-1145837df5c8c6c7664551878d216671ecf8ef6e.tar.bz2
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
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c91
1 files changed, 75 insertions, 16 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 15e0752..0a5d82e 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -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
@@ -4212,4 +4265,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;
+ }
}