]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/38074 (missed inlining on Core2 Duo due to apparent wrong branch...
authorJan Hubicka <jh@suse.cz>
Sat, 6 Dec 2008 08:34:20 +0000 (09:34 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 6 Dec 2008 08:34:20 +0000 (08:34 +0000)
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

gcc/ChangeLog
gcc/cgraphbuild.c
gcc/predict.c

index cf349650fa5c5756757216d709d60acf9e56978e..248ba67c660d9dcba3b38e2840d069ec43ac53d1 100644 (file)
@@ -1,3 +1,14 @@
+2008-12-06  Jan Hubicka  <jh@suse.cz>
+           Jakub Jelinek <jakub@redhat.com>
+
+       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  <bernd.schmidt@analog.com>
 
        PR rtl-optimization/38272
index 958fed7b0ccb68e82c70826fdc7c5be25317bf54..75db87544cea3706c6e65c3cbc541f3da8b95d9f 100644 (file)
@@ -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;
 
index c6e933f510110a6b7adb2662267b2fcc3e7faea4..73dbcbdc4cea99d469bd359882f6c1d9cc867539 100644 (file)
@@ -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);