* 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
+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
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)
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)
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)
#include "optabs.h"
#include "toplev.h"
#include "tm_p.h"
+#include "cfgloop.h"
#ifndef HAVE_conditional_execution
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);
\f
+/* 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
|| (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)
;
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);