mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 14:30:42 +08:00
(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:
parent
abd268e28d
commit
29ae501263
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user