[llvm] [IR] Handle `.__uniq.` in `getGlobalIndentifier` for local linkage ob… (PR #98163)

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 9 07:31:21 PDT 2024


https://github.com/mtrofin created https://github.com/llvm/llvm-project/pull/98163

…jects

The `.__uniq.` particle is used when the name of an object with local linkage incorporates a hash of its defining module - for example, if clang is passed `-funique-internal-linkage-names`. We don't need to add the module name in `getGlobalIndentifier` in this case. This simplifies matters for carrying out information (like profiling data) between pre and post-thinlink: a function's ID stays the same.

>From 97e290a980b604973cec22b4334a30a661e63812 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Mon, 8 Jul 2024 21:16:19 -0700
Subject: [PATCH] [IR] Handle `.__uniq.` in `getGlobalIndentifier` for local
 linkage objects

The `.__uniq.` particle is used when the name of an object with local linkage
incorporates a hash of its defining module - for example, if clang is
passed `-funique-internal-linkage-names`. We don't need to add the module
name in `getGlobalIndentifier` in this case. This simplifies matters for
carrying out information (like profiling data) between pre and post-thinlink:
a function's ID stays the same.
---
 llvm/include/llvm/IR/GlobalValue.h         |  6 ++++++
 llvm/include/llvm/ProfileData/SampleProf.h |  6 +++---
 llvm/lib/IR/Globals.cpp                    | 22 ++++++++++++----------
 llvm/unittests/IR/FunctionTest.cpp         | 22 ++++++++++++++++++++++
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 540a21c1118b8..48ceae04cfb38 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -45,6 +45,12 @@ typedef unsigned ID;
 // Objective-C functions which commonly have :'s in their names.
 inline constexpr char kGlobalIdentifierDelimiter = ';';
 
+struct NameParticles final {
+  static constexpr const char *LLVMSuffix = ".llvm.";
+  static constexpr const char *PartSuffix = ".part.";
+  static constexpr const char *UniqSuffix = ".__uniq.";
+};
+
 class GlobalValue : public Constant {
 public:
   /// An enumeration for the kinds of linkage for global values.
diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h
index 51d590be124f1..2479790e022b7 100644
--- a/llvm/include/llvm/ProfileData/SampleProf.h
+++ b/llvm/include/llvm/ProfileData/SampleProf.h
@@ -1090,9 +1090,9 @@ class FunctionSamples {
 
   /// Name suffixes which canonicalization should handle to avoid
   /// profile mismatch.
-  static constexpr const char *LLVMSuffix = ".llvm.";
-  static constexpr const char *PartSuffix = ".part.";
-  static constexpr const char *UniqSuffix = ".__uniq.";
+  static constexpr const char *LLVMSuffix = NameParticles::LLVMSuffix;
+  static constexpr const char *PartSuffix = NameParticles::PartSuffix;
+  static constexpr const char *UniqSuffix = NameParticles::UniqSuffix;
 
   static StringRef getCanonicalFnName(StringRef FnName,
                                       StringRef Attr = "selected") {
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index c51852987614c..2004d9eb0ba30 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -160,16 +160,18 @@ std::string GlobalValue::getGlobalIdentifier(StringRef Name,
 
   std::string GlobalName;
   if (llvm::GlobalValue::isLocalLinkage(Linkage)) {
-    // For local symbols, prepend the main file name to distinguish them.
-    // Do not include the full path in the file name since there's no guarantee
-    // that it will stay the same, e.g., if the files are checked out from
-    // version control in different locations.
-    if (FileName.empty())
-      GlobalName += "<unknown>";
-    else
-      GlobalName += FileName;
-
-    GlobalName += kGlobalIdentifierDelimiter;
+    if (Name.find(NameParticles::UniqSuffix) == StringRef::npos) {
+      // For local symbols, prepend the main file name to distinguish them.
+      // Do not include the full path in the file name since there's no
+      // guarantee that it will stay the same, e.g., if the files are checked
+      // out from version control in different locations.
+      if (FileName.empty())
+        GlobalName += "<unknown>";
+      else
+        GlobalName += FileName;
+
+      GlobalName += kGlobalIdentifierDelimiter;
+    }
   }
   GlobalName += Name;
   return GlobalName;
diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp
index 9aaff3ea33830..5828b30172c1d 100644
--- a/llvm/unittests/IR/FunctionTest.cpp
+++ b/llvm/unittests/IR/FunctionTest.cpp
@@ -509,4 +509,26 @@ TEST(FunctionTest, UWTable) {
   EXPECT_FALSE(F.hasUWTable());
   EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
 }
+
+TEST(FunctionTest, GlobalIdentifier) {
+  // Technically a GlobalValue test, but using Functions as test subject.
+  LLVMContext Ctx;
+  Module M1("test1", Ctx);
+  Module M2("test2", Ctx);
+  Module M3("test3", Ctx);
+
+  static const char *Name = "F.__uniq.1234";
+
+  auto *G = Function::Create(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false),
+      llvm::GlobalValue::ExternalLinkage, Name, &M1);
+  auto *UniqL1 = Function::Create(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false),
+      llvm::GlobalValue::InternalLinkage, Name, &M2);
+  auto *UniqL2 = Function::Create(
+      llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false),
+      llvm::GlobalValue::InternalLinkage, Name, &M3);
+  EXPECT_EQ(G->getGUID(), UniqL1->getGUID());
+  EXPECT_EQ(UniqL1->getGUID(), UniqL2->getGUID());
+}
 } // end namespace



More information about the llvm-commits mailing list