From 7f42fe2449eeb85253e771f44f8f2a47be961d72 Mon Sep 17 00:00:00 2001
From: rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri, 18 Jul 2003 22:52:05 +0000
Subject: [PATCH] 	* 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
---
 gcc/ChangeLog     | 10 ++++++++++
 gcc/Makefile.in   |  3 ++-
 gcc/basic-block.h |  3 ++-
 gcc/cfgrtl.c      |  5 ++++-
 gcc/ifcvt.c       | 37 +++++++++++++++++++++++++++++++++++++
 5 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8ce7152a5f87..2148c51da185 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 bbe8561a085d..dcffe35f11c0 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 0558fe81f5d8..221b2466985c 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 903f57eac3fd..da629cb4e46c 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 60723efa3b33..bb783fbf57f1 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);
-- 
GitLab