aboutsummaryrefslogtreecommitdiff
path: root/gcc/ra-conflict.c
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 /gcc/ra-conflict.c
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
Diffstat (limited to 'gcc/ra-conflict.c')
-rw-r--r--gcc/ra-conflict.c25
1 files changed, 16 insertions, 9 deletions
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);