Several fixes to make reload handle POST_MODIFY correctly.

From-SVN: r37370
This commit is contained in:
Bernd Schmidt 2000-11-10 17:10:29 +00:00 committed by Bernd Schmidt
parent 29e9c0c4f1
commit 9532e31f94
4 changed files with 83 additions and 38 deletions

View File

@ -1,3 +1,12 @@
2000-11-10 Bernd Schmidt <bernds@redhat.co.uk>
* reload.c (find_reloads_address_1, case POST_MODIFY): Use RELOAD_OTHER
for address reloads. Push replacements for REG_INC notes.
(regno_clobbered_p): New arg SETS. Examine SETs if it's nonzero. All
callers changed.
* reload1.c (choose_reload_regs): Registers set in the insn can't be
used for RELOAD_OTHER reloads.
2000-11-10 Mark Mitchell <mark@codesourcery.com>
* c-dump.h: New file.

View File

@ -4536,7 +4536,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
else if (regno < FIRST_PSEUDO_REGISTER
&& REGNO_MODE_OK_FOR_BASE_P (regno, mode)
&& ! regno_clobbered_p (regno, this_insn, mode))
&& ! regno_clobbered_p (regno, this_insn, mode, 0))
return 0;
/* If we do not have one of the cases above, we must do the reload. */
@ -5155,7 +5155,9 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
if (REG_P (XEXP (op1, 0)))
{
register int regno = REGNO (XEXP (op1, 0));
rtx link;
int regno = REGNO (XEXP (op1, 0));
int reloadnum;
/* A register that is incremented cannot be constant! */
if (regno >= FIRST_PSEUDO_REGISTER
@ -5178,15 +5180,17 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
write back the value after reading it, hence we actually
need two registers. */
find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
&XEXP (tem, 0), opnum, type,
&XEXP (tem, 0), opnum,
RELOAD_OTHER,
ind_levels, insn);
/* Then reload the memory location into a base
register. */
push_reload (tem, tem, &XEXP (x, 0), &XEXP (op1, 0),
BASE_REG_CLASS, GET_MODE (x), GET_MODE (x),
0, 0, opnum, RELOAD_OTHER);
break;
reloadnum = push_reload (tem, tem, &XEXP (x, 0),
&XEXP (op1, 0), BASE_REG_CLASS,
GET_MODE (x), GET_MODE (x), 0,
0, opnum, RELOAD_OTHER);
goto reg_inc;
}
}
@ -5196,12 +5200,19 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
/* We require a base register here... */
if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
{
push_reload (XEXP (op1, 0), XEXP (x, 0),
&XEXP (op1, 0), &XEXP (x, 0),
BASE_REG_CLASS,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
&XEXP (op1, 0), &XEXP (x, 0),
BASE_REG_CLASS,
GET_MODE (x), GET_MODE (x), 0, 0,
opnum, RELOAD_OTHER);
}
/* Update the REG_INC notes. */
reg_inc:
for (link = REG_NOTES (this_insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC
&& REGNO (XEXP (link, 0)) == regno)
push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
}
else
abort ();
@ -5441,7 +5452,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
in this insn, reload it into some other register to be safe.
The CLOBBER is supposed to make the register unavailable
from before this insn to after it. */
if (regno_clobbered_p (regno, this_insn, GET_MODE (x)))
if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
(context ? INDEX_REG_CLASS : BASE_REG_CLASS),
@ -6552,18 +6563,21 @@ find_inc_amount (x, inced)
return 0;
}
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
If SETS is nonzero, also consider SETs. */
int
regno_clobbered_p (regno, insn, mode)
regno_clobbered_p (regno, insn, mode, sets)
unsigned int regno;
rtx insn;
enum machine_mode mode;
int sets;
{
int nregs = HARD_REGNO_NREGS (regno, mode);
int endregno = regno + nregs;
if (GET_CODE (PATTERN (insn)) == CLOBBER
if ((GET_CODE (PATTERN (insn)) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET))
&& GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
{
int test = REGNO (XEXP (PATTERN (insn), 0));
@ -6578,7 +6592,9 @@ regno_clobbered_p (regno, insn, mode)
for (; i >= 0; i--)
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG)
if ((GET_CODE (elt) == CLOBBER
|| (sets && GET_CODE (PATTERN (insn)) == SET))
&& GET_CODE (XEXP (elt, 0)) == REG)
{
int test = REGNO (XEXP (elt, 0));

View File

@ -335,7 +335,8 @@ extern rtx find_equiv_reg PARAMS ((rtx, rtx, enum reg_class, int, short *,
int, enum machine_mode));
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode));
extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode,
int));
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
int earlyclobber_operand_p PARAMS ((rtx));

View File

@ -5544,25 +5544,44 @@ choose_reload_regs (chain)
In particular, we then can't use EQUIV for a
RELOAD_FOR_OUTPUT_ADDRESS reload. */
if (equiv != 0 && regno_clobbered_p (regno, insn, rld[r].mode))
{
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_OPADDR_ADDR:
break;
case RELOAD_OTHER:
case RELOAD_FOR_INPUT:
case RELOAD_FOR_OPERAND_ADDRESS:
if (! rld[r].optional)
reload_override_in[r] = equiv;
/* Fall through. */
default:
equiv = 0;
break;
}
if (equiv != 0)
{
if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_OPADDR_ADDR:
break;
case RELOAD_OTHER:
case RELOAD_FOR_INPUT:
case RELOAD_FOR_OPERAND_ADDRESS:
if (! rld[r].optional)
reload_override_in[r] = equiv;
/* Fall through. */
default:
equiv = 0;
break;
}
else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_OPADDR_ADDR:
case RELOAD_FOR_OPERAND_ADDRESS:
case RELOAD_FOR_INPUT:
break;
case RELOAD_OTHER:
if (! rld[r].optional)
reload_override_in[r] = equiv;
/* Fall through. */
default:
equiv = 0;
break;
}
}
/* If we found an equivalent reg, say no code need be generated
@ -6567,7 +6586,7 @@ emit_output_reload_insns (chain, rl, j)
|| !(set = single_set (insn))
|| rtx_equal_p (old, SET_DEST (set))
|| !reg_mentioned_p (old, SET_SRC (set))
|| !regno_clobbered_p (REGNO (old), insn, rl->mode))
|| !regno_clobbered_p (REGNO (old), insn, rl->mode, 0))
gen_reload (old, reloadreg, rl->opnum,
rl->when_needed);
}