(push_reload, find_reloads): Treat (subreg (pseudo)) and (subreg (mem)) the same.
(push_reload, find_reloads): Treat (subreg (pseudo)) and (subreg (mem)) the same. If we have (subreg:M1 (mem:M2 ...) ...), never do anything special if M1 and M2 are the same size. From-SVN: r5097
This commit is contained in:
parent
126424267e
commit
a61c98cf7f
62
gcc/reload.c
62
gcc/reload.c
|
@ -612,12 +612,14 @@ push_reload (in, out, inloc, outloc, class,
|
||||||
out = gen_rtx (MEM, GET_MODE (out), XEXP (XEXP (out, 0), 0));
|
out = gen_rtx (MEM, GET_MODE (out), XEXP (XEXP (out, 0), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are reloading a (SUBREG (MEM ...) ...) or (SUBREG constant ...),
|
/* If we are reloading a (SUBREG constant ...), really reload just the
|
||||||
really reload just the inside expression in its own mode.
|
inside expression in its own mode.
|
||||||
If we have (SUBREG:M1 (REG:M2 ...) ...) with M1 wider than M2 and the
|
If we have (SUBREG:M1 (MEM:M2 ...) ...) (or an inner REG that is still
|
||||||
register is a pseudo, this will become the same as the above case.
|
a pseudo and hence will become a MEM) with M1 wider than M2 and the
|
||||||
|
register is a pseudo, also reload the inside expression.
|
||||||
For machines that extend byte loads, do this for any SUBREG of a pseudo
|
For machines that extend byte loads, do this for any SUBREG of a pseudo
|
||||||
where both M1 and M2 are a word or smaller.
|
where both M1 and M2 are a word or smaller unless they are the same
|
||||||
|
size.
|
||||||
Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
|
Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
|
||||||
either M1 is not valid for R or M2 is wider than a word but we only
|
either M1 is not valid for R or M2 is wider than a word but we only
|
||||||
need one word to store an M2-sized quantity in R.
|
need one word to store an M2-sized quantity in R.
|
||||||
|
@ -634,19 +636,23 @@ push_reload (in, out, inloc, outloc, class,
|
||||||
reload but the SUBREG does. */
|
reload but the SUBREG does. */
|
||||||
|
|
||||||
if (in != 0 && GET_CODE (in) == SUBREG
|
if (in != 0 && GET_CODE (in) == SUBREG
|
||||||
&& (GET_CODE (SUBREG_REG (in)) != REG
|
&& (CONSTANT_P (SUBREG_REG (in))
|
||||||
|| strict_low
|
|| strict_low
|
||||||
|| (GET_CODE (SUBREG_REG (in)) == REG
|
|| (((GET_CODE (SUBREG_REG (in)) == REG
|
||||||
&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER
|
&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
|
||||||
|
|| GET_CODE (SUBREG_REG (in)) == MEM)
|
||||||
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
||||||
&& GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
|
&& GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
|
||||||
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) <= UNITS_PER_WORD
|
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) <= UNITS_PER_WORD
|
||||||
|
&& (GET_MODE_SIZE (inmode)
|
||||||
|
!= GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
|
||||||
#else
|
#else
|
||||||
&& (GET_MODE_SIZE (inmode)
|
&& (GET_MODE_SIZE (inmode)
|
||||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
|
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
|| (REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
|
|| (GET_CODE (SUBREG_REG (in)) == REG
|
||||||
|
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
|
||||||
/* The case where out is nonzero
|
/* The case where out is nonzero
|
||||||
is handled differently in the following statement. */
|
is handled differently in the following statement. */
|
||||||
&& (out == 0 || SUBREG_WORD (in) == 0)
|
&& (out == 0 || SUBREG_WORD (in) == 0)
|
||||||
|
@ -713,13 +719,16 @@ push_reload (in, out, inloc, outloc, class,
|
||||||
(except in the case of STRICT_LOW_PART,
|
(except in the case of STRICT_LOW_PART,
|
||||||
and in that case the constraint should label it input-output.) */
|
and in that case the constraint should label it input-output.) */
|
||||||
if (out != 0 && GET_CODE (out) == SUBREG
|
if (out != 0 && GET_CODE (out) == SUBREG
|
||||||
&& (GET_CODE (SUBREG_REG (out)) != REG
|
&& (CONSTANT_P (SUBREG_REG (out))
|
||||||
|| strict_low
|
|| strict_low
|
||||||
|| (GET_CODE (SUBREG_REG (out)) == REG
|
|| (((GET_CODE (SUBREG_REG (out)) == REG
|
||||||
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER
|
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|
||||||
|
|| GET_CODE (SUBREG_REG (out)) == MEM)
|
||||||
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
||||||
&& GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
|
&& GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
|
||||||
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) <= UNITS_PER_WORD
|
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) <= UNITS_PER_WORD
|
||||||
|
&& (GET_MODE_SIZE (outmode)
|
||||||
|
!= GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
|
||||||
#else
|
#else
|
||||||
&& (GET_MODE_SIZE (outmode)
|
&& (GET_MODE_SIZE (outmode)
|
||||||
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
|
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
|
||||||
|
@ -2540,25 +2549,30 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||||
{
|
{
|
||||||
offset += SUBREG_WORD (operand);
|
offset += SUBREG_WORD (operand);
|
||||||
operand = SUBREG_REG (operand);
|
operand = SUBREG_REG (operand);
|
||||||
/* Force reload if this is not a register or if there may may
|
/* Force reload if this is a constant or if there may may
|
||||||
be a problem accessing the register in the outer mode. */
|
be a problem accessing OPERAND in the outer mode. */
|
||||||
if (GET_CODE (operand) != REG
|
if (CONSTANT_P (operand)
|
||||||
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
|
||||||
/* If we have a SUBREG where both the inner and outer
|
/* If we have a SUBREG where both the inner and outer
|
||||||
modes are different but no wider than a word, combine.c
|
modes are different size but no wider than a word,
|
||||||
has made assumptions about the behavior of the machine
|
combine.c has made assumptions about the behavior of
|
||||||
in such register access. If the data is, in fact, in
|
the machine in such register access. If the data is,
|
||||||
memory we must always load using the size assumed to
|
in fact, in memory we must always load using the size
|
||||||
be in the register and let the insn do the different-sized
|
assumed to be in the register and let the insn do the
|
||||||
accesses. */
|
different-sized accesses. */
|
||||||
|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
|
|| ((GET_CODE (operand) == MEM
|
||||||
|
|| (GET_CODE (operand)== REG
|
||||||
|
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
|
||||||
&& GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
|
&& GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
|
||||||
&& GET_MODE_SIZE (GET_MODE (operand)) <= UNITS_PER_WORD)
|
&& GET_MODE_SIZE (GET_MODE (operand)) <= UNITS_PER_WORD
|
||||||
|
&& (GET_MODE_SIZE (operand_mode[i])
|
||||||
|
!= GET_MODE_SIZE (GET_MODE (operand))))
|
||||||
#endif
|
#endif
|
||||||
/* Subreg of a hard reg which can't handle the subreg's mode
|
/* Subreg of a hard reg which can't handle the subreg's mode
|
||||||
or which would handle that mode in the wrong number of
|
or which would handle that mode in the wrong number of
|
||||||
registers for subregging to work. */
|
registers for subregging to work. */
|
||||||
|| (REGNO (operand) < FIRST_PSEUDO_REGISTER
|
|| (GET_CODE (operand) == REG
|
||||||
|
&& REGNO (operand) < FIRST_PSEUDO_REGISTER
|
||||||
&& ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
|
&& ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
|
||||||
&& (GET_MODE_SIZE (GET_MODE (operand))
|
&& (GET_MODE_SIZE (GET_MODE (operand))
|
||||||
> UNITS_PER_WORD)
|
> UNITS_PER_WORD)
|
||||||
|
|
Loading…
Reference in New Issue