+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
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)
{
rtx try, before_try, x;
int match_len;
rtx note;
+ bool was_call = false;
/* Record this insn. */
if (--peep2_current < 0)
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)
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))
&& 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)
{
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,