aboutsummaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2008-12-06 09:34:20 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2008-12-06 08:34:20 +0000
commitc0ee00211f683cd8a0974cb211822c50b35b6782 (patch)
tree1c3592ee7c56ccfdd8c2ce7168b872880b33ba1d /gcc/predict.c
parentabc79c3a6d295d42b0a9ab48cea07090b0161ee8 (diff)
downloadgcc-c0ee00211f683cd8a0974cb211822c50b35b6782.zip
gcc-c0ee00211f683cd8a0974cb211822c50b35b6782.tar.gz
gcc-c0ee00211f683cd8a0974cb211822c50b35b6782.tar.bz2
re PR middle-end/38074 (missed inlining on Core2 Duo due to apparent wrong branch prediction/profile)
PR tree-optimization/38074 * cgraphbuild.c (compute_call_stmt_bb_frequency): Fix handling of 0 entry frequency. * predict.c (combine_predictions_for_bb): Ignore predictor predicting in both dirrection for first match heuristics. (tree_bb_level_predictions): Disable noreturn heuristic when there is no returning path. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r142517
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index c6e933f..73dbcbd 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -820,8 +820,33 @@ combine_predictions_for_bb (basic_block bb)
probability = REG_BR_PROB_BASE - probability;
found = true;
+ /* First match heuristics would be widly confused if we predicted
+ both directions. */
if (best_predictor > predictor)
- best_probability = probability, best_predictor = predictor;
+ {
+ struct edge_prediction *pred2;
+ int prob = probability;
+
+ for (pred2 = (struct edge_prediction *) *preds; pred2; pred2 = pred2->ep_next)
+ if (pred2 != pred && pred2->ep_predictor == pred->ep_predictor)
+ {
+ int probability2 = pred->ep_probability;
+
+ if (pred2->ep_edge != first)
+ probability2 = REG_BR_PROB_BASE - probability2;
+
+ if ((probability < REG_BR_PROB_BASE / 2) !=
+ (probability2 < REG_BR_PROB_BASE / 2))
+ break;
+
+ /* If the same predictor later gave better result, go for it! */
+ if ((probability >= REG_BR_PROB_BASE / 2 && (probability2 > probability))
+ || (probability <= REG_BR_PROB_BASE / 2 && (probability2 < probability)))
+ prob = probability2;
+ }
+ if (!pred2)
+ best_probability = prob, best_predictor = predictor;
+ }
d = (combined_probability * probability
+ (REG_BR_PROB_BASE - combined_probability)
@@ -1521,6 +1546,16 @@ static void
tree_bb_level_predictions (void)
{
basic_block bb;
+ bool has_return_edges = false;
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
+ if (!(e->flags & (EDGE_ABNORMAL | EDGE_FAKE | EDGE_EH)))
+ {
+ has_return_edges = true;
+ break;
+ }
apply_return_prediction ();
@@ -1535,7 +1570,8 @@ tree_bb_level_predictions (void)
if (is_gimple_call (stmt))
{
- if (gimple_call_flags (stmt) & ECF_NORETURN)
+ if ((gimple_call_flags (stmt) & ECF_NORETURN)
+ && has_return_edges)
predict_paths_leading_to (bb, PRED_NORETURN,
NOT_TAKEN);
decl = gimple_call_fndecl (stmt);