diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-14 12:18:58 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-14 12:18:58 -0700 |
commit | 1d65f45cfaefa060737af130c3fc69afb3030980 (patch) | |
tree | 2fcbbb5f99b13293753d83230cf9f4e0893a9b51 /gcc/cfgrtl.c | |
parent | 0c433c31b31f25e3f18e58bd8d404c02722d7f7c (diff) | |
download | gcc-1d65f45cfaefa060737af130c3fc69afb3030980.zip gcc-1d65f45cfaefa060737af130c3fc69afb3030980.tar.gz gcc-1d65f45cfaefa060737af130c3fc69afb3030980.tar.bz2 |
Squash commit of EH in gimple
From-SVN: r151696
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r-- | gcc/cfgrtl.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 4c4b3b7..a7e93dd 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1873,12 +1873,16 @@ rtl_verify_flow_info_1 (void) n_abnormal++; } - if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX - && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) + if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) { error ("missing REG_EH_REGION note in the end of bb %i", bb->index); err = 1; } + if (n_eh > 1) + { + error ("too many eh edges %i", bb->index); + err = 1; + } if (n_branch && (!JUMP_P (BB_END (bb)) || (n_branch > 1 && (any_uncondjump_p (BB_END (bb)) @@ -1894,7 +1898,8 @@ rtl_verify_flow_info_1 (void) } if (n_branch != 1 && any_uncondjump_p (BB_END (bb))) { - error ("wrong amount of branch edges after unconditional jump %i", bb->index); + error ("wrong number of branch edges after unconditional jump %i", + bb->index); err = 1; } if (n_branch != 1 && any_condjump_p (BB_END (bb)) @@ -2217,39 +2222,33 @@ purge_dead_edges (basic_block bb) /* Cleanup abnormal edges caused by exceptions or non-local gotos. */ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { + bool remove = false; + /* There are three types of edges we need to handle correctly here: EH edges, abnormal call EH edges, and abnormal call non-EH edges. The latter can appear when nonlocal gotos are used. */ - if (e->flags & EDGE_EH) + if (e->flags & EDGE_ABNORMAL_CALL) { - if (can_throw_internal (insn) - /* If this is a call edge, verify that this is a call insn. */ - && (! (e->flags & EDGE_ABNORMAL_CALL) - || CALL_P (insn))) - { - ei_next (&ei); - continue; - } + if (!CALL_P (insn)) + remove = true; + else if (can_nonlocal_goto (insn)) + ; + else if ((e->flags & EDGE_EH) && can_throw_internal (insn)) + ; + else + remove = true; } - else if (e->flags & EDGE_ABNORMAL_CALL) + else if (e->flags & EDGE_EH) + remove = !can_throw_internal (insn); + + if (remove) { - if (CALL_P (insn) - && (! (note = find_reg_note (insn, REG_EH_REGION, NULL)) - || INTVAL (XEXP (note, 0)) >= 0)) - { - ei_next (&ei); - continue; - } + remove_edge (e); + df_set_bb_dirty (bb); + purged = true; } else - { - ei_next (&ei); - continue; - } - - remove_edge (e); - df_set_bb_dirty (bb); - purged = true; + ei_next (&ei); } if (JUMP_P (insn)) |