predict.c (predicted_by_loop_heuristics_p): New function.
authorJan Hubicka <hubicka@ucw.cz>
Sun, 5 Jun 2016 16:43:19 +0000 (18:43 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 5 Jun 2016 16:43:19 +0000 (16:43 +0000)
* predict.c (predicted_by_loop_heuristics_p): New function.
(predict_iv_comparison): Use it.
(predict_loops): Walk from innermost loops; do not predict edges
leaving multiple loops multiple times; implement
PRED_LOOP_ITERATIONS_MAX heuristics.
* predict.def (PRED_LOOP_ITERATIONS_MAX): New predictor.
* gcc.dg/predict-9.c: Update template.

From-SVN: r237103

gcc/ChangeLog
gcc/predict.c
gcc/predict.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/predict-9.c

index be9848c513d088fa0fbf84a2f4f0c3da436ad9b2..d7a2527cace04f694b7130caed671b5b9f9d53fd 100644 (file)
@@ -1,4 +1,13 @@
-2016-06-03  Jan Hubicka  <hubicka@ucw.cz>
+2016-06-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       * predict.c (predicted_by_loop_heuristics_p): New function.
+       (predict_iv_comparison): Use it.
+       (predict_loops): Walk from innermost loops; do not predict edges
+       leaving multiple loops multiple times; implement
+       PRED_LOOP_ITERATIONS_MAX heuristics.
+       * predict.def (PRED_LOOP_ITERATIONS_MAX): New predictor.
+
+2016-06-05  Jan Hubicka  <hubicka@ucw.cz>
 
        * cfg.c (check_bb_profile): Do not report mismatched profiles when
        only edges out of BB are EH edges.
index 429f44e02714db4efddd13aa940ad8167eca6584..32d45678f259891cb295cce4b1a306b0de714d65 100644 (file)
@@ -1215,6 +1215,27 @@ expr_coherent_p (tree t1, tree t2)
     return false;
 }
 
+/* Return true if E is predicted by one of loop heuristics.  */
+
+static bool
+predicted_by_loop_heuristics_p (basic_block bb)
+{
+  struct edge_prediction *i;
+  edge_prediction **preds = bb_predictions->get (bb);
+
+  if (!preds)
+    return false;
+
+  for (i = *preds; i; i = i->ep_next)
+    if (i->ep_predictor == PRED_LOOP_ITERATIONS_GUESSED
+       || i->ep_predictor == PRED_LOOP_ITERATIONS_MAX
+       || i->ep_predictor == PRED_LOOP_ITERATIONS
+       || i->ep_predictor == PRED_LOOP_EXIT
+       || i->ep_predictor == PRED_LOOP_EXTRA_EXIT)
+      return true;
+  return false;
+}
+
 /* Predict branch probability of BB when BB contains a branch that compares
    an induction variable in LOOP with LOOP_IV_BASE_VAR to LOOP_BOUND_VAR. The
    loop exit is compared using LOOP_BOUND_CODE, with step of LOOP_BOUND_STEP.
@@ -1243,10 +1264,7 @@ predict_iv_comparison (struct loop *loop, basic_block bb,
   edge then_edge;
   edge_iterator ei;
 
-  if (predicted_by_p (bb, PRED_LOOP_ITERATIONS_GUESSED)
-      || predicted_by_p (bb, PRED_LOOP_ITERATIONS)
-      || predicted_by_p (bb, PRED_LOOP_EXIT)
-      || predicted_by_p (bb, PRED_LOOP_EXTRA_EXIT))
+  if (predicted_by_loop_heuristics_p (bb))
     return;
 
   stmt = last_stmt (bb);
@@ -1484,6 +1502,7 @@ predict_extra_loop_exits (edge exit_edge)
     }
 }
 
+
 /* Predict edge probabilities by exploiting loop structure.  */
 
 static void
@@ -1493,10 +1512,10 @@ predict_loops (void)
 
   /* Try to predict out blocks in a loop that are not part of a
      natural loop.  */
-  FOR_EACH_LOOP (loop, 0)
+  FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
     {
       basic_block bb, *bbs;
-      unsigned j, n_exits;
+      unsigned j, n_exits = 0;
       vec<edge> exits;
       struct tree_niter_desc niter_desc;
       edge ex;
@@ -1508,7 +1527,9 @@ predict_loops (void)
       gcond *stmt = NULL;
 
       exits = get_loop_exit_edges (loop);
-      n_exits = exits.length ();
+      FOR_EACH_VEC_ELT (exits, j, ex)
+       if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE)))
+         n_exits ++;
       if (!n_exits)
        {
           exits.release ();
@@ -1522,7 +1543,14 @@ predict_loops (void)
          int max = PARAM_VALUE (PARAM_MAX_PREDICTED_ITERATIONS);
          int probability;
          enum br_predictor predictor;
+         widest_int nit;
 
+         if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE))
+           continue;
+         /* Loop heuristics do not expect exit conditional to be inside
+            inner loop.  We predict from innermost to outermost loop.  */
+         if (predicted_by_loop_heuristics_p (ex->src))
+           continue;
          predict_extra_loop_exits (ex);
 
          if (number_of_iterations_exit (loop, ex, &niter_desc, false, false))
@@ -1543,25 +1571,34 @@ predict_loops (void)
          /* 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)
+         else if (n_exits == 1
+                  && estimated_stmt_executions (loop, &nit))
            {
-             nitercst = estimated_stmt_executions_int (loop);
-             if (nitercst < 0)
-               continue;
-             if (nitercst > max)
+             if (wi::gtu_p (nit, max))
                nitercst = max;
-
+             else
+               nitercst = nit.to_shwi ();
              predictor = PRED_LOOP_ITERATIONS_GUESSED;
            }
+         /* If we have likely upper bound, trust it for very small iteration
+            counts.  Such loops would otherwise get mispredicted by standard
+            LOOP_EXIT heuristics.  */
+         else if (n_exits == 1
+                  && likely_max_stmt_executions (loop, &nit)
+                  && wi::ltu_p (nit,
+                                RDIV (REG_BR_PROB_BASE,
+                                      REG_BR_PROB_BASE
+                                        - predictor_info
+                                                [PRED_LOOP_EXIT].hitrate)))
+           {
+             nitercst = nit.to_shwi ();
+             predictor = PRED_LOOP_ITERATIONS_MAX;
+           }
          else
            continue;
 
-         /* If the prediction for number of iterations is zero, do not
-            predict the exit edges.  */
-         if (nitercst == 0)
-           continue;
-
-         probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
+         gcc_checking_assert (nitercst);
+         probability = RDIV (REG_BR_PROB_BASE, nitercst);
          predict_edge (ex, predictor, probability);
        }
       exits.release ();
@@ -1619,8 +1656,7 @@ predict_loops (void)
          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))
+             && !predicted_by_loop_heuristics_p (bb))
            {
              /* For loop with many exits we don't want to predict all exits
                 with the pretty large probability, because if all exits are
index 67de6f3c6edc04c9ec1a80c7276ed8dbbe587e41..9c7db7ab0721617fe657cb609a79ddaf62a34a92 100644 (file)
@@ -73,6 +73,10 @@ DEF_PREDICTOR (PRED_BUILTIN_EXPECT, "__builtin_expect", PROB_VERY_LIKELY,
 DEF_PREDICTOR (PRED_LOOP_ITERATIONS_GUESSED, "guessed loop iterations",
               PROB_ALWAYS, PRED_FLAG_FIRST_MATCH)
 
+/* Use number of loop iterations guessed by the contents of the loop.  */
+DEF_PREDICTOR (PRED_LOOP_ITERATIONS_MAX, "guessed loop iterations",
+              PROB_ALWAYS, PRED_FLAG_FIRST_MATCH)
+
 /* Branch containing goto is probably not taken.  */
 DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (50), 0)
 
index f327b8243b5156d19f1f367bf5398c8135af4e6e..68881580d3b295880aa079e5b37a4c09284a380f 100644 (file)
@@ -1,3 +1,7 @@
+2016-06-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gcc.dg/predict-9.c: Update template.
+
 2016-06-05  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/49377
index 59be16e6842b8a810303ca9f5bffb224b1576e72..3cba9f9da2b6a4f74cbd6adfb383319148aa0364 100644 (file)
@@ -19,5 +19,5 @@ void foo (int base)
   }
 }
 
-/* { dg-final { scan-tree-dump-times "first match heuristics: 2.0%" 4 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "first match heuristics: 4.5%" 0 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "first match heuristics: 2.0%" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "first match heuristics: 4.5%" 1 "profile_estimate"} } */