Hi,
This patch fixes problems I noticed by exploring profiles of some hot
functions in GCC.  In particular the propagation sometimes changed
precise 0 to afdo 0 for paths calling abort and sometimes we could
propagate more when we accept that some paths has 0 count.
Finally there was important bug in computing all_known which
resulted in BB probabilities to be quite broken after afdo.

Bootstrapped/regtested x86_64-linux, comitted.

gcc/ChangeLog:

        * auto-profile.cc (update_count_by_afdo_count): Make static;
        add variant accepting profile_count. 
        (afdo_find_equiv_class): Use update_count_by_afdo_count.
        (afdo_propagate_edge): Likewise.
        (afdo_propagate): Likewise.
        (afdo_calculate_branch_prob): Fix handling of all_known.
        (afdo_annotate_cfg): Annotate by 0 where both afdo and static
        profile agrees.

diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index a3832016ba8..9b5be665f58 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -1265,8 +1265,8 @@ set_bb_annotated (basic_block bb, bb_set *annotated)
   annotated->insert (bb);
 }
 
-/* Update profile_count by known autofdo count.  */
-void
+/* Update COUNT by known autofdo count C.  */
+static void
 update_count_by_afdo_count (profile_count *count, gcov_type c)
 {
   if (c)
@@ -1279,6 +1279,19 @@ update_count_by_afdo_count (profile_count *count, 
gcov_type c)
     *count = profile_count::zero ().afdo ();
 }
 
+/* Update COUNT by known autofdo count C.  */
+static void
+update_count_by_afdo_count (profile_count *count, profile_count c)
+{
+  if (c.nonzero_p ())
+    *count = c;
+  /* In case we have guessed profile which is already zero, preserve
+     quality info.  */
+  else if (count->nonzero_p ()
+          || count->quality () < c.quality ())
+    *count = c;
+}
+
 /* For a given BB, set its execution count. Attach value profile if a stmt
    is not in PROMOTED, because we only want to promote an indirect call once.
    Return TRUE if BB is annotated.  */
@@ -1419,7 +1432,7 @@ afdo_find_equiv_class (bb_set *annotated_bb)
                  bb1->count.dump (dump_file);
                  fprintf (dump_file, "\n");
                }
-             bb->count = bb1->count;
+             update_count_by_afdo_count (&bb->count, bb1->count);
              set_bb_annotated (bb, annotated_bb);
            }
        }
@@ -1442,7 +1455,7 @@ afdo_find_equiv_class (bb_set *annotated_bb)
                  bb1->count.dump (dump_file);
                  fprintf (dump_file, "\n");
                }
-             bb->count = bb1->count;
+             update_count_by_afdo_count (&bb->count, bb1->count);
              set_bb_annotated (bb, annotated_bb);
            }
        }
@@ -1505,7 +1518,7 @@ afdo_propagate_edge (bool is_succ, bb_set *annotated_bb)
            total_known_count.dump (dump_file);
            fprintf (dump_file, "\n");
          }
-       bb->count = total_known_count;
+       update_count_by_afdo_count (&bb->count, total_known_count);
        set_bb_annotated (bb, annotated_bb);
        changed = true;
       }
@@ -1531,7 +1544,7 @@ afdo_propagate_edge (bool is_succ, bb_set *annotated_bb)
       }
     else if (num_unknown_edges > 1
             && is_bb_annotated (bb, *annotated_bb)
-            && total_known_count >= bb->count)
+            && (total_known_count >= bb->count || !bb->count.nonzero_p ()))
       {
        FOR_EACH_EDGE (e, ei, is_succ ? bb->succs : bb->preds)
          {
@@ -1671,7 +1684,7 @@ afdo_propagate (bb_set *annotated_bb)
     if (!is_bb_annotated (bb, *annotated_bb)
        && is_bb_annotated ((basic_block)bb->aux, *annotated_bb))
       {
-       bb->count = ((basic_block)bb->aux)->count;
+       update_count_by_afdo_count (&bb->count, ((basic_block)bb->aux)->count);
        set_bb_annotated (bb, annotated_bb);
        if (dump_file)
          {
@@ -1994,7 +2007,7 @@ afdo_calculate_branch_prob (bb_set *annotated_bb)
   FOR_EACH_BB_FN (bb, cfun)
     if (is_bb_annotated (bb, *annotated_bb))
       {
-       bool all_known = false;
+       bool all_known = true;
        profile_count total_count = profile_count::zero ().afdo ();
 
        FOR_EACH_EDGE (e, ei, bb->succs)
@@ -2006,7 +2019,7 @@ afdo_calculate_branch_prob (bb_set *annotated_bb)
                   still propagate the rest.  */
                if (e->probability.nonzero_p ())
                  {
-                   all_known = true;
+                   all_known = false;
                    break;
                  }
              }
@@ -2091,6 +2104,22 @@ afdo_annotate_cfg (void)
          set_bb_annotated (bb, &annotated_bb);
        }
     }
+  /* We try to preserve static profile for BBs with 0
+     afdo samples, but if even static profile agrees with 0,
+     consider it final so propagation works better.  */
+  for (basic_block bb : zero_bbs)
+    if (bb->count.nonzero_p ())
+      {
+       update_count_by_afdo_count (&bb->count, 0);
+       set_bb_annotated (bb, &annotated_bb);
+       if (dump_file)
+         {
+           fprintf (dump_file, "  Annotating bb %i with count ", bb->index);
+           bb->count.dump (dump_file);
+           fprintf (dump_file,
+                    " (has 0 count in both static and afdo profile)\n");
+         }
+      }
   /* Exit without clobbering static profile if there was no
      non-zero count.  */
   if (!profile_found)

Reply via email to