OSDN Git Service

* unwind-dw2-fde.c (__deregister_frame_info): Stringize use
[pf3gnuchains/gcc-fork.git] / gcc / flow.c
index 68b3aca..d983ab5 100644 (file)
@@ -2854,6 +2854,21 @@ life_analysis (f, file, flags)
     dump_flow_info (file);
 
   free_basic_block_vars (1);
+
+#ifdef ENABLE_CHECKING
+  {
+    rtx insn;
+
+    /* Search for any REG_LABEL notes whih reference deleted labels.  */
+    for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+      {
+       rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
+
+       if (inote && GET_CODE (inote) == NOTE_INSN_DELETED_LABEL)
+         abort ();
+      }
+  }
+#endif
 }
 
 /* A subroutine of verify_wide_reg, called through for_each_rtx.
@@ -3631,14 +3646,26 @@ propagate_block_delete_insn (bb, insn)
   /* If the insn referred to a label, and that label was attached to
      an ADDR_VEC, it's safe to delete the ADDR_VEC.  In fact, it's
      pretty much mandatory to delete it, because the ADDR_VEC may be
-     referencing labels that no longer exist.  */
+     referencing labels that no longer exist.
+
+     INSN may reference a deleted label, particularly when a jump
+     table has been optimized into a direct jump.  There's no
+     real good way to fix up the reference to the deleted label
+     when the label is deleted, so we just allow it here.
 
-  if (inote)
+     After dead code elimination is complete, we do search for
+     any REG_LABEL notes which reference deleted labels as a
+     sanity check.  */
+
+  if (inote && GET_CODE (inote) == CODE_LABEL)
     {
       rtx label = XEXP (inote, 0);
       rtx next;
 
-      if (LABEL_NUSES (label) == 1
+      /* The label may be forced if it has been put in the constant
+        pool.  If that is the only use we must discard the table
+        jump following it, but not the label itself.  */
+      if (LABEL_NUSES (label) == 1 + LABEL_PRESERVE_P (label)
          && (next = next_nonnote_insn (label)) != NULL
          && GET_CODE (next) == JUMP_INSN
          && (GET_CODE (PATTERN (next)) == ADDR_VEC
@@ -3734,10 +3761,7 @@ propagate_one_insn (pbi, insn)
       pbi->cc0_live = 0;
 
       if (libcall_is_dead)
-       {
-         prev = propagate_block_delete_libcall (pbi->bb, insn, note);
-         insn = NEXT_INSN (prev);
-       }
+       prev = propagate_block_delete_libcall (pbi->bb, insn, note);
       else
        propagate_block_delete_insn (pbi->bb, insn);