gcc/:
authorabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jan 2012 07:29:18 +0000 (07:29 +0000)
committerabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jan 2012 07:29:18 +0000 (07:29 +0000)
2012-01-19 Andrey Belevantsev <abel@ispras.ru>

PR rtl-optimization/51505
* df-problems.c (df_kill_notes): New parameter live. Update comment.
Remove REG_EQUAL/REG_EQUIV notes referring to dead registers.
(df_note_bb_compute): Update the call to df_kill_notes.

testsuite/:
2012-01-19 Andrey Belevantsev <abel@ispras.ru>

PR rtl-optimization/51505
* gcc.dg/pr51505.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183296 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/df-problems.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr51505.c [new file with mode: 0644]

index dc61564..5b70bf3 100644 (file)
@@ -1,3 +1,10 @@
+2012-01-19 Andrey Belevantsev <abel@ispras.ru>
+
+       PR rtl-optimization/51505
+       * df-problems.c (df_kill_notes): New parameter live. Update comment.
+       Remove REG_EQUAL/REG_EQUIV notes referring to dead registers.
+       (df_note_bb_compute): Update the call to df_kill_notes. 
+
 2012-01-18  Aldy Hernandez  <aldyh@redhat.com>
 
        * trans-mem.c (requires_barrier): Remove call to is_global_var.
index 8928454..f9b0bc1 100644 (file)
@@ -2748,10 +2748,12 @@ df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
 
 
 /* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add
-   them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES.  */
+   them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES.  Remove also
+   REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
+   as the bitmap of currently live registers.  */
 
 static void
-df_kill_notes (rtx insn)
+df_kill_notes (rtx insn, bitmap live)
 {
   rtx *pprev = &REG_NOTES (insn);
   rtx link = *pprev;
@@ -2798,6 +2800,45 @@ df_kill_notes (rtx insn)
            }
          break;
 
+       case REG_EQUAL:
+       case REG_EQUIV:
+         {
+           /* Remove the notes that refer to dead registers.  As we have at most
+              one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note
+              so we need to purge the complete EQ_USES vector when removing
+              the note using df_notes_rescan.  */
+           df_ref *use_rec;
+           bool deleted = false;
+
+           for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++)
+             {
+               df_ref use = *use_rec;
+               if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER
+                   && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
+                   && ! bitmap_bit_p (live, DF_REF_REGNO (use)))
+                 {
+                   deleted = true;
+                   break;
+                 }
+             }
+           if (deleted)
+             {
+               rtx next;
+#ifdef REG_DEAD_DEBUGGING
+               df_print_note ("deleting: ", insn, link);
+#endif
+               next = XEXP (link, 1);
+               free_EXPR_LIST_node (link);
+               *pprev = link = next;
+               df_notes_rescan (insn);
+             }
+           else
+             {
+               pprev = &XEXP (link, 1);
+               link = *pprev;
+             }
+           break;
+         }
        default:
          pprev = &XEXP (link, 1);
          link = *pprev;
@@ -3299,7 +3340,7 @@ df_note_bb_compute (unsigned int bb_index,
       debug_insn = DEBUG_INSN_P (insn);
 
       bitmap_clear (do_not_gen);
-      df_kill_notes (insn);
+      df_kill_notes (insn, live);
 
       /* Process the defs.  */
       if (CALL_P (insn))
index 1d982ec..a0d5a19 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-19 Andrey Belevantsev <abel@ispras.ru>
+
+       PR rtl-optimization/51505
+       * gcc.dg/pr51505.c: New test.
+
 2012-01-18  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/51634
diff --git a/gcc/testsuite/gcc.dg/pr51505.c b/gcc/testsuite/gcc.dg/pr51505.c
new file mode 100644 (file)
index 0000000..dbcd322
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR rtl-optimization/51505 */
+/* { dg-do compile } */
+/* { dg-options "-O --param max-cse-insns=1" } */
+struct S
+{
+char a[256];
+};
+
+int bar(struct S, char[16]);
+
+void foo ()
+{
+  struct S u, s1, s2;
+  char e[256];
+  char i;
+  e[i] = ~s1.a[i] & s2.a[i];
+  if (bar(u, e))
+    __builtin_abort ();
+}