From d00af724da724c79a7df0e39efe7b41d74fa7bb5 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
Date: Sun, 15 Jun 2025 18:07:31 -0700
Subject: [PATCH] [AutoFDO][v2] Fix get_original_name to strip only names that
 are generated after auto-profile

get_original_name is used to match profile binary names to
the symbol names in the IR during auto-profile pass.

Hence, we want to strip the compiler added suffixes for names
that are generated after auto-profile pass.

Names we should strip:
* SRA clones (of the form foo.isra.0)
* IPA-CP clonse (in the form bar.constprop.123)
* Partial inlining clones (foo.part.0, foo.cold)
* lto_priv.0
* Nested function as foo.part.0

Others that should not be stripped:
* target_clones (foo.arch_x86_64_v2, foo.avx2)
* OpenMP related suffixes (.omp_fn.N, .omp_cpyfn.N)

Tested by running autoprofiledbootstrap and tree-prof check that
exercises auto-profile pass.

Examples:
ipcp_versionable_function_p.isra.0 -> ipcp_versionable_function_p
ira_loop_edge_freq.constprop.0 -> ira_loop_edge_freq
ira_loop_edge_freq.constprop.1 -> ira_loop_edge_freq
ira_merge_allocno_live_ranges.part.0 -> ira_merge_allocno_live_ranges
gimple_assign_rhs1.part.0 -> gimple_assign_rhs1
gimplify_switch_expr.isra.0 -> gimplify_switch_expr
gimplify_type_sizes.part.0.isra.0 -> gimplify_type_sizes
mark_control_dependent_edges_necessary.part.0.isra.0 ->
mark_control_dependent_edges_necessary
mark_def_interesting.part.0.isra.0 -> mark_def_interesting

gcc/ChangeLog:

	* auto-profile.cc (is_digit): New.
	(get_original_name): Strip suffixes only for compiler generated
	names tat happens after auto-profile.

Signed-off-by: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
---
 gcc/auto-profile.cc | 47 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 8918d1e9f09..0fb29aad5d3 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -345,16 +345,51 @@ static gcov_summary *afdo_profile_info;
 
 /* Helper functions.  */
 
+static bool is_digit (char c)
+{
+  return c >= '0' && c <= '9';
+}
+
 /* Return the original name of NAME: strip the suffix that starts
-   with '.' Caller is responsible for freeing RET.  */
+   with '.' for names that are generetad after auto-profile pass.
+   This is to match profiled names with the names in the IR at this stage.
+   Note that we only have to strip sufix and not in the middle.
+   Caller is responsible for freeing RET.  */
 
 static char *
-get_original_name (const char *name)
+get_original_name (const char *name, bool alloc = true)
 {
-  char *ret = xstrdup (name);
-  char *find = strchr (ret, '.');
-  if (find != NULL)
-    *find = 0;
+  char *ret = alloc ? xstrdup (name) : const_cast<char *> (name);
+  char *last_dot = strrchr (ret, '.');
+  if (last_dot == NULL)
+    return ret;
+  bool only_digits = true;
+  char *ptr = last_dot;
+  while (*(++ptr) != 0)
+    if (!is_digit (*ptr))
+      {
+	only_digits = false;
+	break;
+      }
+  if (only_digits)
+    *last_dot = 0;
+  char *next_dot = strrchr (ret, '.');
+  /* if nested function such as foo.0, return foo.  */
+  if (next_dot == NULL)
+    return ret;
+  /* Suffixes of clones that compiler generates after auto-profile.  */
+  const char *suffixes[] = {"isra", "constprop", "lto_priv", "part", "cold"};
+  for (unsigned i = 0; i < sizeof (suffixes)/sizeof (suffixes[0]); ++i)
+    {
+      if (strncmp (next_dot + 1, suffixes[i], strlen (suffixes[i])) == 0)
+	{
+	  *next_dot = 0;
+	  return get_original_name (ret, false);
+	}
+    }
+  /* Otherwise, it is for clones such as .omp_fn.N that was done before
+     auto-profile and should be kept as it is.  */
+  *last_dot = '.';
   return ret;
 }
 
-- 
2.34.1

