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
This commit is contained in:
parent
b98b952feb
commit
4fd3a10598
4 changed files with 71 additions and 16 deletions
|
@ -1,3 +1,11 @@
|
|||
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>
|
||||
|
||||
* gimplify.c: Fix issues in comments throughout.
|
||||
|
|
|
@ -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
|
||||
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
|
||||
description; code numbers are assigned sequentially to entries in
|
||||
the description, starting with code number 0.
|
||||
|
@ -256,6 +258,8 @@ output_operand_data (void)
|
|||
|
||||
for (d = odata; d; d = d->next)
|
||||
{
|
||||
struct pred_data *pred;
|
||||
|
||||
printf (" {\n");
|
||||
|
||||
printf (" %s,\n",
|
||||
|
@ -269,7 +273,12 @@ output_operand_data (void)
|
|||
|
||||
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");
|
||||
}
|
||||
|
|
66
gcc/optabs.c
66
gcc/optabs.c
|
@ -7001,6 +7001,41 @@ insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
|
|||
(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
|
||||
on success, storing the new operand value back in OP. */
|
||||
|
||||
|
@ -7011,22 +7046,25 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
|
|||
enum machine_mode mode, imode;
|
||||
bool old_volatile_ok, result;
|
||||
|
||||
old_volatile_ok = volatile_ok;
|
||||
mode = op->mode;
|
||||
result = false;
|
||||
switch (op->type)
|
||||
{
|
||||
case EXPAND_FIXED:
|
||||
old_volatile_ok = volatile_ok;
|
||||
volatile_ok = true;
|
||||
break;
|
||||
result = maybe_legitimize_operand_same_code (icode, opno, op);
|
||||
volatile_ok = old_volatile_ok;
|
||||
return result;
|
||||
|
||||
case EXPAND_OUTPUT:
|
||||
gcc_assert (mode != VOIDmode);
|
||||
if (!op->value
|
||||
|| op->value == const0_rtx
|
||||
|| GET_MODE (op->value) != mode
|
||||
|| !insn_operand_matches (icode, opno, op->value))
|
||||
op->value = gen_reg_rtx (mode);
|
||||
if (op->value
|
||||
&& op->value != const0_rtx
|
||||
&& GET_MODE (op->value) == mode
|
||||
&& maybe_legitimize_operand_same_code (icode, opno, op))
|
||||
return true;
|
||||
|
||||
op->value = gen_reg_rtx (mode);
|
||||
break;
|
||||
|
||||
case EXPAND_INPUT:
|
||||
|
@ -7034,9 +7072,10 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
|
|||
gcc_assert (mode != VOIDmode);
|
||||
gcc_assert (GET_MODE (op->value) == VOIDmode
|
||||
|| GET_MODE (op->value) == mode);
|
||||
result = insn_operand_matches (icode, opno, op->value);
|
||||
if (!result)
|
||||
op->value = copy_to_mode_reg (mode, op->value);
|
||||
if (maybe_legitimize_operand_same_code (icode, opno, op))
|
||||
return true;
|
||||
|
||||
op->value = copy_to_mode_reg (mode, op->value);
|
||||
break;
|
||||
|
||||
case EXPAND_CONVERT_TO:
|
||||
|
@ -7070,10 +7109,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
|
|||
goto input;
|
||||
break;
|
||||
}
|
||||
if (!result)
|
||||
result = insn_operand_matches (icode, opno, op->value);
|
||||
volatile_ok = old_volatile_ok;
|
||||
return result;
|
||||
return insn_operand_matches (icode, opno, op->value);
|
||||
}
|
||||
|
||||
/* Make OP describe an input operand that should have the same value
|
||||
|
|
|
@ -272,6 +272,8 @@ struct insn_operand_data
|
|||
const char is_operator;
|
||||
|
||||
const char eliminable;
|
||||
|
||||
const char allows_mem;
|
||||
};
|
||||
|
||||
/* Legal values for insn_data.output_format. Indicate what type of data
|
||||
|
|
Loading…
Add table
Reference in a new issue