diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-25 00:18:10 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-25 00:18:10 +0000 |
commit | 029de010b472ad74e5e8551fe25914bd577840de (patch) | |
tree | 2d19caeef716238a672a769d0702fa34dd850bc3 /gcc/recog.c | |
parent | 4819d8665f112be22c73280485bbc9724a5fafa1 (diff) | |
download | gcc-029de010b472ad74e5e8551fe25914bd577840de.tar.gz |
* recog.c (peephole2_optimize): Split blocks when EH insns are
generated in the middle of a block. Do global life update if
zapped EH edges.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51285 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index cb1cb666a8c..769c267efed 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3000,8 +3000,9 @@ peephole2_optimize (dump_file) int i, b; #ifdef HAVE_conditional_execution sbitmap blocks; - int changed; + bool changed; #endif + bool do_cleanup_cfg = false; /* Initialize the regsets we're going to use. */ for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i) @@ -3011,7 +3012,7 @@ peephole2_optimize (dump_file) #ifdef HAVE_conditional_execution blocks = sbitmap_alloc (n_basic_blocks); sbitmap_zero (blocks); - changed = 0; + changed = false; #else count_or_remove_death_notes (NULL, 1); #endif @@ -3137,20 +3138,46 @@ peephole2_optimize (dump_file) REG_EH_REGION, NULL_RTX))) { rtx x; + edge eh_edge; + + for (eh_edge = bb->succ; eh_edge + ; eh_edge = eh_edge->succ_next) + if (eh_edge->flags & EDGE_EH) + break; + for (x = NEXT_INSN (peep2_insn_data[i].insn); x != NEXT_INSN (try); x = NEXT_INSN (x)) if (GET_CODE (x) == CALL_INSN || (flag_non_call_exceptions && may_trap_p (PATTERN (x)))) - REG_NOTES (x) - = gen_rtx_EXPR_LIST (REG_EH_REGION, - XEXP (note, 0), - REG_NOTES (x)); + { + REG_NOTES (x) + = gen_rtx_EXPR_LIST (REG_EH_REGION, + XEXP (note, 0), + REG_NOTES (x)); + + if (x != bb->end && eh_edge) + { + edge nfte = split_block (bb, x); + edge nehe = make_edge (nfte->src, eh_edge->dest, + eh_edge->flags); + nehe->probability = eh_edge->probability; + nfte->probability + = REG_BR_PROB_BASE - nehe->probability; + + do_cleanup_cfg |= purge_dead_edges (nfte->dest); +#ifdef HAVE_conditional_execution + SET_BIT (blocks, nfte->dest->index); + changed = true; +#endif + bb = nfte->src; + } + } + + /* Converting possibly trapping insn to non-trapping is + possible. Zap dummy outgoing edges. */ + do_cleanup_cfg |= purge_dead_edges (bb); } - /* Converting possibly trapping insn to non-trapping is - possible. Zap dummy outgoing edges. */ - if (try == bb->end) - purge_dead_edges (bb); #ifdef HAVE_conditional_execution /* With conditional execution, we cannot back up the @@ -3159,7 +3186,7 @@ peephole2_optimize (dump_file) So record that we've made a modification to this block and update life information at the end. */ SET_BIT (blocks, b); - changed = 1; + changed = true; for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i) peep2_insn_data[i].insn = NULL_RTX; @@ -3205,9 +3232,20 @@ peephole2_optimize (dump_file) FREE_REG_SET (peep2_insn_data[i].live_before); FREE_REG_SET (live); + /* If we eliminated EH edges, we may be able to merge blocks. Further, + we've changed global life since exception handlers are no longer + reachable. */ + if (do_cleanup_cfg) + { + cleanup_cfg (0); + update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES); + } #ifdef HAVE_conditional_execution - count_or_remove_death_notes (blocks, 1); - update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES); + else + { + count_or_remove_death_notes (blocks, 1); + update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES); + } sbitmap_free (blocks); #endif } |