cfgrtl.c (purge_dead_edges): Handle abnormal call edges created by non-local gotos.
authorRichard Henderson <rth@redhat.com>
Mon, 13 May 2002 23:00:35 +0000 (16:00 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 13 May 2002 23:00:35 +0000 (16:00 -0700)
        * cfgrtl.c (purge_dead_edges): Handle abnormal call edges created
        by non-local gotos.
        * recog.c (peephole2_optimize): Likewise.

From-SVN: r53438

gcc/ChangeLog
gcc/cfgrtl.c
gcc/recog.c

index 17494dc..8b32f16 100644 (file)
@@ -1,3 +1,9 @@
+2002-05-13  Richard Henderson  <rth@redhat.com>
+
+       * cfgrtl.c (purge_dead_edges): Handle abnormal call edges created
+       by non-local gotos.
+       * recog.c (peephole2_optimize): Likewise.
+
 2002-05-13  Andris Pavenis  <pavenis@lanet.lv>
 
        * cppfiles.c (open_file): Change mode (DJGPP only) of redirected
index cd3369c..9a6661d 100644 (file)
@@ -2131,19 +2131,29 @@ purge_dead_edges (bb)
        remove_note (insn, note);
     }
 
-  /* Cleanup abnormal edges caused by throwing insns that have been
-     eliminated.  */
-  if (! can_throw_internal (bb->end))
-    for (e = bb->succ; e; e = next)
-      {
-       next = e->succ_next;
-       if (e->flags & EDGE_EH)
-         {
-           remove_edge (e);
-           bb->flags |= BB_DIRTY;
-           purged = true;
-         }
-      }
+  /* Cleanup abnormal edges caused by exceptions or non-local gotos.  */
+  for (e = bb->succ; e; e = next)
+    {
+      next = e->succ_next;
+      if (e->flags & EDGE_EH)
+       {
+         if (can_throw_internal (bb->end))
+           continue;
+       }
+      else if (e->flags & EDGE_ABNORMAL_CALL)
+       {
+         if (GET_CODE (bb->end) == CALL_INSN
+             && (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
+                 || INTVAL (XEXP (note, 0)) >= 0))
+           continue;
+       }
+      else
+       continue;
+
+      remove_edge (e);
+      bb->flags |= BB_DIRTY;
+      purged = true;
+    }
 
   if (GET_CODE (insn) == JUMP_INSN)
     {
index a0075ef..c3dbee2 100644 (file)
@@ -3051,6 +3051,7 @@ peephole2_optimize (dump_file)
              rtx try, before_try, x;
              int match_len;
              rtx note;
+             bool was_call = false;
 
              /* Record this insn.  */
              if (--peep2_current < 0)
@@ -3077,6 +3078,7 @@ peephole2_optimize (dump_file)
                      old_insn = peep2_insn_data[j].insn;
                      if (GET_CODE (old_insn) != CALL_INSN)
                        continue;
+                     was_call = true;
 
                      new_insn = NULL_RTX;
                      if (GET_CODE (try) == SEQUENCE)
@@ -3140,13 +3142,13 @@ peephole2_optimize (dump_file)
                  delete_insn_chain (insn, peep2_insn_data[i].insn);
 
                  /* Re-insert the EH_REGION notes.  */
-                 if (note)
+                 if (note || (was_call && nonlocal_goto_handler_labels))
                    {
                      edge eh_edge;
 
                      for (eh_edge = bb->succ; eh_edge
                           ; eh_edge = eh_edge->succ_next)
-                       if (eh_edge->flags & EDGE_EH)
+                       if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
                          break;
 
                      for (x = try ; x != before_try ; x = PREV_INSN (x))
@@ -3155,10 +3157,11 @@ peephole2_optimize (dump_file)
                                && may_trap_p (PATTERN (x))
                                && !find_reg_note (x, REG_EH_REGION, NULL)))
                          {
-                           REG_NOTES (x)
-                             = gen_rtx_EXPR_LIST (REG_EH_REGION,
-                                                  XEXP (note, 0),
-                                                  REG_NOTES (x));
+                           if (note)
+                             REG_NOTES (x)
+                               = gen_rtx_EXPR_LIST (REG_EH_REGION,
+                                                    XEXP (note, 0),
+                                                    REG_NOTES (x));
 
                            if (x != bb->end && eh_edge)
                              {
@@ -3166,7 +3169,8 @@ peephole2_optimize (dump_file)
                                int flags;
 
                                nfte = split_block (bb, x);
-                               flags = EDGE_EH | EDGE_ABNORMAL;
+                               flags = (eh_edge->flags
+                                        & (EDGE_EH | EDGE_ABNORMAL));
                                if (GET_CODE (x) == CALL_INSN)
                                  flags |= EDGE_ABNORMAL_CALL;
                                nehe = make_edge (nfte->src, eh_edge->dest,