public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "bin.cheng" <bin.cheng@linux.alibaba.com>
To: "GCC Patches" <gcc-patches@gcc.gnu.org>
Cc: "Jan Hubicka" <hubicka@ucw.cz>,
	 "Richard Biener" <richard.guenther@gmail.com>
Subject: Re: [PATCH AutoFDO/2]Treat ZERO as common profile probability/count
Date: Fri, 02 Nov 2018 05:31:00 -0000	[thread overview]
Message-ID: <7002062a-a7fd-4d38-9bb4-10cff9b66b53.bin.cheng@linux.alibaba.com> (raw)
In-Reply-To: <CAFiYyc0Dj7y4fe8Jj9JGZp3xh0h=vEbohs7kccO5RsXe5u4GNg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4953 bytes --]

------------------------------------------------------------------
Sender:Richard Biener <richard.guenther@gmail.com>
Sent at:2018 Oct 31 (Wed) 17:11
To:bin.cheng <bin.cheng@linux.alibaba.com>; Jan Hubicka <hubicka@ucw.cz>
Cc:GCC Patches <gcc-patches@gcc.gnu.org>
Subject:Re: [PATCH AutoFDO/2]Treat ZERO as common profile probability/count
> 
> 
> On Wed, Oct 31, 2018 at 7:30 AM bin.cheng <bin.cheng@linux.alibaba.com> wrote:
>>
>> Hi,
>> In new profile probability/count infra, we have different precision quality categories,
>> and probabilities/counts of different categories are not supposed to be compared or
>> calculated.  Though in general is an improvement, it introduces unexpected behavior.
>> Specifically, class profile_probablity and profile_count themselves are implemented
>> by comparing probabilities/counts against profile_count::zero().  while zero() is of
>> profile_precision category, it's always compared different to zero of other precision
>> categories including afdo.
>>
>> I can see two ways fixing this: 1) Treat zero as a common probability/count regardless
>> of its category; 2) Provide an "is_zero" method rather than relying on "==" comparison
>> against probability_count::zero().  2) requires lots of code changes so I went with 1)
>> in this patch set.  This patch doesn't handle "always" but it might be.
>>
>> This patch also corrects a minor issue where we try to invert an uninitialized value.
>>
>> Bootstrap and test on x86_64 in patch set.  Is it OK?
> 

Thanks for all the reviews.

> I'll defer on the emit_store_flag_force change, likewise for the zero

As Jeff pointed out too, this is discarded now.

> handling in
> compares - I don't think zeros of different qualities should compare equal.
> Would compares against ::always() not have the very same issue?
> Likewise ::even(),
> ::likely(), etc.?  Those always get guessed quality.

In this version, I went with the second method which adds never_p/zero_p
member function for probability and count.  Check on ZERO value won't fail
unexpected now.  The patch also makes some other changes that avoids
short-circuit returning on ZERO probability/count and let.

> 
> The invert change looks OK to me.  The related change to the always() API would
> suggest to replace guessed_always() with always (guessed) and also do similar
> changes throughout the whole API...
The invert part is split as a standalone patch.  I think adding a default precision
parameter to member functions is a little bit better than having various version
functions here, like you mentioned for from_gcov_type.

Bootstrap and test on x86_64 in patch set.  It fixes all (13) ICE autofdo tests.

Thanks,
bin
2018-11-02  Bin Cheng  <bin.cheng@linux.alibaba.com>

	* profile-count.h (profile_probability::always): Add parameter.
	(profile_probability::invert): Don't invert uninitialized probability.

2018-11-02  Bin Cheng  <bin.cheng@linux.alibaba.com>

	* profile-count.h (profile_probability::never_p): New.
	(profile_probability::operator+, +=, -, -=, *, *=, /, /=): Check ZERO
	probability using never_p.
	(profile_probability::apply_scale): Likewise.
	(profile_probability::apply): Check using uninitialized_p.
	(profile_count::zero_p): New.
	(profile_count::compatible_p): Check ZERO count using zero_p.
	(profile_count::operator+, +=, <, >, <=, >=, apply_scale): Likewise.
	(profile_count::apply_probability, probability_in): Likewise.
	(profile_count::operator-, -=): Likewise.  Don't quick return if RHS
	profile_count is ZERO.
	(profile_count::max): Don't quick return in case of ZERO count.
	* profile-count.c (profile_count::to_frequency): Check ZERO profile
	probability or count using never_p or zero_p.
	(profile_count::to_cgraph_frequency, to_sreal_scale): Likewise.
	(profile_count::adjust_for_ipa_scaling): Likewise.
	(profile_count::combine_with_ipa_count): Likewise.
	(profile_probability::combine_with_count): Likewise.
	* bb-reorder.c (sanitize_hot_paths): Likewise.
	* cfg.c (update_bb_profile_for_threading): Likewise.
	(scale_bbs_frequencies_profile_count): Likewise.
	* ipa-profile.c (ipa_propagate_frequency_1): Likewise.
	(ipa_propagate_frequency): Likewise.
	* ipa-utility.c (ipa_merge_profiles): Likewise.
	* predict.c (maybe_hot_count_p, probably_never_executed): Likewise.
	(probably_never_executed_bb_p, unlikely_executed_stmt_p): Likewise.
	(combine_predictions_for_bb): Likewise.
	(drop_profile, handle_missing_profiles): Likewise.
	(propagate_unlikely_bbs_forward): Likewise.
	(determine_unlikely_bbs): Likewise.
	(estimate_bb_frequencies): Likewise.
	(compute_function_frequency, force_edge_cold): Likewise.
	* profile.c (compute_branch_probabilities): Likewise.
	* shrink-wrap.c (try_shrink_wrapping): Likewise.
	* tree-ssa-loop-manip.c (scale_dominated_blocks_in_loop): Likewise.
	(tree_transform_and_unroll_loop): Likewise.
	* tree-ssa-threadupdate.c (update_profile): Likewise.
	* tree-vect-loop.c (scale_profile_for_vect_loop): Likewise.

[-- Attachment #2: 0002-Dont-invert-uninitialized-value.patch --]
[-- Type: application/octet-stream, Size: 1384 bytes --]

From 06307f1b86c619b87494c573eb54342a25778d71 Mon Sep 17 00:00:00 2001
From: chengbin <bin.cheng@linux.alibaba.com>
Date: Thu, 1 Nov 2018 12:12:44 +0800
Subject: [PATCH 2/5] Dont invert uninitialized value

---
 gcc/profile-count.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index f4d0c340a0a..4289bc5a004 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -200,11 +200,11 @@ public:
       ret.m_quality = profile_guessed;
       return ret;
     }
-  static profile_probability always ()
+  static profile_probability always (enum profile_quality q = profile_precise)
     {
       profile_probability ret;
       ret.m_val = max_probability;
-      ret.m_quality = profile_precise;
+      ret.m_quality = q;
       return ret;
     }
   /* Probabilities which has not been initialized. Either because
@@ -459,10 +459,12 @@ public:
       return RDIV (val * m_val, max_probability);
     }
 
-  /* Return 1-*THIS.  */
+  /* Return 1-*THIS.  It's meaningless to invert an uninitialized value.  */
   profile_probability invert () const
     {
-      return profile_probability::always() - *this;
+      if (! initialized_p ())
+	return *this;
+      return profile_probability::always (m_quality) - *this;
     }
 
   /* Return THIS with quality dropped to GUESSED.  */
-- 
2.14.4.44.g2045bb6


[-- Attachment #3: 0003-Check-zero-probability-count-using-member-function.patch --]
[-- Type: application/octet-stream, Size: 28481 bytes --]

From 5b0e38d146ff8cf618eab144f46601d74c5cd1e5 Mon Sep 17 00:00:00 2001
From: chengbin <bin.cheng@linux.alibaba.com>
Date: Thu, 1 Nov 2018 12:10:37 +0800
Subject: [PATCH 3/5] Check zero probability count using member function.

---
 gcc/bb-reorder.c            |  6 +--
 gcc/cfg.c                   |  4 +-
 gcc/ipa-profile.c           |  6 +--
 gcc/ipa-utils.c             |  6 +--
 gcc/predict.c               | 64 +++++++++++++++----------------
 gcc/profile-count.c         | 18 ++++-----
 gcc/profile-count.h         | 92 ++++++++++++++++++++++-----------------------
 gcc/profile.c               |  2 +-
 gcc/shrink-wrap.c           |  2 +-
 gcc/tree-ssa-loop-manip.c   |  4 +-
 gcc/tree-ssa-threadupdate.c |  2 +-
 gcc/tree-vect-loop.c        |  2 +-
 12 files changed, 103 insertions(+), 105 deletions(-)

diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index e20df160723..3350799a1b1 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1572,8 +1572,7 @@ sanitize_hot_paths (bool walk_up, unsigned int cold_bb_count,
             continue;
 
 	  /* Do not expect profile insanities when profile was not adjusted.  */
-	  if (e->probability == profile_probability::never ()
-	      || e->count () == profile_count::zero ())
+	  if (e->probability.never_p () || (e->count ()).zero_p ())
 	    continue;
 
           if (BB_PARTITION (reach_bb) != BB_COLD_PARTITION)
@@ -1604,8 +1603,7 @@ sanitize_hot_paths (bool walk_up, unsigned int cold_bb_count,
           if (e->flags & EDGE_DFS_BACK)
             continue;
 	  /* Do not expect profile insanities when profile was not adjusted.  */
-	  if (e->probability == profile_probability::never ()
-	      || e->count () == profile_count::zero ())
+	  if (e->probability.never_p () || (e->count ()).zero_p ())
 	    continue;
           /* Select the hottest edge using the edge count, if it is non-zero,
              then fallback to the edge probability.  */
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 7be89d40604..1f776444f85 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -911,7 +911,7 @@ update_bb_profile_for_threading (basic_block bb,
   /* Now rescale the probabilities.  */
   taken_edge->probability -= prob;
   prob = prob.invert ();
-  if (prob == profile_probability::never ())
+  if (prob.never_p ())
     {
       if (dump_file)
 	fprintf (dump_file, "Edge probabilities of bb %i has been reset, "
@@ -940,7 +940,7 @@ scale_bbs_frequencies_profile_count (basic_block *bbs, int nbbs,
 				     profile_count num, profile_count den)
 {
   int i;
-  if (num == profile_count::zero () || den.nonzero_p ())
+  if (num.zero_p () || den.nonzero_p ())
     for (i = 0; i < nbbs; i++)
       bbs[i]->count = bbs[i]->count.apply_scale (num, den);
 }
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index c74f4a4a41d..69e92431323 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -324,7 +324,7 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
 	 it is executed by the train run.  Transfer the function only if all
 	 callers are unlikely executed.  */
       if (profile_info
-	  && !(edge->callee->count.ipa () == profile_count::zero ())
+	  && !((edge->callee->count.ipa ()).zero_p ())
 	  && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED
 	      || (edge->caller->global.inlined_to
 		  && edge->caller->global.inlined_to->frequency
@@ -428,8 +428,8 @@ ipa_propagate_frequency (struct cgraph_node *node)
   if (node->count. ipa().initialized_p ())
     {
       bool hot = false;
-      if (!(node->count. ipa() == profile_count::zero ())
-	  && node->count. ipa() >= get_hot_bb_threshold ())
+      if (!((node->count.ipa ()).zero_p ())
+	  && node->count.ipa () >= get_hot_bb_threshold ())
 	hot = true;
       if (!hot)
 	hot |= contains_hot_call_p (node);
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 9985721f7da..d98e22463da 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -530,9 +530,9 @@ ipa_merge_profiles (struct cgraph_node *dst,
 	     pick more informative one (that is nonzero IPA if other is
 	     uninitialized, guessed or global0).   */
 	  if (!dstbb->count.ipa ().initialized_p ()
-	      || (dstbb->count.ipa () == profile_count::zero ()
+	      || ((dstbb->count.ipa ()).zero_p ()
 		  && (srcbb->count.ipa ().initialized_p ()
-		      && !(srcbb->count.ipa () == profile_count::zero ()))))
+		      && !((srcbb->count.ipa ()).zero_p ()))))
 	    {
 	      dstbb->count = srcbb->count;
 	      for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
@@ -544,7 +544,7 @@ ipa_merge_profiles (struct cgraph_node *dst,
 		}
 	    }	
 	  else if (srcbb->count.ipa ().initialized_p ()
-		   && !(srcbb->count.ipa () == profile_count::zero ()))
+		   && !((srcbb->count.ipa ()).zero_p ()))
 	    {
 	      for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
 		{
diff --git a/gcc/predict.c b/gcc/predict.c
index ab2dc8ed031..24d7c7b45d2 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -155,7 +155,7 @@ maybe_hot_count_p (struct function *fun, profile_count count)
 {
   if (!count.initialized_p ())
     return true;
-  if (count.ipa () == profile_count::zero ())
+  if ((count.ipa ()).zero_p ())
     return false;
   if (!count.ipa_p ())
     {
@@ -212,7 +212,7 @@ probably_never_executed (struct function *fun,
                          profile_count count)
 {
   gcc_checking_assert (fun);
-  if (count.ipa () == profile_count::zero ())
+  if ((count.ipa ()).zero_p ())
     return true;
   /* Do not trust adjusted counts.  This will make us to drop int cold section
      code with low execution count as a result of inlining. These low counts
@@ -248,8 +248,8 @@ probably_never_executed_bb_p (struct function *fun, const_basic_block bb)
 static bool
 unlikely_executed_edge_p (edge e)
 {
-  return (e->count () == profile_count::zero ()
-	  || e->probability == profile_probability::never ())
+  return ((e->count ()).zero_p ()
+	  || e->probability.never_p ())
 	 || (e->flags & (EDGE_EH | EDGE_FAKE));
 }
 
@@ -810,7 +810,7 @@ unlikely_executed_stmt_p (gimple *stmt)
 static bool
 unlikely_executed_bb_p (basic_block bb)
 {
-  if (bb->count == profile_count::zero ())
+  if (bb->count.zero_p ())
     return true;
   if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun) || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
     return false;
@@ -1187,7 +1187,7 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
         e->probability = profile_probability::never ();
      if (!e->probability.initialized_p ())
         nunknown++;
-     else if (e->probability == profile_probability::never ())
+     else if (e->probability.never_p ())
 	nzero++;
     }
 
@@ -3452,7 +3452,7 @@ drop_profile (struct cgraph_node *node, profile_count call_count)
       bool clear_zeros
 	 = !ENTRY_BLOCK_PTR_FOR_FN (fn)->count.nonzero_p ();
       FOR_ALL_BB_FN (bb, fn)
-	if (clear_zeros || !(bb->count == profile_count::zero ()))
+	if (clear_zeros || !(bb->count.zero_p ()))
 	  bb->count = bb->count.guessed_local ();
       fn->cfg->count_max = fn->cfg->count_max.guessed_local ();
     }
@@ -3543,7 +3543,7 @@ handle_missing_profiles (void)
           struct cgraph_node *callee = e->callee;
           struct function *fn = DECL_STRUCT_FUNCTION (callee->decl);
 
-          if (!(e->count.ipa () == profile_count::zero ())
+          if (!((e->count.ipa ()).zero_p ())
 	      && callee->count.ipa ().nonzero_p ())
             continue;
           if ((DECL_COMDAT (callee->decl) || DECL_EXTERNAL (callee->decl))
@@ -3627,7 +3627,7 @@ propagate_unlikely_bbs_forward (void)
   edge_iterator ei;
   edge e;
 
-  if (!(ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ()))
+  if (!(ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.zero_p ()))
     {
       ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux = (void *)(size_t) 1;
       worklist.safe_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
@@ -3636,8 +3636,8 @@ propagate_unlikely_bbs_forward (void)
 	{
 	  bb = worklist.pop ();
 	  FOR_EACH_EDGE (e, ei, bb->succs)
-	    if (!(e->count () == profile_count::zero ())
-		&& !(e->dest->count == profile_count::zero ())
+	    if (!((e->count ()).zero_p ())
+		&& !(e->dest->count.zero_p ())
 		&& !e->dest->aux)
 	      {
 		e->dest->aux = (void *)(size_t) 1;
@@ -3650,7 +3650,7 @@ propagate_unlikely_bbs_forward (void)
     {
       if (!bb->aux)
 	{
-	  if (!(bb->count == profile_count::zero ())
+	  if (!(bb->count.zero_p ())
 	      && (dump_file && (dump_flags & TDF_DETAILS)))
 	    fprintf (dump_file,
 		     "Basic block %i is marked unlikely by forward prop\n",
@@ -3677,7 +3677,7 @@ determine_unlikely_bbs ()
 
   FOR_EACH_BB_FN (bb, cfun)
     {
-      if (!(bb->count == profile_count::zero ())
+      if (!(bb->count.zero_p ())
 	  && unlikely_executed_bb_p (bb))
 	{
           if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3687,7 +3687,7 @@ determine_unlikely_bbs ()
 	}
 
       FOR_EACH_EDGE (e, ei, bb->succs)
-	if (!(e->probability == profile_probability::never ())
+	if (!(e->probability.never_p ())
 	    && unlikely_executed_edge_p (e))
 	  {
             if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3703,13 +3703,13 @@ determine_unlikely_bbs ()
   auto_vec<int, 64> nsuccs;
   nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun));
   FOR_ALL_BB_FN (bb, cfun)
-    if (!(bb->count == profile_count::zero ())
+    if (!(bb->count.zero_p ())
 	&& bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
       {
 	nsuccs[bb->index] = 0;
         FOR_EACH_EDGE (e, ei, bb->succs)
-	  if (!(e->probability == profile_probability::never ())
-	      && !(e->dest->count == profile_count::zero ()))
+	  if (!(e->probability.never_p ())
+	      && !(e->dest->count.zero_p ()))
 	    nsuccs[bb->index]++;
 	if (!nsuccs[bb->index])
 	  worklist.safe_push (bb);
@@ -3717,7 +3717,7 @@ determine_unlikely_bbs ()
   while (worklist.length () > 0)
     {
       bb = worklist.pop ();
-      if (bb->count == profile_count::zero ())
+      if (bb->count.zero_p ())
 	continue;
       if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun))
 	{
@@ -3743,9 +3743,9 @@ determine_unlikely_bbs ()
 		 bb->index);
       bb->count = profile_count::zero ();
       FOR_EACH_EDGE (e, ei, bb->preds)
-	if (!(e->probability == profile_probability::never ()))
+	if (!(e->probability.never_p ()))
 	  {
-	    if (!(e->src->count == profile_count::zero ()))
+	    if (!(e->src->count.zero_p ()))
 	      {
 		gcc_checking_assert (nsuccs[e->src->index] > 0);
 	        nsuccs[e->src->index]--;
@@ -3756,10 +3756,10 @@ 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 ()))
+    if (!(bb->count.zero_p ()))
       FOR_EACH_EDGE (e, ei, bb->succs)
-	if (!(e->probability == profile_probability::never ())
-	    && e->dest->count == profile_count::zero ())
+	if (!(e->probability.never_p ())
+	    && e->dest->count.zero_p ())
 	   {
 	     if (dump_file && (dump_flags & TDF_DETAILS))
 	       fprintf (dump_file, "Edge %i->%i is unlikely because "
@@ -3767,7 +3767,7 @@ determine_unlikely_bbs ()
 			bb->index, e->dest->index);
 	     e->probability = profile_probability::never ();
 	   }
-  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ())
+  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.zero_p ())
     cgraph_node::get (current_function_decl)->count = profile_count::zero ();
 }
 
@@ -3849,7 +3849,7 @@ estimate_bb_frequencies (bool force)
 
 	  /* If we have profile feedback in which this function was never
 	     executed, then preserve this info.  */
-	  if (!(bb->count == profile_count::zero ()))
+	  if (!(bb->count.zero_p ()))
 	    bb->count = count.guessed_local ().combine_with_ipa_count (ipa_count);
           cfun->cfg->count_max = cfun->cfg->count_max.max (bb->count);
 	}
@@ -3877,7 +3877,7 @@ compute_function_frequency (void)
     {
       int flags = flags_from_decl_or_type (current_function_decl);
       if ((ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa_p ()
-	   && ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa() == profile_count::zero ())
+	   && (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa()).zero_p ())
 	  || lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
 	     != NULL)
 	{
@@ -3899,7 +3899,7 @@ compute_function_frequency (void)
 
   node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
   warn_function_cold (current_function_decl);
-  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa() == profile_count::zero ())
+  if ((ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa()).zero_p ())
     return;
   FOR_EACH_BB_FN (bb, cfun)
     {
@@ -4242,7 +4242,7 @@ force_edge_cold (edge e, bool impossible)
 
   /* If edge is already improbably or cold, just return.  */
   if (e->probability <= goal
-      && (!impossible || e->count () == profile_count::zero ()))
+      && (!impossible || (e->count ()).zero_p ()))
     return;
   FOR_EACH_EDGE (e2, ei, e->src->succs)
     if (e2 != e)
@@ -4288,7 +4288,7 @@ force_edge_cold (edge e, bool impossible)
      is unlikely.  */
   else
     {
-      if (prob_sum == profile_probability::never ())
+      if (prob_sum.never_p ())
         e->probability = profile_probability::always ();
       else
 	{
@@ -4301,9 +4301,9 @@ force_edge_cold (edge e, bool impossible)
       if (current_ir_type () != IR_GIMPLE
 	  && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
 	update_br_prob_note (e->src);
-      if (e->src->count == profile_count::zero ())
+      if (e->src->count.zero_p ())
 	return;
-      if (count_sum == profile_count::zero () && impossible)
+      if (count_sum.zero_p () && impossible)
 	{
 	  bool found = false;
 	  if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
@@ -4340,7 +4340,7 @@ force_edge_cold (edge e, bool impossible)
 	 BB has only one predecestor.  This is common case when we are updating
 	 after loop transforms.  */
       if (!(prob_sum > profile_probability::never ())
-	  && count_sum == profile_count::zero ()
+	  && count_sum.zero_p ()
 	  && single_pred_p (e->src) && e->src->count.to_frequency (cfun)
 	     > (impossible ? 0 : 1))
 	{
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index f4ab244e3a3..0e6109cd7b8 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -258,7 +258,7 @@ profile_count::to_frequency (struct function *fun) const
 {
   if (!initialized_p ())
     return BB_FREQ_MAX;
-  if (*this == profile_count::zero ())
+  if (this->zero_p ())
     return 0;
   gcc_assert (REG_BR_PROB_BASE == BB_FREQ_MAX
 	      && fun->cfg->count_max.initialized_p ());
@@ -277,7 +277,7 @@ profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
 {
   if (!initialized_p () || !entry_bb_count.initialized_p ())
     return CGRAPH_FREQ_BASE;
-  if (*this == profile_count::zero ())
+  if (this->zero_p ())
     return 0;
   gcc_checking_assert (entry_bb_count.initialized_p ());
   uint64_t scale;
@@ -300,7 +300,7 @@ profile_count::to_sreal_scale (profile_count in, bool *known) const
     }
   if (known)
     *known = true;
-  if (*this == profile_count::zero ())
+  if (this->zero_p ())
     return 0;
 
   if (!in.m_val)
@@ -327,7 +327,7 @@ profile_count::adjust_for_ipa_scaling (profile_count *num,
   if (*num == *den)
     return;
   /* Scaling to zero is always zero.  */
-  if (*num == profile_count::zero ())
+  if (num->zero_p ())
     return;
   /* If den is non-zero we are safe.  */
   if (den->force_nonzero () == *den)
@@ -349,9 +349,9 @@ profile_count::combine_with_ipa_count (profile_count ipa)
   ipa = ipa.ipa ();
   if (ipa.nonzero_p ())
     return ipa;
-  if (!ipa.initialized_p () || *this == profile_count::zero ())
+  if (!ipa.initialized_p () || this->zero_p ())
     return *this;
-  if (ipa == profile_count::zero ())
+  if (ipa.zero_p ())
     return this->global0 ();
   return this->global0adjusted ();
 }
@@ -387,10 +387,10 @@ profile_probability::combine_with_count (profile_count count1,
      If counts are nonzero we can distribute accordingly. In remaining
      cases just avreage the values and hope for the best.  */
   if (*this == other || count1 == count2
-      || (count2 == profile_count::zero ()
-	  && !(count1 == profile_count::zero ())))
+      || (count2.zero_p ()
+	  && !(count1.zero_p ())))
     return *this;
-  if (count1 == profile_count::zero () && !(count2 == profile_count::zero ()))
+  if (count1.zero_p () && !(count2.zero_p ()))
     return other;
   else if (count1.nonzero_p () || count2.nonzero_p ())
     return *this * count1.probability_in (count1 + count2)
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index 4289bc5a004..2b5e3269250 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -218,6 +218,11 @@ public:
     }
 
 
+  /* Return true if value is zero.  */
+  bool never_p () const
+    {
+      return m_val == 0;
+    }
   /* Return true if value has been initialized.  */
   bool initialized_p () const
     {
@@ -288,9 +293,9 @@ public:
     }
   profile_probability operator+ (const profile_probability &other) const
     {
-      if (other == profile_probability::never ())
+      if (other.never_p ())
 	return *this;
-      if (*this == profile_probability::never ())
+      if (this->never_p ())
 	return other;
       if (!initialized_p () || !other.initialized_p ())
 	return profile_probability::uninitialized ();
@@ -302,9 +307,9 @@ public:
     }
   profile_probability &operator+= (const profile_probability &other)
     {
-      if (other == profile_probability::never ())
+      if (other.never_p ())
 	return *this;
-      if (*this == profile_probability::never ())
+      if (this->never_p ())
 	{
 	  *this = other;
 	  return *this;
@@ -320,8 +325,7 @@ public:
     }
   profile_probability operator- (const profile_probability &other) const
     {
-      if (*this == profile_probability::never ()
-	  || other == profile_probability::never ())
+      if (this->never_p ())
 	return *this;
       if (!initialized_p () || !other.initialized_p ())
 	return profile_probability::uninitialized ();
@@ -332,8 +336,7 @@ public:
     }
   profile_probability &operator-= (const profile_probability &other)
     {
-      if (*this == profile_probability::never ()
-	  || other == profile_probability::never ())
+      if (this->never_p ())
 	return *this;
       if (!initialized_p () || !other.initialized_p ())
 	return *this = profile_probability::uninitialized ();
@@ -346,8 +349,7 @@ public:
     }
   profile_probability operator* (const profile_probability &other) const
     {
-      if (*this == profile_probability::never ()
-	  || other == profile_probability::never ())
+      if (this->never_p () || other.never_p ())
 	return profile_probability::never ();
       if (!initialized_p () || !other.initialized_p ())
 	return profile_probability::uninitialized ();
@@ -358,8 +360,7 @@ public:
     }
   profile_probability &operator*= (const profile_probability &other)
     {
-      if (*this == profile_probability::never ()
-	  || other == profile_probability::never ())
+      if (this->never_p () || other.never_p ())
 	return *this = profile_probability::never ();
       if (!initialized_p () || !other.initialized_p ())
 	return *this = profile_probability::uninitialized ();
@@ -372,7 +373,7 @@ public:
     }
   profile_probability operator/ (const profile_probability &other) const
     {
-      if (*this == profile_probability::never ())
+      if (this->never_p ())
 	return profile_probability::never ();
       if (!initialized_p () || !other.initialized_p ())
 	return profile_probability::uninitialized ();
@@ -399,7 +400,7 @@ public:
     }
   profile_probability &operator/= (const profile_probability &other)
     {
-      if (*this == profile_probability::never ())
+      if (this->never_p ())
 	return *this = profile_probability::never ();
       if (!initialized_p () || !other.initialized_p ())
 	return *this = profile_probability::uninitialized ();
@@ -454,7 +455,7 @@ public:
 
   gcov_type apply (gcov_type val) const
     {
-      if (*this == profile_probability::uninitialized ())
+      if (! initialized_p ())
 	return val / 2;
       return RDIV (val * m_val, max_probability);
     }
@@ -486,7 +487,7 @@ public:
   /* Return *THIS * NUM / DEN.  */
   profile_probability apply_scale (int64_t num, int64_t den) const
     {
-      if (*this == profile_probability::never ())
+      if (this->never_p ())
 	return *this;
       if (!initialized_p ())
 	return profile_probability::uninitialized ();
@@ -657,8 +658,7 @@ private:
     {
       if (!initialized_p () || !other.initialized_p ())
 	return true;
-      if (*this == profile_count::zero ()
-	  || other == profile_count::zero ())
+      if (this->zero_p () || other.zero_p ())
 	return true;
       return ipa_p () == other.ipa_p ();
     }
@@ -704,6 +704,11 @@ public:
       return m_val;
     }
 
+  /* Return true if value is zero.  */
+  bool zero_p () const
+    {
+      return m_val == 0;
+    }
   /* Return true if value has been initialized.  */
   bool initialized_p () const
     {
@@ -760,9 +765,9 @@ public:
     }
   profile_count operator+ (const profile_count &other) const
     {
-      if (other == profile_count::zero ())
+      if (other.zero_p ())
 	return *this;
-      if (*this == profile_count::zero ())
+      if (this->zero_p ())
 	return other;
       if (!initialized_p () || !other.initialized_p ())
 	return profile_count::uninitialized ();
@@ -775,9 +780,9 @@ public:
     }
   profile_count &operator+= (const profile_count &other)
     {
-      if (other == profile_count::zero ())
+      if (other.zero_p ())
 	return *this;
-      if (*this == profile_count::zero ())
+      if (this->zero_p ())
 	{
 	  *this = other;
 	  return *this;
@@ -794,7 +799,7 @@ public:
     }
   profile_count operator- (const profile_count &other) const
     {
-      if (*this == profile_count::zero () || other == profile_count::zero ())
+      if (this->zero_p ())
 	return *this;
       if (!initialized_p () || !other.initialized_p ())
 	return profile_count::uninitialized ();
@@ -806,7 +811,7 @@ public:
     }
   profile_count &operator-= (const profile_count &other)
     {
-      if (*this == profile_count::zero () || other == profile_count::zero ())
+      if (this->zero_p ())
 	return *this;
       if (!initialized_p () || !other.initialized_p ())
 	return *this = profile_count::uninitialized ();
@@ -832,9 +837,9 @@ public:
     {
       if (!initialized_p () || !other.initialized_p ())
 	return false;
-      if (*this == profile_count::zero ())
-	return !(other == profile_count::zero ());
-      if (other == profile_count::zero ())
+      if (this->zero_p ())
+	return !(other.zero_p ());
+      if (other.zero_p ())
 	return false;
       gcc_checking_assert (compatible_p (other));
       return m_val < other.m_val;
@@ -843,10 +848,10 @@ public:
     {
       if (!initialized_p () || !other.initialized_p ())
 	return false;
-      if (*this  == profile_count::zero ())
+      if (this->zero_p ())
 	return false;
-      if (other == profile_count::zero ())
-	return !(*this == profile_count::zero ());
+      if (other.zero_p ())
+	return !(this->zero_p ());
       gcc_checking_assert (compatible_p (other));
       return initialized_p () && other.initialized_p () && m_val > other.m_val;
     }
@@ -867,10 +872,10 @@ public:
     {
       if (!initialized_p () || !other.initialized_p ())
 	return false;
-      if (*this == profile_count::zero ())
+      if (this->zero_p ())
 	return true;
-      if (other == profile_count::zero ())
-	return (*this == profile_count::zero ());
+      if (other.zero_p ())
+	return (this->zero_p ());
       gcc_checking_assert (compatible_p (other));
       return m_val <= other.m_val;
     }
@@ -878,10 +883,10 @@ public:
     {
       if (!initialized_p () || !other.initialized_p ())
 	return false;
-      if (other == profile_count::zero ())
+      if (other.zero_p ())
 	return true;
-      if (*this == profile_count::zero ())
-	return !(other == profile_count::zero ());
+      if (this->zero_p ())
+	return !(other.zero_p ());
       gcc_checking_assert (compatible_p (other));
       return m_val >= other.m_val;
     }
@@ -925,10 +930,6 @@ public:
 	return other;
       if (!other.initialized_p ())
 	return *this;
-      if (*this == profile_count::zero ())
-	return other;
-      if (other == profile_count::zero ())
-	return *this;
       gcc_checking_assert (compatible_p (other));
       if (m_val < other.m_val || (m_val == other.m_val
 				  && m_quality < other.m_quality))
@@ -954,9 +955,9 @@ public:
   /* Scale counter according to PROB.  */
   profile_count apply_probability (profile_probability prob) const
     {
-      if (*this == profile_count::zero ())
+      if (this->zero_p ())
 	return *this;
-      if (prob == profile_probability::never ())
+      if (prob.never_p ())
 	return profile_count::zero ();
       if (!initialized_p ())
 	return profile_count::uninitialized ();
@@ -986,9 +987,9 @@ public:
     }
   profile_count apply_scale (profile_count num, profile_count den) const
     {
-      if (*this == profile_count::zero ())
+      if (this->zero_p ())
 	return *this;
-      if (num == profile_count::zero ())
+      if (num.zero_p ())
 	return num;
       if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
 	return profile_count::uninitialized ();
@@ -1071,8 +1072,7 @@ public:
      OVERALL.  */
   profile_probability probability_in (const profile_count overall) const
     {
-      if (*this == profile_count::zero ()
-	  && !(overall == profile_count::zero ()))
+      if (this->zero_p () && !(overall.zero_p ()))
 	return profile_probability::never ();
       if (!initialized_p () || !overall.initialized_p ()
 	  || !overall.m_val)
diff --git a/gcc/profile.c b/gcc/profile.c
index 2130319b081..70c6c59578d 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -707,7 +707,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
      determined zero counts.  */
   else
     FOR_ALL_BB_FN (bb, cfun)
-      if (!(bb->count == profile_count::zero ()))
+      if (!(bb->count.zero_p ()))
         bb->count = bb->count.global0 ();
 
   bb_gcov_counts.release ();
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index 1ad73798747..88021f11c74 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -922,7 +922,7 @@ try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq)
 	if (dump_file)
 	  fprintf (dump_file, "Duplicated %d to %d\n", bb->index, dup->index);
 	
-	if (num == profile_count::zero () || den.nonzero_p ())
+	if (num.zero_p () || den.nonzero_p ())
 	  bb->count = bb->count.apply_scale (num, den);
 	dup->count -= bb->count;
       }
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 5acee6c98f3..6b6388fc85e 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -1095,7 +1095,7 @@ scale_dominated_blocks_in_loop (struct loop *loop, basic_block bb,
 {
   basic_block son;
 
-  if (!den.nonzero_p () && !(num == profile_count::zero ()))
+  if (!den.nonzero_p () && !(num.zero_p ()))
     return;
 
   for (son = first_dom_son (CDI_DOMINATORS, bb);
@@ -1378,7 +1378,7 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
     {
       /* Avoid dropping loop body profile counter to 0 because of zero count
 	 in loop's preheader.  */
-      if (freq_h.nonzero_p () && !(freq_e == profile_count::zero ()))
+      if (freq_h.nonzero_p () && !(freq_e.zero_p ()))
         freq_e = freq_e.force_nonzero ();
       scale_loop_frequencies (loop, freq_e.probability_in (freq_h));
     }
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 8080dff76d0..77b822c23e7 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -890,7 +890,7 @@ update_profile (edge epath, edge edup, profile_count path_in_count,
       dup_block->count = path_in_count;
     }
 
-  if (path_in_count == profile_count::zero ())
+  if (path_in_count.zero_p ())
     return;
 
   profile_count final_count = epath->count () - path_out_count;
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 177b284e9c6..2a47b20178d 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -8084,7 +8084,7 @@ scale_profile_for_vect_loop (struct loop *loop, unsigned vf)
 
       /* Avoid dropping loop body profile counter to 0 because of zero count
 	 in loop's preheader.  */
-      if (!(freq_e == profile_count::zero ()))
+      if (!(freq_e.zero_p ()))
         freq_e = freq_e.force_nonzero ();
       p = freq_e.apply_scale (new_est_niter + 1, 1).probability_in (freq_h);
       scale_loop_frequencies (loop, p);
-- 
2.14.4.44.g2045bb6


  parent reply	other threads:[~2018-11-02  5:31 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-31  8:33 bin.cheng
2018-10-31  9:43 ` Richard Biener
2018-10-31  9:57   ` Bin.Cheng
2018-11-02  5:31   ` bin.cheng [this message]
2018-11-05 14:38     ` Jan Hubicka
2018-11-05 14:40     ` Jan Hubicka
2018-11-13  6:58       ` Bin.Cheng
     [not found]   ` <20181105141206.4ncu3s2v2jxv6o54@kam.mff.cuni.cz>
2018-11-20 10:54     ` bin.cheng
     [not found]       ` <CAHFci28CQB3KK+Yp7gb8BR61UaGhAJJ-R1yzZPHxitczvgEB3w@mail.gmail.com>
2018-11-28 16:20         ` Jan Hubicka
2018-12-04  8:40           ` Bin.Cheng
2018-12-07 10:00             ` Bin.Cheng
2018-12-07 16:57               ` Jan Hubicka
2018-12-09  6:40                 ` Bin.Cheng
2018-10-31 15:02 ` Jeff Law
2018-11-01  1:11   ` Bin.Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7002062a-a7fd-4d38-9bb4-10cff9b66b53.bin.cheng@linux.alibaba.com \
    --to=bin.cheng@linux.alibaba.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hubicka@ucw.cz \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).