predict.c (combine_predictions_for_bb): Preserve zero predicted eges.
authorJan Hubicka <hubicka@ucw.cz>
Thu, 16 Nov 2017 16:41:22 +0000 (17:41 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 16 Nov 2017 16:41:22 +0000 (16:41 +0000)
* predict.c (combine_predictions_for_bb): Preserve zero predicted
eges.
(expensive_function_p): Remove useless assert.
(determine_unlikely_bbs): Propagate also forward; determine cold blocks

From-SVN: r254832

gcc/ChangeLog
gcc/predict.c

index f6e0f181ccf0a856b506f14dadeb51dc99d20835..5ad2d99455bd09582312665782632f9921f248fd 100644 (file)
@@ -1,3 +1,10 @@
+2017-11-16  Jan Hubicka  <hubicka@ucw.cz>
+
+       * predict.c (combine_predictions_for_bb): Preserve zero predicted       
+       eges.
+       (expensive_function_p): Remove useless assert.
+       (determine_unlikely_bbs): Propagate also forward; determine cold blocks
+
 2017-11-16  Martin Sebor  <msebor@redhat.com>
 
        PR tree-optimization/82588
index f490ec116ad4236340988cb8bdf2c93e4bf4f649..7404f1af1fa17859d66dbe473c6c556ca841f252 100644 (file)
@@ -1118,18 +1118,26 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
   int nedges = 0;
   edge e, first = NULL, second = NULL;
   edge_iterator ei;
+  int nzero = 0;
+  int nunknown = 0;
 
   FOR_EACH_EDGE (e, ei, bb->succs)
-    if (!unlikely_executed_edge_p (e))
-      {
-       nedges ++;
-       if (first && !second)
-         second = e;
-       if (!first)
-         first = e;
-      }
-    else if (!e->probability.initialized_p ())
-      e->probability = profile_probability::never ();
+    {
+      if (!unlikely_executed_edge_p (e))
+        {
+         nedges ++;
+         if (first && !second)
+           second = e;
+         if (!first)
+           first = e;
+        }
+      else if (!e->probability.initialized_p ())
+        e->probability = profile_probability::never ();
+     if (!e->probability.initialized_p ())
+        nunknown++;
+     else if (e->probability == profile_probability::never ())
+       nzero++;
+    }
 
   /* When there is no successor or only one choice, prediction is easy.
 
@@ -1283,8 +1291,27 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
     }
   clear_bb_predictions (bb);
 
-  if ((!bb->count.nonzero_p () || !first->probability.initialized_p ())
-      && !dry_run)
+
+  /* If we have only one successor which is unknown, we can compute missing
+     probablity.  */
+  if (nunknown == 1)
+    {
+      profile_probability prob = profile_probability::always ();
+      edge missing = NULL;
+
+      FOR_EACH_EDGE (e, ei, bb->succs)
+       if (e->probability.initialized_p ())
+         prob -= e->probability;
+       else if (missing == NULL)
+         missing = e;
+       else
+         gcc_unreachable ();
+       missing->probability = prob;
+    }
+  /* If nothing is unknown, we have nothing to update.  */
+  else if (!nunknown && nzero != (int)EDGE_COUNT (bb->succs))
+    ;
+  else if (!dry_run)
     {
       first->probability
         = profile_probability::from_reg_br_prob_base (combined_probability);
@@ -3334,16 +3361,11 @@ expensive_function_p (int threshold)
 {
   basic_block bb;
 
-  /* We can not compute accurately for large thresholds due to scaled
-     frequencies.  */
-  gcc_assert (threshold <= BB_FREQ_MAX);
-
   /* If profile was scaled in a way entry block has count 0, then the function
      is deifnitly taking a lot of time.  */
   if (!ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.nonzero_p ())
     return true;
 
-  /* Maximally BB_FREQ_MAX^2 so overflow won't happen.  */
   profile_count limit = ENTRY_BLOCK_PTR_FOR_FN
                           (cfun)->count.apply_scale (threshold, 1);
   profile_count sum = profile_count::zero ();
@@ -3453,6 +3475,7 @@ determine_unlikely_bbs ()
 
       gcc_checking_assert (!bb->aux);
     }
+  propagate_unlikely_bbs_forward ();
 
   auto_vec<int, 64> nsuccs;
   nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun));
@@ -3498,7 +3521,6 @@ determine_unlikely_bbs ()
       FOR_EACH_EDGE (e, ei, bb->preds)
        if (!(e->probability == profile_probability::never ()))
          {
-           e->probability = profile_probability::never ();
            if (!(e->src->count == profile_count::zero ()))
              {
                nsuccs[e->src->index]--;
@@ -3507,6 +3529,19 @@ determine_unlikely_bbs ()
              }
          }
     }
+  /* Finally all edges from non-0 regions to 0 are unlikely.  */
+  FOR_ALL_BB_FN (bb, cfun)
+    if (!(bb->count == profile_count::zero ()))
+      FOR_EACH_EDGE (e, ei, bb->succs)
+       if (!(e->probability == profile_probability::never ())
+           && e->dest->count == profile_count::zero ())
+          {
+            if (dump_file && (dump_flags & TDF_DETAILS))
+              fprintf (dump_file, "Edge %i->%i is unlikely because "
+                       "it enters unlikely block\n",
+                       bb->index, e->dest->index);
+            e->probability = profile_probability::never ();
+          }
 }
 
 /* Estimate and propagate basic block frequencies using the given branch