From: hubicka Date: Sat, 6 Dec 2008 08:34:20 +0000 (+0000) Subject: PR tree-optimization/38074 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=9f694a827ab82aa4256f0bb5c870eda8f69ec26a;p=pf3gnuchains%2Fgcc-fork.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142517 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf349650fa5..248ba67c660 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-12-06 Jan Hubicka + Jakub Jelinek + + 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. + 2008-12-05 Bernd Schmidt PR rtl-optimization/38272 diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index 958fed7b0cc..75db87544ce 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -109,13 +109,12 @@ int compute_call_stmt_bb_frequency (basic_block bb) { int entry_freq = ENTRY_BLOCK_PTR->frequency; - int freq; + int freq = bb->frequency; if (!entry_freq) - entry_freq = 1; + entry_freq = 1, freq++; - freq = (!bb->frequency && !entry_freq ? CGRAPH_FREQ_BASE - : bb->frequency * CGRAPH_FREQ_BASE / entry_freq); + freq = freq * CGRAPH_FREQ_BASE / entry_freq; if (freq > CGRAPH_FREQ_MAX) freq = CGRAPH_FREQ_MAX; diff --git a/gcc/predict.c b/gcc/predict.c index c6e933f5101..73dbcbdc4ce 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);