From 546c093ec5f84f1659723329061c47070a9956ef Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 13 May 2002 16:00:35 -0700 Subject: 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 --- gcc/ChangeLog | 6 ++++++ gcc/cfgrtl.c | 36 +++++++++++++++++++++++------------- gcc/recog.c | 18 +++++++++++------- 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 + + * cfgrtl.c (purge_dead_edges): Handle abnormal call edges created + by non-local gotos. + * recog.c (peephole2_optimize): Likewise. + 2002-05-13 Andris Pavenis * 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, -- cgit v1.1