[llvm] Compute GUIDs once and store in metadata (PR #184065)

via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 8 17:06:58 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Owen Rodley (orodley)

<details>
<summary>Changes</summary>

This allows us to keep GUIDs consistent across compilation phases which may change the name or linkage type.

See https://discourse.llvm.org/t/rfc-keep-globalvalue-guids-stable/84801

---

Patch is 117.67 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/184065.diff


87 Files Affected:

- (modified) llvm/include/llvm/Analysis/CtxProfAnalysis.h (+5-31) 
- (modified) llvm/include/llvm/Bitcode/BitcodeReader.h (+3-1) 
- (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+3) 
- (modified) llvm/include/llvm/IR/FixedMetadataKinds.def (+1) 
- (modified) llvm/include/llvm/IR/GlobalValue.h (+28-5) 
- (modified) llvm/include/llvm/IR/Module.h (+16) 
- (modified) llvm/include/llvm/IR/ModuleSummaryIndex.h (+11-5) 
- (modified) llvm/include/llvm/LTO/LTO.h (+17) 
- (added) llvm/include/llvm/Transforms/Utils/AssignGUID.h (+42) 
- (modified) llvm/lib/Analysis/CtxProfAnalysis.cpp (+4-40) 
- (modified) llvm/lib/AsmParser/LLParser.cpp (+9-3) 
- (modified) llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp (+1) 
- (modified) llvm/lib/Bitcode/Reader/BitcodeReader.cpp (+49-17) 
- (modified) llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (+44-3) 
- (modified) llvm/lib/IR/Globals.cpp (+42) 
- (modified) llvm/lib/LTO/LTO.cpp (+30-21) 
- (modified) llvm/lib/LTO/LTOBackend.cpp (+7-2) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Passes/PassBuilderPipelines.cpp (+6-3) 
- (modified) llvm/lib/Transforms/IPO/FunctionImport.cpp (+39-21) 
- (modified) llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp (+2) 
- (modified) llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp (+7) 
- (modified) llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp (+2-2) 
- (modified) llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp (+1-2) 
- (modified) llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp (+2-3) 
- (added) llvm/lib/Transforms/Utils/AssignGUID.cpp (+31) 
- (modified) llvm/lib/Transforms/Utils/CMakeLists.txt (+1) 
- (modified) llvm/lib/Transforms/Utils/CallPromotionUtils.cpp (+2-3) 
- (modified) llvm/lib/Transforms/Utils/CloneModule.cpp (+5-1) 
- (modified) llvm/lib/Transforms/Utils/FunctionImportUtils.cpp (+17-2) 
- (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+2-2) 
- (modified) llvm/test/Assembler/index-value-order.ll (+6-3) 
- (modified) llvm/test/Bitcode/thinlto-alias.ll (+1) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-callgraph-partial-sample-profile-summary.ll (+3-2) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll (+1) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll (+3-2) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll (+3-2) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-callgraph.ll (+1) 
- (modified) llvm/test/Bitcode/thinlto-function-summary-refgraph.ll (+1) 
- (modified) llvm/test/Bitcode/thinlto-function-summary.ll (+1) 
- (modified) llvm/test/CodeGen/X86/fat-lto-section.ll (+1-1) 
- (modified) llvm/test/Linker/funcimport2.ll (+1-1) 
- (modified) llvm/test/Other/new-pm-O0-defaults.ll (+2-1) 
- (modified) llvm/test/Other/new-pm-defaults.ll (+2-1) 
- (modified) llvm/test/Other/new-pm-thinlto-prelink-defaults.ll (+2-1) 
- (modified) llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll (+2-1) 
- (modified) llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll (+1) 
- (modified) llvm/test/ThinLTO/AArch64/aarch64_inline.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/ctor-dtor-alias.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/ctor-dtor-alias2.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/deadstrip.ll (+4-4) 
- (modified) llvm/test/ThinLTO/X86/distributed_import.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/funcattrs-prop-exported-internal.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/funcattrs-prop-unknown.ll (+3-3) 
- (modified) llvm/test/ThinLTO/X86/globals-import.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/hidden-escaped-symbols-alt.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/hidden-escaped-symbols.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/import-ro-constant.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/index-const-prop-alias.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/index-const-prop.ll (+3-3) 
- (modified) llvm/test/ThinLTO/X86/linkonce_resolution_comdat.ll (+8-8) 
- (modified) llvm/test/ThinLTO/X86/memprof-dups.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/memprof_callee_type_mismatch.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/memprof_imported_internal.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/memprof_imported_internal2.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/prevailing_weak_globals_import.ll (+1-1) 
- (modified) llvm/test/ThinLTO/X86/visibility-elf.ll (+3-3) 
- (modified) llvm/test/ThinLTO/X86/visibility-macho.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/windows-vftable.ll (+2-2) 
- (modified) llvm/test/ThinLTO/X86/writeonly.ll (+2-2) 
- (added) llvm/test/Transforms/AssignGUID/assign_guid.ll (+18) 
- (modified) llvm/test/Transforms/EmbedBitcode/embed-wpd.ll (+1-1) 
- (modified) llvm/test/Transforms/EmbedBitcode/embed.ll (+7-6) 
- (modified) llvm/test/Transforms/FunctionImport/funcimport-debug-retained-nodes.ll (+2-1) 
- (modified) llvm/test/Transforms/FunctionImport/funcimport.ll (+12-12) 
- (modified) llvm/test/Transforms/LowerTypeTests/cfi-icall-alias.ll (+1-1) 
- (modified) llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll (+2-2) 
- (modified) llvm/test/Transforms/PhaseOrdering/speculative-devirt-then-inliner.ll (+1-1) 
- (modified) llvm/test/Transforms/SampleProfile/ctxsplit.ll (+4-4) 
- (modified) llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll (+3-3) 
- (modified) llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc.ll (+7-7) 
- (modified) llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll (+1-1) 
- (modified) llvm/test/Transforms/WholeProgramDevirt/branch-funnel-profile.ll (+22-22) 
- (modified) llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll (+2-2) 
- (modified) llvm/test/Transforms/WholeProgramDevirt/export-vcp.ll (+3-3) 
- (modified) llvm/tools/llvm-link/llvm-link.cpp (+3-1) 
- (modified) llvm/tools/opt/NewPMDriver.cpp (+8) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/CtxProfAnalysis.h b/llvm/include/llvm/Analysis/CtxProfAnalysis.h
index 5c9823b0f6cc1..90b1d3fc0a688 100644
--- a/llvm/include/llvm/Analysis/CtxProfAnalysis.h
+++ b/llvm/include/llvm/Analysis/CtxProfAnalysis.h
@@ -47,9 +47,6 @@ class PGOContextualProfile {
   // we'll need when we maintain the profiles during IPO transformations.
   std::map<GlobalValue::GUID, FunctionInfo> FuncInfo;
 
-  /// Get the GUID of this Function if it's defined in this module.
-  LLVM_ABI GlobalValue::GUID getDefinedFunctionGUID(const Function &F) const;
-
   // This is meant to be constructed from CtxProfAnalysis, which will also set
   // its state piecemeal.
   PGOContextualProfile() = default;
@@ -68,9 +65,7 @@ class PGOContextualProfile {
 
   LLVM_ABI bool isInSpecializedModule() const;
 
-  bool isFunctionKnown(const Function &F) const {
-    return getDefinedFunctionGUID(F) != 0;
-  }
+  bool isFunctionKnown(const Function &F) const { return !F.isDeclaration(); }
 
   StringRef getFunctionName(GlobalValue::GUID GUID) const {
     auto It = FuncInfo.find(GUID);
@@ -81,22 +76,22 @@ class PGOContextualProfile {
 
   uint32_t getNumCounters(const Function &F) const {
     assert(isFunctionKnown(F));
-    return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex;
+    return FuncInfo.find(F.getGUID())->second.NextCounterIndex;
   }
 
   uint32_t getNumCallsites(const Function &F) const {
     assert(isFunctionKnown(F));
-    return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex;
+    return FuncInfo.find(F.getGUID())->second.NextCallsiteIndex;
   }
 
   uint32_t allocateNextCounterIndex(const Function &F) {
     assert(isFunctionKnown(F));
-    return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCounterIndex++;
+    return FuncInfo.find(F.getGUID())->second.NextCounterIndex++;
   }
 
   uint32_t allocateNextCallsiteIndex(const Function &F) {
     assert(isFunctionKnown(F));
-    return FuncInfo.find(getDefinedFunctionGUID(F))->second.NextCallsiteIndex++;
+    return FuncInfo.find(F.getGUID())->second.NextCallsiteIndex++;
   }
 
   using ConstVisitor = function_ref<void(const PGOCtxProfContext &)>;
@@ -188,26 +183,5 @@ class ProfileAnnotator {
   LLVM_ABI ~ProfileAnnotator();
 };
 
-/// Assign a GUID to functions as metadata. GUID calculation takes linkage into
-/// account, which may change especially through and after thinlto. By
-/// pre-computing and assigning as metadata, this mechanism is resilient to such
-/// changes (as well as name changes e.g. suffix ".llvm." additions).
-
-// FIXME(mtrofin): we can generalize this mechanism to calculate a GUID early in
-// the pass pipeline, associate it with any Global Value, and then use it for
-// PGO and ThinLTO.
-// At that point, this should be moved elsewhere.
-class AssignGUIDPass : public PassInfoMixin<AssignGUIDPass> {
-public:
-  explicit AssignGUIDPass() = default;
-
-  /// Assign a GUID *if* one is not already assign, as a function metadata named
-  /// `GUIDMetadataName`.
-  LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-  LLVM_ABI static const char *GUIDMetadataName;
-  // This should become GlobalValue::getGUID
-  LLVM_ABI static uint64_t getGUID(const Function &F);
-};
-
 } // namespace llvm
 #endif // LLVM_ANALYSIS_CTXPROFANALYSIS_H
diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h
index 772ca82019278..b7cab51857f0b 100644
--- a/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Bitstream/BitCodeEnums.h"
 #include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
@@ -165,7 +166,8 @@ struct ParserCallbacks {
     /// into CombinedIndex.
     LLVM_ABI Error
     readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath,
-                std::function<bool(GlobalValue::GUID)> IsPrevailing = nullptr);
+                std::function<bool(StringRef)> IsPrevailing = nullptr,
+                std::function<void(ValueInfo)> OnValueInfo = nullptr);
   };
 
   struct BitcodeFileContents {
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index bcf596a0d79b2..a3afad599186a 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -120,6 +120,9 @@ enum ModuleCodes {
 
   // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
   MODULE_CODE_IFUNC = 18,
+
+  // GUIDLIST: [n x i64]
+  MODULE_CODE_GUIDLIST = 19,
 };
 
 /// PARAMATTR blocks have code for defining a parameter attribute set.
diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def
index 0d79677d7079e..ced586aaa503e 100644
--- a/llvm/include/llvm/IR/FixedMetadataKinds.def
+++ b/llvm/include/llvm/IR/FixedMetadataKinds.def
@@ -60,3 +60,4 @@ LLVM_FIXED_MD_KIND(MD_alloc_token, "alloc_token", 45)
 LLVM_FIXED_MD_KIND(MD_implicit_ref, "implicit.ref", 46)
 LLVM_FIXED_MD_KIND(MD_nofpclass, "nofpclass", 47)
 LLVM_FIXED_MD_KIND(MD_call_target, "call_target", 48)
+LLVM_FIXED_MD_KIND(MD_unique_id, "guid", 49)
diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 83e695cdd27d9..acc836e1974d4 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -589,17 +589,40 @@ class GlobalValue : public Constant {
   /// used as the key for a global lookup (e.g. profile or ThinLTO).
   LLVM_ABI std::string getGlobalIdentifier() const;
 
+  /// Assign a GUID to this value based on its current name and linkage.
+  /// This GUID will remain the same even if those change. This method is
+  /// idempotent -- if a GUID has already been assigned, calling it again
+  /// will do nothing.
+  ///
+  /// This is private (exposed only to \c AssignGUIDPass), as users don't need
+  /// to call it. GUIDs are assigned only by \c AssignGUIDPass. The pass
+  /// pipeline should be set up such that GUIDs are always available when
+  /// needed. If not, the GUID assignment pass should be moved (or run again)
+  /// such that they are.
+  void assignGUID();
+
+  // assignGUID needs to be accessible from AssignGUIDPass, which is called
+  // early in the pipeline to make GUIDs available to later passes. But we'd
+  // rather not expose it publicly, as no-one else should call it.
+  friend class AssignGUIDPass;
+
 public:
   /// Return a 64-bit global unique ID constructed from the name of a global
   /// symbol. Since this call doesn't supply the linkage or defining filename,
   /// the GUID computation will assume that the global has external linkage.
   LLVM_ABI static GUID getGUIDAssumingExternalLinkage(StringRef GlobalName);
 
-  /// Return a 64-bit global unique ID constructed from global value name
-  /// (i.e. returned by getGlobalIdentifier()).
-  GUID getGUID() const {
-    return getGUIDAssumingExternalLinkage(getGlobalIdentifier());
-  }
+  /// Return a 64-bit global unique ID for this value. It is based on the
+  /// "original" name and linkage of this value (i.e. whenever its GUID was
+  /// assigned). This might not match the current name and linkage.
+  GUID getGUID() const;
+
+  /// Return the GUID for this value if it has been assigned, nullopt
+  /// otherwise. This should only need to be used in some exceptional
+  /// situations. If possible whatever code needs access to a GUID should
+  /// be set up to run after AssignGUIDPass, in which case it will always
+  /// be available.
+  std::optional<GUID> getGUIDIfAssigned() const;
 
   /// @name Materialization
   /// Materialization is used to construct functions only as they're needed.
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 7156a83c9f3cc..b4a13128dd9f7 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -32,6 +32,7 @@
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/TargetParser/Triple.h"
 #include <cstddef>
 #include <cstdint>
@@ -576,7 +577,22 @@ class LLVM_ABI Module {
   // Use global_size() to get the total number of global variables.
   // Use globals() to get the range of all global variables.
 
+  std::optional<GlobalValue::GUID> getGUID(const Value* V) const {
+    const auto It = ValueToGUIDMap.find(V);
+    if (It == ValueToGUIDMap.end()) {
+      return {};
+    }
+
+    return It->getSecond();
+  }
+
+  void insertGUID(const Value* V, GlobalValue::GUID GUID) {
+    ValueToGUIDMap[V] = GUID;
+  }
+
 private:
+  DenseMap<const Value*, GlobalValue::GUID> ValueToGUIDMap;
+
 /// @}
 /// @name Direct access to the globals list, functions list, and symbol table
 /// @{
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index b0b5ef9908a5e..07e019cbe48c4 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -29,6 +29,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/InterleavedRange.h"
 #include "llvm/Support/ScaledNumber.h"
 #include "llvm/Support/StringSaver.h"
@@ -599,8 +600,8 @@ class GlobalValueSummary {
   bool wasPromoted() const { return Flags.Promoted; }
 
   void promote() {
-    assert(GlobalValue::isLocalLinkage(linkage()) &&
-           "unexpected (re-)promotion of non-local symbol");
+    assert(!GlobalValue::isExternalLinkage(linkage()) &&
+           "unexpected (re-)promotion of external symbol");
     assert(!Flags.Promoted);
     Flags.Promoted = true;
     Flags.Linkage = GlobalValue::LinkageTypes::ExternalLinkage;
@@ -1763,14 +1764,19 @@ class ModuleSummaryIndex {
     return ValueInfo(HaveGVs, VP);
   }
 
-  /// Return a ValueInfo for \p GV and mark it as belonging to GV.
-  ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
+  /// Return a ValueInfo for \p GV with GUID \p GUID and mark it as belonging to GV.
+  ValueInfo getOrInsertValueInfo(const GlobalValue *GV, GlobalValue::GUID GUID) {
     assert(HaveGVs);
-    auto VP = getOrInsertValuePtr(GV->getGUID());
+    auto VP = getOrInsertValuePtr(GUID);
     VP->second.U.GV = GV;
     return ValueInfo(HaveGVs, VP);
   }
 
+  /// Return a ValueInfo for \p GV and mark it as belonging to GV.
+  ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
+    return getOrInsertValueInfo(GV, GV->getGUID());
+  }
+
   /// Return the GUID for \p OriginalId in the OidGuidMap.
   GlobalValue::GUID getGUIDFromOriginalID(GlobalValue::GUID OriginalID) const {
     const auto I = OidGuidMap.find(OriginalID);
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 38349b604b6b3..32a47b3c87e1d 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -572,6 +572,23 @@ class LTO {
     /// LTO backend.
     unsigned Partition = Unknown;
 
+    // FIXME: make private, and also make GlobalResolution a class, it has been
+    // becoming more than just a data bag.
+    GlobalValue::GUID GUID = 0;
+
+    void setGUID(GlobalValue::GUID G) {
+      assert(G);
+      assert(!GUID || GUID == G);
+      GUID = G;
+    }
+
+    GlobalValue::GUID getGUID() const {
+      return GUID ? GUID
+                  : GlobalValue::getGUIDAssumingExternalLinkage(
+                        GlobalValue::getGlobalIdentifier(
+                            IRName, GlobalValue::LinkageTypes::ExternalLinkage,
+                            ""));
+    }
     /// Special partition numbers.
     enum : unsigned {
       /// A partition number has not yet been assigned to this global.
diff --git a/llvm/include/llvm/Transforms/Utils/AssignGUID.h b/llvm/include/llvm/Transforms/Utils/AssignGUID.h
new file mode 100644
index 0000000000000..0abd450d5a522
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/AssignGUID.h
@@ -0,0 +1,42 @@
+//===-- AssignGUID.h - Unique identifier assignment pass --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a pass which assigns a a GUID (globally unique identifier)
+// to every GlobalValue in the module, according to its current name, linkage,
+// and originating file. This way we have a consistent identifier even when
+// these inputs to the GUID change (for instance, after externalising a global
+// in ThinLTO).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ASSIGNGUID_H
+#define LLVM_TRANSFORMS_UTILS_ASSIGNGUID_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm {
+
+class AssignGUIDPass : public PassInfoMixin<AssignGUIDPass> {
+public:
+  AssignGUIDPass() = default;
+
+  static void runOnModule(Module &M);
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
+    AssignGUIDPass::runOnModule(M);
+    return PreservedAnalyses::all();
+  }
+
+  static bool isRequired() { return true; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_ASSIGNGUID_H
\ No newline at end of file
diff --git a/llvm/lib/Analysis/CtxProfAnalysis.cpp b/llvm/lib/Analysis/CtxProfAnalysis.cpp
index c4abec02e765a..d4c00e4090220 100644
--- a/llvm/lib/Analysis/CtxProfAnalysis.cpp
+++ b/llvm/lib/Analysis/CtxProfAnalysis.cpp
@@ -50,9 +50,7 @@ static cl::opt<bool> ForceIsInSpecializedModule(
     "ctx-profile-force-is-specialized", cl::init(false),
     cl::desc("Treat the given module as-if it were containing the "
              "post-thinlink module containing the root"));
-
-const char *AssignGUIDPass::GUIDMetadataName = "guid";
-
+ 
 class ProfileAnnotatorImpl final {
   friend class ProfileAnnotator;
   class BBInfo;
@@ -420,33 +418,6 @@ bool ProfileAnnotator::getOutgoingBranchWeights(
   return MaxCount > 0;
 }
 
-PreservedAnalyses AssignGUIDPass::run(Module &M, ModuleAnalysisManager &MAM) {
-  for (auto &F : M.functions()) {
-    if (F.isDeclaration())
-      continue;
-    if (F.getMetadata(GUIDMetadataName))
-      continue;
-    const GlobalValue::GUID GUID = F.getGUID();
-    F.setMetadata(GUIDMetadataName,
-                  MDNode::get(M.getContext(),
-                              {ConstantAsMetadata::get(ConstantInt::get(
-                                  Type::getInt64Ty(M.getContext()), GUID))}));
-  }
-  return PreservedAnalyses::none();
-}
-
-GlobalValue::GUID AssignGUIDPass::getGUID(const Function &F) {
-  if (F.isDeclaration()) {
-    assert(GlobalValue::isExternalLinkage(F.getLinkage()));
-    return F.getGUID();
-  }
-  auto *MD = F.getMetadata(GUIDMetadataName);
-  assert(MD && "guid not found for defined function");
-  return cast<ConstantInt>(cast<ConstantAsMetadata>(MD->getOperand(0))
-                               ->getValue()
-                               ->stripPointerCasts())
-      ->getZExtValue();
-}
 AnalysisKey CtxProfAnalysis::Key;
 
 CtxProfAnalysis::CtxProfAnalysis(std::optional<StringRef> Profile)
@@ -515,7 +486,7 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
   for (const auto &F : M) {
     if (F.isDeclaration())
       continue;
-    auto GUID = AssignGUIDPass::getGUID(F);
+    auto GUID = F.getGUID();
     assert(GUID && "guid not found for defined function");
     const auto &Entry = F.begin();
     uint32_t MaxCounters = 0; // we expect at least a counter.
@@ -549,13 +520,6 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
   return Result;
 }
 
-GlobalValue::GUID
-PGOContextualProfile::getDefinedFunctionGUID(const Function &F) const {
-  if (auto It = FuncInfo.find(AssignGUIDPass::getGUID(F)); It != FuncInfo.end())
-    return It->first;
-  return 0;
-}
-
 CtxProfAnalysisPrinterPass::CtxProfAnalysisPrinterPass(raw_ostream &OS)
     : OS(OS), Mode(PrintLevel) {}
 
@@ -671,7 +635,7 @@ bool PGOContextualProfile::isInSpecializedModule() const {
 
 void PGOContextualProfile::update(Visitor V, const Function &F) {
   assert(isFunctionKnown(F));
-  GlobalValue::GUID G = getDefinedFunctionGUID(F);
+  GlobalValue::GUID G = F.getGUID();
   for (auto *Node = FuncInfo.find(G)->second.Index.Next; Node;
        Node = Node->Next)
     V(*reinterpret_cast<PGOCtxProfContext *>(Node));
@@ -682,7 +646,7 @@ void PGOContextualProfile::visit(ConstVisitor V, const Function *F) const {
     return preorderVisit<const PGOCtxProfContext::CallTargetMapTy,
                          const PGOCtxProfContext>(Profiles.Contexts, V);
   assert(isFunctionKnown(*F));
-  GlobalValue::GUID G = getDefinedFunctionGUID(*F);
+  GlobalValue::GUID G = F->getGUID();
   for (const auto *Node = FuncInfo.find(G)->second.Index.Next; Node;
        Node = Node->Next)
     V(*reinterpret_cast<const PGOCtxProfContext *>(Node));
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 551b88d8b435b..fcfa2ec2be342 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1064,8 +1064,9 @@ bool LLParser::skipModuleSummaryEntry() {
   // support is in place we will look for the tokens corresponding to the
   // expected tags.
   if (Lex.getKind() != lltok::kw_gv && Lex.getKind() != lltok::kw_module &&
-      Lex.getKind() != lltok::kw_typeid && Lex.getKind() != lltok::kw_flags &&
-      Lex.getKind() != lltok::kw_blockcount)
+      Lex.getKind() != lltok::kw_typeid &&
+      Lex.getKind() != lltok::kw_typeidCompatibleVTable &&
+      Lex.getKind() != lltok::kw_flags && Lex.getKind() != lltok::kw_blockcount)
     return tokError(
         "Expected 'gv', 'module', 'typeid', 'flags' or 'blockcount' at the "
         "start of summary entry");
@@ -9847,7 +9848,12 @@ bool LLParser::addGlobalValueToIndex(
       if (!GV)
         return error(Loc, "Reference to undefined global \"" + Name + "\"");
 
-      VI = Index->getOrInsertValueInfo(GV);
+      // Be a little lenient here, to accomodate older files without GUIDs
+      // already computed and assigned as metadata.
+      auto MaybeGUID = GV->getGUIDIfAssigned();
+      GUID = MaybeGUID ? *MaybeGUID : GlobalValue::getGUIDAssumingExternalLinkage(GV->getName());
+
+      VI = Index->getOrInsertValueInfo(GV, GUID);
     } else {
       assert(
           (!GlobalValue::isLocalLinkage(Linkage) || !SourceFileName.empty()) &&
diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
index 911ec7501eb8b..6574ab7a93c58 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
@@ -142,6 +142,7 @@ GetCodeName(unsigned CodeID, unsigned BlockID,
       STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES_UNUSED)
       STRINGIFY_CODE(MODULE_CODE, SOURCE_FILENAME)
       STRINGIFY_CODE(MODULE_CODE, HASH)
+      STRINGIFY_CODE(MODULE_CODE, GUIDLIST)
     }
   case bitc::IDENTIFICATION_BLOCK_ID:
     switch (CodeID) {
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index a781a43112f8c..0b6ce590f00af 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -696,6 +696,9 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
 
   std::optional<ValueTypeCallbackTy> ValueTypeCallback;
 
+  /// A list of GUIDs defined by this module. Indexed by ValueID.
+  std::vector<GlobalValue::GUID> GUIDList;
+
 public:
   BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
                 StringRef ProducerIdentification, LLVMContext &Context);
@@ -974,9 +977,10 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase {
 
   /// Callback to ask whether a symbol is the prevailing copy when invoked
   /// during combined index building.
-  std::function<bool(GlobalValue::GUID)> IsPrevailing;
+  std::function<bool(StringRef)> IsPrevailing = nullptr;
+  std::function<void(ValueInfo)> OnValueInfo = nullptr;
 
-  /// Saves the stack ids from the STACK_IDS record to consult when adding stack
+  /// Saves the stack ids from the STACK_IDS record to consult ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/184065


More information about the llvm-commits mailing list