Commit 9dcf1f86 by Richard Sandiford Committed by Richard Sandiford

poly_int: ira subreg liveness tracking

Normmaly the IRA-reload interface tries to track the liveness of
individual bytes of an allocno if the allocno is sometimes written
to as a SUBREG.  This isn't possible for variable-sized allocnos,
but it doesn't matter because targets with variable-sized registers
should use LRA instead.

This patch adds a get_subreg_tracking_sizes function for deciding
whether it is possible to model a partial read or write.  Later
patches make it return false if anything is variable.

2017-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* ira.c (get_subreg_tracking_sizes): New function.
	(init_live_subregs): Take an integer size rather than a register.
	(build_insn_chain): Use get_subreg_tracking_sizes.  Update calls
	to init_live_subregs.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r255881
parent 7f679e47
...@@ -2,6 +2,15 @@ ...@@ -2,6 +2,15 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* ira.c (get_subreg_tracking_sizes): New function.
(init_live_subregs): Take an integer size rather than a register.
(build_insn_chain): Use get_subreg_tracking_sizes. Update calls
to init_live_subregs.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* expr.c (store_constructor_field): Change bitsize from a * expr.c (store_constructor_field): Change bitsize from a
unsigned HOST_WIDE_INT to a poly_uint64 and bitpos from a unsigned HOST_WIDE_INT to a poly_uint64 and bitpos from a
HOST_WIDE_INT to a poly_int64. HOST_WIDE_INT to a poly_int64.
...@@ -4037,16 +4037,27 @@ pseudo_for_reload_consideration_p (int regno) ...@@ -4037,16 +4037,27 @@ pseudo_for_reload_consideration_p (int regno)
return (reg_renumber[regno] >= 0 || ira_conflicts_p); return (reg_renumber[regno] >= 0 || ira_conflicts_p);
} }
/* Init LIVE_SUBREGS[ALLOCNUM] and LIVE_SUBREGS_USED[ALLOCNUM] using /* Return true if we can track the individual bytes of subreg X.
REG to the number of nregs, and INIT_VALUE to get the When returning true, set *OUTER_SIZE to the number of bytes in
initialization. ALLOCNUM need not be the regno of REG. */ X itself, *INNER_SIZE to the number of bytes in the inner register
and *START to the offset of the first byte. */
static bool
get_subreg_tracking_sizes (rtx x, HOST_WIDE_INT *outer_size,
HOST_WIDE_INT *inner_size, HOST_WIDE_INT *start)
{
rtx reg = regno_reg_rtx[REGNO (SUBREG_REG (x))];
*outer_size = GET_MODE_SIZE (GET_MODE (x));
*inner_size = GET_MODE_SIZE (GET_MODE (reg));
*start = SUBREG_BYTE (x);
return true;
}
/* Init LIVE_SUBREGS[ALLOCNUM] and LIVE_SUBREGS_USED[ALLOCNUM] for
a register with SIZE bytes, making the register live if INIT_VALUE. */
static void static void
init_live_subregs (bool init_value, sbitmap *live_subregs, init_live_subregs (bool init_value, sbitmap *live_subregs,
bitmap live_subregs_used, int allocnum, rtx reg) bitmap live_subregs_used, int allocnum, int size)
{ {
unsigned int regno = REGNO (SUBREG_REG (reg));
int size = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
gcc_assert (size > 0); gcc_assert (size > 0);
/* Been there, done that. */ /* Been there, done that. */
...@@ -4155,19 +4166,26 @@ build_insn_chain (void) ...@@ -4155,19 +4166,26 @@ build_insn_chain (void)
&& (!DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))) && (!DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)))
{ {
rtx reg = DF_REF_REG (def); rtx reg = DF_REF_REG (def);
HOST_WIDE_INT outer_size, inner_size, start;
/* We can model subregs, but not if they are
wrapped in ZERO_EXTRACTS. */ /* We can usually track the liveness of individual
bytes within a subreg. The only exceptions are
subregs wrapped in ZERO_EXTRACTs and subregs whose
size is not known; in those cases we need to be
conservative and treat the definition as a partial
definition of the full register rather than a full
definition of a specific part of the register. */
if (GET_CODE (reg) == SUBREG if (GET_CODE (reg) == SUBREG
&& !DF_REF_FLAGS_IS_SET (def, DF_REF_ZERO_EXTRACT)) && !DF_REF_FLAGS_IS_SET (def, DF_REF_ZERO_EXTRACT)
&& get_subreg_tracking_sizes (reg, &outer_size,
&inner_size, &start))
{ {
unsigned int start = SUBREG_BYTE (reg); HOST_WIDE_INT last = start + outer_size;
unsigned int last = start
+ GET_MODE_SIZE (GET_MODE (reg));
init_live_subregs init_live_subregs
(bitmap_bit_p (live_relevant_regs, regno), (bitmap_bit_p (live_relevant_regs, regno),
live_subregs, live_subregs_used, regno, reg); live_subregs, live_subregs_used, regno,
inner_size);
if (!DF_REF_FLAGS_IS_SET if (!DF_REF_FLAGS_IS_SET
(def, DF_REF_STRICT_LOW_PART)) (def, DF_REF_STRICT_LOW_PART))
...@@ -4252,18 +4270,20 @@ build_insn_chain (void) ...@@ -4252,18 +4270,20 @@ build_insn_chain (void)
if (regno < FIRST_PSEUDO_REGISTER if (regno < FIRST_PSEUDO_REGISTER
|| pseudo_for_reload_consideration_p (regno)) || pseudo_for_reload_consideration_p (regno))
{ {
HOST_WIDE_INT outer_size, inner_size, start;
if (GET_CODE (reg) == SUBREG if (GET_CODE (reg) == SUBREG
&& !DF_REF_FLAGS_IS_SET (use, && !DF_REF_FLAGS_IS_SET (use,
DF_REF_SIGN_EXTRACT DF_REF_SIGN_EXTRACT
| DF_REF_ZERO_EXTRACT)) | DF_REF_ZERO_EXTRACT)
&& get_subreg_tracking_sizes (reg, &outer_size,
&inner_size, &start))
{ {
unsigned int start = SUBREG_BYTE (reg); HOST_WIDE_INT last = start + outer_size;
unsigned int last = start
+ GET_MODE_SIZE (GET_MODE (reg));
init_live_subregs init_live_subregs
(bitmap_bit_p (live_relevant_regs, regno), (bitmap_bit_p (live_relevant_regs, regno),
live_subregs, live_subregs_used, regno, reg); live_subregs, live_subregs_used, regno,
inner_size);
/* Ignore the paradoxical bits. */ /* Ignore the paradoxical bits. */
if (last > SBITMAP_SIZE (live_subregs[regno])) if (last > SBITMAP_SIZE (live_subregs[regno]))
......
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