OSDN Git Service

* tree-ssa-loop-niter.c (compute_estimated_nb_iterations): Fix
[pf3gnuchains/gcc-fork.git] / gcc / predict.c
index df5d310..0e86c52 100644 (file)
@@ -650,6 +650,10 @@ predict_loops (void)
       for (j = 0; VEC_iterate (edge, exits, j, ex); j++)
        {
          tree niter = NULL;
+         HOST_WIDE_INT nitercst;
+         int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
+         int probability;
+         enum br_predictor predictor;
 
          if (number_of_iterations_exit (loop, ex, &niter_desc, false))
            niter = niter_desc.niter;
@@ -658,20 +662,31 @@ predict_loops (void)
 
          if (TREE_CODE (niter) == INTEGER_CST)
            {
-             int probability;
-             int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
              if (host_integerp (niter, 1)
                  && compare_tree_int (niter, max-1) == -1)
-               {
-                 HOST_WIDE_INT nitercst = tree_low_cst (niter, 1) + 1;
-                 probability = ((REG_BR_PROB_BASE + nitercst / 2)
-                                / nitercst);
-               }
+               nitercst = tree_low_cst (niter, 1) + 1;
              else
-               probability = ((REG_BR_PROB_BASE + max / 2) / max);
+               nitercst = max;
+             predictor = PRED_LOOP_ITERATIONS;
+           }
+         /* If we have just one exit and we can derive some information about
+            the number of iterations of the loop from the statements inside
+            the loop, use it to predict this exit.  */
+         else if (n_exits == 1)
+           {
+             nitercst = estimated_loop_iterations_int (loop, false);
+             if (nitercst < 0)
+               continue;
+             if (nitercst > max)
+               nitercst = max;
 
-             predict_edge (ex, PRED_LOOP_ITERATIONS, probability);
+             predictor = PRED_LOOP_ITERATIONS_GUESSED;
            }
+         else
+           continue;
+
+         probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
+         predict_edge (ex, predictor, probability);
        }
       VEC_free (edge, heap, exits);
 
@@ -706,7 +721,11 @@ predict_loops (void)
 
          /* Loop exit heuristics - predict an edge exiting the loop if the
             conditional has no loop header successors as not taken.  */
-         if (!header_found)
+         if (!header_found
+             /* If we already used more reliable loop exit predictors, do not
+                bother with PRED_LOOP_EXIT.  */
+             && !predicted_by_p (bb, PRED_LOOP_ITERATIONS_GUESSED)
+             && !predicted_by_p (bb, PRED_LOOP_ITERATIONS))
            {
              /* For loop with many exits we don't want to predict all exits
                 with the pretty large probability, because if all exits are
@@ -1258,6 +1277,7 @@ tree_estimate_probability (void)
   tree_bb_level_predictions ();
 
   mark_irreducible_loops ();
+  record_loop_exits ();
   if (current_loops)
     predict_loops ();