OSDN Git Service

2004-09-22 Frank Ch. Eigler <fche@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / loop-unswitch.c
index ebbabe8..08780f0 100644 (file)
@@ -174,7 +174,7 @@ unswitch_loops (struct loops *loops)
 static rtx
 may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
 {
-  rtx test, at, insn, op[2];
+  rtx test, at, insn, op[2], stest;
   struct rtx_iv iv;
   unsigned i;
   enum machine_mode mode;
@@ -196,7 +196,7 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
     return NULL_RTX;
 
   /* Condition must be invariant.  */
-  test = get_condition (BB_END (bb), &at, true);
+  test = get_condition (BB_END (bb), &at, true, false);
   if (!test)
     return NULL_RTX;
 
@@ -208,7 +208,7 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
        continue;
 
       insn = iv_get_reaching_def (at, op[i]);
-      if (!iv_analyse (insn, op[i], &iv))
+      if (!iv_analyze (insn, op[i], &iv))
        return NULL_RTX;
       if (iv.step != const0_rtx
          || iv.first_special)
@@ -233,6 +233,12 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn)
       return test;
     }
 
+  stest = simplify_gen_relational (GET_CODE (test), SImode,
+                                  mode, op[0], op[1]);
+  if (stest == const0_rtx
+      || stest == const_true_rtx)
+    return stest;
+
   return canon_condition (gen_rtx_fmt_ee (GET_CODE (test), SImode,
                                          op[0], op[1]));
 }
@@ -262,55 +268,55 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
   basic_block *bbs;
   struct loop *nloop;
   unsigned i;
-  rtx cond, rcond, conds, rconds, acond, cinsn = NULL_RTX;
+  rtx cond, rcond = NULL_RTX, conds, rconds, acond, cinsn = NULL_RTX;
   int repeat;
   edge e;
 
   /* Do not unswitch too much.  */
   if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching anymore, hit max level\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
       return;
     }
 
   /* Only unswitch innermost loops.  */
   if (loop->inner)
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching, not innermost loop\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching, not innermost loop\n");
       return;
     }
 
   /* We must be able to duplicate loop body.  */
   if (!can_duplicate_loop_p (loop))
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching, can't duplicate loop\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n");
       return;
     }
 
   /* The loop should not be too large, to limit code growth.  */
   if (num_loop_insns (loop) > PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching, loop too big\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching, loop too big\n");
       return;
     }
 
   /* Do not unswitch in cold areas.  */
   if (!maybe_hot_bb_p (loop->header))
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching, not hot area\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching, not hot area\n");
       return;
     }
 
   /* Nor if the loop usually does not roll.  */
   if (expected_loop_iterations (loop) < 1)
     {
-      if (rtl_dump_file)
-       fprintf (rtl_dump_file, ";; Not unswitching, loop iterations < 1\n");
+      if (dump_file)
+       fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
       return;
     }
 
@@ -331,13 +337,17 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
          return;
        }
 
-      rcond = reversed_condition (cond);
-      if (rcond)
-       rcond = canon_condition (rcond);
+      if (cond != const0_rtx
+         && cond != const_true_rtx)
+       {
+         rcond = reversed_condition (cond);
+         if (rcond)
+           rcond = canon_condition (rcond);
 
-      /* Check whether the result can be predicted.  */
-      for (acond = cond_checked; acond; acond = XEXP (acond, 1))
-       simplify_using_condition (XEXP (acond, 0), &cond, NULL);
+         /* Check whether the result can be predicted.  */
+         for (acond = cond_checked; acond; acond = XEXP (acond, 1))
+           simplify_using_condition (XEXP (acond, 0), &cond, NULL);
+       }
 
       if (cond == const_true_rtx)
        {
@@ -364,8 +374,8 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
   else
     rconds = cond_checked;
 
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, ";; Unswitching loop\n");
+  if (dump_file)
+    fprintf (dump_file, ";; Unswitching loop\n");
 
   /* Unswitch the loop on this condition.  */
   nloop = unswitch_loop (loops, loop, bbs[i], cond, cinsn);
@@ -379,6 +389,8 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
   free_EXPR_LIST_node (conds);
   if (rcond)
     free_EXPR_LIST_node (rconds);
+
+  free (bbs);
 }
 
 /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON.  We only support