Commit 4fd3a105 by Richard Sandiford Committed by Richard Sandiford

recog.h (insn_operand_data): Add an "allows_mem" field.

gcc/
	* recog.h (insn_operand_data): Add an "allows_mem" field.
	* genoutput.c (output_operand_data): Initialize it.
	* optabs.c (maybe_legitimize_operand_same_code): New function.
	(maybe_legitimize_operand): Use it when matching the original
	op->value.

From-SVN: r172478
parent b98b952f
2011-04-15 Richard Sandiford <richard.sandiford@linaro.org>
* recog.h (insn_operand_data): Add an "allows_mem" field.
* genoutput.c (output_operand_data): Initialize it.
* optabs.c (maybe_legitimize_operand_same_code): New function.
(maybe_legitimize_operand): Use it when matching the original
op->value.
2011-04-15 Eric Botcazou <ebotcazou@adacore.com> 2011-04-15 Eric Botcazou <ebotcazou@adacore.com>
* gimplify.c: Fix issues in comments throughout. * gimplify.c: Fix issues in comments throughout.
......
...@@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see
MATCH_OPERAND; it is zero for operands that should not be changed during MATCH_OPERAND; it is zero for operands that should not be changed during
register elimination such as MATCH_OPERATORs. register elimination such as MATCH_OPERATORs.
g. `allows_mem', is true for operands that accept MEM rtxes.
The code number of an insn is simply its position in the machine The code number of an insn is simply its position in the machine
description; code numbers are assigned sequentially to entries in description; code numbers are assigned sequentially to entries in
the description, starting with code number 0. the description, starting with code number 0.
...@@ -256,6 +258,8 @@ output_operand_data (void) ...@@ -256,6 +258,8 @@ output_operand_data (void)
for (d = odata; d; d = d->next) for (d = odata; d; d = d->next)
{ {
struct pred_data *pred;
printf (" {\n"); printf (" {\n");
printf (" %s,\n", printf (" %s,\n",
...@@ -269,7 +273,12 @@ output_operand_data (void) ...@@ -269,7 +273,12 @@ output_operand_data (void)
printf (" %d,\n", d->constraint == NULL ? 1 : 0); printf (" %d,\n", d->constraint == NULL ? 1 : 0);
printf (" %d\n", d->eliminable); printf (" %d,\n", d->eliminable);
pred = NULL;
if (d->predicate)
pred = lookup_predicate (d->predicate);
printf (" %d\n", pred && pred->codes[MEM]);
printf(" },\n"); printf(" },\n");
} }
......
...@@ -7001,6 +7001,41 @@ insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand) ...@@ -7001,6 +7001,41 @@ insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
(operand, insn_data[(int) icode].operand[opno].mode))); (operand, insn_data[(int) icode].operand[opno].mode)));
} }
/* Like maybe_legitimize_operand, but do not change the code of the
current rtx value. */
static bool
maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
struct expand_operand *op)
{
/* See if the operand matches in its current form. */
if (insn_operand_matches (icode, opno, op->value))
return true;
/* If the operand is a memory whose address has no side effects,
try forcing the address into a register. The check for side
effects is important because force_reg cannot handle things
like auto-modified addresses. */
if (insn_data[(int) icode].operand[opno].allows_mem
&& MEM_P (op->value)
&& !side_effects_p (XEXP (op->value, 0)))
{
rtx addr, mem, last;
last = get_last_insn ();
addr = force_reg (Pmode, XEXP (op->value, 0));
mem = replace_equiv_address (op->value, addr);
if (insn_operand_matches (icode, opno, mem))
{
op->value = mem;
return true;
}
delete_insns_since (last);
}
return false;
}
/* Try to make OP match operand OPNO of instruction ICODE. Return true /* Try to make OP match operand OPNO of instruction ICODE. Return true
on success, storing the new operand value back in OP. */ on success, storing the new operand value back in OP. */
...@@ -7011,22 +7046,25 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7011,22 +7046,25 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
enum machine_mode mode, imode; enum machine_mode mode, imode;
bool old_volatile_ok, result; bool old_volatile_ok, result;
old_volatile_ok = volatile_ok;
mode = op->mode; mode = op->mode;
result = false;
switch (op->type) switch (op->type)
{ {
case EXPAND_FIXED: case EXPAND_FIXED:
old_volatile_ok = volatile_ok;
volatile_ok = true; volatile_ok = true;
break; result = maybe_legitimize_operand_same_code (icode, opno, op);
volatile_ok = old_volatile_ok;
return result;
case EXPAND_OUTPUT: case EXPAND_OUTPUT:
gcc_assert (mode != VOIDmode); gcc_assert (mode != VOIDmode);
if (!op->value if (op->value
|| op->value == const0_rtx && op->value != const0_rtx
|| GET_MODE (op->value) != mode && GET_MODE (op->value) == mode
|| !insn_operand_matches (icode, opno, op->value)) && maybe_legitimize_operand_same_code (icode, opno, op))
op->value = gen_reg_rtx (mode); return true;
op->value = gen_reg_rtx (mode);
break; break;
case EXPAND_INPUT: case EXPAND_INPUT:
...@@ -7034,9 +7072,10 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7034,9 +7072,10 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
gcc_assert (mode != VOIDmode); gcc_assert (mode != VOIDmode);
gcc_assert (GET_MODE (op->value) == VOIDmode gcc_assert (GET_MODE (op->value) == VOIDmode
|| GET_MODE (op->value) == mode); || GET_MODE (op->value) == mode);
result = insn_operand_matches (icode, opno, op->value); if (maybe_legitimize_operand_same_code (icode, opno, op))
if (!result) return true;
op->value = copy_to_mode_reg (mode, op->value);
op->value = copy_to_mode_reg (mode, op->value);
break; break;
case EXPAND_CONVERT_TO: case EXPAND_CONVERT_TO:
...@@ -7070,10 +7109,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7070,10 +7109,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
goto input; goto input;
break; break;
} }
if (!result) return insn_operand_matches (icode, opno, op->value);
result = insn_operand_matches (icode, opno, op->value);
volatile_ok = old_volatile_ok;
return result;
} }
/* Make OP describe an input operand that should have the same value /* Make OP describe an input operand that should have the same value
......
...@@ -272,6 +272,8 @@ struct insn_operand_data ...@@ -272,6 +272,8 @@ struct insn_operand_data
const char is_operator; const char is_operator;
const char eliminable; const char eliminable;
const char allows_mem;
}; };
/* Legal values for insn_data.output_format. Indicate what type of data /* Legal values for insn_data.output_format. Indicate what type of data
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment