aboutsummaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2016-05-28 16:52:46 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2016-05-28 14:52:46 +0000
commit5aabc487d3bd2d6c973c0b18edba58267b623c3d (patch)
treecda2da680f59be1be71bb82a043b341eb9bbc379 /gcc/predict.c
parent018b22f3316ae73a57c0c19f7598b34afac954f7 (diff)
downloadgcc-5aabc487d3bd2d6c973c0b18edba58267b623c3d.zip
gcc-5aabc487d3bd2d6c973c0b18edba58267b623c3d.tar.gz
gcc-5aabc487d3bd2d6c973c0b18edba58267b623c3d.tar.bz2
predict.c (edge_predicted_by_p): New function.
* 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
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index f1e22ae..22ec8a0 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -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);
}