[llvm] [WIP][NFC] Using GUID metadata (PR #124002)

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 12:59:57 PST 2025


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

None

>From 975ef269b9c165f3dfd242446a57843e353cf707 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Fri, 16 Aug 2024 17:00:22 -0700
Subject: [PATCH] [WIP][NFC] Using GUID metadata

---
 .../llvm/Analysis/AssignGUIDAnalysis.h        | 37 ++++++++++
 llvm/include/llvm/Analysis/CtxProfAnalysis.h  | 21 ------
 llvm/include/llvm/Bitcode/LLVMBitCodes.h      |  3 +
 llvm/include/llvm/IR/GlobalValue.h            | 30 ++++++--
 llvm/include/llvm/IR/ModuleSummaryIndex.h     | 12 +--
 llvm/include/llvm/IR/ModuleSummaryIndexYAML.h |  2 +-
 llvm/include/llvm/LTO/LTO.h                   |  4 +-
 llvm/include/llvm/ProfileData/SampleProf.h    |  2 +-
 .../Utils/SampleProfileLoaderBaseImpl.h       |  4 +-
 llvm/lib/Analysis/AssignGUIDAnalysis.cpp      | 47 ++++++++++++
 llvm/lib/Analysis/CMakeLists.txt              |  1 +
 llvm/lib/Analysis/CtxProfAnalysis.cpp         | 32 +-------
 llvm/lib/Analysis/ModuleSummaryAnalysis.cpp   |  9 ++-
 llvm/lib/AsmParser/LLParser.cpp               |  8 +-
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp     | 12 ++-
 llvm/lib/Bitcode/Writer/BitcodeWriter.cpp     | 74 ++++++++++++++-----
 llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp |  4 +
 .../CodeGen/AsmPrinter/PseudoProbePrinter.cpp |  3 +-
 llvm/lib/CodeGen/PseudoProbeInserter.cpp      |  2 +-
 llvm/lib/IR/AsmWriter.cpp                     |  2 +-
 llvm/lib/IR/Globals.cpp                       | 32 ++++++++
 llvm/lib/LTO/LTO.cpp                          | 67 +++++++++++------
 llvm/lib/LTO/ThinLTOCodeGenerator.cpp         | 16 ++--
 llvm/lib/Passes/PassBuilder.cpp               |  1 +
 llvm/lib/Passes/PassBuilderPipelines.cpp      |  6 --
 llvm/lib/Passes/PassRegistry.def              |  2 +-
 llvm/lib/ProfileData/InstrProf.cpp            |  6 +-
 llvm/lib/ProfileData/MemProf.cpp              |  2 +-
 llvm/lib/ProfileData/SampleProfReader.cpp     |  2 +-
 llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp   |  2 +-
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |  2 +-
 llvm/lib/Transforms/IPO/FunctionImport.cpp    | 43 +++++++++--
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    |  8 +-
 .../IPO/MemProfContextDisambiguation.cpp      |  8 +-
 llvm/lib/Transforms/IPO/SampleProfile.cpp     | 13 ++--
 .../lib/Transforms/IPO/SampleProfileProbe.cpp |  2 +-
 .../Transforms/IPO/ThinLTOBitcodeWriter.cpp   |  3 +-
 .../lib/Transforms/IPO/WholeProgramDevirt.cpp | 16 ++--
 .../Instrumentation/MemProfiler.cpp           |  4 +-
 .../Instrumentation/PGOCtxProfFlattening.cpp  |  2 +-
 .../Instrumentation/PGOCtxProfLowering.cpp    |  3 +-
 .../Instrumentation/PGOInstrumentation.cpp    |  4 +-
 .../Transforms/Utils/CallPromotionUtils.cpp   |  4 +-
 .../Transforms/Utils/FunctionImportUtils.cpp  | 21 +++++-
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  4 +-
 llvm/test/ThinLTO/X86/weak_resolution.ll      |  4 +-
 llvm/test/ThinLTO/X86/windows-vftable.ll      |  4 +-
 llvm/test/ThinLTO/X86/writeonly.ll            |  4 +-
 llvm/test/Transforms/EmbedBitcode/embed.ll    |  4 +-
 .../Transforms/FunctionImport/funcimport.ll   | 30 ++++----
 .../FunctionImport/funcimport_cutoff.ll       |  6 +-
 .../FunctionImport/funcimport_forcecold.ll    |  2 +-
 .../funcimport_forcecold_samplepgo.ll         |  2 +-
 .../Transforms/FunctionImport/inlineasm.ll    |  2 +-
 .../Transforms/FunctionImport/noinline.ll     |  2 +-
 .../Transforms/PGOProfile/comdat_rename.ll    |  2 +-
 .../PGOProfile/counter_promo_sampling.ll      |  4 +-
 .../PGOProfile/cspgo_profile_summary.ll       |  2 +-
 .../PGOProfile/ctx-instrumentation.ll         | 50 ++++++++-----
 llvm/test/Transforms/PGOProfile/select2.ll    |  2 +-
 .../thinlto_indirect_call_promotion.ll        |  4 +-
 .../PGOProfile/thinlto_samplepgo_icp.ll       |  2 +-
 .../Transforms/ThinLTOBitcodeWriter/split.ll  |  2 +-
 .../WholeProgramDevirt/export-single-impl.ll  | 24 +++---
 .../WholeProgramDevirt/export-vcp.ll          |  6 +-
 llvm/tools/llvm-profgen/ProfiledBinary.cpp    |  9 ++-
 66 files changed, 488 insertions(+), 261 deletions(-)
 create mode 100644 llvm/include/llvm/Analysis/AssignGUIDAnalysis.h
 create mode 100644 llvm/lib/Analysis/AssignGUIDAnalysis.cpp

diff --git a/llvm/include/llvm/Analysis/AssignGUIDAnalysis.h b/llvm/include/llvm/Analysis/AssignGUIDAnalysis.h
new file mode 100644
index 00000000000000..d6790169839b59
--- /dev/null
+++ b/llvm/include/llvm/Analysis/AssignGUIDAnalysis.h
@@ -0,0 +1,37 @@
+//===- AssignGUIDAnalysis.h - assign a GUID to each GV   ------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_ANALYSIS_ASSIGNGUIDANALYSIS_H
+#define LLVM_ANALYSIS_ASSIGNGUIDANALYSIS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+/// 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).
+class AssignGUIDAnalysis : public AnalysisInfoMixin<AssignGUIDAnalysis> {
+public:
+  explicit AssignGUIDAnalysis() = default;
+  static AnalysisKey Key;
+
+  class Result {
+    friend class AssignGUIDAnalysis;
+    Module &M;
+    Result(Module &M);
+
+  public:
+    void generateGuidTable();
+  };
+  /// Assign a GUID *if* one is not already assign, as a function metadata named
+  /// `GUIDMetadataName`.
+  Result run(Module &M, ModuleAnalysisManager &MAM);
+};
+} // namespace llvm
+#endif
\ No newline at end of file
diff --git a/llvm/include/llvm/Analysis/CtxProfAnalysis.h b/llvm/include/llvm/Analysis/CtxProfAnalysis.h
index d3b7ba96e4faa5..7a46c3e4f1d639 100644
--- a/llvm/include/llvm/Analysis/CtxProfAnalysis.h
+++ b/llvm/include/llvm/Analysis/CtxProfAnalysis.h
@@ -134,26 +134,5 @@ class CtxProfAnalysisPrinterPass
   const PrintMode Mode;
 };
 
-/// 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`.
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-  static const char *GUIDMetadataName;
-  // This should become GlobalValue::getGUID
-  static uint64_t getGUID(const Function &F);
-};
-
 } // namespace llvm
 #endif // LLVM_ANALYSIS_CTXPROFANALYSIS_H
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 05ed148148d7cb..3d6a79f8a56a71 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 uint64_t]
+  MODULE_CODE_GUIDLIST = 19,
 };
 
 /// PARAMATTR blocks have code for defining a parameter attribute set.
diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 53eddebdd6ae68..31287713c5e3bf 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -569,6 +569,12 @@ class GlobalValue : public Constant {
     return Name;
   }
 
+  /// Declare a type to represent a global unique identifier for a global value.
+  /// This is a 64 bits hash that is used by PGO and ThinLTO to have a compact
+  /// unique way to identify a symbol.
+  using GUID = uint64_t;
+
+private:
   /// Return the modified name for a global value suitable to be
   /// used as the key for a global lookup (e.g. profile or ThinLTO).
   /// The value's original name is \c Name and has linkage of type
@@ -581,18 +587,30 @@ class GlobalValue : public Constant {
   /// used as the key for a global lookup (e.g. profile or ThinLTO).
   std::string getGlobalIdentifier() const;
 
-  /// Declare a type to represent a global unique identifier for a global value.
-  /// This is a 64 bits hash that is used by PGO and ThinLTO to have a compact
-  /// unique way to identify a symbol.
-  using GUID = uint64_t;
-
   /// Return a 64-bit global unique ID constructed from global value name
   /// (i.e. returned by getGlobalIdentifier()).
   static GUID getGUID(StringRef GlobalName);
 
+public:
+  std::string getGlobalIdentifierForPGO() const {
+    return getGlobalIdentifier();
+  }
+
   /// Return a 64-bit global unique ID constructed from global value name
   /// (i.e. returned by getGlobalIdentifier()).
-  GUID getGUID() const { return getGUID(getGlobalIdentifier()); }
+  GUID getGUID() const;
+  void setGUIDIfNotPresent(GUID ForceValue = 0);
+  
+  // FIXME: remove when we switch PGO to the guid metadata mechanism.
+  static std::string getGlobalIdentifierForPGO(StringRef Name,
+                                               LinkageTypes Linkage,
+                                               StringRef FileName) {
+    return getGlobalIdentifier(Name, Linkage, FileName);
+  }
+
+  static GUID getGUIDForExternalLinkageValue(StringRef GlobalName) {
+    return getGUID(GlobalName);
+  }
 
   /// @name Materialization
   /// Materialization is used to construct functions only as they're needed.
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 288aba16702f56..6afbf060b5315b 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -1657,8 +1657,10 @@ class ModuleSummaryIndex {
   /// Add a global value summary for a value of the given name.
   void addGlobalValueSummary(StringRef ValueName,
                              std::unique_ptr<GlobalValueSummary> Summary) {
-    addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
-                          std::move(Summary));
+    addGlobalValueSummary(
+        getOrInsertValueInfo(
+            GlobalValue::getGUIDForExternalLinkageValue(ValueName)),
+        std::move(Summary));
   }
 
   /// Add a global value summary for the given ValueInfo.
@@ -1796,19 +1798,19 @@ class ModuleSummaryIndex {
   /// This accessor can mutate the map and therefore should not be used in
   /// the ThinLTO backends.
   TypeIdSummary &getOrInsertTypeIdSummary(StringRef TypeId) {
-    auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
+    auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUIDForExternalLinkageValue(TypeId));
     for (auto &[GUID, TypeIdPair] : make_range(TidIter))
       if (TypeIdPair.first == TypeId)
         return TypeIdPair.second;
     auto It = TypeIdMap.insert(
-        {GlobalValue::getGUID(TypeId), {std::string(TypeId), TypeIdSummary()}});
+        {GlobalValue::getGUIDForExternalLinkageValue(TypeId), {std::string(TypeId), TypeIdSummary()}});
     return It->second.second;
   }
 
   /// This returns either a pointer to the type id summary (if present in the
   /// summary map) or null (if not present). This may be used when importing.
   const TypeIdSummary *getTypeIdSummary(StringRef TypeId) const {
-    auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUID(TypeId));
+    auto TidIter = TypeIdMap.equal_range(GlobalValue::getGUIDForExternalLinkageValue(TypeId));
     for (const auto &[GUID, TypeIdPair] : make_range(TidIter))
       if (TypeIdPair.first == TypeId)
         return &TypeIdPair.second;
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h b/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
index 902d1305c818ac..84973a8d5cc82e 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -270,7 +270,7 @@ template <> struct CustomMappingTraits<TypeIdSummaryMapTy> {
   static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) {
     TypeIdSummary TId;
     io.mapRequired(Key.str().c_str(), TId);
-    V.insert({GlobalValue::getGUID(Key), {std::string(Key), TId}});
+    V.insert({GlobalValue::getGUIDForExternalLinkageValue(Key), {std::string(Key), TId}});
   }
   static void output(IO &io, TypeIdSummaryMapTy &V) {
     for (auto &TidIter : V)
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index fc6e93606de122..c6f931ad7a38b1 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -62,7 +62,9 @@ void thinLTOInternalizeAndPromoteInIndex(
     ModuleSummaryIndex &Index,
     function_ref<bool(StringRef, ValueInfo)> isExported,
     function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
-        isPrevailing);
+        isPrevailing,
+    function_ref<void(GlobalValue::GUID, const GlobalValueSummary &)>
+        onPromotion);
 
 /// Computes a unique hash for the Module considering the current list of
 /// export/import and other global analysis results.
diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h
index e7b154dff06971..c35994ed1ed31f 100644
--- a/llvm/include/llvm/ProfileData/SampleProf.h
+++ b/llvm/include/llvm/ProfileData/SampleProf.h
@@ -1299,7 +1299,7 @@ class FunctionSamples {
 static inline FunctionId getRepInFormat(StringRef Name) {
   if (Name.empty() || !FunctionSamples::UseMD5)
     return FunctionId(Name);
-  return FunctionId(Function::getGUID(Name));
+  return FunctionId(Function::getGUIDForExternalLinkageValue(Name));
 }
 
 raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS);
diff --git a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
index 5132dca7c6a22b..943817a625af75 100644
--- a/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
+++ b/llvm/include/llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h
@@ -109,11 +109,11 @@ class PseudoProbeManager {
   }
 
   const PseudoProbeDescriptor *getDesc(StringRef FProfileName) const {
-    return getDesc(Function::getGUID(FProfileName));
+    return getDesc(Function::getGUIDForExternalLinkageValue(FProfileName));
   }
 
   const PseudoProbeDescriptor *getDesc(const Function &F) const {
-    return getDesc(Function::getGUID(FunctionSamples::getCanonicalFnName(F)));
+    return getDesc(Function::getGUIDForExternalLinkageValue(FunctionSamples::getCanonicalFnName(F)));
   }
 
   bool profileIsHashMismatched(const PseudoProbeDescriptor &FuncDesc,
diff --git a/llvm/lib/Analysis/AssignGUIDAnalysis.cpp b/llvm/lib/Analysis/AssignGUIDAnalysis.cpp
new file mode 100644
index 00000000000000..7d49430b8ca239
--- /dev/null
+++ b/llvm/lib/Analysis/AssignGUIDAnalysis.cpp
@@ -0,0 +1,47 @@
+//===- AssignGUIDAnalysis.cpp - assign a GUID to GV -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Having a consistent GUID for GVs throughout frontend optimization, thinlto,
+// and backend optimization is essential to PGO.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
+#include "llvm/IR/Analysis.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+
+AnalysisKey AssignGUIDAnalysis::Key;
+
+AssignGUIDAnalysis::Result::Result(Module &M) : M(M) {
+  for (auto &GV : M.globals())
+    GV.setGUIDIfNotPresent();
+  for (auto &F : M.functions())
+    F.setGUIDIfNotPresent();
+}
+
+AssignGUIDAnalysis::Result AssignGUIDAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
+  return Result(M);
+}
+
+void AssignGUIDAnalysis::Result::generateGuidTable() {
+  auto *N = M.getOrInsertNamedMetadata("guid_table");
+  assert(N->getNumOperands() == 0 && "Expected guid_table to be empty");
+  for (auto &GV : M.globals())
+    if (auto *MD = GV.getMetadata("guid"))
+      N->addOperand(
+          MDNode::get(GV.getContext(), {ValueAsMetadata::get(&GV), MD}));
+  for (auto &F : M.functions())
+    if (auto *MD = F.getMetadata("guid"))
+      N->addOperand(
+          MDNode::get(F.getContext(), {ValueAsMetadata::get(&F), MD}));
+}
\ No newline at end of file
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 393803fad89383..21e54395c3ea62 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -28,6 +28,7 @@ add_llvm_component_library(LLVMAnalysis
   AliasAnalysisEvaluator.cpp
   AliasSetTracker.cpp
   Analysis.cpp
+  AssignGUIDAnalysis.cpp
   AssumeBundleQueries.cpp
   AssumptionCache.cpp
   BasicAliasAnalysis.cpp
diff --git a/llvm/lib/Analysis/CtxProfAnalysis.cpp b/llvm/lib/Analysis/CtxProfAnalysis.cpp
index 560d9c742d5e7d..42f41e236e12da 100644
--- a/llvm/lib/Analysis/CtxProfAnalysis.cpp
+++ b/llvm/lib/Analysis/CtxProfAnalysis.cpp
@@ -74,35 +74,7 @@ Value toJSON(const PGOCtxProfContext::CallTargetMapTy &P) {
 } // namespace json
 } // namespace llvm
 
-const char *AssignGUIDPass::GUIDMetadataName = "guid";
 
-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 GlobalValue::getGUID(F.getGlobalIdentifier());
-  }
-  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)
@@ -154,7 +126,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.
@@ -189,7 +161,7 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
 
 GlobalValue::GUID
 PGOContextualProfile::getDefinedFunctionGUID(const Function &F) const {
-  if (auto It = FuncInfo.find(AssignGUIDPass::getGUID(F)); It != FuncInfo.end())
+  if (auto It = FuncInfo.find(F.getGUID()); It != FuncInfo.end())
     return It->first;
   return 0;
 }
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 2d4961dade9db1..e5cbb6550ba67c 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/BlockFrequencyInfo.h"
 #include "llvm/Analysis/BranchProbabilityInfo.h"
 #include "llvm/Analysis/ConstantFolding.h"
@@ -218,7 +219,7 @@ static void addIntrinsicToSummary(
     auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
     if (!TypeId)
       break;
-    GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
+    GlobalValue::GUID Guid = GlobalValue::getGUIDForExternalLinkageValue(TypeId->getString());
 
     // Produce a summary from type.test intrinsics. We only summarize type.test
     // intrinsics that are used other than by an llvm.assume intrinsic.
@@ -246,7 +247,7 @@ static void addIntrinsicToSummary(
     auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
     if (!TypeId)
       break;
-    GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
+    GlobalValue::GUID Guid = GlobalValue::getGUIDForExternalLinkageValue(TypeId->getString());
 
     SmallVector<DevirtCallSite, 4> DevirtCalls;
     SmallVector<Instruction *, 4> LoadedPtrs;
@@ -878,7 +879,8 @@ static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
 
 // Set LiveRoot flag on entries matching the given value name.
 static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
-  if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))
+  if (ValueInfo VI =
+          Index.getValueInfo(GlobalValue::getGUIDForExternalLinkageValue(Name)))
     for (const auto &Summary : VI.getSummaryList())
       Summary->setLive(true);
 }
@@ -1099,6 +1101,7 @@ AnalysisKey ModuleSummaryIndexAnalysis::Key;
 ModuleSummaryIndex
 ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
   ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
+  AM.getResult<AssignGUIDAnalysis>(M);
   auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
   bool NeedSSI = needsParamAccessSummary(M);
   return buildModuleSummaryIndex(
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 66edf1e5a29573..42d273c9875a66 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -8802,7 +8802,7 @@ bool LLParser::parseTypeIdEntry(unsigned ID) {
     for (auto TIDRef : FwdRefTIDs->second) {
       assert(!*TIDRef.first &&
              "Forward referenced type id GUID expected to be 0");
-      *TIDRef.first = GlobalValue::getGUID(Name);
+      *TIDRef.first = GlobalValue::getGUIDForExternalLinkageValue(Name);
     }
     ForwardRefTypeIds.erase(FwdRefTIDs);
   }
@@ -8907,7 +8907,7 @@ bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) {
     for (auto TIDRef : FwdRefTIDs->second) {
       assert(!*TIDRef.first &&
              "Forward referenced type id GUID expected to be 0");
-      *TIDRef.first = GlobalValue::getGUID(Name);
+      *TIDRef.first = GlobalValue::getGUIDForExternalLinkageValue(Name);
     }
     ForwardRefTypeIds.erase(FwdRefTIDs);
   }
@@ -9223,8 +9223,8 @@ bool LLParser::addGlobalValueToIndex(
       assert(
           (!GlobalValue::isLocalLinkage(Linkage) || !SourceFileName.empty()) &&
           "Need a source_filename to compute GUID for local");
-      GUID = GlobalValue::getGUID(
-          GlobalValue::getGlobalIdentifier(Name, Linkage, SourceFileName));
+      GUID = GlobalValue::getGUIDForExternalLinkageValue(
+          GlobalValue::getGlobalIdentifierForPGO(Name, Linkage, SourceFileName));
       VI = Index->getOrInsertValueInfo(GUID, Index->saveString(Name));
     }
   }
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 027a29764148f0..103aaf1817c232 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -968,6 +968,8 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase {
   /// ids from the lists in the callsite and alloc entries to the index.
   std::vector<uint64_t> StackIds;
 
+  SmallVector<GlobalValue::GUID, 64> DefinedGUIDs;
+
 public:
   ModuleSummaryIndexBitcodeReader(
       BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex,
@@ -7114,12 +7116,11 @@ ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) {
 void ModuleSummaryIndexBitcodeReader::setValueGUID(
     uint64_t ValueID, StringRef ValueName, GlobalValue::LinkageTypes Linkage,
     StringRef SourceFileName) {
-  std::string GlobalId =
-      GlobalValue::getGlobalIdentifier(ValueName, Linkage, SourceFileName);
-  auto ValueGUID = GlobalValue::getGUID(GlobalId);
+  const GlobalValue::GUID ValueGUID = DefinedGUIDs[ValueID];
+
   auto OriginalNameID = ValueGUID;
   if (GlobalValue::isLocalLinkage(Linkage))
-    OriginalNameID = GlobalValue::getGUID(ValueName);
+    OriginalNameID = GlobalValue::getGUIDForExternalLinkageValue(ValueName);
   if (PrintSummaryGUIDs)
     dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is "
            << ValueName << "\n";
@@ -7339,6 +7340,9 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() {
           // was historically always the start of the regular bitcode header.
           VSTOffset = Record[0] - 1;
           break;
+        case bitc::MODULE_CODE_GUIDLIST:
+          llvm::append_range(DefinedGUIDs, Record);
+          break;
         // v1 GLOBALVAR: [pointer type, isconst,     initid,       linkage, ...]
         // v1 FUNCTION:  [type,         callingconv, isproto,      linkage, ...]
         // v1 ALIAS:     [alias type,   addrspace,   aliasee val#, linkage, ...]
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a5942153dc2d64..583839636dd9f2 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -135,6 +135,43 @@ enum {
   FUNCTION_DEBUG_RECORD_VALUE_ABBREV,
 };
 
+class IndexPreservingModuleVisitor final {
+  const Module &M;
+  llvm::function_ref<void(const GlobalVariable &GV)> GlobalVariableVisitor;
+  llvm::function_ref<void(const Function &GV)> FunctionVisitor;
+  llvm::function_ref<void(const GlobalAlias &GV)> AliasVisitor;
+
+public:
+  IndexPreservingModuleVisitor(
+      const Module &M,
+      llvm::function_ref<void(const GlobalVariable &GV)> GlobalVariableVisitor,
+      llvm::function_ref<void(const Function &GV)> FunctionVisitor,
+      llvm::function_ref<void(const GlobalAlias &GV)> AliasVisitor)
+      : M(M), GlobalVariableVisitor(GlobalVariableVisitor),
+        FunctionVisitor(FunctionVisitor), AliasVisitor(AliasVisitor) {}
+
+  void buildGUIDTableAndVisit(BitstreamWriter &Stream, bool HasIndex) {
+    if (HasIndex) {
+      SmallVector<uint64_t, 64> GUIDs;
+      for (const GlobalVariable &GV : M.globals())
+        GUIDs.push_back(GV.getGUID());
+
+      for (const Function &F : M)
+        GUIDs.push_back(F.getGUID());
+
+      for (const GlobalAlias &A : M.aliases())
+        GUIDs.push_back(A.getGUID());
+      Stream.EmitRecord(bitc::MODULE_CODE_GUIDLIST, GUIDs);
+    }
+    for (const GlobalVariable &GV : M.globals())
+      GlobalVariableVisitor(GV);
+    for (const Function &F : M)
+      FunctionVisitor(F);
+    for (const GlobalAlias &A : M.aliases())
+      AliasVisitor(A);
+  }
+};
+
 /// Abstract class to manage the bitcode writing, subclassed for each bitcode
 /// file type.
 class BitcodeWriterBase {
@@ -1533,7 +1570,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
   }
 
   // Emit the global variable information.
-  for (const GlobalVariable &GV : M.globals()) {
+  auto GVVisitor = [&] (const GlobalVariable &GV) {
     unsigned AbbrevToUse = 0;
 
     // GLOBALVAR: [strtab offset, strtab size, type, isconst, initid,
@@ -1581,10 +1618,10 @@ void ModuleBitcodeWriter::writeModuleInfo() {
 
     Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
     Vals.clear();
-  }
+  };
 
   // Emit the function proto information.
-  for (const Function &F : M) {
+  auto FuncVisitor = [&](const Function &F) {
     // FUNCTION:  [strtab offset, strtab size, type, callingconv, isproto,
     //             linkage, paramattrs, alignment, section, visibility, gc,
     //             unnamed_addr, prologuedata, dllstorageclass, comdat,
@@ -1619,10 +1656,10 @@ void ModuleBitcodeWriter::writeModuleInfo() {
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
     Vals.clear();
-  }
+  };
 
   // Emit the alias information.
-  for (const GlobalAlias &A : M.aliases()) {
+  auto GAVisitor =[&] (const GlobalAlias &A) {
     // ALIAS: [strtab offset, strtab size, alias type, aliasee val#, linkage,
     //         visibility, dllstorageclass, threadlocal, unnamed_addr,
     //         DSO_Local]
@@ -1643,7 +1680,9 @@ void ModuleBitcodeWriter::writeModuleInfo() {
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
     Vals.clear();
-  }
+  };
+  IndexPreservingModuleVisitor V(M, GVVisitor, FuncVisitor, GAVisitor);
+  V.buildGUIDTableAndVisit(Stream, !!Index);
 
   // Emit the ifunc information.
   for (const GlobalIFunc &I : M.ifuncs()) {
@@ -4806,8 +4845,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
 
   if (!Index.cfiFunctionDefs().empty()) {
     for (auto &S : Index.cfiFunctionDefs()) {
-      if (DefOrUseGUIDs.contains(
-              GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
+      if (DefOrUseGUIDs.count(
+              GlobalValue::getGUIDForExternalLinkageValue(GlobalValue::dropLLVMManglingEscape(S)))) {
         NameVals.push_back(StrtabBuilder.add(S));
         NameVals.push_back(S.size());
       }
@@ -4820,8 +4859,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
 
   if (!Index.cfiFunctionDecls().empty()) {
     for (auto &S : Index.cfiFunctionDecls()) {
-      if (DefOrUseGUIDs.contains(
-              GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
+      if (DefOrUseGUIDs.count(
+              GlobalValue::getGUIDForExternalLinkageValue(GlobalValue::dropLLVMManglingEscape(S)))) {
         NameVals.push_back(StrtabBuilder.add(S));
         NameVals.push_back(S.size());
       }
@@ -5256,7 +5295,7 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
   }
 
   // Emit the global variable information.
-  for (const GlobalVariable &GV : M.globals()) {
+  auto GVVisitor = [&] (const GlobalVariable &GV) {
     // GLOBALVAR: [strtab offset, strtab size, 0, 0, 0, linkage]
     Vals.push_back(StrtabBuilder.add(GV.getName()));
     Vals.push_back(GV.getName().size());
@@ -5267,10 +5306,10 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
 
     Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals);
     Vals.clear();
-  }
+  };
 
   // Emit the function proto information.
-  for (const Function &F : M) {
+  auto FVisitor = [&] (const Function &F) {
     // FUNCTION:  [strtab offset, strtab size, 0, 0, 0, linkage]
     Vals.push_back(StrtabBuilder.add(F.getName()));
     Vals.push_back(F.getName().size());
@@ -5281,10 +5320,10 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
 
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals);
     Vals.clear();
-  }
+  };
 
   // Emit the alias information.
-  for (const GlobalAlias &A : M.aliases()) {
+  auto GAVisitor = [&](const GlobalAlias &A) {
     // ALIAS: [strtab offset, strtab size, 0, 0, 0, linkage]
     Vals.push_back(StrtabBuilder.add(A.getName()));
     Vals.push_back(A.getName().size());
@@ -5295,8 +5334,9 @@ void ThinLinkBitcodeWriter::writeSimplifiedModuleInfo() {
 
     Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals);
     Vals.clear();
-  }
-
+  };
+  IndexPreservingModuleVisitor V(M, GVVisitor, FVisitor, GAVisitor);
+  V.buildGUIDTableAndVisit(Stream, !!Index);
   // Emit the ifunc information.
   for (const GlobalIFunc &I : M.ifuncs()) {
     // IFUNC: [strtab offset, strtab size, 0, 0, 0, linkage]
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index 5f66e1ea0a8352..29ff9efda0843b 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/IR/PassManager.h"
@@ -29,6 +30,9 @@ PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
   const ModuleSummaryIndex *Index =
       EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
                        : nullptr;
+  if (EmitSummaryIndex)
+    AM.getResult<AssignGUIDAnalysis>(M).generateGuidTable();
+
   WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
 
   return PreservedAnalyses::all();
diff --git a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
index 5dda38383a6567..88a4e81e43e14a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
@@ -14,6 +14,7 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/PseudoProbe.h"
 #include "llvm/MC/MCPseudoProbe.h"
 #include "llvm/MC/MCStreamer.h"
@@ -34,7 +35,7 @@ void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
     // Use caching to avoid redundant md5 computation for build speed.
     uint64_t &CallerGuid = NameGuidMap[Name];
     if (!CallerGuid)
-      CallerGuid = Function::getGUID(Name);
+      CallerGuid = GlobalValue::getGUIDForExternalLinkageValue(Name);
     uint64_t CallerProbeId = PseudoProbeDwarfDiscriminator::extractProbeIndex(
         InlinedAt->getDiscriminator());
     ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
diff --git a/llvm/lib/CodeGen/PseudoProbeInserter.cpp b/llvm/lib/CodeGen/PseudoProbeInserter.cpp
index 913e0035b046f9..8c0af6b5951b94 100644
--- a/llvm/lib/CodeGen/PseudoProbeInserter.cpp
+++ b/llvm/lib/CodeGen/PseudoProbeInserter.cpp
@@ -129,7 +129,7 @@ class PseudoProbeInserter : public MachineFunctionPass {
 private:
   uint64_t getFuncGUID(Module *M, DILocation *DL) {
     auto Name = DL->getSubprogramLinkageName();
-    return Function::getGUID(Name);
+    return GlobalValue::getGUIDForExternalLinkageValue(Name);
   }
 
   bool ShouldRun = false;
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 70e3af941bf77b..a0f533b9a9627b 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -3082,7 +3082,7 @@ void AssemblyWriter::printModuleSummaryIndex() {
 
   // Print the TypeIdCompatibleVtableMap entries.
   for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
-    auto GUID = GlobalValue::getGUID(TId.first);
+    auto GUID = GlobalValue::getGUIDForExternalLinkageValue(TId.first);
     Out << "^" << Machine.getTypeIdCompatibleVtableSlot(TId.first)
         << " = typeidCompatibleVTable: (name: \"" << TId.first << "\"";
     printTypeIdCompatibleVtableSummary(TId.second);
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index 2bc69cdb712b0a..08645a7372833b 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -18,6 +18,7 @@
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -175,6 +176,37 @@ std::string GlobalValue::getGlobalIdentifier(StringRef Name,
   return GlobalName;
 }
 
+static const char *GUIDMetadataName = "guid";
+
+void GlobalValue::setGUIDIfNotPresent(GUID ForceValue) {
+  if (isa<GlobalAlias>(this))
+    return;
+  if (auto *F = dyn_cast<Function>(this); F && F->getIntrinsicID())
+    return;
+  if (getMetadata(GUIDMetadataName) && !ForceValue)
+    return;
+  const GUID WithGUID =
+      ForceValue ? ForceValue : GlobalValue::getGUID(getGlobalIdentifier());
+  setMetadata(GUIDMetadataName,
+              MDNode::get(getContext(),
+                          {ConstantAsMetadata::get(ConstantInt::get(
+                              Type::getInt64Ty(getContext()), WithGUID))}));
+}
+
+GlobalValue::GUID GlobalValue::getGUID() const {
+  if (isa<GlobalAlias>(this))
+    return GlobalValue::getGUID(getGlobalIdentifier());
+  if (auto *F = dyn_cast<Function>(this); F && F->getIntrinsicID())
+    return GlobalValue::getGUID(getGlobalIdentifier());
+
+  auto *MD = getMetadata(GUIDMetadataName);
+  assert(MD);
+  return cast<ConstantInt>(cast<ConstantAsMetadata>(MD->getOperand(0))
+                               ->getValue()
+                               ->stripPointerCasts())
+      ->getZExtValue();
+}
+
 std::string GlobalValue::getGlobalIdentifier() const {
   return getGlobalIdentifier(getName(), getLinkage(),
                              getParent()->getSourceFileName());
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 5d9a5cbd18f156..72d03db8add736 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -444,7 +444,9 @@ void llvm::thinLTOResolvePrevailingInIndex(
 static void thinLTOInternalizeAndPromoteGUID(
     ValueInfo VI, function_ref<bool(StringRef, ValueInfo)> isExported,
     function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
-        isPrevailing) {
+        isPrevailing,
+    function_ref<void(GlobalValue::GUID, const GlobalValueSummary &)>
+        onPromotion) {
   auto ExternallyVisibleCopies =
       llvm::count_if(VI.getSummaryList(),
                      [](const std::unique_ptr<GlobalValueSummary> &Summary) {
@@ -455,8 +457,10 @@ static void thinLTOInternalizeAndPromoteGUID(
     // First see if we need to promote an internal value because it is not
     // exported.
     if (isExported(S->modulePath(), VI)) {
-      if (GlobalValue::isLocalLinkage(S->linkage()))
+      if (GlobalValue::isLocalLinkage(S->linkage())) {
         S->setLinkage(GlobalValue::ExternalLinkage);
+        onPromotion(VI.getGUID(), *S);
+      }
       continue;
     }
 
@@ -524,10 +528,12 @@ void llvm::thinLTOInternalizeAndPromoteInIndex(
     ModuleSummaryIndex &Index,
     function_ref<bool(StringRef, ValueInfo)> isExported,
     function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
-        isPrevailing) {
+        isPrevailing,
+    function_ref<void(GlobalValue::GUID, const GlobalValueSummary &)>
+        onPromotion) {
   for (auto &I : Index)
     thinLTOInternalizeAndPromoteGUID(Index.getValueInfo(I), isExported,
-                                     isPrevailing);
+                                     isPrevailing, onPromotion);
 }
 
 // Requires a destructor for std::vector<InputModule>.
@@ -832,6 +838,18 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
 
   if (Error Err = M.materializeMetadata())
     return std::move(Err);
+  auto *Map = M.getNamedMetadata("guid_table");
+  assert(Map);
+  for (auto I = 0U, E = Map->getNumOperands(); I < E; ++I) {
+    auto *N = Map->getOperand(I);
+    auto *V = cast<ValueAsMetadata>(N->getOperand(0))->getValue();
+    auto *GO = cast<GlobalObject>(V);
+    const auto *GUID = cast<ConstantAsMetadata>(
+        cast<MDNode>(N->getOperand(1).get())->getOperand(0));
+    GO->setGUIDIfNotPresent(
+        cast<ConstantInt>(GUID->getValue()->stripPointerCasts())
+            ->getZExtValue());
+  }
 
   // If cfi.functions is present and we are in regular LTO mode, LowerTypeTests
   // will rename local functions in the merged module as "<function name>.1".
@@ -1019,8 +1037,7 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
     SymbolResolution Res = *ResITmp++;
 
     if (!Sym.getIRName().empty()) {
-      auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
-          Sym.getIRName(), GlobalValue::ExternalLinkage, ""));
+      auto GUID = GlobalValue::getGUIDForExternalLinkageValue(Sym.getIRName());
       if (Res.Prevailing)
         ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier();
     }
@@ -1029,8 +1046,8 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
   if (Error Err =
           BM.readSummary(ThinLTO.CombinedIndex, BM.getModuleIdentifier(),
                          [&](GlobalValue::GUID GUID) {
-                           return ThinLTO.PrevailingModuleForGUID[GUID] ==
-                                  BM.getModuleIdentifier();
+                           return ThinLTO.PrevailingModuleForGUID.lookup(
+                                      GUID) == BM.getModuleIdentifier();
                          }))
     return Err;
   LLVM_DEBUG(dbgs() << "Module " << BM.getModuleIdentifier() << "\n");
@@ -1040,10 +1057,9 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
     SymbolResolution Res = *ResI++;
 
     if (!Sym.getIRName().empty()) {
-      auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
-          Sym.getIRName(), GlobalValue::ExternalLinkage, ""));
+      auto GUID = GlobalValue::getGUIDForExternalLinkageValue(Sym.getIRName());
       if (Res.Prevailing) {
-        assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
+        assert(ThinLTO.PrevailingModuleForGUID.lookup(GUID) ==
                BM.getModuleIdentifier());
 
         // For linker redefined symbols (via --wrap or --defsym) we want to
@@ -1150,7 +1166,7 @@ Error LTO::run(AddStreamFn AddStream, FileCache Cache) {
     if (Res.second.IRName.empty())
       continue;
 
-    GlobalValue::GUID GUID = GlobalValue::getGUID(
+    GlobalValue::GUID GUID = GlobalValue::getGUIDForExternalLinkageValue(
         GlobalValue::dropLLVMManglingEscape(Res.second.IRName));
 
     if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
@@ -1453,10 +1469,10 @@ class InProcessThinBackend : public ThinBackendProc {
         Cache(std::move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
     for (auto &Name : CombinedIndex.cfiFunctionDefs())
       CfiFunctionDefs.insert(
-          GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
+          GlobalValue::getGUIDForExternalLinkageValue(GlobalValue::dropLLVMManglingEscape(Name)));
     for (auto &Name : CombinedIndex.cfiFunctionDecls())
       CfiFunctionDecls.insert(
-          GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
+          GlobalValue::getGUIDForExternalLinkageValue(GlobalValue::dropLLVMManglingEscape(Name)));
   }
 
   Error runThinLTOBackendThread(
@@ -1766,7 +1782,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
                                LocalWPDTargetsMap);
 
   auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
-    return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
+    return ThinLTO.PrevailingModuleForGUID.lookup(GUID) == S->modulePath();
   };
   if (EnableMemProfContextDisambiguation) {
     MemProfContextDisambiguation ContextDisambiguation;
@@ -1783,7 +1799,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
     if (Res.second.Partition != GlobalResolution::External ||
         !Res.second.isPrevailingIRSymbol())
       continue;
-    auto GUID = GlobalValue::getGUID(
+    auto GUID = GlobalValue::getGUIDForExternalLinkageValue(
         GlobalValue::dropLLVMManglingEscape(Res.second.IRName));
     // Mark exported unless index-based analysis determined it to be dead.
     if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
@@ -1803,11 +1819,11 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
   // Any functions referenced by the jump table in the regular LTO object must
   // be exported.
   for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
-    ExportedGUIDs.insert(
-        GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def)));
+    ExportedGUIDs.insert(GlobalValue::getGUIDForExternalLinkageValue(
+        GlobalValue::dropLLVMManglingEscape(Def)));
   for (auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
-    ExportedGUIDs.insert(
-        GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Decl)));
+    ExportedGUIDs.insert(GlobalValue::getGUIDForExternalLinkageValue(
+        GlobalValue::dropLLVMManglingEscape(Decl)));
 
   auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
     const auto &ExportList = ExportLists.find(ModuleIdentifier);
@@ -1820,8 +1836,15 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
   updateIndexWPDForExports(ThinLTO.CombinedIndex, isExported,
                            LocalWPDTargetsMap);
 
-  thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported,
-                                      isPrevailing);
+  thinLTOInternalizeAndPromoteInIndex(
+      ThinLTO.CombinedIndex, isExported, isPrevailing,
+      [&](auto GUID, const auto &Summary) {
+        auto Ins = ThinLTO.PrevailingModuleForGUID.insert(
+            {GUID, Summary.modulePath()});
+        (void)Ins;
+        assert(Ins.second && "Should not have had a prevailing definition for "
+                             "an internal symbol.");
+      });
 
   auto recordNewLinkage = [&](StringRef ModuleIdentifier,
                               GlobalValue::GUID GUID,
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 76268c950cf581..bd7846aab2d8fa 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -297,7 +297,8 @@ addUsedSymbolToPreservedGUID(const lto::InputFile &File,
                              DenseSet<GlobalValue::GUID> &PreservedGUID) {
   for (const auto &Sym : File.symbols()) {
     if (Sym.isUsed())
-      PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
+      PreservedGUID.insert(
+          GlobalValue::getGUIDForExternalLinkageValue(Sym.getIRName()));
   }
 }
 
@@ -310,8 +311,8 @@ static void computeGUIDPreservedSymbols(const lto::InputFile &File,
   // compute the GUID for the symbol.
   for (const auto &Sym : File.symbols()) {
     if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())
-      GUIDs.insert(GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
-          Sym.getIRName(), GlobalValue::ExternalLinkage, "")));
+      GUIDs.insert(
+          GlobalValue::getGUIDForExternalLinkageValue(Sym.getIRName()));
   }
 }
 
@@ -711,7 +712,8 @@ void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index,
   // in the module.
   thinLTOInternalizeAndPromoteInIndex(
       Index, IsExported(ExportLists, GUIDPreservedSymbols),
-      IsPrevailing(PrevailingCopy));
+      IsPrevailing(PrevailingCopy),
+      [&](auto GUID, const auto &S) { PrevailingCopy.insert({GUID, &S}); });
 
   // FIXME Set ClearDSOLocalOnDeclarations.
   promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
@@ -894,7 +896,8 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule,
   // in the module.
   thinLTOInternalizeAndPromoteInIndex(
       Index, IsExported(ExportLists, GUIDPreservedSymbols),
-      IsPrevailing(PrevailingCopy));
+      IsPrevailing(PrevailingCopy),
+      [&](auto GUID, const auto &S) { PrevailingCopy.insert({GUID, &S}); });
 
   // FIXME Set ClearDSOLocalOnDeclarations.
   promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
@@ -1095,7 +1098,8 @@ void ThinLTOCodeGenerator::run() {
                            LocalWPDTargetsMap);
   thinLTOInternalizeAndPromoteInIndex(
       *Index, IsExported(ExportLists, GUIDPreservedSymbols),
-      IsPrevailing(PrevailingCopy));
+      IsPrevailing(PrevailingCopy),
+      [&](auto GUID, const auto &S) { PrevailingCopy.insert({GUID, &S}); });
 
   thinLTOPropagateFunctionAttrs(*Index, IsPrevailing(PrevailingCopy));
 
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index c34f9148cce58b..f55b995ccbb8ae 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Analysis/AliasAnalysisEvaluator.h"
 #include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/BlockFrequencyInfo.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 3e44c160f82aff..aac0767ebb88b7 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1197,12 +1197,6 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
                       PGOOpt->FS);
   } else if (IsCtxProfGen || IsCtxProfUse) {
     MPM.addPass(PGOInstrumentationGen(PGOInstrumentationType::CTXPROF));
-    // In pre-link, we just want the instrumented IR. We use the contextual
-    // profile in the post-thinlink phase.
-    // The instrumentation will be removed in post-thinlink after IPO.
-    // FIXME(mtrofin): move AssignGUIDPass if there is agreement to use this
-    // mechanism for GUIDs.
-    MPM.addPass(AssignGUIDPass());
     if (IsCtxProfUse)
       return MPM;
     addPostPGOLoopRotation(MPM, Level);
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 4f5f680a6e9535..adcda1bc9bcb37 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -18,6 +18,7 @@
 #ifndef MODULE_ANALYSIS
 #define MODULE_ANALYSIS(NAME, CREATE_PASS)
 #endif
+MODULE_ANALYSIS("assign-guid", AssignGUIDAnalysis())
 MODULE_ANALYSIS("callgraph", CallGraphAnalysis())
 MODULE_ANALYSIS("collector-metadata", CollectorMetadataAnalysis())
 MODULE_ANALYSIS("ctx-prof-analysis", CtxProfAnalysis())
@@ -46,7 +47,6 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA())
 #endif
 MODULE_PASS("always-inline", AlwaysInlinerPass())
 MODULE_PASS("annotation2metadata", Annotation2MetadataPass())
-MODULE_PASS("assign-guid", AssignGUIDPass())
 MODULE_PASS("attributor", AttributorPass())
 MODULE_PASS("attributor-light", AttributorLightPass())
 MODULE_PASS("called-value-propagation", CalledValuePropagationPass())
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index b9937c9429b77d..50f005b777c35b 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -322,7 +322,7 @@ static std::string
 getIRPGONameForGlobalObject(const GlobalObject &GO,
                             GlobalValue::LinkageTypes Linkage,
                             StringRef FileName) {
-  return GlobalValue::getGlobalIdentifier(GO.getName(), Linkage, FileName);
+  return GlobalValue::getGlobalIdentifierForPGO(GO.getName(), Linkage, FileName);
 }
 
 static std::optional<std::string> lookupPGONameFromMetadata(MDNode *MD) {
@@ -517,7 +517,7 @@ Error InstrProfSymtab::addVTableWithName(GlobalVariable &VTable,
 
     bool Inserted = true;
     std::tie(std::ignore, Inserted) =
-        MD5VTableMap.try_emplace(GlobalValue::getGUID(Name), &VTable);
+        MD5VTableMap.try_emplace(GlobalValue::getGUIDForExternalLinkageValue(Name), &VTable);
     if (!Inserted)
       LLVM_DEBUG(dbgs() << "GUID conflict within one module");
     return Error::success();
@@ -634,7 +634,7 @@ Error InstrProfSymtab::addFuncWithName(Function &F, StringRef PGOFuncName) {
   auto NameToGUIDMap = [&](StringRef Name) -> Error {
     if (Error E = addFuncName(Name))
       return E;
-    MD5FuncMap.emplace_back(Function::getGUID(Name), &F);
+    MD5FuncMap.emplace_back(Function::getGUIDForExternalLinkageValue(Name), &F);
     return Error::success();
   };
   if (Error E = NameToGUIDMap(PGOFuncName))
diff --git a/llvm/lib/ProfileData/MemProf.cpp b/llvm/lib/ProfileData/MemProf.cpp
index 6d784053f877d4..38f638707aa137 100644
--- a/llvm/lib/ProfileData/MemProf.cpp
+++ b/llvm/lib/ProfileData/MemProf.cpp
@@ -370,7 +370,7 @@ GlobalValue::GUID IndexedMemProfRecord::getGUID(const StringRef FunctionName) {
   // We use the function guid which we expect to be a uint64_t. At
   // this time, it is the lower 64 bits of the md5 of the canonical
   // function name.
-  return Function::getGUID(CanonicalName);
+  return Function::getGUIDForExternalLinkageValue(CanonicalName);
 }
 
 Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer) {
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp
index 98c78443785275..40a6116217c842 100644
--- a/llvm/lib/ProfileData/SampleProfReader.cpp
+++ b/llvm/lib/ProfileData/SampleProfReader.cpp
@@ -898,7 +898,7 @@ std::error_code SampleProfileReaderExtBinaryBase::readFuncProfiles(
     DenseSet<uint64_t> FuncGuidsToUse;
     if (useMD5()) {
       for (auto Name : FuncsToUse)
-        FuncGuidsToUse.insert(Function::getGUID(Name));
+        FuncGuidsToUse.insert(Function::getGUIDForExternalLinkageValue(Name));
     }
 
     // For each function in current module, load all context profiles for
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 7ad300c6cccd45..ba9afa28e93a49 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -181,7 +181,7 @@ void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
       case Mips::JAL:
       case Mips::JAL_MM:
         if (MI.getOperand(0).isGlobal() &&
-            MI.getOperand(0).getGlobal()->getGlobalIdentifier() == "_mcount")
+            MI.getOperand(0).getGlobal()->getGlobalIdentifierForPGO() == "_mcount")
           emitMCountABI(MI, MBB, MF);
         break;
       case Mips::JALRPseudo:
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index dcde86388dcd9d..fe0d16c8ce793d 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -3100,7 +3100,7 @@ bool PPCAIXAsmPrinter::doInitialization(Module &M) {
     if (Aliasee->hasCommonLinkage()) {
       report_fatal_error("Aliases to common variables are not allowed on AIX:"
                          "\n\tAlias attribute for " +
-                             Alias.getGlobalIdentifier() +
+                             Alias.getGlobalIdentifierForPGO() +
                              " is invalid because " + Aliasee->getName() +
                              " is common.",
                          false);
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 1aac8e07135875..cd69b89337388a 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/IR/AutoUpgrade.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalObject.h"
@@ -571,7 +572,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
       if (PotentialCandidates.empty()) {
         LLVM_DEBUG(dbgs() << "[Workload] Not importing " << VI.name()
                           << " because can't find eligible Callee. Guid is: "
-                          << Function::getGUID(VI.name()) << "\n");
+                          << VI.getGUID() << "\n");
         continue;
       }
       /// We will prefer importing the prevailing candidate, if not, we'll
@@ -625,7 +626,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
       }
       LLVM_DEBUG(dbgs() << "[Workload][Including]" << VI.name() << " from "
                         << ExportingModule << " : "
-                        << Function::getGUID(VI.name()) << "\n");
+                        << VI.getGUID() << "\n");
       ImportList.addDefinition(ExportingModule, VI.getGUID());
       GVI.onImportingSummary(*GVS);
       if (ExportLists)
@@ -1349,6 +1350,7 @@ void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index,
   for (auto &EI : FS->mutableCalls()) {
     if (!EI.first.getSummaryList().empty())
       continue;
+    // FIXME: remove when we remove "original name".
     auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());
     if (GUID == 0)
       continue;
@@ -1574,16 +1576,21 @@ bool llvm::convertToDeclaration(GlobalValue &GV) {
   LLVM_DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName()
                     << "\n");
   if (Function *F = dyn_cast<Function>(&GV)) {
+    auto OldGUID = F->getGUID();
     F->deleteBody();
     F->clearMetadata();
+    F->setGUIDIfNotPresent(OldGUID);
     F->setComdat(nullptr);
   } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {
     V->setInitializer(nullptr);
     V->setLinkage(GlobalValue::ExternalLinkage);
+    auto OldGUID = V->getGUID();
     V->clearMetadata();
+    V->setGUIDIfNotPresent(OldGUID);
     V->setComdat(nullptr);
   } else {
-    GlobalValue *NewGV;
+    GlobalValue *NewGV = nullptr;
+    auto OldGUID = GV.getGUID();
     if (GV.getValueType()->isFunctionTy())
       NewGV =
           Function::Create(cast<FunctionType>(GV.getValueType()),
@@ -1597,6 +1604,7 @@ bool llvm::convertToDeclaration(GlobalValue &GV) {
                              /*insertbefore*/ nullptr, GV.getThreadLocalMode(),
                              GV.getType()->getAddressSpace());
     NewGV->takeName(&GV);
+    NewGV->setGUIDIfNotPresent(OldGUID);
     GV.replaceAllUsesWith(NewGV);
     return false;
   }
@@ -1748,6 +1756,8 @@ void llvm::thinLTOInternalizeModule(Module &TheModule,
 
     // Lookup the linkage recorded in the summaries during global analysis.
     auto GS = DefinedGlobals.find(GV.getGUID());
+    // // FIXME: this can get removed when we switch sample pgo to the new guid
+    // // mechanism and can remove the "original name" concept.
     if (GS == DefinedGlobals.end()) {
       // Must have been promoted (possibly conservatively). Find original
       // name so that we can access the correct summary and see if it can
@@ -1756,10 +1766,10 @@ void llvm::thinLTOInternalizeModule(Module &TheModule,
       // and internalizing again.
       StringRef OrigName =
           ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName());
-      std::string OrigId = GlobalValue::getGlobalIdentifier(
+      std::string OrigId = GlobalValue::getGlobalIdentifierForPGO(
           OrigName, GlobalValue::InternalLinkage,
           TheModule.getSourceFileName());
-      GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId));
+      GS = DefinedGlobals.find(GlobalValue::getGUIDForExternalLinkageValue(OrigId));
       if (GS == DefinedGlobals.end()) {
         // Also check the original non-promoted non-globalized name. In some
         // cases a preempted weak value is linked in as a local copy because
@@ -1767,10 +1777,11 @@ void llvm::thinLTOInternalizeModule(Module &TheModule,
         // In that case, since it was originally not a local value, it was
         // recorded in the index using the original name.
         // FIXME: This may not be needed once PR27866 is fixed.
-        GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName));
+        GS = DefinedGlobals.find(GlobalValue::getGUIDForExternalLinkageValue(OrigName));
         assert(GS != DefinedGlobals.end());
       }
     }
+    assert(GS != DefinedGlobals.end());
     return !GlobalValue::isLocalLinkage(GS->second->linkage());
   };
 
@@ -1831,13 +1842,29 @@ Expected<bool> FunctionImporter::importFunctions(
     if (Error Err = SrcModule->materializeMetadata())
       return std::move(Err);
 
+    SmallDenseMap<const GlobalObject*, GlobalValue::GUID> GOToGuidMap;
+    auto *Map = SrcModule->getNamedMetadata("guid_table");
+    assert(Map);
+    for (auto I = 0U, E = Map->getNumOperands(); I < E; ++I) {
+      const auto *N = Map->getOperand(I);
+      const auto *V = cast<ValueAsMetadata>(N->getOperand(0))->getValue();
+      const auto *GO = cast<GlobalObject>(V);
+      const auto *GUID = cast<ConstantAsMetadata>(
+          cast<MDNode>(N->getOperand(1).get())->getOperand(0));
+      GOToGuidMap[GO] = cast<ConstantInt>(GUID->getValue()->stripPointerCasts())
+                            ->getZExtValue();
+    }
+    Map->eraseFromParent();
+
+    auto &ImportGUIDs = FunctionsToImportPerModule->second;
+
     // Find the globals to import
     SetVector<GlobalValue *> GlobalsToImport;
     for (Function &F : *SrcModule) {
       if (!F.hasName())
         continue;
-      auto GUID = F.getGUID();
-      auto MaybeImportType = ImportList.getImportType(ModName, GUID);
+      auto GUID = GOToGuidMap[&F];
+      auto MaybeImportType = getImportType(ImportGUIDs, GUID);
       bool ImportDefinition = MaybeImportType == GlobalValueSummary::Definition;
 
       LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not")
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 0742b259c489c0..687a1e2b9b7a0c 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -2097,7 +2097,8 @@ bool LowerTypeTestsModule::lower() {
                 ->getValue()
                 ->getUniqueInteger()
                 .getZExtValue());
-        const GlobalValue::GUID GUID = GlobalValue::getGUID(
+        const GlobalValue::GUID GUID =
+            GlobalValue::getGUIDForExternalLinkageValue(
                 GlobalValue::dropLLVMManglingEscape(FunctionName));
         // Do not emit jumptable entries for functions that are not-live and
         // have no live references (and are not exported with cross-DSO CFI.)
@@ -2303,8 +2304,9 @@ bool LowerTypeTestsModule::lower() {
     DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
     for (auto &P : TypeIdInfo) {
       if (auto *TypeId = dyn_cast<MDString>(P.first))
-        MetadataByGUID[GlobalValue::getGUID(TypeId->getString())].push_back(
-            TypeId);
+        MetadataByGUID[GlobalValue::getGUIDForExternalLinkageValue(
+                           TypeId->getString())]
+            .push_back(TypeId);
     }
 
     for (auto &P : *ExportSummary) {
diff --git a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
index f8c150a675e645..503046ef3f14f2 100644
--- a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
+++ b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
@@ -3634,15 +3634,15 @@ static ValueInfo findValueInfoForFunc(const Function &F, const Module &M,
     // See if theFn was internalized, by checking index directly with
     // original name (this avoids the name adjustment done by getGUID() for
     // internal symbols).
-    TheFnVI = ImportSummary->getValueInfo(GlobalValue::getGUID(F.getName()));
+    TheFnVI = ImportSummary->getValueInfo(GlobalValue::getGUIDForExternalLinkageValue(F.getName()));
   if (TheFnVI)
     return TheFnVI;
   // Now query with the original name before any promotion was performed.
   StringRef OrigName =
       ModuleSummaryIndex::getOriginalNameBeforePromote(F.getName());
-  std::string OrigId = GlobalValue::getGlobalIdentifier(
+  std::string OrigId = GlobalValue::getGlobalIdentifierForPGO(
       OrigName, GlobalValue::InternalLinkage, M.getSourceFileName());
-  TheFnVI = ImportSummary->getValueInfo(GlobalValue::getGUID(OrigId));
+  TheFnVI = ImportSummary->getValueInfo(GlobalValue::getGUIDForExternalLinkageValue(OrigId));
   if (TheFnVI)
     return TheFnVI;
   // Could be a promoted local imported from another module. We need to pass
@@ -3651,7 +3651,7 @@ static ValueInfo findValueInfoForFunc(const Function &F, const Module &M,
   // index. This would not work if there were same-named locals in multiple
   // modules, however.
   auto OrigGUID =
-      ImportSummary->getGUIDFromOriginalID(GlobalValue::getGUID(OrigName));
+      ImportSummary->getGUIDFromOriginalID(GlobalValue::getGUIDForExternalLinkageValue(OrigName));
   if (OrigGUID)
     TheFnVI = ImportSummary->getValueInfo(OrigGUID);
   return TheFnVI;
diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp
index 6af284d513efc3..00df120ebb344f 100644
--- a/llvm/lib/Transforms/IPO/SampleProfile.cpp
+++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp
@@ -361,7 +361,7 @@ class GUIDToFuncNameMapper {
     for (const auto &F : CurrentModule) {
       StringRef OrigName = F.getName();
       CurrentGUIDToFuncNameMap.insert(
-          {Function::getGUID(OrigName), OrigName});
+          {Function::getGUIDForExternalLinkageValue(OrigName), OrigName});
 
       // Local to global var promotion used by optimization like thinlto
       // will rename the var and add suffix like ".llvm.xxx" to the
@@ -373,7 +373,7 @@ class GUIDToFuncNameMapper {
       StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
       if (CanonName != OrigName)
         CurrentGUIDToFuncNameMap.insert(
-            {Function::getGUID(CanonName), CanonName});
+            {Function::getGUIDForExternalLinkageValue(CanonName), CanonName});
     }
 
     // Update GUIDToFuncNameMap for each function including inlinees.
@@ -818,7 +818,7 @@ static bool doesHistoryAllowICP(const Instruction &Inst, StringRef Candidate) {
     // If the promotion candidate has NOMORE_ICP_MAGICNUM count in the
     // metadata, it means the candidate has been promoted for this
     // indirect call.
-    if (V.Value == Function::getGUID(Candidate))
+    if (V.Value == Function::getGUIDForExternalLinkageValue(Candidate))
       return false;
     NumPromoted++;
     // If already have MaxNumPromotions promotion, don't do it anymore.
@@ -949,7 +949,7 @@ bool SampleProfileLoader::tryPromoteAndInlineCandidate(
     // For promoted target, set its value with NOMORE_ICP_MAGICNUM count
     // in the value profile metadata so the target won't be promoted again.
     SmallVector<InstrProfValueData, 1> SortedCallTargets = {InstrProfValueData{
-        Function::getGUID(R->second->getName()), NOMORE_ICP_MAGICNUM}};
+        Function::getGUIDForExternalLinkageValue(R->second->getName()), NOMORE_ICP_MAGICNUM}};
     updateIDTMetaData(CI, SortedCallTargets, 0);
 
     auto *DI = &pgo::promoteIndirectCall(
@@ -1037,7 +1037,7 @@ void SampleProfileLoader::findExternalInlineCandidate(
     // just add the direct GUID and move on
     if (!Samples) {
       InlinedGUIDs.insert(
-          Function::getGUID(CB->getCalledFunction()->getName()));
+          GlobalValue::getGUIDForExternalLinkageValue(CB->getCalledFunction()->getName()));
       return;
     }
     // Otherwise, drop the threshold to import everything that we can
@@ -2258,7 +2258,8 @@ bool SampleProfileLoader::runOnFunction(Function &F, ModuleAnalysisManager *AM)
     // cold in sampled binary will actually not be cold after current build.
     StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
     if ((FunctionSamples::UseMD5 &&
-         GUIDsInProfile.count(Function::getGUID(CanonName))) ||
+         GUIDsInProfile.count(
+             GlobalValue::getGUIDForExternalLinkageValue(CanonName))) ||
         (!FunctionSamples::UseMD5 && NamesInProfile.count(CanonName)))
       initialEntryCount = -1;
   }
diff --git a/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp b/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
index b489d4fdaa2104..9e5c0dfede6614 100644
--- a/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
+++ b/llvm/lib/Transforms/IPO/SampleProfileProbe.cpp
@@ -353,7 +353,7 @@ void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
     if (FName.empty())
       FName = SP->getName();
   }
-  uint64_t Guid = Function::getGUID(FName);
+  uint64_t Guid = Function::getGUIDForExternalLinkageValue(FName);
 
   // Assign an artificial debug line to a probe that doesn't come with a real
   // line. A probe not having a debug line will get an incomplete inline
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index 9bf29c46938eba..8a777bfcbcc8c4 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -580,7 +581,7 @@ PreservedAnalyses
 llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
   FunctionAnalysisManager &FAM =
       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
-
+  AM.getResult<AssignGUIDAnalysis>(M).generateGuidTable();
   ScopedDbgInfoFormatSetter FormatSetter(M, M.IsNewDbgInfoFormat &&
                                                 WriteNewDbgInfoFormatToBitcode);
   if (M.IsNewDbgInfoFormat)
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index 19bc841b10529b..1e6ea113e52c81 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -58,8 +58,10 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/CtxProfAnalysis.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/Analysis/TypeMetadataUtils.h"
 #include "llvm/Bitcode/BitcodeReader.h"
@@ -763,6 +765,7 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
     return FAM.getResult<DominatorTreeAnalysis>(F);
   };
   if (UseCommandLine) {
+    AM.getResult<AssignGUIDAnalysis>(M);
     if (!DevirtModule::runForTesting(M, AARGetter, OREGetter, LookupDomTree))
       return PreservedAnalyses::all();
     return PreservedAnalyses::none();
@@ -833,6 +836,7 @@ void llvm::updateVCallVisibilityInModule(
     // Add linkage unit visibility to any variable with type metadata, which are
     // the vtable definitions. We won't have an existing vcall_visibility
     // metadata on vtable definitions with public visibility.
+    GV.setGUIDIfNotPresent();
     if (GV.hasMetadata(LLVMContext::MD_type) &&
         GV.getVCallVisibility() == GlobalObject::VCallVisibilityPublic &&
         // Don't upgrade the visibility for symbols exported to the dynamic
@@ -2204,7 +2208,6 @@ DevirtModule::lookUpFunctionValueInfo(Function *TheFn,
          "Caller guarantees ExportSummary is not nullptr");
 
   const auto TheFnGUID = TheFn->getGUID();
-  const auto TheFnGUIDWithExportedName = GlobalValue::getGUID(TheFn->getName());
   // Look up ValueInfo with the GUID in the current linkage.
   ValueInfo TheFnVI = ExportSummary->getValueInfo(TheFnGUID);
   // If no entry is found and GUID is different from GUID computed using
@@ -2215,9 +2218,6 @@ DevirtModule::lookUpFunctionValueInfo(Function *TheFn,
   // 1. LTO could enable global value internalization via
   // `enable-lto-internalization`.
   // 2. The GUID in ExportedSummary is computed using exported name.
-  if ((!TheFnVI) && (TheFnGUID != TheFnGUIDWithExportedName)) {
-    TheFnVI = ExportSummary->getValueInfo(TheFnGUIDWithExportedName);
-  }
   return TheFnVI;
 }
 
@@ -2302,7 +2302,7 @@ bool DevirtModule::run() {
     DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
     for (auto &P : TypeIdMap) {
       if (auto *TypeId = dyn_cast<MDString>(P.first))
-        MetadataByGUID[GlobalValue::getGUID(TypeId->getString())].push_back(
+        MetadataByGUID[GlobalValue::getGUIDForExternalLinkageValue(TypeId->getString())].push_back(
             TypeId);
     }
 
@@ -2386,8 +2386,8 @@ bool DevirtModule::run() {
     // llvm.type.test intrinsics to the function summaries so that the
     // LowerTypeTests pass will export them.
     if (ExportSummary && isa<MDString>(S.first.TypeID)) {
-      auto GUID =
-          GlobalValue::getGUID(cast<MDString>(S.first.TypeID)->getString());
+      auto GUID = GlobalValue::getGUIDForExternalLinkageValue(
+          cast<MDString>(S.first.TypeID)->getString());
       for (auto *FS : S.second.CSInfo.SummaryTypeCheckedLoadUsers)
         FS->addTypeTest(GUID);
       for (auto &CCS : S.second.ConstCSInfo)
@@ -2443,7 +2443,7 @@ void DevirtIndex::run() {
 
   DenseMap<GlobalValue::GUID, std::vector<StringRef>> NameByGUID;
   for (const auto &P : ExportSummary.typeIdCompatibleVtableMap()) {
-    NameByGUID[GlobalValue::getGUID(P.first)].push_back(P.first);
+    NameByGUID[GlobalValue::getGUIDForExternalLinkageValue(P.first)].push_back(P.first);
     // Create the type id summary resolution regardlness of whether we can
     // devirtualize, so that lower type tests knows the type id is used on
     // a global and not Unsat. We do this here rather than in the loop over the
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
index 4a43120c9a9e7f..91cdf1d1b63d3e 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
@@ -808,7 +808,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
   // 'unique-internal-linkage-names' can make MemProf work better for local
   // linkage function.
   auto FuncName = F.getName();
-  auto FuncGUID = Function::getGUID(FuncName);
+  auto FuncGUID = Function::getGUIDForExternalLinkageValue(FuncName);
   std::optional<memprof::MemProfRecord> MemProfRec;
   auto Err = MemProfReader->getMemProfRecord(FuncGUID).moveInto(MemProfRec);
   if (Err) {
@@ -924,7 +924,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
         StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
         if (Name.empty())
           Name = DIL->getScope()->getSubprogram()->getName();
-        auto CalleeGUID = Function::getGUID(Name);
+        auto CalleeGUID = GlobalValue::getGUIDForExternalLinkageValue(Name);
         auto StackId = computeStackId(CalleeGUID, GetOffset(DIL),
                                       ProfileHasColumns ? DIL->getColumn() : 0);
         // Check if we have found the profile's leaf frame. If yes, collect
diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp
index fc78d8c60ec050..d2d1db1f588e87 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp
@@ -330,7 +330,7 @@ PreservedAnalyses PGOCtxProfFlatteningPass::run(Module &M,
            "Function has unreacheable basic blocks. The expectation was that "
            "DCE was run before.");
 
-    auto It = FlattenedProfile.find(AssignGUIDPass::getGUID(F));
+    auto It = FlattenedProfile.find(F.getGUID());
     // If this function didn't appear in the contextual profile, it's cold.
     if (It == FlattenedProfile.end())
       clearColdFunctionProfile(F);
diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
index b620306628729b..9da16bdd4e8a86 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
@@ -226,8 +226,7 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
 
       IRBuilder<> Builder(Mark);
 
-      Guid = Builder.getInt64(
-          AssignGUIDPass::getGUID(cast<Function>(*Mark->getNameValue())));
+      Guid = Builder.getInt64(F.getGUID());
       // The type of the context of this function is now knowable since we have
       // NumCallsites and NumCounters. We delcare it here because it's more
       // convenient - we have the Builder.
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 9dd4a561edfddc..aa02b03c723244 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -59,6 +59,7 @@
 #include "llvm/ADT/iterator.h"
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/AssignGUIDAnalysis.h"
 #include "llvm/Analysis/BranchProbabilityInfo.h"
 #include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -1948,6 +1949,7 @@ PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
 
 PreservedAnalyses PGOInstrumentationGen::run(Module &M,
                                              ModuleAnalysisManager &MAM) {
+  MAM.getResult<AssignGUIDAnalysis>(M);
   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
   auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
     return FAM.getResult<TargetLibraryAnalysis>(F);
@@ -2302,7 +2304,7 @@ PGOInstrumentationUse::PGOInstrumentationUse(
 
 PreservedAnalyses PGOInstrumentationUse::run(Module &M,
                                              ModuleAnalysisManager &MAM) {
-
+  MAM.getResult<AssignGUIDAnalysis>(M);
   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
   auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
     return FAM.getResult<TargetLibraryAnalysis>(F);
diff --git a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
index 5f872c352429c1..92e8499f73b263 100644
--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -614,11 +614,11 @@ CallBase *llvm::promoteCallWithIfThenElse(CallBase &CB, Function &Callee,
   IndirectBBIns->setIndex(IndirectID);
   IndirectBBIns->insertInto(&IndirectBB, IndirectBB.getFirstInsertionPt());
 
-  const GlobalValue::GUID CalleeGUID = AssignGUIDPass::getGUID(Callee);
+  const GlobalValue::GUID CalleeGUID = Callee.getGUID();
   const uint32_t NewCountersSize = IndirectID + 1;
 
   auto ProfileUpdater = [&](PGOCtxProfContext &Ctx) {
-    assert(Ctx.guid() == AssignGUIDPass::getGUID(Caller));
+    assert(Ctx.guid() == Caller.getGUID());
     assert(NewCountersSize - 2 == Ctx.counters().size());
     // All the ctx-es belonging to a function must have the same size counters.
     Ctx.resizeCounters(NewCountersSize);
diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
index 766c7501550da5..7e2d8ea05ac15c 100644
--- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
@@ -220,8 +220,25 @@ FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,
 void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
 
   ValueInfo VI;
-  if (GV.hasName())
-    VI = ImportIndex.getValueInfo(GV.getGUID());
+  if (auto *F = dyn_cast<Function>(&GV);
+      F && !F->isDeclaration() && !F->isMaterializable()) {
+    VI = ImportIndex.getValueInfo(F->getGUID());
+    // Set synthetic function entry counts.
+    if (VI && ImportIndex.hasSyntheticEntryCounts()) {
+      for (const auto &S : VI.getSummaryList()) {
+        auto *FS = cast<FunctionSummary>(S->getBaseObject());
+        if (FS->modulePath() == M.getModuleIdentifier()) {
+          F->setEntryCount(Function::ProfileCount(FS->entryCount(),
+                                                  Function::PCT_Synthetic));
+          break;
+        }
+      }
+    }
+  }
+  if (auto *GA = dyn_cast<GlobalAlias>(&GV))
+    VI = ImportIndex.getValueInfo(GA->getGUID());
+  if (auto *GVar = dyn_cast<GlobalVariable>(&GV))
+    VI = ImportIndex.getValueInfo(GVar->getGUID());
 
   // We should always have a ValueInfo (i.e. GV in index) for definitions when
   // we are exporting, and also when importing that value.
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 2e05fa80464b8d..c446525b789c0d 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2274,7 +2274,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
   // Get some preliminary data about the callsite before it might get inlined.
   // Inlining shouldn't delete the callee, but it's cleaner (and low-cost) to
   // get this data upfront and rely less on InlineFunction's behavior.
-  const auto CalleeGUID = AssignGUIDPass::getGUID(Callee);
+  const auto CalleeGUID = Callee.getGUID();
   auto *CallsiteIDIns = CtxProfAnalysis::getCallsiteInstrumentation(CB);
   const auto CallsiteID =
       static_cast<uint32_t>(CallsiteIDIns->getIndex()->getZExtValue());
@@ -2299,7 +2299,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
   const uint32_t NewCountersSize = CtxProf.getNumCounters(Caller);
 
   auto Updater = [&](PGOCtxProfContext &Ctx) {
-    assert(Ctx.guid() == AssignGUIDPass::getGUID(Caller));
+    assert(Ctx.guid() == Caller.getGUID());
     const auto &[CalleeCounterMap, CalleeCallsiteMap] = IndicesMaps;
     assert(
         (Ctx.counters().size() +
diff --git a/llvm/test/ThinLTO/X86/weak_resolution.ll b/llvm/test/ThinLTO/X86/weak_resolution.ll
index 15db40a65fcb84..272baf1eaf3e52 100644
--- a/llvm/test/ThinLTO/X86/weak_resolution.ll
+++ b/llvm/test/ThinLTO/X86/weak_resolution.ll
@@ -91,7 +91,7 @@ entry:
 ; MOD1: define weak void @linkoncefunc()
 ;; New LTO API will use dso_local
 ; MOD1-INT: define weak{{.*}} void @linkoncefunc()
-; MOD2: declare void @linkoncefunc()
+; MOD2: declare !guid !7 void @linkoncefunc()
 define linkonce void @linkoncefunc() #0 {
 entry:
   ret void
@@ -103,7 +103,7 @@ entry:
   ret void
 }
 ; MOD1: define weak void @weakfunc()
-; MOD2: declare void @weakfunc()
+; MOD2: declare !guid !11 void @weakfunc()
 define weak void @weakfunc() #0 {
 entry:
   ret void
diff --git a/llvm/test/ThinLTO/X86/windows-vftable.ll b/llvm/test/ThinLTO/X86/windows-vftable.ll
index c38c10fc3e9c64..ee9da37a5be4be 100644
--- a/llvm/test/ThinLTO/X86/windows-vftable.ll
+++ b/llvm/test/ThinLTO/X86/windows-vftable.ll
@@ -9,8 +9,8 @@
 
 ; CHECK: @anon = private unnamed_addr constant { [2 x ptr] } { [2 x ptr] [ptr null, ptr @"??_Gbad_array_new_length at stdext@@UEAAPEAXI at Z"] }, comdat($"??_7bad_array_new_length at stdext@@6B@")
 ; CHECK: @"??_7bad_array_new_length at stdext@@6B@" = unnamed_addr alias ptr, getelementptr inbounds ({ [4 x ptr] }, ptr @anon, i32 0, i32 0, i32 1){{$}}
-; CHECK: define available_externally dso_local noundef ptr @"??_Gbad_array_new_length at stdext@@UEAAPEAXI at Z"(ptr noundef nonnull %this) {
-; CHECK: define available_externally dso_local void @"?_Throw_bad_array_new_length at std@@YAXXZ"(ptr noundef nonnull %0) unnamed_addr {
+; CHECK: define available_externally dso_local noundef ptr @"??_Gbad_array_new_length at stdext@@UEAAPEAXI at Z"(ptr noundef nonnull %this)
+; CHECK: define available_externally dso_local void @"?_Throw_bad_array_new_length at std@@YAXXZ"(ptr noundef nonnull %0) unnamed_addr
 
 target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.26.0"
diff --git a/llvm/test/ThinLTO/X86/writeonly.ll b/llvm/test/ThinLTO/X86/writeonly.ll
index 65c93a79afa909..cb61a3df2ac099 100644
--- a/llvm/test/ThinLTO/X86/writeonly.ll
+++ b/llvm/test/ThinLTO/X86/writeonly.ll
@@ -11,8 +11,8 @@
 ; RUN: llvm-dis %t1.imported.bc -o - | FileCheck %s --check-prefix=IMPORT
 ; RUN: llvm-lto -thinlto-action=optimize %t1.imported.bc -o - | llvm-dis - -o - | FileCheck %s --check-prefix=OPTIMIZE
 
-; IMPORT:      @gBar = internal local_unnamed_addr global i32 0, align 4, !dbg !0
-; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4, !dbg !5
+; IMPORT:      @gBar = internal local_unnamed_addr global i32 0, align 4, !dbg !1
+; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 0, align 4, !dbg !7
 ; IMPORT: !DICompileUnit({{.*}})
 
 ; STATS:  2 module-summary-index - Number of live global variables marked write only 
diff --git a/llvm/test/Transforms/EmbedBitcode/embed.ll b/llvm/test/Transforms/EmbedBitcode/embed.ll
index dffb5cf7554772..66a484cf3a265d 100644
--- a/llvm/test/Transforms/EmbedBitcode/embed.ll
+++ b/llvm/test/Transforms/EmbedBitcode/embed.ll
@@ -13,6 +13,6 @@
 ; CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm.metadata"
 
 ;; Make sure the metadata correlates to the .llvm.lto section.
-; CHECK: !llvm.embedded.objects = !{!1}
-; CHECK: !0 = !{}
+; CHECK: !llvm.embedded.objects = !{![[#]]}
+; CHECK: ![[#]] = !{}
 ; CHECK: !{ptr @llvm.embedded.object, !".llvm.lto"}
diff --git a/llvm/test/Transforms/FunctionImport/funcimport.ll b/llvm/test/Transforms/FunctionImport/funcimport.ll
index 8f7e8340d4909a..0c9fe1dd5e3dee 100644
--- a/llvm/test/Transforms/FunctionImport/funcimport.ll
+++ b/llvm/test/Transforms/FunctionImport/funcimport.ll
@@ -44,7 +44,7 @@ entry:
 }
 
 ; Won't import weak alias
-; CHECK-DAG: declare void @weakalias
+; CHECK-DAG: declare !guid ![[#]] void @weakalias
 declare void @weakalias(...) #1
 
 ; External alias imported as available_externally copy of aliasee
@@ -57,8 +57,8 @@ declare void @linkoncealias(...) #1
 ; CHECK-DAG: define available_externally void @linkoncealias()
 
 ; INSTLIMDEF-DAG: Import referencestatics
-; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !thinlto_src_module !0 !thinlto_src_file !1 {
-; INSTLIM5-DAG: declare i32 @referencestatics(...)
+; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
+; INSTLIM5-DAG: declare !guid ![[#]] i32 @referencestatics(...)
 declare i32 @referencestatics(...) #1
 
 ; The import of referencestatics will expose call to staticfunc that
@@ -66,27 +66,27 @@ declare i32 @referencestatics(...) #1
 ; Ensure that the call is to the properly-renamed function.
 ; INSTLIMDEF-DAG: Import staticfunc
 ; INSTLIMDEF-DAG: %call = call i32 @staticfunc.llvm.
-; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm.{{.*}} !thinlto_src_module !0 !thinlto_src_file !1 {
+; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm.{{.*}} !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 
 ; INSTLIMDEF-DAG: Import referenceglobals
-; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) !thinlto_src_module !0 !thinlto_src_file !1 {
+; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 declare i32 @referenceglobals(...) #1
 
 ; The import of referenceglobals will expose call to globalfunc1 that
 ; should in turn be imported.
 ; INSTLIMDEF-DAG: Import globalfunc1
-; CHECK-DAG: define available_externally void @globalfunc1() !thinlto_src_module !0 !thinlto_src_file !1
+; CHECK-DAG: define available_externally void @globalfunc1() !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]]
 
 ; INSTLIMDEF-DAG: Import referencecommon
-; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) !thinlto_src_module !0 !thinlto_src_file !1 {
+; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 declare i32 @referencecommon(...) #1
 
 ; INSTLIMDEF-DAG: Import setfuncptr
-; CHECK-DAG: define available_externally void @setfuncptr() !thinlto_src_module !0 !thinlto_src_file !1 {
+; CHECK-DAG: define available_externally void @setfuncptr() !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 declare void @setfuncptr(...) #1
 
 ; INSTLIMDEF-DAG: Import callfuncptr
-; CHECK-DAG: define available_externally void @callfuncptr() !thinlto_src_module !0 !thinlto_src_file !1 {
+; CHECK-DAG: define available_externally void @callfuncptr() !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 declare void @callfuncptr(...) #1
 
 ; Ensure that all uses of local variable @P which has used in setfuncptr
@@ -97,26 +97,26 @@ declare void @callfuncptr(...) #1
 
 ; Ensure that @referencelargelinkonce definition is pulled in, but later we
 ; also check that the linkonceodr function is not.
-; CHECK-DAG: define available_externally void @referencelargelinkonce() !thinlto_src_module !0 !thinlto_src_file !1 {
-; INSTLIM5-DAG: declare void @linkonceodr()
+; CHECK-DAG: define available_externally void @referencelargelinkonce() !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
+; INSTLIM5-DAG: declare !guid ![[#]] void @linkonceodr()
 declare void @referencelargelinkonce(...)
 
 ; Won't import weak func
-; CHECK-DAG: declare void @weakfunc(...)
+; CHECK-DAG: declare !guid ![[#]] void @weakfunc(...)
 declare void @weakfunc(...) #1
 
 ; Won't import linkonce func
-; CHECK-DAG: declare void @linkoncefunc2(...)
+; CHECK-DAG: declare !guid ![[#]] void @linkoncefunc2(...)
 declare void @linkoncefunc2(...) #1
 
 ; INSTLIMDEF-DAG: Import funcwithpersonality
-; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality ptr @__gxx_personality_v0 !thinlto_src_module !0 !thinlto_src_file !1 {
+; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality ptr @__gxx_personality_v0 !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 ; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}()
 
 ; We can import variadic functions without a va_start, since the inliner
 ; can handle them.
 ; INSTLIMDEF-DAG: Import variadic_no_va_start
-; CHECK-DAG: define available_externally void @variadic_no_va_start(...) !thinlto_src_module !0 !thinlto_src_file !1 {
+; CHECK-DAG: define available_externally void @variadic_no_va_start(...) !guid ![[#]] !thinlto_src_module ![[F1:#]] !thinlto_src_file ![[F2:#]] {
 declare void @variadic_no_va_start(...)
 
 ; We can import variadic functions with a va_start, since the inliner
diff --git a/llvm/test/Transforms/FunctionImport/funcimport_cutoff.ll b/llvm/test/Transforms/FunctionImport/funcimport_cutoff.ll
index 168afd3ca8784f..3ee0104ac1ba7c 100644
--- a/llvm/test/Transforms/FunctionImport/funcimport_cutoff.ll
+++ b/llvm/test/Transforms/FunctionImport/funcimport_cutoff.ll
@@ -38,10 +38,10 @@ declare void @bar()
 ; Check -S output
 ; IMPORT-DAG: define available_externally void @foo()
 ; IMPORT-DAG: define available_externally void @bar()
-; NOIMPORT-DAG: declare void @foo()
-; NOIMPORT-DAG: declare void @bar()
+; NOIMPORT-DAG: declare !guid ![[#]] void @foo()
+; NOIMPORT-DAG: declare !guid ![[#]] void @bar()
 ; IMPORT1-DAG: define available_externally void @foo()
-; IMPORT1-DAG: declare void @bar()
+; IMPORT1-DAG: declare !guid ![[#]] void @bar()
 
 ; Check -stats output
 ; IMPORT: 2 function-import - Number of functions imported
diff --git a/llvm/test/Transforms/FunctionImport/funcimport_forcecold.ll b/llvm/test/Transforms/FunctionImport/funcimport_forcecold.ll
index b0289974521502..d40fed6a999b82 100644
--- a/llvm/test/Transforms/FunctionImport/funcimport_forcecold.ll
+++ b/llvm/test/Transforms/FunctionImport/funcimport_forcecold.ll
@@ -32,5 +32,5 @@ entry:
 ; IMPORT: Import foo
 ; NOIMPORT-NOT: Import foo
 ; IMPORT: define available_externally void @foo()
-; NOIMPORT: declare void @foo()
+; NOIMPORT: declare !guid ![[#]] void @foo()
 declare void @foo()
diff --git a/llvm/test/Transforms/FunctionImport/funcimport_forcecold_samplepgo.ll b/llvm/test/Transforms/FunctionImport/funcimport_forcecold_samplepgo.ll
index 43b8e88783eccf..69bbcee308e18b 100644
--- a/llvm/test/Transforms/FunctionImport/funcimport_forcecold_samplepgo.ll
+++ b/llvm/test/Transforms/FunctionImport/funcimport_forcecold_samplepgo.ll
@@ -31,7 +31,7 @@ entry:
 ; IMPORT: Import foo
 ; NOIMPORT-NOT: Import foo
 ; IMPORT: define available_externally void @foo()
-; NOIMPORT: declare void @foo()
+; NOIMPORT: declare !guid ![[#]] void @foo()
 declare void @foo()
 
 !1 = !{!"function_entry_count", i64 110, i64 6699318081062747564}
diff --git a/llvm/test/Transforms/FunctionImport/inlineasm.ll b/llvm/test/Transforms/FunctionImport/inlineasm.ll
index 39c384d1229694..c31dc90e158b87 100644
--- a/llvm/test/Transforms/FunctionImport/inlineasm.ll
+++ b/llvm/test/Transforms/FunctionImport/inlineasm.ll
@@ -15,5 +15,5 @@ entry:
   ret i32 0
 }
 
-; CHECK: declare void @foo(ptr)
+; CHECK: declare !guid ![[#]] void @foo(ptr)
 declare void @foo(ptr) #1
diff --git a/llvm/test/Transforms/FunctionImport/noinline.ll b/llvm/test/Transforms/FunctionImport/noinline.ll
index 8687f1b3b5f7cc..1d8efe3095afab 100644
--- a/llvm/test/Transforms/FunctionImport/noinline.ll
+++ b/llvm/test/Transforms/FunctionImport/noinline.ll
@@ -18,6 +18,6 @@ entry:
   ret i32 0
 }
 
-; NOIMPORT: declare void @foo(ptr)
+; NOIMPORT: declare !guid ![[#]] void @foo(ptr)
 ; IMPORT: define available_externally void @foo
 declare void @foo(ptr) #1
diff --git a/llvm/test/Transforms/PGOProfile/comdat_rename.ll b/llvm/test/Transforms/PGOProfile/comdat_rename.ll
index 489c315efc853a..2db1acefa05e8b 100644
--- a/llvm/test/Transforms/PGOProfile/comdat_rename.ll
+++ b/llvm/test/Transforms/PGOProfile/comdat_rename.ll
@@ -51,7 +51,7 @@ define linkonce void @tf2() comdat($tf) {
 ; CHECK: @aef = weak alias void (), ptr @aef.[[SINGLEBB_HASH]]
 
 define available_externally void @aef() {
-; CHECK: define linkonce_odr void @aef.[[SINGLEBB_HASH]]() comdat {
+; CHECK: define linkonce_odr void @aef.[[SINGLEBB_HASH]]() comdat !guid ![[#]] {
   ret void
 }
 
diff --git a/llvm/test/Transforms/PGOProfile/counter_promo_sampling.ll b/llvm/test/Transforms/PGOProfile/counter_promo_sampling.ll
index 9d083fe04015e6..32ad2fbf0396e9 100644
--- a/llvm/test/Transforms/PGOProfile/counter_promo_sampling.ll
+++ b/llvm/test/Transforms/PGOProfile/counter_promo_sampling.ll
@@ -7,7 +7,7 @@ define void @foo(i32 %n, i32 %N) {
 ; SAMPLING-LABEL: @foo
 ; SAMPLING:  %[[VV0:[0-9]+]] = load i16, ptr @__llvm_profile_sampling, align 2
 ; SAMPLING:  %[[VV1:[0-9]+]] = icmp ule i16 %[[VV0]], 200
-; SAMPLING:  br i1 %[[VV1]], label {{.*}}, label {{.*}}, !prof !0
+; SAMPLING:  br i1 %[[VV1]], label {{.*}}, label {{.*}}, !prof !1
 ; SAMPLING: {{.*}} = load {{.*}} @__profc_foo{{.*}} 3)
 ; SAMPLING-NEXT: add
 ; SAMPLING-NEXT: store {{.*}}@__profc_foo{{.*}}3)
@@ -75,4 +75,4 @@ bb12:
 
 declare void @bar(i32)
 
-; SAMPLING: !0 = !{!"branch_weights", i32 200, i32 65336}
+; SAMPLING: !1 = !{!"branch_weights", i32 200, i32 65336}
diff --git a/llvm/test/Transforms/PGOProfile/cspgo_profile_summary.ll b/llvm/test/Transforms/PGOProfile/cspgo_profile_summary.ll
index 7040bac6a4c43f..841551b2615c80 100644
--- a/llvm/test/Transforms/PGOProfile/cspgo_profile_summary.ll
+++ b/llvm/test/Transforms/PGOProfile/cspgo_profile_summary.ll
@@ -134,7 +134,7 @@ entry:
 ; PGOSUMMARY: {{![0-9]+}} = !{!"NumFunctions", i64 8}
 ; PGOSUMMARY-DAG: ![[BW_PGO_BAR]] = !{!"branch_weights", i32 100000, i32 100000}
 
-; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", !1}
+; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", ![[#]]}
 ; CSPGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"InstrProf"}
 ; CSPGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 2100001}
 ; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 800000}
diff --git a/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll b/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll
index c94c2b4da57a98..e21903f2fcc76f 100644
--- a/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll
+++ b/llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4
 ; RUN: opt -passes=ctx-instr-gen -profile-context-root=an_entrypoint \
 ; RUN:   -S < %s | FileCheck --check-prefix=INSTRUMENT %s
-; RUN: opt -passes=ctx-instr-gen,assign-guid,ctx-instr-lower -profile-context-root=an_entrypoint \
+; RUN: opt -passes=ctx-instr-gen,ctx-instr-lower -profile-context-root=an_entrypoint \
 ; RUN:   -profile-context-root=another_entrypoint_no_callees \
 ; RUN:   -S < %s | FileCheck --check-prefix=LOWERING %s
 
@@ -16,7 +16,7 @@ declare void @bar()
 ;.
 define void @foo(i32 %a, ptr %fct) {
 ; INSTRUMENT-LABEL: define void @foo(
-; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) {
+; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) !guid [[META1:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 0)
 ; INSTRUMENT-NEXT:    [[T:%.*]] = icmp eq i32 [[A]], 0
 ; INSTRUMENT-NEXT:    br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]]
@@ -33,7 +33,7 @@ define void @foo(i32 %a, ptr %fct) {
 ; INSTRUMENT-NEXT:    ret void
 ;
 ; LOWERING-LABEL: define void @foo(
-; LOWERING-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) !guid [[META0:![0-9]+]] {
+; LOWERING-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) !guid [[META1:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @foo, i64 6699318081062747564, i32 2, i32 2)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], 1
@@ -78,7 +78,7 @@ exit:
 
 define void @an_entrypoint(i32 %a) {
 ; INSTRUMENT-LABEL: define void @an_entrypoint(
-; INSTRUMENT-SAME: i32 [[A:%.*]]) {
+; INSTRUMENT-SAME: i32 [[A:%.*]]) !guid [[META2:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 0)
 ; INSTRUMENT-NEXT:    [[T:%.*]] = icmp eq i32 [[A]], 0
 ; INSTRUMENT-NEXT:    br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]]
@@ -91,7 +91,7 @@ define void @an_entrypoint(i32 %a) {
 ; INSTRUMENT-NEXT:    ret void
 ;
 ; LOWERING-LABEL: define void @an_entrypoint(
-; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META1:![0-9]+]] {
+; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META2:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @an_entrypoint_ctx_root, i64 4909520559318251808, i32 2, i32 1)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], 1
@@ -130,7 +130,7 @@ no:
 
 define void @another_entrypoint_no_callees(i32 %a) {
 ; INSTRUMENT-LABEL: define void @another_entrypoint_no_callees(
-; INSTRUMENT-SAME: i32 [[A:%.*]]) {
+; INSTRUMENT-SAME: i32 [[A:%.*]]) !guid [[META3:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 0)
 ; INSTRUMENT-NEXT:    [[T:%.*]] = icmp eq i32 [[A]], 0
 ; INSTRUMENT-NEXT:    br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]]
@@ -141,7 +141,7 @@ define void @another_entrypoint_no_callees(i32 %a) {
 ; INSTRUMENT-NEXT:    ret void
 ;
 ; LOWERING-LABEL: define void @another_entrypoint_no_callees(
-; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META2:![0-9]+]] {
+; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META3:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @another_entrypoint_no_callees_ctx_root, i64 -6371873725078000974, i32 2, i32 0)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], -2
@@ -170,12 +170,12 @@ no:
 
 define void @simple(i32 %a) {
 ; INSTRUMENT-LABEL: define void @simple(
-; INSTRUMENT-SAME: i32 [[A:%.*]]) {
+; INSTRUMENT-SAME: i32 [[A:%.*]]) !guid [[META4:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @simple, i64 742261418966908927, i32 1, i32 0)
 ; INSTRUMENT-NEXT:    ret void
 ;
 ; LOWERING-LABEL: define void @simple(
-; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META3:![0-9]+]] {
+; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META4:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @simple, i64 -3006003237940970099, i32 1, i32 0)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], -2
@@ -188,7 +188,7 @@ define void @simple(i32 %a) {
 
 define i32 @no_callsites(i32 %a) {
 ; INSTRUMENT-LABEL: define i32 @no_callsites(
-; INSTRUMENT-SAME: i32 [[A:%.*]]) {
+; INSTRUMENT-SAME: i32 [[A:%.*]]) !guid [[META5:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 0)
 ; INSTRUMENT-NEXT:    [[C:%.*]] = icmp eq i32 [[A]], 0
 ; INSTRUMENT-NEXT:    br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]]
@@ -199,7 +199,7 @@ define i32 @no_callsites(i32 %a) {
 ; INSTRUMENT-NEXT:    ret i32 0
 ;
 ; LOWERING-LABEL: define i32 @no_callsites(
-; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META4:![0-9]+]] {
+; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META5:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @no_callsites, i64 5679753335911435902, i32 2, i32 0)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], -2
@@ -224,14 +224,15 @@ no:
 }
 
 define void @no_counters() {
-; INSTRUMENT-LABEL: define void @no_counters() {
+; INSTRUMENT-LABEL: define void @no_counters(
+; INSTRUMENT-SAME: ) !guid [[META6:![0-9]+]] {
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.increment(ptr @no_counters, i64 742261418966908927, i32 1, i32 0)
 ; INSTRUMENT-NEXT:    call void @llvm.instrprof.callsite(ptr @no_counters, i64 742261418966908927, i32 1, i32 0, ptr @bar)
 ; INSTRUMENT-NEXT:    call void @bar()
 ; INSTRUMENT-NEXT:    ret void
 ;
 ; LOWERING-LABEL: define void @no_counters(
-; LOWERING-SAME: ) !guid [[META5:![0-9]+]] {
+; LOWERING-SAME: ) !guid [[META6:![0-9]+]] {
 ; LOWERING-NEXT:    [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @no_counters, i64 5458232184388660970, i32 1, i32 1)
 ; LOWERING-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64
 ; LOWERING-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], 1
@@ -251,15 +252,24 @@ define void @no_counters() {
   ret void
 }
 ;.
+; INSTRUMENT: attributes #[[ATTR0:[0-9]+]] = { nounwind }
+;.
 ; LOWERING: attributes #[[ATTR0:[0-9]+]] = { nounwind }
 ; LOWERING: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
 ;.
-; INSTRUMENT: attributes #[[ATTR0:[0-9]+]] = { nounwind }
+; INSTRUMENT: [[META0:![0-9]+]] = !{i64 -2012135647395072713}
+; INSTRUMENT: [[META1]] = !{i64 6699318081062747564}
+; INSTRUMENT: [[META2]] = !{i64 4909520559318251808}
+; INSTRUMENT: [[META3]] = !{i64 -6371873725078000974}
+; INSTRUMENT: [[META4]] = !{i64 -3006003237940970099}
+; INSTRUMENT: [[META5]] = !{i64 5679753335911435902}
+; INSTRUMENT: [[META6]] = !{i64 5458232184388660970}
 ;.
-; LOWERING: [[META0]] = !{i64 6699318081062747564}
-; LOWERING: [[META1]] = !{i64 4909520559318251808}
-; LOWERING: [[META2]] = !{i64 -6371873725078000974}
-; LOWERING: [[META3]] = !{i64 -3006003237940970099}
-; LOWERING: [[META4]] = !{i64 5679753335911435902}
-; LOWERING: [[META5]] = !{i64 5458232184388660970}
+; LOWERING: [[META0:![0-9]+]] = !{i64 -2012135647395072713}
+; LOWERING: [[META1]] = !{i64 6699318081062747564}
+; LOWERING: [[META2]] = !{i64 4909520559318251808}
+; LOWERING: [[META3]] = !{i64 -6371873725078000974}
+; LOWERING: [[META4]] = !{i64 -3006003237940970099}
+; LOWERING: [[META5]] = !{i64 5679753335911435902}
+; LOWERING: [[META6]] = !{i64 5458232184388660970}
 ;.
diff --git a/llvm/test/Transforms/PGOProfile/select2.ll b/llvm/test/Transforms/PGOProfile/select2.ll
index d79e3ebcafa4e1..02e91db7247550 100644
--- a/llvm/test/Transforms/PGOProfile/select2.ll
+++ b/llvm/test/Transforms/PGOProfile/select2.ll
@@ -5,7 +5,7 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
 target triple = "x86_64-unknown-linux-gnu"
 
 define i32 @foo(i32 %n) {
-;USE: define i32 @foo(i32 %n) !prof ![[ENTRY_COUNT:[0-9]+]] {
+;USE: define i32 @foo(i32 %n) !prof ![[ENTRY_COUNT:[0-9]+]] !guid ![[#]] {
 entry:
   br label %for.cond
 
diff --git a/llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll b/llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll
index d2f4696ccf41d7..3947d85ed68647 100644
--- a/llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll
+++ b/llvm/test/Transforms/PGOProfile/thinlto_indirect_call_promotion.ll
@@ -23,8 +23,8 @@
 
 ; Test that callee with local linkage has `PGOFuncName` metadata while callee with external doesn't have it.
 ; RUN: llvm-dis lib.bc -o - | FileCheck %s --check-prefix=PGOName
-; PGOName-DAG: define void @_Z7callee1v() {{.*}} !prof ![[#]] {
-; PGOName-DAG: define internal void @_ZL7callee0v() {{.*}} !prof ![[#]] !PGOFuncName ![[#MD:]] {
+; PGOName-DAG: define void @_Z7callee1v() {{.*}} !prof ![[#]] !guid ![[#]] {
+; PGOName-DAG: define internal void @_ZL7callee0v() {{.*}} !prof ![[#]] !guid ![[#]] !PGOFuncName ![[#MD:]] {
 ; The source filename of `lib.ll` is specified as "lib.cc" (i.e., the name does
 ; not change with the directory), so match the full name here.
 ; PGOName: ![[#MD]] = !{!"lib.cc;_ZL7callee0v"}
diff --git a/llvm/test/Transforms/PGOProfile/thinlto_samplepgo_icp.ll b/llvm/test/Transforms/PGOProfile/thinlto_samplepgo_icp.ll
index e04da9336b8e82..51b3eddf0b187a 100644
--- a/llvm/test/Transforms/PGOProfile/thinlto_samplepgo_icp.ll
+++ b/llvm/test/Transforms/PGOProfile/thinlto_samplepgo_icp.ll
@@ -4,7 +4,7 @@
 ; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
 
 ; Checks if calls to static target functions are properly imported and promoted
-; by ICP. Note that the GUID in the profile is from the oroginal name.
+; by ICP. Note that the GUID in the profile is from the original name.
 ; RUN: opt -passes=function-import -summary-file %t3.thinlto.bc %t.bc -o %t4.bc -print-imports 2>&1 | FileCheck %s --check-prefix=IMPORTS
 ; IMPORTS: Import _ZL3foov.llvm.0
 ; RUN: opt %t4.bc -icp-lto -passes=pgo-icall-prom -S | FileCheck %s --check-prefix=ICALL-PROM
diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
index 8b4ef0820debcd..6f90658a5587ba 100644
--- a/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
+++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
@@ -30,7 +30,7 @@
 
 $g = comdat any
 
-; M0: @g = external global i8{{$}}
+; M0: @g = external global i8, !guid !0{{$}}
 ; M1: @g = global i8 42, comdat, !type !0
 @g = global i8 42, comdat, !type !0
 
diff --git a/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll b/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll
index c27b4b34ac04e2..58099a384658c2 100644
--- a/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll
+++ b/llvm/test/Transforms/WholeProgramDevirt/export-single-impl.ll
@@ -64,16 +64,16 @@ $vf4 = comdat largest
 @vt1 = constant ptr @vf1, !type !0
 
 ; CHECK: @vt2 = constant ptr @vf2
- at vt2 = constant ptr @vf2, !type !1
+ at vt2 = constant ptr @vf2, !type !2
 
- at vt3 = constant ptr @vf3, !type !2
+ at vt3 = constant ptr @vf3, !type !4
 
 ; CHECK: @vt4 = constant ptr @vf4.llvm.merged, comdat($vf4.llvm.merged)
- at vt4 = constant ptr @vf4, comdat($vf4), !type !3
+ at vt4 = constant ptr @vf4, comdat($vf4), !type !6
 
- at vt5 = constant ptr @vf5, !type !4
+ at vt5 = constant ptr @vf5, !type !8
 
-; CHECK: declare void @vf1(ptr)
+; CHECK: declare !guid !11 void @vf1(ptr)
 declare void @vf1(ptr)
 
 ; CHECK: define void @vf2(ptr %0)
@@ -81,12 +81,12 @@ define void @vf2(ptr) {
   ret void
 }
 
-; CHECK: define hidden void @vf3.llvm.merged(ptr %0) {
+; CHECK: define hidden void @vf3.llvm.merged(ptr %0) !guid !13 {
 define internal void @vf3(ptr) {
   ret void
 }
 
-; CHECK: define hidden void @vf4.llvm.merged(ptr %0) comdat {
+; CHECK: define hidden void @vf4.llvm.merged(ptr %0) comdat !guid !14 {
 define internal void @vf4(ptr) comdat {
   ret void
 }
@@ -94,8 +94,8 @@ define internal void @vf4(ptr) comdat {
 declare void @vf5(ptr)
 
 !0 = !{i32 0, !"typeid1"}
-!1 = !{i32 0, !"typeid2"}
-!2 = !{i32 0, !"typeid3"}
-!3 = !{i32 0, !"typeid4"}
-!4 = !{i32 0, !5}
-!5 = distinct !{}
+!2 = !{i32 0, !"typeid2"}
+!4 = !{i32 0, !"typeid3"}
+!6 = !{i32 0, !"typeid4"}
+!8 = !{i32 0, !9}
+!9 = distinct !{}
diff --git a/llvm/test/Transforms/WholeProgramDevirt/export-vcp.ll b/llvm/test/Transforms/WholeProgramDevirt/export-vcp.ll
index 24aba548ea9ac6..03dfdbf8314f9d 100644
--- a/llvm/test/Transforms/WholeProgramDevirt/export-vcp.ll
+++ b/llvm/test/Transforms/WholeProgramDevirt/export-vcp.ll
@@ -60,10 +60,10 @@ target datalayout = "e-p:64:64"
 ; CHECK: [[CVT3D:.*]] = private constant { [8 x i8], ptr, [0 x i8] } { [8 x i8] c"\00\00\00\00\00\00\00\01", ptr @vf1i1, [0 x i8] zeroinitializer }, !type !0
 @vt3d = constant ptr @vf1i1, !type !0
 
-; CHECK: [[CVT4A:.*]] = private constant { [8 x i8], ptr, [0 x i8] } { [8 x i8] c"\00\00\00\00\01\00\00\00", ptr @vf1i32, [0 x i8] zeroinitializer }, !type !1
+; CHECK: [[CVT4A:.*]] = private constant { [8 x i8], ptr, [0 x i8] } { [8 x i8] c"\00\00\00\00\01\00\00\00", ptr @vf1i32, [0 x i8] zeroinitializer }, !type !5
 @vt4a = constant ptr @vf1i32, !type !1
 
-; CHECK: [[CVT4B:.*]] = private constant { [8 x i8], ptr, [0 x i8] } { [8 x i8] c"\00\00\00\00\02\00\00\00", ptr @vf2i32, [0 x i8] zeroinitializer }, !type !1
+; CHECK: [[CVT4B:.*]] = private constant { [8 x i8], ptr, [0 x i8] } { [8 x i8] c"\00\00\00\00\02\00\00\00", ptr @vf2i32, [0 x i8] zeroinitializer }, !type !5
 @vt4b = constant ptr @vf2i32, !type !1
 
 ; X86: @__typeid_typeid3_0_12_24_byte = hidden alias i8, inttoptr (i32 -1 to ptr)
@@ -96,7 +96,7 @@ define i32 @vf2i32(ptr %this, i32, i32) readnone {
 }
 
 ; CHECK: !0 = !{i32 8, !"typeid3"}
-; CHECK: !1 = !{i32 8, !"typeid4"}
+; CHECK: !5 = !{i32 8, !"typeid4"}
 
 !0 = !{i32 0, !"typeid3"}
 !1 = !{i32 0, !"typeid4"}
diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
index e4fc3816cd0c45..f56b321539a742 100644
--- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp
+++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp
@@ -410,17 +410,18 @@ void ProfiledBinary::decodePseudoProbe(const ELFObjectFileBase *Obj) {
       FuncStartAddresses = SymbolStartAddrs;
     } else {
       for (auto &F : DisassembleFunctionSet) {
-        auto GUID = Function::getGUID(F.first());
+        auto GUID = GlobalValue::getGUIDForExternalLinkageValue(F.first());
         if (auto StartAddr = SymbolStartAddrs.lookup(GUID)) {
           FuncStartAddresses[GUID] = StartAddr;
           FuncRange &Range = StartAddrToFuncRangeMap[StartAddr];
-          GuidFilter.insert(Function::getGUID(Range.getFuncName()));
+          GuidFilter.insert(
+              GlobalValue::getGUIDForExternalLinkageValue(Range.getFuncName()));
         }
       }
     }
   } else {
     for (auto *F : ProfiledFunctions) {
-      GuidFilter.insert(Function::getGUID(F->FuncName));
+      GuidFilter.insert(GlobalValue::getGUIDForExternalLinkageValue(F->FuncName));
       for (auto &Range : F->Ranges) {
         auto GUIDs = StartAddrToSymMap.equal_range(Range.first);
         for (const auto &[StartAddr, Func] : make_range(GUIDs))
@@ -775,7 +776,7 @@ void ProfiledBinary::populateElfSymbolAddressList(
   for (const SymbolRef &Symbol : Obj->symbols()) {
     const uint64_t Addr = unwrapOrError(Symbol.getAddress(), FileName);
     const StringRef Name = unwrapOrError(Symbol.getName(), FileName);
-    uint64_t GUID = Function::getGUID(Name);
+    uint64_t GUID = GlobalValue::getGUIDForExternalLinkageValue(Name);
     SymbolStartAddrs[GUID] = Addr;
     StartAddrToSymMap.emplace(Addr, GUID);
   }



More information about the llvm-commits mailing list