reload.c (reload_inner_reg_of_subreg): Change type of return value and type of OUTPUT parameter to bool and adjust.
* reload.c (reload_inner_reg_of_subreg): Change type of return value and type of OUTPUT parameter to bool and adjust. Document MODE and OUTPUT parameters. Use HARD_REGISTER_P. Reorder final condition and improve associated comment. (push_reload): Clarify and update comments about reloading of subregs. Adjust calls to reload_inner_reg_of_subreg. Compute the class upfront for the reloading of subregs in the out case as well. From-SVN: r180526
This commit is contained in:
parent
bfd5f9f59d
commit
d9d09ca2d6
|
@ -1,3 +1,13 @@
|
|||
2011-10-26 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* reload.c (reload_inner_reg_of_subreg): Change type of return value
|
||||
and type of OUTPUT parameter to bool and adjust. Document MODE and
|
||||
OUTPUT parameters. Use HARD_REGISTER_P. Reorder final condition
|
||||
and improve associated comment.
|
||||
(push_reload): Clarify and update comments about reloading of subregs.
|
||||
Adjust calls to reload_inner_reg_of_subreg. Compute the class upfront
|
||||
for the reloading of subregs in the out case as well.
|
||||
|
||||
2011-10-26 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR debug/50826
|
||||
|
@ -12,7 +22,7 @@
|
|||
(statement_sink_location): Use it.
|
||||
* params.def (SINK_FREQUENCY_THRESHOLD): New PARAM.
|
||||
|
||||
2011-10-14 Iain Sandoe <iains@gcc.gnu.org>
|
||||
2011-10-26 Iain Sandoe <iains@gcc.gnu.org>
|
||||
|
||||
PR target/48108
|
||||
* config/darwin.c (top level): Amend comments concerning LTO output.
|
||||
|
|
89
gcc/reload.c
89
gcc/reload.c
|
@ -256,7 +256,6 @@ static int push_secondary_reload (int, rtx, int, int, enum reg_class,
|
|||
enum insn_code *, secondary_reload_info *);
|
||||
static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
|
||||
int, unsigned int);
|
||||
static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int);
|
||||
static void push_replacement (rtx *, int, enum machine_mode);
|
||||
static void dup_replacements (rtx *, rtx *);
|
||||
static void combine_reloads (void);
|
||||
|
@ -791,39 +790,39 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
|
|||
return n_reloads;
|
||||
}
|
||||
|
||||
/* Return nonzero if X is a SUBREG which will require reloading of its
|
||||
SUBREG_REG expression. */
|
||||
/* Return true if X is a SUBREG that will need reloading of its SUBREG_REG
|
||||
expression. MODE is the mode that X will be used in. OUTPUT is true if
|
||||
the function is invoked for the output part of an enclosing reload. */
|
||||
|
||||
static int
|
||||
reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, int output)
|
||||
static bool
|
||||
reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, bool output)
|
||||
{
|
||||
rtx inner;
|
||||
|
||||
/* Only SUBREGs are problematical. */
|
||||
if (GET_CODE (x) != SUBREG)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
inner = SUBREG_REG (x);
|
||||
|
||||
/* If INNER is a constant or PLUS, then INNER must be reloaded. */
|
||||
/* If INNER is a constant or PLUS, then INNER will need reloading. */
|
||||
if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
/* If INNER is not a hard register, then INNER will not need to
|
||||
be reloaded. */
|
||||
if (!REG_P (inner)
|
||||
|| REGNO (inner) >= FIRST_PSEUDO_REGISTER)
|
||||
return 0;
|
||||
/* If INNER is not a hard register, then INNER will not need reloading. */
|
||||
if (!(REG_P (inner) && HARD_REGISTER_P (inner)))
|
||||
return false;
|
||||
|
||||
/* If INNER is not ok for MODE, then INNER will need reloading. */
|
||||
if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
|
||||
return 1;
|
||||
if (!HARD_REGNO_MODE_OK (subreg_regno (x), mode))
|
||||
return true;
|
||||
|
||||
/* If the outer part is a word or smaller, INNER larger than a
|
||||
word and the number of regs for INNER is not the same as the
|
||||
number of words in INNER, then INNER will need reloading. */
|
||||
return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
|
||||
&& output
|
||||
/* If this is for an output, and the outer part is a word or smaller,
|
||||
INNER is larger than a word and the number of registers in INNER is
|
||||
not the same as the number of words in INNER, then INNER will need
|
||||
reloading (with an in-out reload). */
|
||||
return (output
|
||||
&& GET_MODE_SIZE (mode) <= UNITS_PER_WORD
|
||||
&& GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
|
||||
&& ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
|
||||
!= (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
|
||||
|
@ -990,9 +989,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
|||
For machines that extend byte loads, do this for any SUBREG of a pseudo
|
||||
where both M1 and M2 are a word or smaller, M1 is wider than M2, and
|
||||
M2 is an integral mode that gets extended when loaded.
|
||||
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
|
||||
need one word to store an M2-sized quantity in R.
|
||||
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 need one register to store an M2-sized quantity in R.
|
||||
(However, if OUT is nonzero, we need to reload the reg *and*
|
||||
the subreg, so do nothing here, and let following statement handle it.)
|
||||
|
||||
|
@ -1082,17 +1081,16 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
|||
inmode = GET_MODE (in);
|
||||
}
|
||||
|
||||
/* 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
|
||||
need one word to store an M2-sized quantity in R.
|
||||
/* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R
|
||||
where M1 is not valid for R if it was not handled by the code above.
|
||||
|
||||
Similar issue for (SUBREG constant ...) if it was not handled by the
|
||||
code above. This can happen if SUBREG_BYTE != 0.
|
||||
|
||||
However, we must reload the inner reg *as well as* the subreg in
|
||||
that case. */
|
||||
|
||||
/* Similar issue for (SUBREG constant ...) if it was not handled by the
|
||||
code above. This can happen if SUBREG_BYTE != 0. */
|
||||
|
||||
if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
|
||||
if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
|
||||
{
|
||||
enum reg_class in_class = rclass;
|
||||
|
||||
|
@ -1168,31 +1166,32 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|
|||
outmode = GET_MODE (out);
|
||||
}
|
||||
|
||||
/* 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
|
||||
need one word to store an M2-sized quantity in R.
|
||||
/* 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 need one register to store an M2-sized quantity in R.
|
||||
|
||||
However, we must reload the inner reg *as well as* the subreg in
|
||||
that case. In this case, the inner reg is an in-out reload. */
|
||||
that case and the inner reg is an in-out reload. */
|
||||
|
||||
if (out != 0 && reload_inner_reg_of_subreg (out, outmode, 1))
|
||||
if (out != 0 && reload_inner_reg_of_subreg (out, outmode, true))
|
||||
{
|
||||
enum reg_class in_out_class
|
||||
= find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
|
||||
subreg_regno_offset (REGNO (SUBREG_REG (out)),
|
||||
GET_MODE (SUBREG_REG (out)),
|
||||
SUBREG_BYTE (out),
|
||||
GET_MODE (out)),
|
||||
REGNO (SUBREG_REG (out)));
|
||||
|
||||
/* This relies on the fact that emit_reload_insns outputs the
|
||||
instructions for output reloads of type RELOAD_OTHER in reverse
|
||||
order of the reloads. Thus if the outer reload is also of type
|
||||
RELOAD_OTHER, we are guaranteed that this inner reload will be
|
||||
output after the outer reload. */
|
||||
dont_remove_subreg = 1;
|
||||
push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
|
||||
&SUBREG_REG (out),
|
||||
find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
|
||||
subreg_regno_offset (REGNO (SUBREG_REG (out)),
|
||||
GET_MODE (SUBREG_REG (out)),
|
||||
SUBREG_BYTE (out),
|
||||
GET_MODE (out)),
|
||||
REGNO (SUBREG_REG (out))),
|
||||
VOIDmode, VOIDmode, 0, 0,
|
||||
opnum, RELOAD_OTHER);
|
||||
&SUBREG_REG (out), in_out_class, VOIDmode, VOIDmode,
|
||||
0, 0, opnum, RELOAD_OTHER);
|
||||
dont_remove_subreg = 1;
|
||||
}
|
||||
|
||||
/* If IN appears in OUT, we can't share any input-only reload for IN. */
|
||||
|
|
Loading…
Reference in New Issue