Commit d9d09ca2 by Eric Botcazou

reload.c (reload_inner_reg_of_subreg): Change type of return value and type of…

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
parent bfd5f9f5
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> 2011-10-26 Alexandre Oliva <aoliva@redhat.com>
PR debug/50826 PR debug/50826
...@@ -12,7 +22,7 @@ ...@@ -12,7 +22,7 @@
(statement_sink_location): Use it. (statement_sink_location): Use it.
* params.def (SINK_FREQUENCY_THRESHOLD): New PARAM. * 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 PR target/48108
* config/darwin.c (top level): Amend comments concerning LTO output. * config/darwin.c (top level): Amend comments concerning LTO output.
...@@ -256,7 +256,6 @@ static int push_secondary_reload (int, rtx, int, int, enum reg_class, ...@@ -256,7 +256,6 @@ static int push_secondary_reload (int, rtx, int, int, enum reg_class,
enum insn_code *, secondary_reload_info *); enum insn_code *, secondary_reload_info *);
static enum reg_class find_valid_class (enum machine_mode, enum machine_mode, static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
int, unsigned int); 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 push_replacement (rtx *, int, enum machine_mode);
static void dup_replacements (rtx *, rtx *); static void dup_replacements (rtx *, rtx *);
static void combine_reloads (void); static void combine_reloads (void);
...@@ -791,39 +790,39 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass, ...@@ -791,39 +790,39 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
return n_reloads; return n_reloads;
} }
/* Return nonzero if X is a SUBREG which will require reloading of its /* Return true if X is a SUBREG that will need reloading of its SUBREG_REG
SUBREG_REG expression. */ 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 static bool
reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, int output) reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, bool output)
{ {
rtx inner; rtx inner;
/* Only SUBREGs are problematical. */ /* Only SUBREGs are problematical. */
if (GET_CODE (x) != SUBREG) if (GET_CODE (x) != SUBREG)
return 0; return false;
inner = SUBREG_REG (x); 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) 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 /* If INNER is not a hard register, then INNER will not need reloading. */
be reloaded. */ if (!(REG_P (inner) && HARD_REGISTER_P (inner)))
if (!REG_P (inner) return false;
|| REGNO (inner) >= FIRST_PSEUDO_REGISTER)
return 0;
/* If INNER is not ok for MODE, then INNER will need reloading. */ /* If INNER is not ok for MODE, then INNER will need reloading. */
if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode)) if (!HARD_REGNO_MODE_OK (subreg_regno (x), mode))
return 1; return true;
/* If the outer part is a word or smaller, INNER larger than a /* If this is for an output, and the outer part is a word or smaller,
word and the number of regs for INNER is not the same as the INNER is larger than a word and the number of registers in INNER is
number of words in INNER, then INNER will need reloading. */ not the same as the number of words in INNER, then INNER will need
return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD reloading (with an in-out reload). */
&& output 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
&& ((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)])); != (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
...@@ -990,9 +989,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, ...@@ -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 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 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. 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
either M1 is not valid for R or M2 is wider than a word but we only where either M1 is not valid for R or M2 is wider than a word but we
need one word to store an M2-sized quantity in R. only need one register to store an M2-sized quantity in R.
(However, if OUT is nonzero, we need to reload the reg *and* (However, if OUT is nonzero, we need to reload the reg *and*
the subreg, so do nothing here, and let following statement handle it.) 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, ...@@ -1082,17 +1081,16 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
inmode = GET_MODE (in); inmode = GET_MODE (in);
} }
/* 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
either M1 is not valid for R or M2 is wider than a word but we only where M1 is not valid for R if it was not handled by the code above.
need one word to store an M2-sized quantity in R.
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 However, we must reload the inner reg *as well as* the subreg in
that case. */ that case. */
/* Similar issue for (SUBREG constant ...) if it was not handled by the if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
code above. This can happen if SUBREG_BYTE != 0. */
if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
{ {
enum reg_class in_class = rclass; enum reg_class in_class = rclass;
...@@ -1168,31 +1166,32 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, ...@@ -1168,31 +1166,32 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
outmode = GET_MODE (out); outmode = GET_MODE (out);
} }
/* 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
either M1 is not valid for R or M2 is wider than a word but we only where either M1 is not valid for R or M2 is wider than a word but we
need one word to store an M2-sized quantity in R. 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 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 /* This relies on the fact that emit_reload_insns outputs the
instructions for output reloads of type RELOAD_OTHER in reverse instructions for output reloads of type RELOAD_OTHER in reverse
order of the reloads. Thus if the outer reload is also of type order of the reloads. Thus if the outer reload is also of type
RELOAD_OTHER, we are guaranteed that this inner reload will be RELOAD_OTHER, we are guaranteed that this inner reload will be
output after the outer reload. */ output after the outer reload. */
dont_remove_subreg = 1;
push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out), push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
&SUBREG_REG (out), &SUBREG_REG (out), in_out_class, VOIDmode, VOIDmode,
find_valid_class (outmode, GET_MODE (SUBREG_REG (out)), 0, 0, opnum, RELOAD_OTHER);
subreg_regno_offset (REGNO (SUBREG_REG (out)), dont_remove_subreg = 1;
GET_MODE (SUBREG_REG (out)),
SUBREG_BYTE (out),
GET_MODE (out)),
REGNO (SUBREG_REG (out))),
VOIDmode, VOIDmode, 0, 0,
opnum, RELOAD_OTHER);
} }
/* If IN appears in OUT, we can't share any input-only reload for IN. */ /* If IN appears in OUT, we can't share any input-only reload for IN. */
......
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