summaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-15 17:55:58 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-15 17:55:58 +0000
commit6182a80f9ca413f49350c49e938a2cbfe21663e9 (patch)
tree83b6fb18e33436103a7c2a0c17e90eae2899f811 /gcc/reload1.c
parent2948450ddbe2ce320cd3740cb3a5b46be5edc07d (diff)
downloadgcc-6182a80f9ca413f49350c49e938a2cbfe21663e9.tar.gz
* reload.h, reload1.c (eliminate_regs), caller-save.c, dbxout.c,
dwarfout.c, dwarf2out.c, reload.c, sdbout.c: Revert March 15 change. * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the SUBREG_REG if the word count is unchanged. * reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve subregs of identical word size for push_reload. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@17105 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c103
1 files changed, 48 insertions, 55 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index c8573dc39bc..3cfa1f88498 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -980,7 +980,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, 0);
+ rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX);
if (strict_memory_address_p (GET_MODE (regno_reg_rtx[i]),
XEXP (x, 0)))
@@ -2812,11 +2812,10 @@ static struct rtvec_def *old_asm_operands_vec, *new_asm_operands_vec;
the proper thing. */
rtx
-eliminate_regs (x, mem_mode, insn, storing)
+eliminate_regs (x, mem_mode, insn)
rtx x;
enum machine_mode mem_mode;
rtx insn;
- int storing;
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
@@ -2845,7 +2844,7 @@ eliminate_regs (x, mem_mode, insn, storing)
/* This is only for the benefit of the debugging backends, which call
eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
removed after CSE. */
- new = eliminate_regs (XEXP (x, 0), 0, insn, 0);
+ new = eliminate_regs (XEXP (x, 0), 0, insn);
if (GET_CODE (new) == MEM)
return XEXP (new, 0);
return x;
@@ -2881,8 +2880,7 @@ eliminate_regs (x, mem_mode, insn, storing)
elimination) and ignore the fact that this is actually a
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, 0);
+ new = eliminate_regs (reg_equiv_memory_loc[regno], mem_mode, insn);
if (new != reg_equiv_memory_loc[regno])
{
cannot_omit_stores[regno] = 1;
@@ -2944,8 +2942,8 @@ eliminate_regs (x, mem_mode, insn, storing)
reload. This is the desired action. */
{
- rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
- rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
+ rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
+ rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
{
@@ -3016,9 +3014,9 @@ eliminate_regs (x, mem_mode, insn, storing)
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, 0);
+ rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new1
- = XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn, 0) : 0;
+ = XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn) : 0;
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
return gen_rtx (code, GET_MODE (x), new0, new1);
@@ -3029,7 +3027,7 @@ eliminate_regs (x, mem_mode, insn, storing)
/* 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, 0);
+ new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1));
}
@@ -3042,7 +3040,7 @@ eliminate_regs (x, mem_mode, insn, storing)
strictly needed, but it simplifies the code. */
if (XEXP (x, 1))
{
- new = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
+ new = eliminate_regs (XEXP (x, 1), mem_mode, insn);
if (new != XEXP (x, 1))
return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
}
@@ -3078,7 +3076,7 @@ eliminate_regs (x, mem_mode, insn, storing)
case ABS:
case SQRT:
case FFS:
- new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
+ new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@@ -3097,7 +3095,7 @@ eliminate_regs (x, mem_mode, insn, storing)
&& reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
{
new = eliminate_regs (reg_equiv_memory_loc[REGNO (SUBREG_REG (x))],
- mem_mode, insn, 0);
+ mem_mode, insn);
/* If we didn't change anything, we must retain the pseudo. */
if (new == reg_equiv_memory_loc[REGNO (SUBREG_REG (x))])
@@ -3117,37 +3115,38 @@ eliminate_regs (x, mem_mode, insn, storing)
}
}
else
- new = eliminate_regs (SUBREG_REG (x), mem_mode, insn, 0);
+ new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
if (new != XEXP (x, 0))
{
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
+ if (GET_CODE (new) == MEM
+ && x_size <= new_size
+#ifdef WORD_REGISTER_OPERATIONS
+ /* On these machines, combine can create rtl of the form
+ (set (subreg:m1 (reg:m2 R) 0) ...)
+ where m1 < m2, and expects something interesting to
+ happen to the entire word. Moreover, it will use the
+ (reg:m2 R) later, expecting all bits to be preserved.
+ So if the number of words is the same, preserve the
+ subreg so that push_reloads can see it. */
+ && ! ((x_size-1)/UNITS_PER_WORD == (new_size-1)/UNITS_PER_WORD)
+#endif
#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
- && 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)
+ /* 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);
@@ -3175,7 +3174,7 @@ eliminate_regs (x, mem_mode, insn, storing)
if (ep->from_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
- new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
+ new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@@ -3188,7 +3187,7 @@ eliminate_regs (x, mem_mode, insn, storing)
if (ep->to_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
- new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
+ new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@@ -3206,7 +3205,7 @@ eliminate_regs (x, mem_mode, insn, storing)
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, 0);
+ mem_mode, insn);
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
if (temp_vec[i] != ASM_OPERANDS_INPUT (x, i))
@@ -3277,8 +3276,8 @@ eliminate_regs (x, mem_mode, insn, storing)
/* Now avoid the loop below in this common case. */
{
- rtx new0 = eliminate_regs (SET_DEST (x), 0, insn, 1);
- rtx new1 = eliminate_regs (SET_SRC (x), 0, insn, 0);
+ rtx new0 = eliminate_regs (SET_DEST (x), 0, insn);
+ rtx new1 = eliminate_regs (SET_SRC (x), 0, insn);
/* If SET_DEST changed from a REG to a MEM and INSN is an insn,
write a CLOBBER insn. */
@@ -3287,12 +3286,6 @@ eliminate_regs (x, mem_mode, insn, storing)
&& GET_CODE (insn) != INSN_LIST)
emit_insn_after (gen_rtx (CLOBBER, VOIDmode, SET_DEST (x)), insn);
- /* If SET_DEST was a partial-word subreg, NEW0 may have been widened
- to spill the entire register (see SUBREG case above). If the
- widths of SET_DEST and NEW0 no longer match, adjust NEW1. */
- if (GET_MODE (SET_DEST (x)) != GET_MODE (new0))
- new1 = gen_rtx (SUBREG, GET_MODE (new0), new1, 0);
-
if (new0 != SET_DEST (x) || new1 != SET_SRC (x))
return gen_rtx (SET, VOIDmode, new0, new1);
}
@@ -3304,12 +3297,12 @@ eliminate_regs (x, mem_mode, insn, storing)
eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
removed after CSE. */
if (GET_CODE (XEXP (x, 0)) == ADDRESSOF)
- return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, insn, 0);
+ return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, 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, 0);
+ new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
if (new != XEXP (x, 0))
{
new = gen_rtx (MEM, GET_MODE (x), new);
@@ -3332,7 +3325,7 @@ eliminate_regs (x, mem_mode, insn, storing)
{
if (*fmt == 'e')
{
- new = eliminate_regs (XEXP (x, i), mem_mode, insn, 0);
+ new = eliminate_regs (XEXP (x, i), mem_mode, insn);
if (new != XEXP (x, i) && ! copied)
{
rtx new_x = rtx_alloc (code);
@@ -3349,7 +3342,7 @@ eliminate_regs (x, mem_mode, insn, storing)
int copied_vec = 0;
for (j = 0; j < XVECLEN (x, i); j++)
{
- new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn, 0);
+ new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn);
if (new != XVECEXP (x, i, j) && ! copied_vec)
{
rtvec new_v = gen_rtvec_vv (XVECLEN (x, i),
@@ -3527,7 +3520,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, 0);
+ new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
if (new_body != old_body)
{
/* If we aren't replacing things permanently and we changed something,
@@ -3616,7 +3609,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), 0);
+ REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn));
if (! replace)
pop_obstacks ();
@@ -4090,7 +4083,7 @@ reload_as_needed (first, live_known)
XEXP (XEXP (PATTERN (insn), 0), 0)
= eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
GET_MODE (XEXP (PATTERN (insn), 0)),
- NULL_RTX, 0);
+ NULL_RTX);
/* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */