(eliminate_regs): Add STORING arg.

(eliminate_regs, case SET): Pass that we are storing to recursive call.
(eliminate_regs, case SUBREG): If storing and same number of words, use
larger mode.

From-SVN: r13704
This commit is contained in:
Richard Kenner 1997-03-15 07:14:27 -05:00
parent abd268e28d
commit 29ae501263
1 changed files with 50 additions and 38 deletions

View File

@ -946,7 +946,7 @@ reload (first, global, dumpfile)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
{
rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX);
rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX, 0);
if (strict_memory_address_p (GET_MODE (regno_reg_rtx[i]),
XEXP (x, 0)))
@ -2759,10 +2759,11 @@ static struct rtvec_def *old_asm_operands_vec, *new_asm_operands_vec;
the proper thing. */
rtx
eliminate_regs (x, mem_mode, insn)
eliminate_regs (x, mem_mode, insn, storing)
rtx x;
enum machine_mode mem_mode;
rtx insn;
int storing;
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
@ -2819,7 +2820,7 @@ eliminate_regs (x, mem_mode, insn)
reference to the pseudo. Ensure we make a copy of the
address in case it is shared. */
new = eliminate_regs (reg_equiv_memory_loc[regno],
mem_mode, insn);
mem_mode, insn, 0);
if (new != reg_equiv_memory_loc[regno])
{
cannot_omit_stores[regno] = 1;
@ -2881,8 +2882,8 @@ eliminate_regs (x, mem_mode, insn)
reload. This is the desired action. */
{
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
{
@ -2953,9 +2954,9 @@ eliminate_regs (x, mem_mode, insn)
case GE: case GT: case GEU: case GTU:
case LE: case LT: case LEU: case LTU:
{
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
rtx new1
= XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn) : 0;
= XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn, 0) : 0;
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
return gen_rtx (code, GET_MODE (x), new0, new1);
@ -2966,7 +2967,7 @@ eliminate_regs (x, mem_mode, insn)
/* If we have something in XEXP (x, 0), the usual case, eliminate it. */
if (XEXP (x, 0))
{
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
if (new != XEXP (x, 0))
x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1));
}
@ -2979,7 +2980,7 @@ eliminate_regs (x, mem_mode, insn)
strictly needed, but it simplifies the code. */
if (XEXP (x, 1))
{
new = eliminate_regs (XEXP (x, 1), mem_mode, insn);
new = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
if (new != XEXP (x, 1))
return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
}
@ -3015,7 +3016,7 @@ eliminate_regs (x, mem_mode, insn)
case ABS:
case SQRT:
case FFS:
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3034,7 +3035,7 @@ eliminate_regs (x, mem_mode, insn)
&& reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
{
new = eliminate_regs (reg_equiv_memory_loc[REGNO (SUBREG_REG (x))],
mem_mode, insn);
mem_mode, insn, 0);
/* If we didn't change anything, we must retain the pseudo. */
if (new == reg_equiv_memory_loc[REGNO (SUBREG_REG (x))])
@ -3054,27 +3055,37 @@ eliminate_regs (x, mem_mode, insn)
}
}
else
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn, 0);
if (new != XEXP (x, 0))
{
if (GET_CODE (new) == MEM
&& (GET_MODE_SIZE (GET_MODE (x))
<= GET_MODE_SIZE (GET_MODE (new)))
int x_size = GET_MODE_SIZE (GET_MODE (x));
int new_size = GET_MODE_SIZE (GET_MODE (new));
/* When asked to spill a partial word subreg, we need to go
ahead and spill the whole thing against the possibility
that we reload the whole reg and find garbage at the top. */
if (storing
&& GET_CODE (new) == MEM
&& x_size < new_size
&& ((x_size + UNITS_PER_WORD-1) / UNITS_PER_WORD
== (new_size + UNITS_PER_WORD-1) / UNITS_PER_WORD))
return new;
else if (GET_CODE (new) == MEM
&& x_size <= new_size
#ifdef LOAD_EXTEND_OP
/* On these machines we will be reloading what is
inside the SUBREG if it originally was a pseudo and
the inner and outer modes are both a word or
smaller. So leave the SUBREG then. */
&& ! (GET_CODE (SUBREG_REG (x)) == REG
&& GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (new)) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (x))
> GET_MODE_SIZE (GET_MODE (new)))
&& INTEGRAL_MODE_P (GET_MODE (new))
&& LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
/* On these machines we will be reloading what is
inside the SUBREG if it originally was a pseudo and
the inner and outer modes are both a word or
smaller. So leave the SUBREG then. */
&& ! (GET_CODE (SUBREG_REG (x)) == REG
&& x_size <= UNITS_PER_WORD
&& new_size <= UNITS_PER_WORD
&& x_size > new_size
&& INTEGRAL_MODE_P (GET_MODE (new))
&& LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
#endif
)
)
{
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
enum machine_mode mode = GET_MODE (x);
@ -3102,7 +3113,7 @@ eliminate_regs (x, mem_mode, insn)
if (ep->from_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3115,7 +3126,7 @@ eliminate_regs (x, mem_mode, insn)
if (ep->to_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3133,7 +3144,7 @@ eliminate_regs (x, mem_mode, insn)
temp_vec = (rtx *) alloca (XVECLEN (x, 3) * sizeof (rtx));
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
temp_vec[i] = eliminate_regs (ASM_OPERANDS_INPUT (x, i),
mem_mode, insn);
mem_mode, insn, 0);
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
if (temp_vec[i] != ASM_OPERANDS_INPUT (x, i))
@ -3204,8 +3215,8 @@ eliminate_regs (x, mem_mode, insn)
/* Now avoid the loop below in this common case. */
{
rtx new0 = eliminate_regs (SET_DEST (x), 0, insn);
rtx new1 = eliminate_regs (SET_SRC (x), 0, insn);
rtx new0 = eliminate_regs (SET_DEST (x), 0, insn, 1);
rtx new1 = eliminate_regs (SET_SRC (x), 0, insn, 0);
/* If SET_DEST changed from a REG to a MEM and INSN is an insn,
write a CLOBBER insn. */
@ -3224,7 +3235,7 @@ eliminate_regs (x, mem_mode, insn)
/* Our only special processing is to pass the mode of the MEM to our
recursive call and copy the flags. While we are here, handle this
case more efficiently. */
new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn, 0);
if (new != XEXP (x, 0))
{
new = gen_rtx (MEM, GET_MODE (x), new);
@ -3244,7 +3255,7 @@ eliminate_regs (x, mem_mode, insn)
{
if (*fmt == 'e')
{
new = eliminate_regs (XEXP (x, i), mem_mode, insn);
new = eliminate_regs (XEXP (x, i), mem_mode, insn, 0);
if (new != XEXP (x, i) && ! copied)
{
rtx new_x = rtx_alloc (code);
@ -3261,7 +3272,7 @@ eliminate_regs (x, mem_mode, insn)
int copied_vec = 0;
for (j = 0; j < XVECLEN (x, i); j++)
{
new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn);
new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn, 0);
if (new != XVECEXP (x, i, j) && ! copied_vec)
{
rtvec new_v = gen_rtvec_vv (XVECLEN (x, i),
@ -3439,7 +3450,7 @@ eliminate_regs_in_insn (insn, replace)
but now can do this as a load-address. This saves an insn in this
common case. */
new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX, 0);
if (new_body != old_body)
{
/* If we aren't replacing things permanently and we changed something,
@ -3528,7 +3539,7 @@ eliminate_regs_in_insn (insn, replace)
of spill registers to be needed in the final reload pass than in
the pre-passes. */
if (val && REG_NOTES (insn) != 0)
REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn));
REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn), 0);
if (! replace)
pop_obstacks ();
@ -4006,7 +4017,8 @@ reload_as_needed (first, live_known)
&& GET_CODE (XEXP (PATTERN (insn), 0)) == MEM)
XEXP (XEXP (PATTERN (insn), 0), 0)
= eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
GET_MODE (XEXP (PATTERN (insn), 0)), NULL_RTX);
GET_MODE (XEXP (PATTERN (insn), 0)),
NULL_RTX, 0);
/* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */