re PR rtl-optimization/34998 (gcc.c-torture/execute/20040709-1.c fails for -EL -mips1...
authorRichard Sandiford <rsandifo@nildram.co.uk>
Wed, 30 Jan 2008 11:18:27 +0000 (11:18 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Jan 2008 11:18:27 +0000 (11:18 +0000)
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

gcc/ChangeLog
gcc/global.c
gcc/ra-conflict.c

index 176a1372e662353b13ec27e37694817adf4e7221..f2021d2c51ad73353f661a163735f0e1e159feb4 100644 (file)
@@ -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
index b8a0ec7815850059ebeb9d7fd81ae448c6f39ce1..12641a60cba593f782417be9274fccdf64c4ee8c 100644 (file)
@@ -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];
index ce1dfdfcfb7782f24d394c29fc8decf8afbce97e..78d4f9246f07935201361bb5ff82ed719b087067 100644 (file)
@@ -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);