https://gcc.gnu.org/g:f359866eea8b58a56af14688323e1fd2cd039ad3

commit r16-980-gf359866eea8b58a56af14688323e1fd2cd039ad3
Author: Kugan Vivekanandarajah <kvivekana...@nvidia.com>
Date:   Fri May 30 13:33:42 2025 +1000

    [AUTOFDO] Merge profiles of clones before annotating
    
    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 <kvivekana...@nvidia.com>

Diff:
---
 gcc/auto-profile.cc | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 3eefb970fde3..91cc8db2c832 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -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;
 }

Reply via email to