diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-18 22:52:05 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-18 22:52:05 +0000 |
commit | 7f42fe2449eeb85253e771f44f8f2a47be961d72 (patch) | |
tree | 97345dfea977f820d999cfa91b9565f89057e6f7 /gcc/ifcvt.c | |
parent | 4e4ff25cca81ca35d333e94016289468eddcd555 (diff) | |
download | gcc-7f42fe2449eeb85253e771f44f8f2a47be961d72.tar.gz |
* Makefile.in (ifcvt.o): Add cfgloop.h.
* basic-block.h (EDGE_LOOP_EXIT): New flag.
* cfgrtl.c (rtl_verify_flow_info_1): Handle it correctly.
* ifcvt.c: Include cfgloop.h.
(mark_loop_exit_edges): New static function.
(if_convert): Call it.
(find_if_header): Ignore branches out of loops.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69572 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r-- | gcc/ifcvt.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 60723efa3b3..bb783fbf57f 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -38,6 +38,7 @@ #include "optabs.h" #include "toplev.h" #include "tm_p.h" +#include "cfgloop.h" #ifndef HAVE_conditional_execution @@ -110,7 +111,36 @@ static int dead_or_predicable (basic_block, basic_block, basic_block, basic_block, int); static void noce_emit_move_insn (rtx, rtx); static rtx block_has_only_trap (basic_block); +static void mark_loop_exit_edges (void); +/* Sets EDGE_LOOP_EXIT flag for all loop exits. */ +static void +mark_loop_exit_edges () +{ + struct loops loops; + basic_block bb; + edge e; + + flow_loops_find (&loops, LOOP_TREE); + + if (loops.num > 1) + { + FOR_EACH_BB (bb) + { + for (e = bb->succ; e; e = e->succ_next) + { + if (find_common_loop (bb->loop_father, e->dest->loop_father) + != bb->loop_father) + e->flags |= EDGE_LOOP_EXIT; + else + e->flags &= ~EDGE_LOOP_EXIT; + } + } + } + + flow_loops_free (&loops); +} + /* Count the number of non-jump active insns in BB. */ static int @@ -2111,6 +2141,11 @@ find_if_header (basic_block test_bb, int pass) || (else_edge->flags & EDGE_COMPLEX)) return NULL; + /* Nor exit the loop. */ + if ((then_edge->flags & EDGE_LOOP_EXIT) + || (else_edge->flags & EDGE_LOOP_EXIT)) + return NULL; + /* The THEN edge is canonically the one that falls through. */ if (then_edge->flags & EDGE_FALLTHRU) ; @@ -3077,6 +3112,8 @@ if_convert (int x_life_data_ok) num_removed_blocks = 0; life_data_ok = (x_life_data_ok != 0); + mark_loop_exit_edges (); + /* Free up basic_block_for_insn so that we don't have to keep it up to date, either here or in merge_blocks. */ free_basic_block_vars (1); |