Set edges to region known to be executed 0 times to have probability 0

Jan Hubicka hubicka@ucw.cz
Thu Nov 16 16:57:00 GMT 2017


Hi,
this patch fixes one profilemismatch issue in testsuite where we end up with
non-zero probability with edge to BB calling abort.

When detecting regions known to be executed 0 times, we should also set
edges leading to them to be executed 0 times.

The other change makes combine_predictions_for_bb to preserve this information
even if static branch prediction thinks otherwise.

Finally I noticed one unnecesary assert and fact htat I forgot to add call
to propagate_unlikely_bbs_forward while breaking it out of
propagate_unlikely_bbs.

Bootstrapped/regtested x86_64-linux, comitted.

	* 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
Index: predict.c
===================================================================
--- predict.c	(revision 254812)
+++ predict.c	(working copy)
@@ -1118,18 +1118,26 @@ combine_predictions_for_bb (basic_block
   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
     }
   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



More information about the Gcc-patches mailing list