]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Handle functions with 0 profile in auto-profile
authorJan Hubicka <hubicka@ucw.cz>
Sun, 22 Jun 2025 04:55:41 +0000 (06:55 +0200)
committerJan Hubicka <hubicka@ucw.cz>
Sun, 22 Jun 2025 05:01:24 +0000 (07:01 +0200)
This is the last part of the infrastructure to allow functions with
local profiles and 0 global autofdo counts.

Bootstrapped/regtested x86_64-linux, comitted.

gcc/ChangeLog:

* auto-profile.cc (afdo_set_bb_count): Dump inline stacks
and reasons when lookup failed.
(afdo_set_bb_count): Record info about BBs with zero AFDO count.
(afdo_annotate_cfg): Set profile to global0_afdo if there are
no samples in profile.

gcc/auto-profile.cc

index 202f1083633d62424b3104303114010f82bbb55d..a3832016ba80f57061e9228121654e8ac54132ff 100644 (file)
@@ -914,12 +914,33 @@ autofdo_source_profile::get_callsite_total_count (
 
   get_inline_stack_in_node (gimple_location (edge->call_stmt), &stack,
                            edge->caller);
+  if (dump_file)
+    {
+      if (!edge->caller->inlined_to)
+       fprintf (dump_file, "Looking up afdo profile for call %s -> %s stack:",
+                edge->caller->dump_name (), edge->callee->dump_name ());
+      else
+       fprintf (dump_file, "Looking up afdo profile for call %s -> %s transitively %s stack:",
+                edge->caller->dump_name (), edge->callee->dump_name (),
+                edge->caller->inlined_to->dump_name ());
+      dump_inline_stack (dump_file, &stack);
+    }
 
   function_instance *s = get_function_instance_by_inline_stack (stack);
-  if (s == NULL
-      ||(afdo_string_table->get_index_by_decl (edge->callee->decl)
-        != s->name()))
-    return 0;
+  if (s == NULL)
+    {
+      if (dump_file)
+       fprintf (dump_file, "No function instance found\n");
+      return 0;
+    }
+  if (afdo_string_table->get_index_by_decl (edge->callee->decl) != s->name ())
+    {
+      if (dump_file)
+       fprintf (dump_file, "Mismatched name of callee %s and profile %s\n",
+                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (edge->callee->decl)),
+                afdo_string_table->get_name (s->name ()));
+      return 0;
+    }
 
   return s->total_count () * afdo_count_scale;
 }
@@ -1263,7 +1284,7 @@ update_count_by_afdo_count (profile_count *count, gcov_type c)
    Return TRUE if BB is annotated.  */
 
 static bool
-afdo_set_bb_count (basic_block bb)
+afdo_set_bb_count (basic_block bb, hash_set <basic_block> &zero_bbs)
 {
   gimple_stmt_iterator gsi;
   gcov_type max_count = 0;
@@ -1348,6 +1369,13 @@ afdo_set_bb_count (basic_block bb)
                 (int64_t)(max_count * afdo_count_scale));
       return true;
     }
+  else
+    {
+      if (dump_file)
+       fprintf (dump_file,
+                " bb %i has statements with 0 count\n", bb->index);
+      zero_bbs.add (bb);
+    }
   return false;
 }
 
@@ -2050,9 +2078,10 @@ afdo_annotate_cfg (void)
   /* In the first pass only store non-zero counts.  */
   gcov_type head_count = s->head_count () * autofdo::afdo_count_scale;
   bool profile_found = head_count > 0;
+  hash_set <basic_block> zero_bbs;
   FOR_EACH_BB_FN (bb, cfun)
     {
-      if (afdo_set_bb_count (bb))
+      if (afdo_set_bb_count (bb, zero_bbs))
        {
          if (bb->count.quality () == AFDO)
            {
@@ -2063,14 +2092,30 @@ afdo_annotate_cfg (void)
        }
     }
   /* Exit without clobbering static profile if there was no
-     non-zero count.
-     ??? Instead of keeping guessed profile we can introduce
-     GUESSED_GLOBAL0_AFDO.  */
+     non-zero count.  */
   if (!profile_found)
     {
-      if (dump_file)
-       fprintf (dump_file, "No afdo samples found"
-                "; keeping original profile\n");
+      /* create_gcov only dumps symbols with some samples in them.
+        This means that we get nonempty zero_bbs only if some
+        nonzero counts in profile were not matched with statements.
+        ??? We can adjust create_gcov to also recordinfo
+        about function with no samples.  Then we can distinguish
+        between lost profiles which should be kept local and
+        real functions with 0 samples during train run.  */
+      if (zero_bbs.is_empty ())
+       {
+         if (dump_file)
+           fprintf (dump_file, "No afdo samples found"
+                    "; Setting global count to afdo0\n");
+       }
+      else
+       {
+         if (dump_file)
+           fprintf (dump_file, "Setting global count to afdo0\n");
+       }
+      FOR_ALL_BB_FN (bb, cfun)
+       if (bb->count.quality () == GUESSED_LOCAL)
+         bb->count = bb->count.global0afdo ();
 
       loop_optimizer_finalize ();
       free_dominance_info (CDI_DOMINATORS);