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