reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that boiled down to && ! 0.

* reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
        boiled down to && ! 0.
        * reload.c (find_reloads): Always force (subreg (mem)) to be
        reloaded if WORD_REGISTER_OPERATIONS.
        * reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
        SUBREGs of CONST_INTs.
        * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
        SUBREG_REG if the word count is unchanged, also in the input reload
        case.  Disable non-applicable sanity checks.
        * reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
        to require the SUBREG mode to be smaller than the SUBREG_REG mode.
        * reload1.c (eliminate_regs): Likewise.
        * 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.
Various alpha fixes from the mainline sources.

Co-Authored-By: J"orn Rennecke <amylaar@cygnus.co.uk>
Co-Authored-By: Jim Wilson <wilson@cygnus.com>

From-SVN: r19336
This commit is contained in:
Richard Henderson
1998-04-19 18:22:13 -07:00
committed by Jeff Law
parent 620a5a20ec
commit 495bf6087a
3 changed files with 95 additions and 34 deletions

View File

@@ -1,3 +1,29 @@
Mon Apr 20 02:17:37 1998 Richard Henderson <rth@cygnus.com>
Jim Wilson <wilson@cygnus.com>
J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that
boiled down to && ! 0.
* reload.c (find_reloads): Always force (subreg (mem)) to be
reloaded if WORD_REGISTER_OPERATIONS.
* reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical
SUBREGs of CONST_INTs.
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
SUBREG_REG if the word count is unchanged, also in the input reload
case. Disable non-applicable sanity checks.
* reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test
to require the SUBREG mode to be smaller than the SUBREG_REG mode.
* reload1.c (eliminate_regs): Likewise.
* 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.
Mon Apr 20 00:58:48 1998 H.J. Lu (hjl@gnu.org)
* reg-stack.c (subst_asm_stack_regs): Change to return the last

View File

@@ -889,6 +889,13 @@ push_reload (in, out, inloc, outloc, class,
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
&& INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
&& LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
#endif
#ifdef WORD_REGISTER_OPERATIONS
|| ((GET_MODE_SIZE (inmode)
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
&& ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
/ UNITS_PER_WORD)))
#endif
))
|| (GET_CODE (SUBREG_REG (in)) == REG
@@ -927,7 +934,7 @@ push_reload (in, out, inloc, outloc, class,
in_subreg_loc = inloc;
inloc = &SUBREG_REG (in);
in = *inloc;
#ifndef LOAD_EXTEND_OP
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
if (GET_CODE (in) == MEM)
/* This is supposed to happen only for paradoxical subregs made by
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
@@ -989,7 +996,15 @@ push_reload (in, out, inloc, outloc, class,
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|| GET_CODE (SUBREG_REG (out)) == MEM)
&& ((GET_MODE_SIZE (outmode)
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
#ifdef WORD_REGISTER_OPERATIONS
|| ((GET_MODE_SIZE (outmode)
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
&& ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
/ UNITS_PER_WORD)))
#endif
))
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
@@ -1023,7 +1038,7 @@ push_reload (in, out, inloc, outloc, class,
out_subreg_loc = outloc;
outloc = &SUBREG_REG (out);
out = *outloc;
#ifndef LOAD_EXTEND_OP
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
if (GET_CODE (out) == MEM
&& GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
abort ();
@@ -2757,10 +2772,20 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
register access. If the data is, in fact, in memory we
must always load using the size assumed to be in the
register and let the insn do the different-sized
accesses. */
accesses.
This is doubly true if WORD_REGISTER_OPERATIONS. In
this case eliminate_regs has left non-paradoxical
subregs for push_reloads to see. Make sure it does
by forcing the reload.
??? When is it right at this stage to have a subreg
of a mem that is _not_ to be handled specialy? IMO
those should have been reduced to just a mem. */
|| ((GET_CODE (operand) == MEM
|| (GET_CODE (operand)== REG
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
#ifndef WORD_REGISTER_OPERATIONS
&& (((GET_MODE_BITSIZE (GET_MODE (operand))
< BIGGEST_ALIGNMENT)
&& (GET_MODE_SIZE (operand_mode[i])
@@ -2775,7 +2800,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
&& INTEGRAL_MODE_P (GET_MODE (operand))
&& LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
#endif
))
)
#endif
)
/* Subreg of a hard reg which can't handle the subreg's mode
or which would handle that mode in the wrong number of
registers for subregging to work. */
@@ -4162,6 +4189,29 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
GET_MODE (SUBREG_REG (x)))) != 0)
return tem;
/* If the SUBREG is wider than a word, the above test will fail.
For example, we might have a SImode SUBREG of a DImode SUBREG_REG
for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
a 32 bit target. We still can - and have to - handle this
for non-paradoxical subregs of CONST_INTs. */
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0
&& GET_CODE (reg_equiv_constant[regno]) == CONST_INT
&& (GET_MODE_SIZE (GET_MODE (x))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
{
int shift = SUBREG_WORD (x) * BITS_PER_WORD;
if (WORDS_BIG_ENDIAN)
shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
- GET_MODE_BITSIZE (GET_MODE (x))
- shift);
/* Here we use the knowledge that CONST_INTs have a
HOST_WIDE_INT field. */
if (shift >= HOST_BITS_PER_WIDE_INT)
shift = HOST_BITS_PER_WIDE_INT - 1;
return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
}
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0
&& GET_MODE (reg_equiv_constant[regno]) == VOIDmode)

View File

@@ -3108,30 +3108,21 @@ eliminate_regs (x, mem_mode, insn, storing)
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
&& 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)
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
)
)
|| (x_size == new_size))
)
{
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
enum machine_mode mode = GET_MODE (x);
@@ -3271,12 +3262,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);
}