diff options
author | Richard Henderson <rth@redhat.com> | 2002-05-13 16:00:35 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-05-13 16:00:35 -0700 |
commit | 546c093ec5f84f1659723329061c47070a9956ef (patch) | |
tree | 5f32b69c8a701e1b7a8f5a41ad0369d83f86c15c | |
parent | bde5348670f9371fb8eff9ae1b4c91a1903074a6 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 36 | ||||
-rw-r--r-- | 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 <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, |