From: Zdenek Dvorak Date: Fri, 18 Jul 2003 22:52:05 +0000 (+0200) Subject: Makefile.in (ifcvt.o): Add cfgloop.h. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=65f43cdfee83049bc0008c71b182e813c4c86306;p=gcc.git Makefile.in (ifcvt.o): Add cfgloop.h. * 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. From-SVN: r69572 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8ce7152a5f8..2148c51da18 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-07-19 Zdenek Dvorak + + * 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. + 2003-07-18 Kazu Hirata * combine.c (simplify_comparison): Don't share rtx when converting diff --git a/gcc/Makefile.in b/gcc/Makefile.in index bbe8561a085..dcffe35f11c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1790,7 +1790,8 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ resource.h $(OBSTACK_H) flags.h $(TM_P_H) ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(REGS_H) toplev.h flags.h insn-config.h function.h $(RECOG_H) \ - $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) real.h $(OPTABS_H) + $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) real.h $(OPTABS_H) \ + cfgloop.h params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) toplev.h hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H) diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 0558fe81f5d..221b2466985 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -152,7 +152,8 @@ typedef struct edge_def { flow. */ #define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */ #define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */ -#define EDGE_ALL_FLAGS 511 +#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */ +#define EDGE_ALL_FLAGS 1023 #define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH) diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 903f57eac3f..da629cb4e46 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1907,7 +1907,10 @@ rtl_verify_flow_info_1 (void) if (e->flags & EDGE_FALLTHRU) n_fallthru++, fallthru = e; - if ((e->flags & ~(EDGE_DFS_BACK | EDGE_CAN_FALLTHRU | EDGE_IRREDUCIBLE_LOOP)) == 0) + if ((e->flags & ~(EDGE_DFS_BACK + | EDGE_CAN_FALLTHRU + | EDGE_IRREDUCIBLE_LOOP + | EDGE_LOOP_EXIT)) == 0) n_branch++; if (e->flags & EDGE_ABNORMAL_CALL) 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);