aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2008-01-30 11:18:27 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2008-01-30 11:18:27 +0000
commitf36a5a8853c2407900cdc21b3a400130aa6f6dda (patch)
tree6593f73075d1b463fa35f873cbf27a2fb1776eb3
parent393c005884c547ee6d4cebb2fb938e6214714e9e (diff)
downloadgcc-f36a5a8853c2407900cdc21b3a400130aa6f6dda.zip
gcc-f36a5a8853c2407900cdc21b3a400130aa6f6dda.tar.gz
gcc-f36a5a8853c2407900cdc21b3a400130aa6f6dda.tar.bz2
re PR rtl-optimization/34998 (gcc.c-torture/execute/20040709-1.c fails for -EL -mips16 -O3)
gcc/ PR rtl-optimization/34998 * global.c (build_insn_chain): Treat non-subreg_lowpart SUBREGs of pseudos as clobbering all the words covered by the SUBREG, not just all the bytes. * ra-conflict.c (clear_reg_in_live): Likewise. Take the original df_ref rather than an extract parameter. (global_conflicts): Update call accordingly. From-SVN: r131960
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/global.c11
-rw-r--r--gcc/ra-conflict.c25
3 files changed, 37 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 176a137..f2021d2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-01-30 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR rtl-optimization/34998
+ * global.c (build_insn_chain): Treat non-subreg_lowpart
+ SUBREGs of pseudos as clobbering all the words covered by the
+ SUBREG, not just all the bytes.
+ * ra-conflict.c (clear_reg_in_live): Likewise. Take the
+ original df_ref rather than an extract parameter.
+ (global_conflicts): Update call accordingly.
+
2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange
diff --git a/gcc/global.c b/gcc/global.c
index b8a0ec7..12641a6 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -1501,6 +1501,17 @@ build_insn_chain (void)
live_subregs,
live_subregs_used,
regno, reg);
+
+ if (!DF_REF_FLAGS_IS_SET
+ (def, DF_REF_STRICT_LOWER_PART))
+ {
+ /* Expand the range to cover entire words.
+ Bytes added here are "don't care". */
+ start = start / UNITS_PER_WORD * UNITS_PER_WORD;
+ last = ((last + UNITS_PER_WORD - 1)
+ / UNITS_PER_WORD * UNITS_PER_WORD);
+ }
+
/* Ignore the paradoxical bits. */
if ((int)last > live_subregs_used[regno])
last = live_subregs_used[regno];
diff --git a/gcc/ra-conflict.c b/gcc/ra-conflict.c
index ce1dfdf..78d4f92 100644
--- a/gcc/ra-conflict.c
+++ b/gcc/ra-conflict.c
@@ -441,16 +441,14 @@ ra_init_live_subregs (bool init_value,
/* Set REG to be not live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
- HARD_REGS_LIVE. If EXTRACT is false, assume that the entire reg is
- set not live even if REG is a subreg. */
+ HARD_REGS_LIVE. DEF is the definition of the register. */
inline static void
clear_reg_in_live (sparseset allocnos_live,
sbitmap *live_subregs,
int *live_subregs_used,
HARD_REG_SET *hard_regs_live,
- rtx reg,
- bool extract)
+ rtx reg, struct df_ref *def)
{
unsigned int regno = (GET_CODE (reg) == SUBREG)
? REGNO (SUBREG_REG (reg)): REGNO (reg);
@@ -458,8 +456,8 @@ clear_reg_in_live (sparseset allocnos_live,
if (allocnum >= 0)
{
- if ((GET_CODE (reg) == SUBREG) && !extract)
-
+ if (GET_CODE (reg) == SUBREG
+ && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
{
unsigned int start = SUBREG_BYTE (reg);
unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
@@ -467,6 +465,15 @@ clear_reg_in_live (sparseset allocnos_live,
ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum),
live_subregs, live_subregs_used, allocnum, reg);
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_STRICT_LOWER_PART))
+ {
+ /* Expand the range to cover entire words.
+ Bytes added here are "don't care". */
+ start = start / UNITS_PER_WORD * UNITS_PER_WORD;
+ last = ((last + UNITS_PER_WORD - 1)
+ / UNITS_PER_WORD * UNITS_PER_WORD);
+ }
+
/* Ignore the paradoxical bits. */
if ((int)last > live_subregs_used[allocnum])
last = live_subregs_used[allocnum];
@@ -503,7 +510,8 @@ clear_reg_in_live (sparseset allocnos_live,
if (! fixed_regs[regno])
{
unsigned int start = regno;
- if ((GET_CODE (reg) == SUBREG) && !extract)
+ if (GET_CODE (reg) == SUBREG
+ && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
{
unsigned int last;
start += SUBREG_BYTE (reg);
@@ -890,8 +898,7 @@ global_conflicts (void)
rtx reg = DF_REF_REG (def);
clear_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
- &hard_regs_live, reg,
- DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT));
+ &hard_regs_live, reg, def);
if (dump_file)
dump_ref (dump_file, " clearing def", "\n",
reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);