summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-18 22:52:05 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-18 22:52:05 +0000
commit7f42fe2449eeb85253e771f44f8f2a47be961d72 (patch)
tree97345dfea977f820d999cfa91b9565f89057e6f7 /gcc
parent4e4ff25cca81ca35d333e94016289468eddcd555 (diff)
downloadppe42-gcc-7f42fe2449eeb85253e771f44f8f2a47be961d72.tar.gz
ppe42-gcc-7f42fe2449eeb85253e771f44f8f2a47be961d72.zip
* 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')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/basic-block.h3
-rw-r--r--gcc/cfgrtl.c5
-rw-r--r--gcc/ifcvt.c37
5 files changed, 55 insertions, 3 deletions
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 <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * 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 <kazu@cs.umass.edu>
* 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);
OpenPOWER on IntegriCloud