]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AUTOFDO] Merge profiles of clones before annotating
authorKugan Vivekanandarajah <kvivekananda@nvidia.com>
Fri, 30 May 2025 03:33:42 +0000 (13:33 +1000)
committerKugan Vivekanandarajah <kvivekananda@nvidia.com>
Fri, 30 May 2025 03:34:46 +0000 (13:34 +1000)
This patch add support for merging profiles from multiple clones.
That is, when optimized binaries have clones such as IPA-CP clone or SRA
clones, genarted gcov will have profiled them spereately.
Currently we pick one and ignore the rest. This patch fixes this by
merging the profiles.

gcc/ChangeLog:

* auto-profile.cc (function_instance::merge): New.
(autofdo_source_profile::read): Call merge.

Signed-off-by: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
gcc/auto-profile.cc

index 3eefb970fde338590a16cdfb9e48c34dbe691248..91cc8db2c83291d0325a4c6c58d4253dd516ddcd 100644 (file)
@@ -233,6 +233,10 @@ public:
   function_instance *get_function_instance_by_decl (unsigned lineno,
                                                     tree decl) const;
 
+  /* Merge profile of clones.  Note that cloning hasnt been performed when
+     we annotate the CFG (at this stage).  */
+  void merge (function_instance *other);
+
   /* Store the profile info for LOC in INFO. Return TRUE if profile info
      is found.  */
   bool get_count_info (location_t loc, count_info *info) const;
@@ -558,6 +562,27 @@ function_instance::get_function_instance_by_decl (unsigned lineno,
   return NULL;
 }
 
+/* Merge profile of clones.  Note that cloning hasnt been performed when
+   we annotate the CFG (at this stage).  */
+
+void function_instance::merge (function_instance *other)
+{
+  total_count_ += other->total_count_;
+  head_count_ += other->head_count_;
+
+  for (callsite_map::const_iterator iter = other->callsites.begin ();
+       iter != other->callsites.end (); ++iter)
+    if (callsites.count (iter->first) == 0)
+       callsites[iter->first] = iter->second;
+
+  for (position_count_map::const_iterator iter = pos_counts.begin ();
+       iter != pos_counts.end (); ++iter)
+    if (pos_counts.count (iter->first) == 0)
+      pos_counts[iter->first] = iter->second;
+    else
+      pos_counts[iter->first].count += iter->second.count;
+}
+
 /* Store the profile info for LOC in INFO. Return TRUE if profile info
    is found.  */
 
@@ -838,7 +863,14 @@ autofdo_source_profile::read ()
       function_instance::function_instance_stack stack;
       function_instance *s = function_instance::read_function_instance (
           &stack, gcov_read_counter ());
-      map_[s->name ()] = s;
+      int fun_id = afdo_string_table->get_index
+             (afdo_string_table->get_name (s->name ()));
+      /* If function_instace with get_original_name (without the clone
+        suffix) exixts, merge the function instances.  */
+      if (map_.count (fun_id) == 0)
+       map_[fun_id] = s;
+      else
+       map_[fun_id]->merge (s);
     }
   return true;
 }