reorg.c (emit_delay_sequence): Remove death notes, not merely nop them out.
authorRichard Henderson <rth@redhat.com>
Sun, 6 Jan 2002 10:25:07 +0000 (02:25 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 6 Jan 2002 10:25:07 +0000 (02:25 -0800)
        * reorg.c (emit_delay_sequence): Remove death notes, not merely
        nop them out.  Increment label reference count for REG_LABEL.
        (fill_slots_from_thread): Frob label reference count around
        delete_related_insns.

From-SVN: r48580

gcc/ChangeLog
gcc/reorg.c

index 292a195..b76365c 100644 (file)
@@ -1,3 +1,10 @@
+2002-01-06  Richard Henderson  <rth@redhat.com>
+
+       * reorg.c (emit_delay_sequence): Remove death notes, not merely
+       nop them out.  Increment label reference count for REG_LABEL.
+       (fill_slots_from_thread): Frob label reference count around
+       delete_related_insns.
+
 2002-01-05  Richard Henderson  <rth@redhat.com>
 
        * cfgcleanup.c (try_forward_edges): Detect infinite loops while
index 409ed7d..b1c33f5 100644 (file)
@@ -489,7 +489,7 @@ emit_delay_sequence (insn, list, length)
   for (li = list; li; li = XEXP (li, 1), i++)
     {
       rtx tem = XEXP (li, 0);
-      rtx note;
+      rtx note, next;
 
       /* Show that this copy of the insn isn't deleted.  */
       INSN_DELETED_P (tem) = 0;
@@ -498,11 +498,26 @@ emit_delay_sequence (insn, list, length)
       PREV_INSN (tem) = XVECEXP (seq, 0, i - 1);
       NEXT_INSN (XVECEXP (seq, 0, i - 1)) = tem;
 
-      /* Remove any REG_DEAD notes because we can't rely on them now
-        that the insn has been moved.  */
-      for (note = REG_NOTES (tem); note; note = XEXP (note, 1))
-       if (REG_NOTE_KIND (note) == REG_DEAD)
-         XEXP (note, 0) = const0_rtx;
+      for (note = REG_NOTES (tem); note; note = next)
+       {
+         next = XEXP (note, 1);
+         switch (REG_NOTE_KIND (note))
+           {
+           case REG_DEAD:
+             /* Remove any REG_DEAD notes because we can't rely on them now
+                that the insn has been moved.  */
+             remove_note (tem, note);
+             break;
+
+           case REG_LABEL:
+             /* Keep the label reference count up to date.  */
+             LABEL_NUSES (XEXP (note, 0)) ++;
+             break;
+
+           default:
+             break;
+           }
+       }
     }
 
   NEXT_INSN (XVECEXP (seq, 0, length)) = NEXT_INSN (seq_insn);
@@ -2703,6 +2718,8 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
                     starting point of this thread.  */
                  if (own_thread)
                    {
+                     rtx note;
+
                      update_block (trial, thread);
                      if (trial == thread)
                        {
@@ -2710,7 +2727,18 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
                          if (new_thread == trial)
                            new_thread = thread;
                        }
+
+                     /* We are moving this insn, not deleting it.  We must
+                        temporarily increment the use count on any referenced
+                        label lest it be deleted by delete_related_insns.  */
+                     note = find_reg_note (trial, REG_LABEL, 0);
+                     if (note)
+                       LABEL_NUSES (XEXP (note, 0))++;
+
                      delete_related_insns (trial);
+
+                     if (note)
+                       LABEL_NUSES (XEXP (note, 0))--;
                    }
                  else
                    new_thread = next_active_insn (trial);