Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / loop-doloop.c
index 5f64569..b47901b 100644 (file)
@@ -1,6 +1,5 @@
 /* Perform doloop optimizations
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2004-2013 Free Software Foundation, Inc.
    Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
 
 This file is part of GCC.
@@ -31,9 +30,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "tm_p.h"
 #include "cfgloop.h"
-#include "output.h"
 #include "params.h"
 #include "target.h"
+#include "dumpfile.h"
 
 /* This module is used to modify loops with a determinable number of
    iterations to use special low-overhead looping instructions.
@@ -410,6 +409,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
   basic_block loop_end = desc->out_edge->src;
   enum machine_mode mode;
   rtx true_prob_val;
+  double_int iterations;
 
   jump_insn = BB_END (loop_end);
 
@@ -460,9 +460,10 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
 
       /* Determine if the iteration counter will be non-negative.
         Note that the maximum value loaded is iterations_max - 1.  */
-      if (desc->niter_max
-         <= ((unsigned HOST_WIDEST_INT) 1
-             << (GET_MODE_PRECISION (mode) - 1)))
+      if (max_loop_iterations (loop, &iterations)
+         && (iterations.ule (double_int_one.llshift
+                              (GET_MODE_PRECISION (mode) - 1,
+                               GET_MODE_PRECISION (mode)))))
        nonneg = 1;
       break;
 
@@ -548,10 +549,19 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
   {
     rtx init;
     unsigned level = get_loop_level (loop) + 1;
+    double_int iter;
+    rtx iter_rtx;
+
+    if (!max_loop_iterations (loop, &iter)
+       || !iter.fits_shwi ())
+      iter_rtx = const0_rtx;
+    else
+      iter_rtx = GEN_INT (iter.to_shwi());
     init = gen_doloop_begin (counter_reg,
                             desc->const_iter ? desc->niter_expr : const0_rtx,
-                            GEN_INT (desc->niter_max),
-                            GEN_INT (level));
+                            iter_rtx,
+                            GEN_INT (level),
+                            doloop_seq);
     if (init)
       {
        start_sequence ();
@@ -608,6 +618,8 @@ doloop_optimize (struct loop *loop)
   struct niter_desc *desc;
   unsigned word_mode_size;
   unsigned HOST_WIDE_INT word_mode_max;
+  double_int iter;
+  int entered_at_top;
 
   if (dump_file)
     fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
@@ -658,7 +670,11 @@ doloop_optimize (struct loop *loop)
 
   count = copy_rtx (desc->niter_expr);
   iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
-  iterations_max = GEN_INT (desc->niter_max);
+  if (!max_loop_iterations (loop, &iter)
+      || !iter.fits_shwi ())
+    iterations_max = const0_rtx;
+  else
+    iterations_max = GEN_INT (iter.to_shwi());
   level = get_loop_level (loop) + 1;
 
   /* Generate looping insn.  If the pattern FAILs then give up trying
@@ -666,8 +682,11 @@ doloop_optimize (struct loop *loop)
      not like.  */
   start_label = block_label (desc->in_edge->dest);
   doloop_reg = gen_reg_rtx (mode);
+  entered_at_top = (loop->latch == desc->in_edge->dest
+                   && contains_no_active_insn_p (loop->latch));
   doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
-                              GEN_INT (level), start_label);
+                              GEN_INT (level), start_label,
+                              GEN_INT (entered_at_top));
 
   word_mode_size = GET_MODE_PRECISION (word_mode);
   word_mode_max
@@ -678,7 +697,7 @@ doloop_optimize (struct loop *loop)
         computed, we must be sure that the number of iterations fits into
         the new mode.  */
       && (word_mode_size >= GET_MODE_PRECISION (mode)
-         || desc->niter_max <= word_mode_max))
+         || iter.ule (double_int::from_shwi (word_mode_max))))
     {
       if (word_mode_size > GET_MODE_PRECISION (mode))
        {
@@ -697,7 +716,8 @@ doloop_optimize (struct loop *loop)
        }
       PUT_MODE (doloop_reg, word_mode);
       doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
-                                  GEN_INT (level), start_label);
+                                  GEN_INT (level), start_label,
+                                  GEN_INT (entered_at_top));
     }
   if (! doloop_seq)
     {
@@ -747,7 +767,6 @@ doloop_optimize_loops (void)
   iv_analysis_done ();
 
 #ifdef ENABLE_CHECKING
-  verify_dominators (CDI_DOMINATORS);
   verify_loop_structure ();
 #endif
 }