re PR rtl-optimization/57518 (Redundant insn generated in LRA)
authorWei Mi <wmi@google.com>
Wed, 19 Jun 2013 21:57:42 +0000 (21:57 +0000)
committerWei Mi <wmi@gcc.gnu.org>
Wed, 19 Jun 2013 21:57:42 +0000 (21:57 +0000)
2013-06-19  Wei Mi  <wmi@google.com>

PR rtl-optimization/57518
* ira.c (set_paradoxical_subreg): Set pdx_subregs[regno]
if regno is used in paradoxical subreg.
(update_equiv_regs): Check pdx_subregs[regno] before
set a reg to be equivalent with a mem.

From-SVN: r200224

gcc/ChangeLog
gcc/ira.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr57518.c [new file with mode: 0644]

index c754159..8973cb9 100644 (file)
@@ -1,3 +1,11 @@
+2013-06-19  Wei Mi  <wmi@google.com>
+
+       PR rtl-optimization/57518
+       * ira.c (set_paradoxical_subreg): Set pdx_subregs[regno]
+       if regno is used in paradoxical subreg.
+       (update_equiv_regs): Check pdx_subregs[regno] before
+       set a reg to be equivalent with a mem.
+
 2013-06-19  Matthias Klose  <doko@ubuntu.com>
 
        PR driver/57651
index ff901aa..ee0c5e8 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2863,6 +2863,28 @@ no_equiv (rtx reg, const_rtx store ATTRIBUTE_UNUSED,
     }
 }
 
+/* Check whether the SUBREG is a paradoxical subreg and set the result
+   in PDX_SUBREGS.  */
+
+static int
+set_paradoxical_subreg (rtx *subreg, void *pdx_subregs)
+{
+  rtx reg;
+
+  if ((*subreg) == NULL_RTX)
+    return 1;
+  if (GET_CODE (*subreg) != SUBREG)
+    return 0;
+  reg = SUBREG_REG (*subreg);
+  if (!REG_P (reg))
+    return 0;
+
+  if (paradoxical_subreg_p (*subreg))
+    ((bool *)pdx_subregs)[REGNO (reg)] = true;
+
+  return 0;
+}
+
 /* In DEBUG_INSN location adjust REGs from CLEARED_REGS bitmap to the
    equivalent replacement.  */
 
@@ -2901,16 +2923,33 @@ update_equiv_regs (void)
   basic_block bb;
   int loop_depth;
   bitmap cleared_regs;
+  bool *pdx_subregs;
 
   /* We need to keep track of whether or not we recorded a LABEL_REF so
      that we know if the jump optimizer needs to be rerun.  */
   recorded_label_ref = 0;
 
+  /* Use pdx_subregs to show whether a reg is used in a paradoxical
+     subreg.  */
+  pdx_subregs = XCNEWVEC (bool, max_regno);
+
   reg_equiv = XCNEWVEC (struct equivalence, max_regno);
   grow_reg_equivs ();
 
   init_alias_analysis ();
 
+  /* Scan insns and set pdx_subregs[regno] if the reg is used in a
+     paradoxical subreg. Don't set such reg sequivalent to a mem,
+     because lra will not substitute such equiv memory in order to
+     prevent access beyond allocated memory for paradoxical memory subreg.  */
+  FOR_EACH_BB (bb)
+    FOR_BB_INSNS (bb, insn)
+      {
+       if (! INSN_P (insn))
+         continue;
+       for_each_rtx (&insn, set_paradoxical_subreg, (void *)pdx_subregs);
+      }
+
   /* Scan the insns and find which registers have equivalences.  Do this
      in a separate scan of the insns because (due to -fcse-follow-jumps)
      a register can be set below its use.  */
@@ -3012,6 +3051,13 @@ update_equiv_regs (void)
              continue;
            }
 
+         /* Don't set reg (if pdx_subregs[regno] == true) equivalent to a mem.  */
+         if (MEM_P (src) && pdx_subregs[regno])
+           {
+             note_stores (set, no_equiv, NULL);
+             continue;
+           }
+
          note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
 
          /* cse sometimes generates function invariants, but doesn't put a
@@ -3170,7 +3216,8 @@ update_equiv_regs (void)
          && reg_equiv[regno].init_insns != const0_rtx
          && ! find_reg_note (XEXP (reg_equiv[regno].init_insns, 0),
                              REG_EQUIV, NULL_RTX)
-         && ! contains_replace_regs (XEXP (dest, 0)))
+         && ! contains_replace_regs (XEXP (dest, 0))
+         && ! pdx_subregs[regno])
        {
          rtx init_insn = XEXP (reg_equiv[regno].init_insns, 0);
          if (validate_equiv_mem (init_insn, src, dest)
@@ -3361,6 +3408,7 @@ update_equiv_regs (void)
 
   end_alias_analysis ();
   free (reg_equiv);
+  free (pdx_subregs);
   return recorded_label_ref;
 }
 
index c70ea03..7930071 100644 (file)
@@ -1,3 +1,8 @@
+2013-06-19  Wei Mi  <wmi@google.com>
+
+       PR rtl-optimization/57518
+       * testsuite/gcc.dg/pr57518.c: New test.
+
 2013-06-19  Igor Zamyatin  <igor.zamyatin@intel.com>
 
        * gcc.dg/tree-ssa/loop-19.c: Add -fno-common.
diff --git a/gcc/testsuite/gcc.dg/pr57518.c b/gcc/testsuite/gcc.dg/pr57518.c
new file mode 100644 (file)
index 0000000..4c84a85
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/57130 */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-ira" } */
+/* { dg-final { scan-rtl-dump-not "REG_EQUIV.*mem.*\"ip\"" "ira" } } */
+
+char ip[10];
+int total;
+
+void foo() {
+  int t;
+
+  t = ip[2];
+  total = t & 0x3;
+}