aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-05-13 16:00:35 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-05-13 16:00:35 -0700
commit546c093ec5f84f1659723329061c47070a9956ef (patch)
tree5f32b69c8a701e1b7a8f5a41ad0369d83f86c15c
parentbde5348670f9371fb8eff9ae1b4c91a1903074a6 (diff)
downloadgcc-546c093ec5f84f1659723329061c47070a9956ef.zip
gcc-546c093ec5f84f1659723329061c47070a9956ef.tar.gz
gcc-546c093ec5f84f1659723329061c47070a9956ef.tar.bz2
cfgrtl.c (purge_dead_edges): Handle abnormal call edges created by non-local gotos.
* cfgrtl.c (purge_dead_edges): Handle abnormal call edges created by non-local gotos. * recog.c (peephole2_optimize): Likewise. From-SVN: r53438
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cfgrtl.c36
-rw-r--r--gcc/recog.c18
3 files changed, 40 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 17494dc..8b32f16 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index cd3369c..9a6661d 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -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)
{
diff --git a/gcc/recog.c b/gcc/recog.c
index a0075ef..c3dbee2 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -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,