predict.c (edge_predicted_by_p): New function.
authorJan Hubicka <hubicka@ucw.cz>
Sat, 28 May 2016 14:52:46 +0000 (16:52 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 28 May 2016 14:52:46 +0000 (14:52 +0000)
* predict.c (edge_predicted_by_p): New function.
(predict_paths_for_bb): Do not put multiple predictions of the same type
on one edge.

From-SVN: r236848

gcc/ChangeLog
gcc/predict.c

index 86cf148bcde944b02a0298f0bca7a42fcca21497..3a75b8034e2cdf5f9e753ad9bf4009502c503131 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-27  Jan Hubicka  <hubicka@ucw.cz>
+
+       * predict.c (edge_predicted_by_p): New function.
+       (predict_paths_for_bb): Do not put multiple predictions of the same type
+       on one edge.
+
 2016-05-27  Jan Hubicka  <hubicka@ucw.cz>
 
        * tree-ssa-loop-niter.c (number_of_iterations_exit): Revert accidental
index f1e22aef5f41f394d0ea439c0d3f130d9b81aa1f..22ec8a053a015669752a5e7b98fb7ee826010564 100644 (file)
@@ -478,6 +478,31 @@ gimple_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
   return false;
 }
 
+/* Return true if the one of outgoing edges is already predicted by
+   PREDICTOR for edge E predicted as TAKEN.  */
+
+bool
+edge_predicted_by_p (edge e, enum br_predictor predictor, bool taken)
+{
+  struct edge_prediction *i;
+  basic_block bb = e->src;
+  edge_prediction **preds = bb_predictions->get (bb);
+  if (!preds)
+    return false;
+
+  int probability = predictor_info[(int) predictor].hitrate;
+
+  if (taken != TAKEN)
+    probability = REG_BR_PROB_BASE - probability;
+
+  for (i = *preds; i; i = i->ep_next)
+    if (i->ep_predictor == predictor
+       && i->ep_edge == e
+       && i->ep_probability == probability)
+      return true;
+  return false;
+}
+
 /* Return true when the probability of edge is reliable.
 
    The profile guessing code is good at predicting branch outcome (ie.
@@ -2415,7 +2440,10 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
         regions that are only reachable by abnormal edges.  We simply
         prevent visiting given BB twice.  */
       if (found)
-        predict_edge_def (e, pred, taken);
+       {
+         if (!edge_predicted_by_p (e, pred, taken))
+            predict_edge_def (e, pred, taken);
+       }
       else if (bitmap_set_bit (visited, e->src->index))
        predict_paths_for_bb (e->src, e->src, pred, taken, visited);
     }