OSDN Git Service

* config/rs6000/altivec.h: Convert () prototypes to ISO C90.
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
index 60723ef..782960b 100644 (file)
@@ -38,6 +38,8 @@
 #include "optabs.h"
 #include "toplev.h"
 #include "tm_p.h"
+#include "cfgloop.h"
+#include "target.h"
 
 
 #ifndef HAVE_conditional_execution
@@ -110,7 +112,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);
 \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
@@ -1366,7 +1397,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
     }
 
   cond = canonicalize_condition (if_info->jump, cond, reverse,
-                                earliest, target);
+                                earliest, target, false);
   if (! cond || ! reg_mentioned_p (target, cond))
     return NULL;
 
@@ -1640,7 +1671,8 @@ noce_get_condition (rtx jump, rtx *earliest)
   /* Otherwise, fall back on canonicalize_condition to do the dirty
      work of manipulating MODE_CC values and COMPARE rtx codes.  */
 
-  tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
+  tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
+                               false);
   if (!tmp)
     return NULL_RTX;
 
@@ -1659,7 +1691,8 @@ noce_get_condition (rtx jump, rtx *earliest)
   tmp = XEXP (tmp, 0);
   if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
     return NULL_RTX;
-  tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp);
+  tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp,
+                               false);
   if (!tmp)
     return NULL_RTX;
 
@@ -2111,6 +2144,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 +3115,9 @@ if_convert (int x_life_data_ok)
   num_removed_blocks = 0;
   life_data_ok = (x_life_data_ok != 0);
 
+  if (! (* targetm.cannot_modify_jumps_p) ())
+    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);