Commit 486d8509 by Richard Kenner

(push_reload): Make test in LOAD_EXTEND_OP case more precise; handle CLASS_CANNOT_CHANGE_SIZE.

(push_reload): Make test in LOAD_EXTEND_OP case more precise; handle
CLASS_CANNOT_CHANGE_SIZE.
(find_relods): When setting force_reloads, make LOAD_EXTEND_OP case
more precise.

From-SVN: r7868
parent cc33944a
...@@ -777,8 +777,8 @@ push_reload (in, out, inloc, outloc, class, ...@@ -777,8 +777,8 @@ push_reload (in, out, inloc, outloc, class,
a pseudo and hence will become a MEM) with M1 wider than M2 and the a pseudo and hence will become a MEM) with M1 wider than M2 and the
register is a pseudo, also reload the inside expression. 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 unless they are the same where both M1 and M2 are a word or smaller, M1 is wider than M2, and
size. M2 is an integral mode that gets extended when loaded.
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.
...@@ -792,7 +792,11 @@ push_reload (in, out, inloc, outloc, class, ...@@ -792,7 +792,11 @@ push_reload (in, out, inloc, outloc, class,
STRICT_LOW_PART (presumably, in == out in the cas). STRICT_LOW_PART (presumably, in == out in the cas).
Also reload the inner expression if it does not require a secondary Also reload the inner expression if it does not require a secondary
reload but the SUBREG does. */ reload but the SUBREG does.
Finally, reload the inner expression if it is a register that is in
the class whose registers cannot be referenced in a different size
and M1 is not the same size as M2. */
if (in != 0 && GET_CODE (in) == SUBREG if (in != 0 && GET_CODE (in) == SUBREG
&& (CONSTANT_P (SUBREG_REG (in)) && (CONSTANT_P (SUBREG_REG (in))
...@@ -808,7 +812,9 @@ push_reload (in, out, inloc, outloc, class, ...@@ -808,7 +812,9 @@ push_reload (in, out, inloc, outloc, class,
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
<= UNITS_PER_WORD) <= UNITS_PER_WORD)
&& (GET_MODE_SIZE (inmode) && (GET_MODE_SIZE (inmode)
!= GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))) > 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 #endif
)) ))
|| (GET_CODE (SUBREG_REG (in)) == REG || (GET_CODE (SUBREG_REG (in)) == REG
...@@ -833,6 +839,15 @@ push_reload (in, out, inloc, outloc, class, ...@@ -833,6 +839,15 @@ push_reload (in, out, inloc, outloc, class,
SUBREG_REG (in)) SUBREG_REG (in))
== NO_REGS)) == NO_REGS))
#endif #endif
#ifdef CLASS_CANNOT_CHANGE_SIZE
|| (GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
&& (TEST_HARD_REG_BIT
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
REGNO (SUBREG_REG (in))))
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
!= GET_MODE_SIZE (inmode)))
#endif
)) ))
{ {
in_subreg_loc = inloc; in_subreg_loc = inloc;
...@@ -885,15 +900,7 @@ push_reload (in, out, inloc, outloc, class, ...@@ -885,15 +900,7 @@ push_reload (in, out, inloc, outloc, class,
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER) && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|| GET_CODE (SUBREG_REG (out)) == MEM) || GET_CODE (SUBREG_REG (out)) == MEM)
&& ((GET_MODE_SIZE (outmode) && ((GET_MODE_SIZE (outmode)
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
#ifdef LOAD_EXTEND_OP
|| (GET_MODE_SIZE (outmode) <= 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)))))
#endif
))
|| (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_MODE_SIZE (outmode) <= UNITS_PER_WORD && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
...@@ -913,6 +920,15 @@ push_reload (in, out, inloc, outloc, class, ...@@ -913,6 +920,15 @@ push_reload (in, out, inloc, outloc, class,
SUBREG_REG (out)) SUBREG_REG (out))
== NO_REGS)) == NO_REGS))
#endif #endif
#ifdef CLASS_CANNOT_CHANGE_SIZE
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& (TEST_HARD_REG_BIT
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
REGNO (SUBREG_REG (out))))
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
!= GET_MODE_SIZE (outmode)))
#endif
)) ))
{ {
out_subreg_loc = outloc; out_subreg_loc = outloc;
...@@ -2553,9 +2569,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -2553,9 +2569,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
may not be enough to do the outer reference. may not be enough to do the outer reference.
On machines that extend byte operations and we have a On machines that extend byte operations and we have a
SUBREG where both the inner and outer modes are different SUBREG where both the inner and outer modes are no wider
size but no wider than a word, combine.c has made than a word and the inner mode is narrower, is integral,
assumptions about the behavior of the machine in such and gets extended when loaded from memory, combine.c has
made assumptions about the behavior of the machine in such
register access. If the data is, in fact, in memory we register access. If the data is, in fact, in memory we
must always load using the size assumed to be in the must always load using the size assumed to be in the
register and let the insn do the different-sized register and let the insn do the different-sized
...@@ -2572,7 +2589,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -2572,7 +2589,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
&& (GET_MODE_SIZE (GET_MODE (operand)) && (GET_MODE_SIZE (GET_MODE (operand))
<= UNITS_PER_WORD) <= UNITS_PER_WORD)
&& (GET_MODE_SIZE (operand_mode[i]) && (GET_MODE_SIZE (operand_mode[i])
!= GET_MODE_SIZE (GET_MODE (operand)))) > GET_MODE_SIZE (GET_MODE (operand)))
&& 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 /* Subreg of a hard reg which can't handle the subreg's mode
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment