[llvm] Move a lot of symbol code to use the symbol string pool (PR #115796)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 3 22:27:14 PST 2024


https://github.com/lhames updated https://github.com/llvm/llvm-project/pull/115796

>From ef474926bb899bb5eb5ad9afe553c4828b1d8e94 Mon Sep 17 00:00:00 2001
From: jared w <jared.wyles at gmail.com>
Date: Thu, 28 Nov 2024 18:30:29 +1100
Subject: [PATCH 01/16] [jit] Moving all the symbol instances to be backed by a
 single pool this reduces the amount of string comparisons we have to do.

Mostly a lot of api changes to plump through the string pool instances.
---
 .gitignore                                    |   2 +
 bolt/include/bolt/Core/BinaryContext.h        |  19 ++-
 bolt/lib/Core/BinaryContext.cpp               |  10 +-
 bolt/lib/Rewrite/DWARFRewriter.cpp            |   3 +-
 bolt/lib/Rewrite/JITLinkLinker.cpp            |  10 +-
 bolt/lib/Rewrite/MachORewriteInstance.cpp     |   3 +-
 bolt/lib/Rewrite/RewriteInstance.cpp          |   3 +-
 bolt/unittests/Core/BinaryContext.cpp         |   5 +-
 bolt/unittests/Core/MCPlusBuilder.cpp         |   3 +-
 .../llvm/ExecutionEngine/JITLink/COFF.h       |   3 +-
 .../ExecutionEngine/JITLink/COFF_x86_64.h     |   4 +-
 .../llvm/ExecutionEngine/JITLink/ELF.h        |   3 +-
 .../ExecutionEngine/JITLink/ELF_aarch32.h     |   4 +-
 .../ExecutionEngine/JITLink/ELF_aarch64.h     |   4 +-
 .../llvm/ExecutionEngine/JITLink/ELF_i386.h   |   3 +-
 .../ExecutionEngine/JITLink/ELF_loongarch.h   |   4 +-
 .../llvm/ExecutionEngine/JITLink/ELF_ppc64.h  |   7 +-
 .../llvm/ExecutionEngine/JITLink/ELF_riscv.h  |   3 +-
 .../llvm/ExecutionEngine/JITLink/ELF_x86_64.h |   3 +-
 .../llvm/ExecutionEngine/JITLink/JITLink.h    | 148 ++++++++++++------
 .../llvm/ExecutionEngine/JITLink/MachO.h      |   3 +-
 .../ExecutionEngine/JITLink/MachO_arm64.h     |   4 +-
 .../ExecutionEngine/JITLink/MachO_x86_64.h    |   4 +-
 .../ExecutionEngine/JITLink/TableManager.h    |   4 +-
 llvm/include/llvm/ExecutionEngine/Orc/Core.h  |   2 +-
 .../Orc/ExecutorProcessControl.h              |   2 +-
 .../llvm/ExecutionEngine/RuntimeDyldChecker.h |   1 +
 llvm/lib/ExecutionEngine/JITLink/COFF.cpp     |   5 +-
 .../JITLink/COFFLinkGraphBuilder.cpp          |  86 +++++-----
 .../JITLink/COFFLinkGraphBuilder.h            |  20 +--
 .../ExecutionEngine/JITLink/COFF_x86_64.cpp   |  27 ++--
 .../DefineExternalSectionStartAndEndSymbols.h |  18 +--
 .../JITLink/EHFrameSupport.cpp                |   6 +-
 llvm/lib/ExecutionEngine/JITLink/ELF.cpp      |  21 +--
 .../JITLink/ELFLinkGraphBuilder.h             |  14 +-
 .../ExecutionEngine/JITLink/ELF_aarch32.cpp   |  17 +-
 .../ExecutionEngine/JITLink/ELF_aarch64.cpp   |  28 ++--
 llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp |  14 +-
 .../ExecutionEngine/JITLink/ELF_loongarch.cpp |  18 ++-
 .../lib/ExecutionEngine/JITLink/ELF_ppc64.cpp |  35 +++--
 .../lib/ExecutionEngine/JITLink/ELF_riscv.cpp |  14 +-
 .../ExecutionEngine/JITLink/ELF_x86_64.cpp    |  17 +-
 llvm/lib/ExecutionEngine/JITLink/JITLink.cpp  |  38 +++--
 .../JITLink/JITLinkGeneric.cpp                |   5 +-
 .../JITLink/JITLinkMemoryManager.cpp          |   5 +-
 llvm/lib/ExecutionEngine/JITLink/MachO.cpp    |   7 +-
 .../JITLink/MachOLinkGraphBuilder.cpp         |  21 +--
 .../JITLink/MachOLinkGraphBuilder.h           |   8 +-
 .../ExecutionEngine/JITLink/MachO_arm64.cpp   |  11 +-
 .../ExecutionEngine/JITLink/MachO_x86_64.cpp  |   9 +-
 .../JITLink/PerGraphGOTAndPLTStubsBuilder.h   |   8 +-
 llvm/lib/ExecutionEngine/JITLink/aarch32.cpp  |   8 +-
 llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp |   6 +-
 .../Orc/Debugging/DebuggerSupportPlugin.cpp   |   4 +-
 .../Orc/Debugging/PerfSupportPlugin.cpp       |   4 +-
 .../Orc/Debugging/VTuneSupportPlugin.cpp      |   2 +-
 .../ExecutionEngine/Orc/ELFNixPlatform.cpp    |  31 ++--
 .../ExecutionEngine/Orc/ExecutionUtils.cpp    |  10 +-
 .../ExecutionEngine/Orc/IndirectionUtils.cpp  |   2 +-
 .../Orc/JITLinkRedirectableSymbolManager.cpp  |   8 +-
 .../Orc/LazyObjectLinkingLayer.cpp            |   4 +-
 .../lib/ExecutionEngine/Orc/MachOPlatform.cpp |  32 ++--
 .../Orc/ObjectFileInterface.cpp               |   2 +-
 .../Orc/ObjectLinkingLayer.cpp                |  57 +++----
 llvm/lib/ExecutionEngine/Orc/SectCreate.cpp   |   1 +
 .../RuntimeDyld/RuntimeDyldELF.cpp            |   1 +
 .../RuntimeDyld/RuntimeDyldImpl.h             |   1 +
 llvm/tools/llvm-jitlink/llvm-jitlink.cpp      |  50 +++---
 llvm/tools/llvm-jitlink/llvm-jitlink.h        |   7 +-
 .../JITLink/AArch32ErrorTests.cpp             |  10 +-
 .../JITLink/EHFrameSupportTests.cpp           |  10 +-
 .../JITLink/JITLinkTestUtils.cpp              |   7 +-
 .../JITLink/LinkGraphTests.cpp                |  49 ++++--
 .../JITLink/MachOLinkGraphTests.cpp           |   6 +-
 .../JITLink/MemoryManagerErrorTests.cpp       |   7 +-
 .../ExecutionEngine/JITLink/StubsTests.cpp    |  17 +-
 .../Orc/JITLinkRedirectionManagerTest.cpp     |   2 +-
 .../Orc/ObjectLinkingLayerTest.cpp            |  51 +++---
 78 files changed, 636 insertions(+), 469 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0e7c6c79001338..a84268a7f68632 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,8 @@ autoconf/autom4te.cache
 # VS2017 and VSCode config files.
 .vscode
 .vs
+#zed config files
+.zed
 # pythonenv for github Codespaces
 pythonenv*
 # clangd index. (".clangd" is a config file now, thus trailing slash)
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index c9b0e103ed5145..115e59ca0697e5 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -28,6 +28,7 @@
 #include "llvm/ADT/iterator.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
@@ -276,11 +277,10 @@ class BinaryContext {
   void deregisterSectionName(const BinarySection &Section);
 
 public:
-  static Expected<std::unique_ptr<BinaryContext>>
-  createBinaryContext(Triple TheTriple, StringRef InputFileName,
-                      SubtargetFeatures *Features, bool IsPIC,
-                      std::unique_ptr<DWARFContext> DwCtx,
-                      JournalingStreams Logger);
+  static Expected<std::unique_ptr<BinaryContext>> createBinaryContext(
+      Triple TheTriple, std::shared_ptr<orc::SymbolStringPool> SSP,
+      StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC,
+      std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger);
 
   /// Superset of compiler units that will contain overwritten code that needs
   /// new debug info. In a few cases, functions may end up not being
@@ -372,6 +372,7 @@ class BinaryContext {
   bool hasSymbolsWithFileName() const { return HasSymbolsWithFileName; }
   void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = Value; }
 
+  std::shared_ptr<orc::SymbolStringPool> getSymbolStringPool() { return SSP; }
   /// Return true if relocations against symbol with a given name
   /// must be created.
   bool forceSymbolRelocations(StringRef SymbolName) const;
@@ -631,6 +632,8 @@ class BinaryContext {
 
   std::unique_ptr<Triple> TheTriple;
 
+  std::shared_ptr<orc::SymbolStringPool> SSP;
+
   const Target *TheTarget;
 
   std::string TripleName;
@@ -807,8 +810,10 @@ class BinaryContext {
 
   BinaryContext(std::unique_ptr<MCContext> Ctx,
                 std::unique_ptr<DWARFContext> DwCtx,
-                std::unique_ptr<Triple> TheTriple, const Target *TheTarget,
-                std::string TripleName, std::unique_ptr<MCCodeEmitter> MCE,
+                std::unique_ptr<Triple> TheTriple,
+                std::shared_ptr<orc::SymbolStringPool> SSP,
+                const Target *TheTarget, std::string TripleName,
+                std::unique_ptr<MCCodeEmitter> MCE,
                 std::unique_ptr<MCObjectFileInfo> MOFI,
                 std::unique_ptr<const MCAsmInfo> AsmInfo,
                 std::unique_ptr<const MCInstrInfo> MII,
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index a808ece12da19c..3956bfac59bd42 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -123,6 +123,7 @@ void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) {
 BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
                              std::unique_ptr<DWARFContext> DwCtx,
                              std::unique_ptr<Triple> TheTriple,
+                             std::shared_ptr<orc::SymbolStringPool> SSP,
                              const Target *TheTarget, std::string TripleName,
                              std::unique_ptr<MCCodeEmitter> MCE,
                              std::unique_ptr<MCObjectFileInfo> MOFI,
@@ -136,7 +137,7 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
                              std::unique_ptr<MCDisassembler> DisAsm,
                              JournalingStreams Logger)
     : Ctx(std::move(Ctx)), DwCtx(std::move(DwCtx)),
-      TheTriple(std::move(TheTriple)), TheTarget(TheTarget),
+      TheTriple(std::move(TheTriple)), SSP(std::move(SSP)), TheTarget(TheTarget),
       TripleName(TripleName), MCE(std::move(MCE)), MOFI(std::move(MOFI)),
       AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), STI(std::move(STI)),
       InstPrinter(std::move(InstPrinter)), MIA(std::move(MIA)),
@@ -159,8 +160,9 @@ BinaryContext::~BinaryContext() {
 /// Create BinaryContext for a given architecture \p ArchName and
 /// triple \p TripleName.
 Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
-    Triple TheTriple, StringRef InputFileName, SubtargetFeatures *Features,
-    bool IsPIC, std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger) {
+    Triple TheTriple, std::shared_ptr<orc::SymbolStringPool> SSP,
+    StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC,
+    std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger) {
   StringRef ArchName = "";
   std::string FeaturesStr = "";
   switch (TheTriple.getArch()) {
@@ -283,7 +285,7 @@ Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
 
   auto BC = std::make_unique<BinaryContext>(
       std::move(Ctx), std::move(DwCtx), std::make_unique<Triple>(TheTriple),
-      TheTarget, std::string(TripleName), std::move(MCE), std::move(MOFI),
+      std::move(SSP), TheTarget, std::string(TripleName), std::move(MCE), std::move(MOFI),
       std::move(AsmInfo), std::move(MII), std::move(STI),
       std::move(InstructionPrinter), std::move(MIA), nullptr, std::move(MRI),
       std::move(DisAsm), Logger);
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 1b5ba8b49d3637..308881081321a2 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -1691,7 +1691,8 @@ namespace {
 std::unique_ptr<BinaryContext>
 createDwarfOnlyBC(const object::ObjectFile &File) {
   return cantFail(BinaryContext::createBinaryContext(
-      File.makeTriple(), File.getFileName(), nullptr, false,
+      File.makeTriple(), std::make_shared<orc::SymbolStringPool>(),
+      File.getFileName(), nullptr, false,
       DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore,
                            nullptr, "", WithColor::defaultErrorHandler,
                            WithColor::defaultWarningHandler),
diff --git a/bolt/lib/Rewrite/JITLinkLinker.cpp b/bolt/lib/Rewrite/JITLinkLinker.cpp
index be8f9dd03467e1..1d6f8428432d72 100644
--- a/bolt/lib/Rewrite/JITLinkLinker.cpp
+++ b/bolt/lib/Rewrite/JITLinkLinker.cpp
@@ -122,7 +122,7 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext {
     jitlink::AsyncLookupResult AllResults;
 
     for (const auto &Symbol : Symbols) {
-      std::string SymName = Symbol.first.str();
+      std::string SymName = (*Symbol.first).str();
       LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n");
 
       if (auto Address = Linker.lookupSymbol(SymName)) {
@@ -167,7 +167,11 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext {
   Error notifyResolved(jitlink::LinkGraph &G) override {
     for (auto *Symbol : G.defined_symbols()) {
       SymbolInfo Info{Symbol->getAddress().getValue(), Symbol->getSize()};
-      Linker.Symtab.insert({Symbol->getName().str(), Info});
+      auto Name = Symbol->getName();
+      std::string NameStr("");
+      if (Name)
+        NameStr = (*Name).str();
+      Linker.Symtab.insert({NameStr, Info});
     }
 
     return Error::success();
@@ -189,7 +193,7 @@ JITLinkLinker::~JITLinkLinker() { cantFail(MM->deallocate(std::move(Allocs))); }
 
 void JITLinkLinker::loadObject(MemoryBufferRef Obj,
                                SectionsMapper MapSections) {
-  auto LG = jitlink::createLinkGraphFromObject(Obj);
+  auto LG = jitlink::createLinkGraphFromObject(Obj, BC.getSymbolStringPool());
   if (auto E = LG.takeError()) {
     errs() << "BOLT-ERROR: JITLink failed: " << E << '\n';
     exit(1);
diff --git a/bolt/lib/Rewrite/MachORewriteInstance.cpp b/bolt/lib/Rewrite/MachORewriteInstance.cpp
index c328232de61a34..2f05b03290ba3a 100644
--- a/bolt/lib/Rewrite/MachORewriteInstance.cpp
+++ b/bolt/lib/Rewrite/MachORewriteInstance.cpp
@@ -74,7 +74,8 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile,
   ErrorAsOutParameter EAO(&Err);
   Relocation::Arch = InputFile->makeTriple().getArch();
   auto BCOrErr = BinaryContext::createBinaryContext(
-      InputFile->makeTriple(), InputFile->getFileName(), nullptr,
+      InputFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
+      InputFile->getFileName(), nullptr,
       /* IsPIC */ true, DWARFContext::create(*InputFile),
       {llvm::outs(), llvm::errs()});
   if (Error E = BCOrErr.takeError()) {
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 7059a3dd231099..63e18fea92ec52 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -356,7 +356,8 @@ RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc,
 
   Relocation::Arch = TheTriple.getArch();
   auto BCOrErr = BinaryContext::createBinaryContext(
-      TheTriple, File->getFileName(), Features.get(), IsPIC,
+      TheTriple, std::make_shared<orc::SymbolStringPool>(), 
+      File->getFileName(), Features.get(), IsPIC,
       DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore,
                            nullptr, opts::DWPPathName,
                            WithColor::defaultErrorHandler,
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index 05b898d34af56c..fec02d811a632a 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -48,7 +48,8 @@ struct BinaryContextTester : public testing::TestWithParam<Triple::ArchType> {
   void initializeBOLT() {
     Relocation::Arch = ObjFile->makeTriple().getArch();
     BC = cantFail(BinaryContext::createBinaryContext(
-        ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true,
+        ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(), 
+        ObjFile->getFileName(), nullptr, true,
         DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
     ASSERT_FALSE(!BC);
   }
@@ -216,4 +217,4 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) {
       BC->getBaseAddressForMapping(0xaaaaaaab1000, 0x1000);
   ASSERT_TRUE(BaseAddress.has_value());
   ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL);
-}
\ No newline at end of file
+}
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp
index cd6f24c4570a79..5488cae3662845 100644
--- a/bolt/unittests/Core/MCPlusBuilder.cpp
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -58,7 +58,8 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
   void initializeBolt() {
     Relocation::Arch = ObjFile->makeTriple().getArch();
     BC = cantFail(BinaryContext::createBinaryContext(
-        ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true,
+        ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
+        ObjFile->getFileName(), nullptr, true,
         DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
     ASSERT_FALSE(!BC);
     BC->initializeTarget(std::unique_ptr<MCPlusBuilder>(
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/COFF.h b/llvm/include/llvm/ExecutionEngine/JITLink/COFF.h
index 87d3648d37e8ba..33b661933ace83 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/COFF.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/COFF.h
@@ -24,7 +24,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer,
+                              std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// Link the given graph.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/COFF_x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/COFF_x86_64.h
index fff32d6d960933..2072ae9dfdbe70 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/COFF_x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/COFF_x86_64.h
@@ -23,8 +23,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromCOFFObject_x86_64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a COFF x86-64 object file.
 void link_COFF_x86_64(std::unique_ptr<LinkGraph> G,
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
index 038591f9add055..3decba65f380cb 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
@@ -24,7 +24,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer,
+                             std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// Link the given graph.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch32.h
index 25d1c3aac2c26e..b865414e520c29 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch32.h
@@ -24,8 +24,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch32(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be an ELF arm/thumb object
 /// file.
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h
index 50eb598139ea0b..45a7a0100593f3 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_aarch64.h
@@ -25,8 +25,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF aarch64 relocatable
 /// object file.
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_i386.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_i386.h
index 44ebd969946113..0752f214d9d582 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_i386.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_i386.h
@@ -26,7 +26,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer,
+                                  std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF i386 relocatable
 /// object file.
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h
index 4d7655c4b988b7..7e5d0f1f918521 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_loongarch.h
@@ -25,8 +25,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_loongarch(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be an ELF loongarch object
 /// file.
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_ppc64.h
index 8db986a4a9fa15..c5049a54cdf1d5 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_ppc64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_ppc64.h
@@ -25,15 +25,16 @@ namespace llvm::jitlink {
 ///
 /// WARNING: The big-endian backend has not been tested yet.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
+                                   std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// Create a LinkGraph from an ELF/ppc64le relocatable object.
 ///
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_ppc64le(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_ppc64le(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF ppc64le object file.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_riscv.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_riscv.h
index a0e573baca066f..d00b5c2868baf6 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_riscv.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_riscv.h
@@ -26,7 +26,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer,
+                                   std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF riscv object file.
 void link_ELF_riscv(std::unique_ptr<LinkGraph> G,
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
index fbe5765438d240..140dad7b82e002 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
@@ -24,7 +24,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffe,
+                                    std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF x86-64 object file.
 void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 9844214c537a06..838ae45ac9b2cb 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -23,6 +23,7 @@
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/BinaryStreamWriter.h"
@@ -422,10 +423,11 @@ class Symbol {
   friend class LinkGraph;
 
 private:
-  Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset, StringRef Name,
-         orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive,
-         bool IsCallable)
-      : Name(Name), Base(&Base), Offset(Offset), WeakRef(0), Size(Size) {
+  Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset,
+         orc::SymbolStringPtr &&Name, orc::ExecutorAddrDiff Size, Linkage L,
+         Scope S, bool IsLive, bool IsCallable)
+      : Name(std::move(Name)), Base(&Base), Offset(Offset), WeakRef(0),
+        Size(Size) {
     assert(Offset <= MaxOffset && "Offset out of range");
     setLinkage(L);
     setScope(S);
@@ -435,26 +437,29 @@ class Symbol {
   }
 
   static Symbol &constructExternal(BumpPtrAllocator &Allocator,
-                                   Addressable &Base, StringRef Name,
+                                   Addressable &Base,
+                                   orc::SymbolStringPtr &&Name,
                                    orc::ExecutorAddrDiff Size, Linkage L,
                                    bool WeaklyReferenced) {
     assert(!Base.isDefined() &&
            "Cannot create external symbol from defined block");
-    assert(!Name.empty() && "External symbol name cannot be empty");
+    assert(Name && "External symbol name cannot be empty");
     auto *Sym = Allocator.Allocate<Symbol>();
-    new (Sym) Symbol(Base, 0, Name, Size, L, Scope::Default, false, false);
+    new (Sym)
+        Symbol(Base, 0, std::move(Name), Size, L, Scope::Default, false, false);
     Sym->setWeaklyReferenced(WeaklyReferenced);
     return *Sym;
   }
 
   static Symbol &constructAbsolute(BumpPtrAllocator &Allocator,
-                                   Addressable &Base, StringRef Name,
+                                   Addressable &Base,
+                                   orc::SymbolStringPtr &&Name,
                                    orc::ExecutorAddrDiff Size, Linkage L,
                                    Scope S, bool IsLive) {
     assert(!Base.isDefined() &&
            "Cannot create absolute symbol from a defined block");
     auto *Sym = Allocator.Allocate<Symbol>();
-    new (Sym) Symbol(Base, 0, Name, Size, L, S, IsLive, false);
+    new (Sym) Symbol(Base, 0, std::move(Name), Size, L, S, IsLive, false);
     return *Sym;
   }
 
@@ -465,20 +470,22 @@ class Symbol {
     assert((Offset + Size) <= Base.getSize() &&
            "Symbol extends past end of block");
     auto *Sym = Allocator.Allocate<Symbol>();
-    new (Sym) Symbol(Base, Offset, StringRef(), Size, Linkage::Strong,
-                     Scope::Local, IsLive, IsCallable);
+    new (Sym) Symbol(Base, Offset, nullptr, Size, Linkage::Strong, Scope::Local,
+                     IsLive, IsCallable);
     return *Sym;
   }
 
   static Symbol &constructNamedDef(BumpPtrAllocator &Allocator, Block &Base,
-                                   orc::ExecutorAddrDiff Offset, StringRef Name,
+                                   orc::ExecutorAddrDiff Offset,
+                                   orc::SymbolStringPtr Name,
                                    orc::ExecutorAddrDiff Size, Linkage L,
                                    Scope S, bool IsLive, bool IsCallable) {
     assert((Offset + Size) <= Base.getSize() &&
            "Symbol extends past end of block");
-    assert(!Name.empty() && "Name cannot be empty");
+    assert(Name && "Name cannot be empty");
     auto *Sym = Allocator.Allocate<Symbol>();
-    new (Sym) Symbol(Base, Offset, Name, Size, L, S, IsLive, IsCallable);
+    new (Sym)
+        Symbol(Base, Offset, std::move(Name), Size, L, S, IsLive, IsCallable);
     return *Sym;
   }
 
@@ -495,18 +502,19 @@ class Symbol {
   Symbol &operator=(Symbol &&) = delete;
 
   /// Returns true if this symbol has a name.
-  bool hasName() const { return !Name.empty(); }
+  bool hasName() const { return Name != nullptr; }
 
   /// Returns the name of this symbol (empty if the symbol is anonymous).
-  StringRef getName() const {
-    assert((!Name.empty() || getScope() == Scope::Local) &&
+  const orc::SymbolStringPtr &getName() const {
+    assert((hasName() || getScope() == Scope::Local) &&
            "Anonymous symbol has non-local scope");
+
     return Name;
   }
 
   /// Rename this symbol. The client is responsible for updating scope and
   /// linkage if this name-change requires it.
-  void setName(StringRef Name) { this->Name = Name; }
+  void setName(const orc::SymbolStringPtr Name) { this->Name = Name; }
 
   /// Returns true if this Symbol has content (potentially) defined within this
   /// object file (i.e. is anything but an external or absolute symbol).
@@ -613,7 +621,7 @@ class Symbol {
 
   /// Set the linkage for this Symbol.
   void setLinkage(Linkage L) {
-    assert((L == Linkage::Strong || (!Base->isAbsolute() && !Name.empty())) &&
+    assert((L == Linkage::Strong || (!Base->isAbsolute() && Name)) &&
            "Linkage can only be applied to defined named symbols");
     this->L = static_cast<uint8_t>(L);
   }
@@ -623,7 +631,7 @@ class Symbol {
 
   /// Set the visibility for this Symbol.
   void setScope(Scope S) {
-    assert((!Name.empty() || S == Scope::Local) &&
+    assert((hasName() || S == Scope::Local) &&
            "Can not set anonymous symbol to non-local scope");
     assert((S != Scope::Local || Base->isDefined() || Base->isAbsolute()) &&
            "Invalid visibility for symbol type");
@@ -675,8 +683,7 @@ class Symbol {
 
   static constexpr uint64_t MaxOffset = (1ULL << 59) - 1;
 
-  // FIXME: A char* or SymbolStringPtr may pack better.
-  StringRef Name;
+  orc::SymbolStringPtr Name = nullptr;
   Addressable *Base = nullptr;
   uint64_t Offset : 57;
   uint64_t L : 1;
@@ -1001,22 +1008,23 @@ class LinkGraph {
 
   using GetEdgeKindNameFunction = const char *(*)(Edge::Kind);
 
-  LinkGraph(std::string Name, const Triple &TT, SubtargetFeatures Features,
-            unsigned PointerSize, llvm::endianness Endianness,
+  LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
+            const Triple &TT, SubtargetFeatures Features, unsigned PointerSize,
+            llvm::endianness Endianness,
             GetEdgeKindNameFunction GetEdgeKindName)
-      : Name(std::move(Name)), TT(TT), Features(std::move(Features)),
+      : Name(std::move(Name)), SSP(std::move(SSP)), TT(TT), Features(std::move(Features)),
         PointerSize(PointerSize), Endianness(Endianness),
         GetEdgeKindName(std::move(GetEdgeKindName)) {}
 
-  LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
-            llvm::endianness Endianness,
+  LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
+            const Triple &TT, unsigned PointerSize, llvm::endianness Endianness,
             GetEdgeKindNameFunction GetEdgeKindName)
-      : LinkGraph(std::move(Name), TT, SubtargetFeatures(), PointerSize,
+      : LinkGraph(std::move(Name), std::move(SSP), TT, SubtargetFeatures(), PointerSize,
                   Endianness, GetEdgeKindName) {}
 
-  LinkGraph(std::string Name, const Triple &TT,
-            GetEdgeKindNameFunction GetEdgeKindName)
-      : LinkGraph(std::move(Name), TT, SubtargetFeatures(),
+  LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
+            const Triple &TT, GetEdgeKindNameFunction GetEdgeKindName)
+      : LinkGraph(std::move(Name), std::move(SSP), TT, SubtargetFeatures(),
                   Triple::getArchPointerBitWidth(TT.getArch()) / 8,
                   TT.isLittleEndian() ? endianness::little : endianness::big,
                   GetEdgeKindName) {
@@ -1028,6 +1036,7 @@ class LinkGraph {
   LinkGraph &operator=(const LinkGraph &) = delete;
   LinkGraph(LinkGraph &&) = delete;
   LinkGraph &operator=(LinkGraph &&) = delete;
+  ~LinkGraph();
 
   /// Returns the name of this graph (usually the name of the original
   /// underlying MemoryBuffer).
@@ -1047,6 +1056,8 @@ class LinkGraph {
 
   const char *getEdgeKindName(Edge::Kind K) const { return GetEdgeKindName(K); }
 
+  std::shared_ptr<orc::SymbolStringPool> getSymbolStringPool() { return SSP; }
+
   /// Allocate a mutable buffer of the given size using the LinkGraph's
   /// allocator.
   MutableArrayRef<char> allocateBuffer(size_t Size) {
@@ -1260,6 +1271,10 @@ class LinkGraph {
     return splitBlockImpl(std::move(Blocks), Cache);
   }
 
+  //
+  orc::SymbolStringPtr intern(StringRef SymbolName) {
+    return SSP->intern(SymbolName);
+  }
   /// Add an external symbol.
   /// Some formats (e.g. ELF) allow Symbols to have sizes. For Symbols whose
   /// size is not known, you should substitute '0'.
@@ -1268,18 +1283,25 @@ class LinkGraph {
   /// found or an error will be emitted. Externals that are weakly referenced
   /// are permitted to be undefined, in which case they are assigned an address
   /// of 0.
-  Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
+  Symbol &addExternalSymbol(orc::SymbolStringPtr Name,
+                            orc::ExecutorAddrDiff Size,
                             bool IsWeaklyReferenced) {
-    assert(!ExternalSymbols.contains(Name) && "Duplicate external symbol");
+    assert(!ExternalSymbols.contains(*Name) && "Duplicate external symbol");
     auto &Sym = Symbol::constructExternal(
-        Allocator, createAddressable(orc::ExecutorAddr(), false), Name, Size,
-        Linkage::Strong, IsWeaklyReferenced);
-    ExternalSymbols.insert({Sym.getName(), &Sym});
+        Allocator, createAddressable(orc::ExecutorAddr(), false),
+        std::move(Name), Size, Linkage::Strong, IsWeaklyReferenced);
+    ExternalSymbols.insert({*Sym.getName(), &Sym});
     return Sym;
   }
 
+  Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
+                            bool IsWeaklyReferenced) {
+    return addExternalSymbol(SSP->intern(Name), Size, IsWeaklyReferenced);
+  }
+
   /// Add an absolute symbol.
-  Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
+  Symbol &addAbsoluteSymbol(orc::SymbolStringPtr Name,
+                            orc::ExecutorAddr Address,
                             orc::ExecutorAddrDiff Size, Linkage L, Scope S,
                             bool IsLive) {
     assert((S == Scope::Local || llvm::count_if(AbsoluteSymbols,
@@ -1288,11 +1310,18 @@ class LinkGraph {
                                                }) == 0) &&
                                     "Duplicate absolute symbol");
     auto &Sym = Symbol::constructAbsolute(Allocator, createAddressable(Address),
-                                          Name, Size, L, S, IsLive);
+                                          std::move(Name), Size, L, S, IsLive);
     AbsoluteSymbols.insert(&Sym);
     return Sym;
   }
 
+  Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
+                            orc::ExecutorAddrDiff Size, Linkage L, Scope S,
+                            bool IsLive) {
+
+    return addAbsoluteSymbol(SSP->intern(Name), Address, Size, L, S, IsLive);
+  }
+
   /// Add an anonymous symbol.
   Symbol &addAnonymousSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
                              orc::ExecutorAddrDiff Size, bool IsCallable,
@@ -1307,13 +1336,22 @@ class LinkGraph {
   Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
                            StringRef Name, orc::ExecutorAddrDiff Size,
                            Linkage L, Scope S, bool IsCallable, bool IsLive) {
+    return addDefinedSymbol(Content, Offset, SSP->intern(Name), Size, L, S,
+                            IsCallable, IsLive);
+  }
+
+  Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
+                           orc::SymbolStringPtr Name,
+                           orc::ExecutorAddrDiff Size, Linkage L, Scope S,
+                           bool IsCallable, bool IsLive) {
     assert((S == Scope::Local || llvm::count_if(defined_symbols(),
                                                 [&](const Symbol *Sym) {
                                                   return Sym->getName() == Name;
                                                 }) == 0) &&
            "Duplicate defined symbol");
-    auto &Sym = Symbol::constructNamedDef(Allocator, Content, Offset, Name,
-                                          Size, L, S, IsLive, IsCallable);
+    auto &Sym =
+        Symbol::constructNamedDef(Allocator, Content, Offset, std::move(Name),
+                                  Size, L, S, IsLive, IsCallable);
     Content.getSection().addSymbol(Sym);
     return Sym;
   }
@@ -1398,7 +1436,7 @@ class LinkGraph {
       Sec.removeSymbol(Sym);
       Sym.makeExternal(createAddressable(orc::ExecutorAddr(), false));
     }
-    ExternalSymbols.insert({Sym.getName(), &Sym});
+    ExternalSymbols.insert({*Sym.getName(), &Sym});
   }
 
   /// Make the given symbol an absolute with the given address (must not already
@@ -1412,10 +1450,10 @@ class LinkGraph {
   void makeAbsolute(Symbol &Sym, orc::ExecutorAddr Address) {
     assert(!Sym.isAbsolute() && "Symbol is already absolute");
     if (Sym.isExternal()) {
-      assert(ExternalSymbols.contains(Sym.getName()) &&
+      assert(ExternalSymbols.contains(*Sym.getName()) &&
              "Sym is not in the absolute symbols set");
       assert(Sym.getOffset() == 0 && "External is not at offset 0");
-      ExternalSymbols.erase(Sym.getName());
+      ExternalSymbols.erase(*Sym.getName());
       auto &A = Sym.getAddressable();
       A.setAbsolute(true);
       A.setAddress(Address);
@@ -1440,9 +1478,9 @@ class LinkGraph {
              "Symbol is not in the absolutes set");
       AbsoluteSymbols.erase(&Sym);
     } else {
-      assert(ExternalSymbols.contains(Sym.getName()) &&
+      assert(ExternalSymbols.contains(*Sym.getName()) &&
              "Symbol is not in the externals set");
-      ExternalSymbols.erase(Sym.getName());
+      ExternalSymbols.erase(*Sym.getName());
     }
     Addressable &OldBase = *Sym.Base;
     Sym.setBlock(Content);
@@ -1527,9 +1565,9 @@ class LinkGraph {
   void removeExternalSymbol(Symbol &Sym) {
     assert(!Sym.isDefined() && !Sym.isAbsolute() &&
            "Sym is not an external symbol");
-    assert(ExternalSymbols.contains(Sym.getName()) &&
+    assert(ExternalSymbols.contains(*Sym.getName()) &&
            "Symbol is not in the externals set");
-    ExternalSymbols.erase(Sym.getName());
+    ExternalSymbols.erase(*Sym.getName());
     Addressable &Base = *Sym.Base;
     assert(llvm::none_of(external_symbols(),
                          [&](Symbol *AS) { return AS->Base == &Base; }) &&
@@ -1600,12 +1638,14 @@ class LinkGraph {
   BumpPtrAllocator Allocator;
 
   std::string Name;
+  std::shared_ptr<orc::SymbolStringPool> SSP;
   Triple TT;
   SubtargetFeatures Features;
   unsigned PointerSize;
   llvm::endianness Endianness;
   GetEdgeKindNameFunction GetEdgeKindName = nullptr;
   DenseMap<StringRef, std::unique_ptr<Section>> Sections;
+  //FIXME(jared): these should become dense maps 
   ExternalSymbolMap ExternalSymbols;
   AbsoluteSymbolSet AbsoluteSymbols;
   orc::shared::AllocActions AAs;
@@ -1828,7 +1868,8 @@ enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF);
 
 /// A map of symbol names to resolved addresses.
-using AsyncLookupResult = DenseMap<StringRef, orc::ExecutorSymbolDef>;
+using AsyncLookupResult =
+    DenseMap<orc::SymbolStringPtr, orc::ExecutorSymbolDef>;
 
 /// A function object to call with a resolved symbol map (See AsyncLookupResult)
 /// or an error if resolution failed.
@@ -1861,7 +1902,7 @@ createLookupContinuation(Continuation Cont) {
 /// Holds context for a single jitLink invocation.
 class JITLinkContext {
 public:
-  using LookupMap = DenseMap<StringRef, SymbolLookupFlags>;
+  using LookupMap = DenseMap<orc::SymbolStringPtr, SymbolLookupFlags>;
 
   /// Create a JITLinkContext.
   JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
@@ -1994,11 +2035,14 @@ void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs) {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromObject(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
+                          std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// Create a \c LinkGraph defining the given absolute symbols.
-std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
-                                                    orc::SymbolMap Symbols);
+std::unique_ptr<LinkGraph>
+absoluteSymbolsLinkGraph(const Triple &TT,
+                         std::shared_ptr<orc::SymbolStringPool> SSP,
+                         orc::SymbolMap Symbols);
 
 /// Link the given graph.
 void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h b/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
index bb8da0ab9db27a..2010b32cdf7660 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/MachO.h
@@ -25,7 +25,8 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer);
+createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer,
+                               std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given ObjBuffer, which must be a MachO object file.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h b/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
index 31721bf999ec18..31770c2a601e56 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/MachO_arm64.h
@@ -23,8 +23,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_arm64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a MachO arm64 object file.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
index 6aee8c354f91e6..72e9883ba18b8f 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
@@ -23,8 +23,8 @@ namespace jitlink {
 /// Note: The graph does not take ownership of the underlying buffer, nor copy
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_x86_64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given LinkGraph.
 ///
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h b/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
index 7ab8ae3e53cec2..d20c9c94d38067 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
@@ -39,7 +39,7 @@ template <typename TableManagerImplT> class TableManager {
       auto &Entry = impl().createEntry(G, Target);
       DEBUG_WITH_TYPE("jitlink", {
         dbgs() << "    Created " << impl().getSectionName() << " entry for "
-               << Target.getName() << ": " << Entry << "\n";
+               << *Target.getName() << ": " << Entry << "\n";
       });
       EntryI = Entries.insert(std::make_pair(Target.getName(), &Entry)).first;
     }
@@ -69,7 +69,7 @@ template <typename TableManagerImplT> class TableManager {
 
 private:
   TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
-  DenseMap<StringRef, Symbol *> Entries;
+  DenseMap<orc::SymbolStringPtr, Symbol *> Entries;
 };
 
 } // namespace jitlink
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index e892005c53d8ec..6a4d11744ac4b6 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -1783,7 +1783,7 @@ template <typename MaterializationUnitType>
 Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU,
                        ResourceTrackerSP RT) {
   assert(MU && "Can not define with a null MU");
-
+  
   if (MU->getSymbols().empty()) {
     // Empty MUs are allowable but pathological, so issue a warning.
     DEBUG_WITH_TYPE("orc", {
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h
index 5d5326c4a469ee..dcf5592f1717c2 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h
@@ -181,7 +181,7 @@ class ExecutorProcessControl {
 
   ExecutorProcessControl(std::shared_ptr<SymbolStringPool> SSP,
                          std::unique_ptr<TaskDispatcher> D)
-    : SSP(std::move(SSP)), D(std::move(D)) {}
+      : SSP(std::move(SSP)), D(std::move(D)) {}
 
   virtual ~ExecutorProcessControl();
 
diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index 034c134a13731d..92fdd376abd1d6 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -10,6 +10,7 @@
 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
 
 #include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/TargetParser/Triple.h"
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFF.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF.cpp
index 4503642f52a9da..d370e99169b149 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFF.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFF.cpp
@@ -40,7 +40,8 @@ static StringRef getMachineName(uint16_t Machine) {
 }
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer,
+                              std::shared_ptr<orc::SymbolStringPool> SSP) {
   StringRef Data = ObjectBuffer.getBuffer();
 
   // Check magic
@@ -108,7 +109,7 @@ createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer) {
 
   switch (Machine) {
   case COFF::IMAGE_FILE_MACHINE_AMD64:
-    return createLinkGraphFromCOFFObject_x86_64(ObjectBuffer);
+    return createLinkGraphFromCOFFObject_x86_64(ObjectBuffer, std::move(SSP));
   default:
     return make_error<JITLinkError>(
         "Unsupported target machine architecture in COFF object " +
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
index 92630650ec9372..14df746dcaebf3 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
@@ -11,6 +11,8 @@
 //===----------------------------------------------------------------------===//
 #include "COFFLinkGraphBuilder.h"
 
+#include <memory>
+
 #define DEBUG_TYPE "jitlink"
 
 static const char *CommonSectionName = "__common";
@@ -24,12 +26,16 @@ static Triple createTripleWithCOFFFormat(Triple T) {
 }
 
 COFFLinkGraphBuilder::COFFLinkGraphBuilder(
-    const object::COFFObjectFile &Obj, Triple TT, SubtargetFeatures Features,
+    const object::COFFObjectFile &Obj,
+    std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
+    SubtargetFeatures Features,
     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
-    : Obj(Obj), G(std::make_unique<LinkGraph>(
-                    Obj.getFileName().str(), createTripleWithCOFFFormat(TT),
-                    std::move(Features), getPointerSize(Obj),
-                    getEndianness(Obj), std::move(GetEdgeKindName))) {
+    : Obj(Obj),
+      G(std::make_unique<LinkGraph>(
+          Obj.getFileName().str(), std::move(SSP), 
+          createTripleWithCOFFFormat(TT),
+          std::move(Features), getPointerSize(Obj), getEndianness(Obj),
+          std::move(GetEdgeKindName))) {
   LLVM_DEBUG({
     dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName()
            << "\"\n";
@@ -226,18 +232,19 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
             " (" + toString(SecOrErr.takeError()) + ")");
       Sec = *SecOrErr;
     }
+    auto InternedSymbolName = G->intern(std::move(SymbolName));
 
     // Create jitlink symbol
     jitlink::Symbol *GSym = nullptr;
     if (Sym->isFileRecord())
       LLVM_DEBUG({
         dbgs() << "    " << SymIndex << ": Skipping FileRecord symbol \""
-               << SymbolName << "\" in "
+               << *InternedSymbolName << "\" in "
                << getCOFFSectionName(SectionIndex, Sec, *Sym)
                << " (index: " << SectionIndex << ") \n";
       });
     else if (Sym->isUndefined()) {
-      GSym = createExternalSymbol(SymIndex, SymbolName, *Sym, Sec);
+      GSym = createExternalSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
     } else if (Sym->isWeakExternal()) {
       auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>();
       COFFSymbolIndex TagIndex = WeakExternal->TagIndex;
@@ -246,7 +253,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
           {SymIndex, TagIndex, Characteristics, SymbolName});
     } else {
       Expected<jitlink::Symbol *> NewGSym =
-          createDefinedSymbol(SymIndex, SymbolName, *Sym, Sec);
+          createDefinedSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
       if (!NewGSym)
         return NewGSym.takeError();
       GSym = *NewGSym;
@@ -254,7 +261,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
         LLVM_DEBUG({
           dbgs() << "    " << SymIndex
                  << ": Creating defined graph symbol for COFF symbol \""
-                 << SymbolName << "\" in "
+                 << *InternedSymbolName << "\" in "
                  << getCOFFSectionName(SectionIndex, Sec, *Sym)
                  << " (index: " << SectionIndex << ") \n";
           dbgs() << "      " << *GSym << "\n";
@@ -293,14 +300,13 @@ Error COFFLinkGraphBuilder::handleDirectiveSection(StringRef Str) {
       if (From.empty() || To.empty())
         return make_error<JITLinkError>(
             "Invalid COFF /alternatename directive");
-      AlternateNames[From] = To;
+      AlternateNames[G->intern(From)] = G->intern(To);
       break;
     }
     case COFF_OPT_incl: {
-      auto DataCopy = G->allocateContent(S);
-      StringRef StrCopy(DataCopy.data(), DataCopy.size());
-      ExternalSymbols[StrCopy] = &G->addExternalSymbol(StrCopy, 0, false);
-      ExternalSymbols[StrCopy]->setLive(true);
+      auto Symbol = &G->addExternalSymbol(S, 0, false);
+      Symbol->setLive(true);
+      ExternalSymbols[Symbol->getName()] = Symbol;
       break;
     }
     case COFF_OPT_export:
@@ -332,8 +338,8 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
               ? Scope::Default
               : Scope::Local;
 
-      auto NewSymbol =
-          createAliasSymbol(WeakExternal.SymbolName, Linkage::Weak, S, *Target);
+      auto NewSymbol = createAliasSymbol(G->intern(WeakExternal.SymbolName),
+                                         Linkage::Weak, S, *Target);
       if (!NewSymbol)
         return NewSymbol.takeError();
       setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias,
@@ -354,37 +360,44 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
 }
 
 Error COFFLinkGraphBuilder::handleAlternateNames() {
-  for (auto &KeyValue : AlternateNames)
-    if (DefinedSymbols.count(KeyValue.second) &&
-        ExternalSymbols.count(KeyValue.first)) {
-      auto *Target = DefinedSymbols[KeyValue.second];
-      auto *Alias = ExternalSymbols[KeyValue.first];
+  for (auto &KeyValue : AlternateNames) {
+    auto DefinedSymbolName = KeyValue.second;
+    auto ExternalSymbolsName = KeyValue.first;
+    if (DefinedSymbols.count(DefinedSymbolName) &&
+        ExternalSymbols.count(ExternalSymbolsName)) {
+      auto *Target = DefinedSymbols[DefinedSymbolName];
+      auto *Alias = ExternalSymbols[ExternalSymbolsName];
       G->makeDefined(*Alias, Target->getBlock(), Target->getOffset(),
                      Target->getSize(), Linkage::Weak, Scope::Local, false);
     }
+  }
   return Error::success();
 }
 
 Symbol *COFFLinkGraphBuilder::createExternalSymbol(
-    COFFSymbolIndex SymIndex, StringRef SymbolName,
+    COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
     object::COFFSymbolRef Symbol, const object::coff_section *Section) {
-  if (!ExternalSymbols.count(SymbolName))
-    ExternalSymbols[SymbolName] =
-        &G->addExternalSymbol(SymbolName, Symbol.getValue(), false);
+  llvm::jitlink::Symbol *Sym = nullptr;
+  if (!ExternalSymbols.count(SymbolName)) {
+    Sym = &G->addExternalSymbol(*SymbolName, Symbol.getValue(), false);
+    ExternalSymbols[Sym->getName()] = Sym;
+  } else {
+    Sym = ExternalSymbols[SymbolName];
+  }
 
   LLVM_DEBUG({
     dbgs() << "    " << SymIndex
            << ": Creating external graph symbol for COFF symbol \""
-           << SymbolName << "\" in "
+           << *Sym->getName() << "\" in "
            << getCOFFSectionName(Symbol.getSectionNumber(), Section, Symbol)
            << " (index: " << Symbol.getSectionNumber() << ") \n";
   });
-  return ExternalSymbols[SymbolName];
+  return Sym;
 }
 
-Expected<Symbol *> COFFLinkGraphBuilder::createAliasSymbol(StringRef SymbolName,
-                                                           Linkage L, Scope S,
-                                                           Symbol &Target) {
+Expected<Symbol *>
+COFFLinkGraphBuilder::createAliasSymbol(orc::SymbolStringPtr SymbolName,
+                                        Linkage L, Scope S, Symbol &Target) {
   if (!Target.isDefined()) {
     // FIXME: Support this when there's a way to handle this.
     return make_error<JITLinkError>("Weak external symbol with external "
@@ -460,8 +473,9 @@ Error COFFLinkGraphBuilder::calculateImplicitSizeOfSymbols() {
 }
 
 Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
-    COFFSymbolIndex SymIndex, StringRef SymbolName,
+    COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
     object::COFFSymbolRef Symbol, const object::coff_section *Section) {
+
   if (Symbol.isCommon()) {
     // FIXME: correct alignment
     return &G->addDefinedSymbol(
@@ -470,6 +484,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
         0, SymbolName, Symbol.getValue(), Linkage::Weak, Scope::Default,
         false, false);
   }
+
   if (Symbol.isAbsolute())
     return &G->addAbsoluteSymbol(SymbolName,
                                  orc::ExecutorAddr(Symbol.getValue()), 0,
@@ -486,7 +501,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
       dbgs() << "    " << SymIndex
              << ": Skipping graph symbol since section was not created for "
                 "COFF symbol \""
-             << SymbolName << "\" in section " << Symbol.getSectionNumber()
+             << *SymbolName << "\" in section " << Symbol.getSectionNumber()
              << "\n";
     });
     return nullptr;
@@ -603,7 +618,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
 // Process the second symbol of COMDAT sequence.
 Expected<Symbol *>
 COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
-                                         StringRef SymbolName,
+                                         orc::SymbolStringPtr SymbolName,
                                          object::COFFSymbolRef Symbol) {
   Block *B = getGraphBlock(Symbol.getSectionNumber());
   auto &PendingComdatExport = PendingComdatExports[Symbol.getSectionNumber()];
@@ -616,8 +631,9 @@ COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
       false);
   LLVM_DEBUG({
     dbgs() << "    " << SymIndex
-           << ": Exporting COMDAT graph symbol for COFF symbol \"" << SymbolName
-           << "\" in section " << Symbol.getSectionNumber() << "\n";
+           << ": Exporting COMDAT graph symbol for COFF symbol \""
+           << *SymbolName << "\" in section " << Symbol.getSectionNumber()
+           << "\n";
     dbgs() << "      " << *GSym << "\n";
   });
   setGraphSymbol(Symbol.getSectionNumber(), PendingComdatExport->SymbolIndex,
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
index e5f3ce8c53f5ee..def0d94dda4684 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
@@ -37,7 +37,8 @@ class COFFLinkGraphBuilder {
   using COFFSectionIndex = int32_t;
   using COFFSymbolIndex = int32_t;
 
-  COFFLinkGraphBuilder(const object::COFFObjectFile &Obj, Triple TT,
+  COFFLinkGraphBuilder(const object::COFFObjectFile &Obj,
+                       std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
                        SubtargetFeatures Features,
                        LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
 
@@ -134,20 +135,21 @@ class COFFLinkGraphBuilder {
 
   Section &getCommonSection();
 
-  Symbol *createExternalSymbol(COFFSymbolIndex SymIndex, StringRef SymbolName,
+  Symbol *createExternalSymbol(COFFSymbolIndex SymIndex,
+                               orc::SymbolStringPtr SymbolName,
                                object::COFFSymbolRef Symbol,
                                const object::coff_section *Section);
-  Expected<Symbol *> createAliasSymbol(StringRef SymbolName, Linkage L, Scope S,
-                                       Symbol &Target);
+  Expected<Symbol *> createAliasSymbol(orc::SymbolStringPtr SymbolName,
+                                       Linkage L, Scope S, Symbol &Target);
   Expected<Symbol *> createDefinedSymbol(COFFSymbolIndex SymIndex,
-                                         StringRef SymbolName,
+                                         orc::SymbolStringPtr SymbolName,
                                          object::COFFSymbolRef Symbol,
                                          const object::coff_section *Section);
   Expected<Symbol *> createCOMDATExportRequest(
       COFFSymbolIndex SymIndex, object::COFFSymbolRef Symbol,
       const object::coff_aux_section_definition *Definition);
   Expected<Symbol *> exportCOMDATSymbol(COFFSymbolIndex SymIndex,
-                                        StringRef SymbolName,
+                                        orc::SymbolStringPtr SymbolName,
                                         object::COFFSymbolRef Symbol);
 
   Error handleDirectiveSection(StringRef Str);
@@ -176,9 +178,9 @@ class COFFLinkGraphBuilder {
   std::vector<Block *> GraphBlocks;
   std::vector<Symbol *> GraphSymbols;
 
-  DenseMap<StringRef, StringRef> AlternateNames;
-  DenseMap<StringRef, Symbol *> ExternalSymbols;
-  DenseMap<StringRef, Symbol *> DefinedSymbols;
+  DenseMap<orc::SymbolStringPtr, orc::SymbolStringPtr> AlternateNames;
+  DenseMap<orc::SymbolStringPtr, Symbol *> ExternalSymbols;
+  DenseMap<orc::SymbolStringPtr, Symbol *> DefinedSymbols;
 };
 
 template <typename RelocHandlerFunction>
diff --git a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
index 3257a2ae94f66d..5f2fd1b376a5da 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
@@ -148,6 +148,7 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
         SectionIdx = getObject().getNumberOfSections() + 1;
       else
         SectionIdx = COFFSymbol.getSectionNumber();
+
       auto *AbsSym = &getGraph().addAbsoluteSymbol(
           "secidx", orc::ExecutorAddr(SectionIdx), 2, Linkage::Strong,
           Scope::Local, false);
@@ -181,14 +182,20 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
   }
 
 public:
-  COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T,
-                              const SubtargetFeatures Features)
-      : COFFLinkGraphBuilder(Obj, std::move(T), std::move(Features),
+  COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj,
+                              std::shared_ptr<orc::SymbolStringPool> SSP,
+                              const Triple T, const SubtargetFeatures Features)
+      : COFFLinkGraphBuilder(Obj, std::move(SSP), std::move(T),
+                             std::move(Features),
                              getCOFFX86RelocationKindName) {}
 };
 
 class COFFLinkGraphLowering_x86_64 {
 public:
+  COFFLinkGraphLowering_x86_64(std::shared_ptr<orc::SymbolStringPool> SSP)
+      : SSP(std::move(SSP)) {
+    imageBaseName = this->SSP->intern("__ImageBase");
+  }
   // Lowers COFF x86_64 specific edges to generic x86_64 edges.
   Error lowerCOFFRelocationEdges(LinkGraph &G, JITLinkContext &Ctx) {
     for (auto *B : G.blocks()) {
@@ -230,8 +237,7 @@ class COFFLinkGraphLowering_x86_64 {
   }
 
 private:
-  static StringRef getImageBaseSymbolName() { return "__ImageBase"; }
-
+  orc::SymbolStringPtr & getImageBaseSymbolName() { return this->imageBaseName; }
   orc::ExecutorAddr getSectionStart(Section &Sec) {
     if (!SectionStartCache.count(&Sec)) {
       SectionRange Range(Sec);
@@ -271,12 +277,13 @@ class COFFLinkGraphLowering_x86_64 {
 
   DenseMap<Section *, orc::ExecutorAddr> SectionStartCache;
   orc::ExecutorAddr ImageBase;
+  std::shared_ptr<orc::SymbolStringPool> SSP;
+  orc::SymbolStringPtr imageBaseName = nullptr;
 };
 
 Error lowerEdges_COFF_x86_64(LinkGraph &G, JITLinkContext *Ctx) {
   LLVM_DEBUG(dbgs() << "Lowering COFF x86_64 edges:\n");
-  COFFLinkGraphLowering_x86_64 GraphLowering;
-
+  COFFLinkGraphLowering_x86_64 GraphLowering(G.getSymbolStringPool());
   if (auto Err = GraphLowering.lowerCOFFRelocationEdges(G, *Ctx))
     return Err;
 
@@ -305,8 +312,8 @@ const char *getCOFFX86RelocationKindName(Edge::Kind R) {
   }
 }
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromCOFFObject_x86_64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -320,7 +327,7 @@ createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer) {
   if (!Features)
     return Features.takeError();
 
-  return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple(),
+  return COFFLinkGraphBuilder_x86_64(**COFFObj, std::move(SSP), (*COFFObj)->makeTriple(),
                                      std::move(*Features))
       .buildGraph();
 }
diff --git a/llvm/lib/ExecutionEngine/JITLink/DefineExternalSectionStartAndEndSymbols.h b/llvm/lib/ExecutionEngine/JITLink/DefineExternalSectionStartAndEndSymbols.h
index 49cfc5dec25bb5..c7a2f071c29f32 100644
--- a/llvm/lib/ExecutionEngine/JITLink/DefineExternalSectionStartAndEndSymbols.h
+++ b/llvm/lib/ExecutionEngine/JITLink/DefineExternalSectionStartAndEndSymbols.h
@@ -112,13 +112,13 @@ identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
   constexpr StringRef EndSymbolPrefix = "__stop_";
 
   auto SymName = Sym.getName();
-  if (SymName.starts_with(StartSymbolPrefix)) {
-    if (auto *Sec =
-            G.findSectionByName(SymName.drop_front(StartSymbolPrefix.size())))
+  if ((*SymName).starts_with(StartSymbolPrefix)) {
+    if (auto *Sec = G.findSectionByName(
+            (*SymName).drop_front(StartSymbolPrefix.size())))
       return {*Sec, true};
-  } else if (SymName.starts_with(EndSymbolPrefix)) {
+  } else if ((*SymName).starts_with(EndSymbolPrefix)) {
     if (auto *Sec =
-            G.findSectionByName(SymName.drop_front(EndSymbolPrefix.size())))
+            G.findSectionByName((*SymName).drop_front(EndSymbolPrefix.size())))
       return {*Sec, false};
   }
   return {};
@@ -131,15 +131,15 @@ identifyMachOSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
   constexpr StringRef EndSymbolPrefix = "section$end$";
 
   auto SymName = Sym.getName();
-  if (SymName.starts_with(StartSymbolPrefix)) {
+  if ((*SymName).starts_with(StartSymbolPrefix)) {
     auto [SegName, SecName] =
-      SymName.drop_front(StartSymbolPrefix.size()).split('$');
+        (*SymName).drop_front(StartSymbolPrefix.size()).split('$');
     std::string SectionName = (SegName + "," + SecName).str();
     if (auto *Sec = G.findSectionByName(SectionName))
       return {*Sec, true};
-  } else if (SymName.starts_with(EndSymbolPrefix)) {
+  } else if ((*SymName).starts_with(EndSymbolPrefix)) {
     auto [SegName, SecName] =
-      SymName.drop_front(EndSymbolPrefix.size()).split('$');
+        (*SymName).drop_front(EndSymbolPrefix.size()).split('$');
     std::string SectionName = (SegName + "," + SecName).str();
     if (auto *Sec = G.findSectionByName(SectionName))
       return {*Sec, false};
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
index 8b6c88da52eb8f..c6d29badb3a45e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
@@ -371,7 +371,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
         dbgs() << "      WARNING: Not adding keep-alive edge to FDE at "
                << RecordAddress << ", which points to "
                << ((*PCBegin)->isExternal() ? "external" : "absolute")
-               << " symbol \"" << (*PCBegin)->getName()
+               << " symbol \"" << *(*PCBegin)->getName()
                << "\" -- FDE must be kept alive manually or it will be "
                << "dead stripped.\n";
       });
@@ -524,7 +524,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
                << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
                << FieldName << " at " << EdgeI->second.Target->getAddress();
         if (EdgeI->second.Target->hasName())
-          dbgs() << " (" << EdgeI->second.Target->getName() << ")";
+          dbgs() << " (" << *EdgeI->second.Target->getName() << ")";
         dbgs() << "\n";
       });
       if (auto Err = skipEncodedPointer(PointerEncoding, RecordReader))
@@ -590,7 +590,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
            << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
            << FieldName << " at " << TargetSym->getAddress();
     if (TargetSym->hasName())
-      dbgs() << " (" << TargetSym->getName() << ")";
+      dbgs() << " (" << *TargetSym->getName() << ")";
     dbgs() << "\n";
   });
 
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
index d92feeccf5e929..663a883a4bcce1 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
@@ -69,7 +69,8 @@ Expected<uint16_t> readTargetMachineArch(StringRef Buffer) {
 }
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer,
+                             std::shared_ptr<orc::SymbolStringPool> SSP) {
   StringRef Buffer = ObjectBuffer.getBuffer();
   if (Buffer.size() < ELF::EI_NIDENT)
     return make_error<JITLinkError>("Truncated ELF buffer");
@@ -84,23 +85,23 @@ createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) {
 
   switch (*TargetMachineArch) {
   case ELF::EM_AARCH64:
-    return createLinkGraphFromELFObject_aarch64(ObjectBuffer);
+    return createLinkGraphFromELFObject_aarch64(ObjectBuffer, std::move(SSP));
   case ELF::EM_ARM:
-    return createLinkGraphFromELFObject_aarch32(ObjectBuffer);
-  case ELF::EM_LOONGARCH:
-    return createLinkGraphFromELFObject_loongarch(ObjectBuffer);
+    return createLinkGraphFromELFObject_aarch32(ObjectBuffer, std::move(SSP));
   case ELF::EM_PPC64: {
     if (DataEncoding == ELF::ELFDATA2LSB)
-      return createLinkGraphFromELFObject_ppc64le(ObjectBuffer);
+      return createLinkGraphFromELFObject_ppc64le(ObjectBuffer, std::move(SSP));
     else
-      return createLinkGraphFromELFObject_ppc64(ObjectBuffer);
+      return createLinkGraphFromELFObject_ppc64(ObjectBuffer, std::move(SSP));
   }
+  case ELF::EM_LOONGARCH:
+    return createLinkGraphFromELFObject_loongarch(ObjectBuffer, std::move(SSP));
   case ELF::EM_RISCV:
-    return createLinkGraphFromELFObject_riscv(ObjectBuffer);
+    return createLinkGraphFromELFObject_riscv(ObjectBuffer, std::move(SSP));
   case ELF::EM_X86_64:
-    return createLinkGraphFromELFObject_x86_64(ObjectBuffer);
+    return createLinkGraphFromELFObject_x86_64(ObjectBuffer, std::move(SSP));
   case ELF::EM_386:
-    return createLinkGraphFromELFObject_i386(ObjectBuffer);
+    return createLinkGraphFromELFObject_i386(ObjectBuffer, std::move(SSP));
   default:
     return make_error<JITLinkError>(
         "Unsupported target machine architecture in ELF object " +
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
index c05961c64837ce..fbe40fe5f75716 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
@@ -58,7 +58,8 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
   using ELFFile = object::ELFFile<ELFT>;
 
 public:
-  ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
+  ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj,
+                      std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
                       SubtargetFeatures Features, StringRef FileName,
                       LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
 
@@ -189,12 +190,13 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
 
 template <typename ELFT>
 ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
-    const ELFFile &Obj, Triple TT, SubtargetFeatures Features,
-    StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
+    const ELFFile &Obj, std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
+    SubtargetFeatures Features, StringRef FileName,
+    LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
     : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
-          FileName.str(), Triple(std::move(TT)), std::move(Features),
-          ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness),
-          std::move(GetEdgeKindName))),
+          FileName.str(), std::move(SSP), Triple(std::move(TT)),
+          std::move(Features), ELFT::Is64Bits ? 8 : 4,
+          llvm::endianness(ELFT::Endianness), std::move(GetEdgeKindName))),
       Obj(Obj) {
   LLVM_DEBUG(
       { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
index 866de2cb227c35..acff568ed37900 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
@@ -219,10 +219,11 @@ class ELFLinkGraphBuilder_aarch32
 
 public:
   ELFLinkGraphBuilder_aarch32(StringRef FileName,
-                              const llvm::object::ELFFile<ELFT> &Obj, Triple TT,
-                              SubtargetFeatures Features,
+                              const llvm::object::ELFFile<ELFT> &Obj,
+                              std::shared_ptr<orc::SymbolStringPool> SSP,
+                              Triple TT, SubtargetFeatures Features,
                               aarch32::ArmConfig ArmCfg)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT), std::move(Features),
                                   FileName, getELFAArch32EdgeKindName),
         ArmCfg(std::move(ArmCfg)) {}
 };
@@ -239,8 +240,8 @@ Error buildTables_ELF_aarch32(LinkGraph &G) {
   return Error::success();
 }
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch32(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -273,7 +274,8 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
   case Triple::thumb: {
     auto &ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
     return ELFLinkGraphBuilder_aarch32<llvm::endianness::little>(
-               (*ELFObj)->getFileName(), ELFFile, TT, std::move(*Features),
+               (*ELFObj)->getFileName(), ELFFile, std::move(SSP), 
+               TT, std::move(*Features),
                ArmCfg)
         .buildGraph();
   }
@@ -281,7 +283,8 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
   case Triple::thumbeb: {
     auto &ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
     return ELFLinkGraphBuilder_aarch32<llvm::endianness::big>(
-               (*ELFObj)->getFileName(), ELFFile, TT, std::move(*Features),
+               (*ELFObj)->getFileName(), ELFFile, std::move(SSP),
+               TT, std::move(*Features),
                ArmCfg)
         .buildGraph();
   }
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
index 86e50548907995..deefa4b58ce20c 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
@@ -52,10 +52,13 @@ class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
   }
 
   Error getOrCreateGOTSymbol(LinkGraph &G) {
+    auto InteredGOTSymbolName =
+        G.getSymbolStringPool()->intern(ELFGOTSymbolName);
+
     auto DefineExternalGOTSymbolIfPresent =
         createDefineExternalSectionStartAndEndSymbolsPass(
             [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
-              if (Sym.getName() == ELFGOTSymbolName)
+              if (*Sym.getName() == ELFGOTSymbolName)
                 if (auto *GOTSection = G.findSectionByName(
                         aarch64::GOTTableManager::getSectionName())) {
                   GOTSymbol = &Sym;
@@ -81,7 +84,7 @@ class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
 
       // Check for an existing defined symbol.
       for (auto *Sym : GOTSection->symbols())
-        if (Sym->getName() == ELFGOTSymbolName) {
+        if (Sym->getName() == InteredGOTSymbolName) {
           GOTSymbol = Sym;
           return Error::success();
         }
@@ -90,11 +93,12 @@ class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
       SectionRange SR(*GOTSection);
       if (SR.empty())
         GOTSymbol =
-            &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
+            // FIXME: we should only do this once
+            &G.addAbsoluteSymbol(InteredGOTSymbolName, orc::ExecutorAddr(), 0,
                                  Linkage::Strong, Scope::Local, true);
       else
         GOTSymbol =
-            &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
+            &G.addDefinedSymbol(*SR.getFirstBlock(), 0, InteredGOTSymbolName, 0,
                                 Linkage::Strong, Scope::Local, false, true);
     }
 
@@ -103,7 +107,7 @@ class ELFJITLinker_aarch64 : public JITLinker<ELFJITLinker_aarch64> {
     // we just need to point the GOT symbol at some address in this graph.
     if (!GOTSymbol) {
       for (auto *Sym : G.external_symbols()) {
-        if (Sym->getName() == ELFGOTSymbolName) {
+        if (*Sym->getName() == ELFGOTSymbolName) {
           auto Blocks = G.blocks();
           if (!Blocks.empty()) {
             G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
@@ -525,9 +529,11 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder<ELFT> {
 
 public:
   ELFLinkGraphBuilder_aarch64(StringRef FileName,
-                              const object::ELFFile<ELFT> &Obj, Triple TT,
-                              SubtargetFeatures Features)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
+                              const object::ELFFile<ELFT> &Obj,
+                              std::shared_ptr<orc::SymbolStringPool> SSP,
+                              Triple TT, SubtargetFeatures Features)
+
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT), std::move(Features),
                                   FileName, aarch64::getEdgeKindName) {}
 };
 
@@ -665,8 +671,8 @@ Error buildTables_ELF_aarch64(LinkGraph &G) {
 namespace llvm {
 namespace jitlink {
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -685,7 +691,7 @@ createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
 
   auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
   return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(
-             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
              (*ELFObj)->makeTriple(), std::move(*Features))
       .buildGraph();
 }
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
index 2d5f28cad1cc6d..ce2ecf94c4dd0f 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
@@ -56,7 +56,8 @@ class ELFJITLinker_i386 : public JITLinker<ELFJITLinker_i386> {
     auto DefineExternalGOTSymbolIfPresent =
         createDefineExternalSectionStartAndEndSymbolsPass(
             [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
-              if (Sym.getName() == ELFGOTSymbolName)
+              if (Sym.getName() != nullptr &&
+                  *Sym.getName() == ELFGOTSymbolName)
                 if (auto *GOTSection = G.findSectionByName(
                         i386::GOTTableManager::getSectionName())) {
                   GOTSymbol = &Sym;
@@ -82,7 +83,7 @@ class ELFJITLinker_i386 : public JITLinker<ELFJITLinker_i386> {
 
       // Check for an existing defined symbol.
       for (auto *Sym : GOTSection->symbols())
-        if (Sym->getName() == ELFGOTSymbolName) {
+        if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
           GOTSymbol = Sym;
           return Error::success();
         }
@@ -224,13 +225,15 @@ class ELFLinkGraphBuilder_i386 : public ELFLinkGraphBuilder<ELFT> {
 
 public:
   ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile<ELFT> &Obj,
+                           std::shared_ptr<orc::SymbolStringPool> SSP,
                            Triple TT, SubtargetFeatures Features)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT), std::move(Features),
                                   FileName, i386::getEdgeKindName) {}
 };
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer,
+                                  std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -248,8 +251,9 @@ createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer) {
          "Only i386 (little endian) is supported for now");
 
   auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
+
   return ELFLinkGraphBuilder_i386<object::ELF32LE>(
-             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
              (*ELFObj)->makeTriple(), std::move(*Features))
       .buildGraph();
 }
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
index 42fcfebd12d616..f3a281395a0332 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
@@ -131,10 +131,12 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
 
 public:
   ELFLinkGraphBuilder_loongarch(StringRef FileName,
-                                const object::ELFFile<ELFT> &Obj, Triple TT,
-                                SubtargetFeatures Features)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
-                                  FileName, loongarch::getEdgeKindName) {}
+                                const object::ELFFile<ELFT> &Obj,
+                                std::shared_ptr<orc::SymbolStringPool> SSP,
+                                Triple TT, SubtargetFeatures Features)
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
+                                  std::move(Features), FileName,
+                                  loongarch::getEdgeKindName) {}
 };
 
 Error buildTables_ELF_loongarch(LinkGraph &G) {
@@ -151,8 +153,8 @@ Error buildTables_ELF_loongarch(LinkGraph &G) {
 namespace llvm {
 namespace jitlink {
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_loongarch(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -169,7 +171,7 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
   if ((*ELFObj)->getArch() == Triple::loongarch64) {
     auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
     return ELFLinkGraphBuilder_loongarch<object::ELF64LE>(
-               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
                (*ELFObj)->makeTriple(), std::move(*Features))
         .buildGraph();
   }
@@ -178,7 +180,7 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
          "Invalid triple for LoongArch ELF object file");
   auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
   return ELFLinkGraphBuilder_loongarch<object::ELF32LE>(
-             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
              (*ELFObj)->makeTriple(), std::move(*Features))
       .buildGraph();
 }
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
index 3b86250b60a44c..83b51eb61e1ccc 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
@@ -106,14 +106,14 @@ Symbol &createELFGOTHeader(LinkGraph &G,
   Symbol *TOCSymbol = nullptr;
 
   for (Symbol *Sym : G.defined_symbols())
-    if (LLVM_UNLIKELY(Sym->getName() == ELFTOCSymbolName)) {
+    if (LLVM_UNLIKELY(Sym->hasName() && *Sym->getName() == ELFTOCSymbolName)) {
       TOCSymbol = Sym;
       break;
     }
 
   if (LLVM_LIKELY(TOCSymbol == nullptr)) {
     for (Symbol *Sym : G.external_symbols())
-      if (Sym->getName() == ELFTOCSymbolName) {
+      if (Sym->hasName() && *Sym->getName() == ELFTOCSymbolName) {
         TOCSymbol = Sym;
         break;
       }
@@ -393,10 +393,12 @@ class ELFLinkGraphBuilder_ppc64
 
 public:
   ELFLinkGraphBuilder_ppc64(StringRef FileName,
-                            const object::ELFFile<ELFT> &Obj, Triple TT,
-                            SubtargetFeatures Features)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
-                                  FileName, ppc64::getEdgeKindName) {}
+                            const object::ELFFile<ELFT> &Obj,
+                            std::shared_ptr<orc::SymbolStringPool> SSP,
+                            Triple TT, SubtargetFeatures Features)
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
+                                  std::move(Features), FileName,
+                                  ppc64::getEdgeKindName) {}
 };
 
 template <llvm::endianness Endianness>
@@ -417,7 +419,8 @@ class ELFJITLinker_ppc64 : public JITLinker<ELFJITLinker_ppc64<Endianness>> {
 
   Error defineTOCBase(LinkGraph &G) {
     for (Symbol *Sym : G.defined_symbols()) {
-      if (LLVM_UNLIKELY(Sym->getName() == ELFTOCSymbolName)) {
+      if (LLVM_UNLIKELY(Sym->hasName() &&
+                        *Sym->getName() == ELFTOCSymbolName)) {
         TOCSymbol = Sym;
         return Error::success();
       }
@@ -427,7 +430,7 @@ class ELFJITLinker_ppc64 : public JITLinker<ELFJITLinker_ppc64<Endianness>> {
            "TOCSymbol should not be defined at this point");
 
     for (Symbol *Sym : G.external_symbols()) {
-      if (Sym->getName() == ELFTOCSymbolName) {
+      if (Sym->hasName() && *Sym->getName() == ELFTOCSymbolName) {
         TOCSymbol = Sym;
         break;
       }
@@ -463,7 +466,8 @@ class ELFJITLinker_ppc64 : public JITLinker<ELFJITLinker_ppc64<Endianness>> {
 
 template <llvm::endianness Endianness>
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
+                                   std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -480,7 +484,7 @@ createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
   using ELFT = object::ELFType<Endianness, true>;
   auto &ELFObjFile = cast<object::ELFObjectFile<ELFT>>(**ELFObj);
   return ELFLinkGraphBuilder_ppc64<Endianness>(
-             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+             (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
              (*ELFObj)->makeTriple(), std::move(*Features))
       .buildGraph();
 }
@@ -517,15 +521,16 @@ void link_ELF_ppc64(std::unique_ptr<LinkGraph> G,
 }
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
+                                   std::shared_ptr<orc::SymbolStringPool> SSP) {
   return createLinkGraphFromELFObject_ppc64<llvm::endianness::big>(
-      std::move(ObjectBuffer));
+      std::move(ObjectBuffer), std::move(SSP));
 }
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_ppc64le(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_ppc64le(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   return createLinkGraphFromELFObject_ppc64<llvm::endianness::little>(
-      std::move(ObjectBuffer));
+      std::move(ObjectBuffer), std::move(SSP));
 }
 
 /// jit-link the given object buffer, which must be a ELF ppc64 object file.
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
index 0cf548ede93890..df4269fb573dff 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
@@ -927,14 +927,16 @@ class ELFLinkGraphBuilder_riscv : public ELFLinkGraphBuilder<ELFT> {
 
 public:
   ELFLinkGraphBuilder_riscv(StringRef FileName,
-                            const object::ELFFile<ELFT> &Obj, Triple TT,
-                            SubtargetFeatures Features)
-      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
+                            const object::ELFFile<ELFT> &Obj,
+                            std::shared_ptr<orc::SymbolStringPool> SSP,
+                            Triple TT, SubtargetFeatures Features)
+      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT), std::move(Features),
                                   FileName, riscv::getEdgeKindName) {}
 };
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer,
+                                   std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -951,7 +953,7 @@ createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
   if ((*ELFObj)->getArch() == Triple::riscv64) {
     auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
     return ELFLinkGraphBuilder_riscv<object::ELF64LE>(
-               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
                (*ELFObj)->makeTriple(), std::move(*Features))
         .buildGraph();
   } else {
@@ -959,7 +961,7 @@ createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
            "Invalid triple for RISCV ELF object file");
     auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
     return ELFLinkGraphBuilder_riscv<object::ELF32LE>(
-               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
+               (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
                (*ELFObj)->makeTriple(), std::move(*Features))
         .buildGraph();
   }
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
index 44122726fb5c08..bccda8e90a1fb5 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
@@ -238,9 +238,10 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
 
 public:
   ELFLinkGraphBuilder_x86_64(StringRef FileName,
+                             std::shared_ptr<orc::SymbolStringPool> SSP,
                              const object::ELFFile<object::ELF64LE> &Obj,
                              SubtargetFeatures Features)
-      : ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"),
+      : ELFLinkGraphBuilder(Obj, std::move(SSP), Triple("x86_64-unknown-linux"),
                             std::move(Features), FileName,
                             x86_64::getEdgeKindName) {}
 };
@@ -261,12 +262,12 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
 
 private:
   Symbol *GOTSymbol = nullptr;
-
   Error getOrCreateGOTSymbol(LinkGraph &G) {
     auto DefineExternalGOTSymbolIfPresent =
         createDefineExternalSectionStartAndEndSymbolsPass(
             [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
-              if (Sym.getName() == ELFGOTSymbolName)
+              if (Sym.getName() != nullptr &&
+                  *Sym.getName() == ELFGOTSymbolName)
                 if (auto *GOTSection = G.findSectionByName(
                         x86_64::GOTTableManager::getSectionName())) {
                   GOTSymbol = &Sym;
@@ -292,7 +293,7 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
 
       // Check for an existing defined symbol.
       for (auto *Sym : GOTSection->symbols())
-        if (Sym->getName() == ELFGOTSymbolName) {
+        if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
           GOTSymbol = Sym;
           return Error::success();
         }
@@ -314,7 +315,7 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
     // we just need to point the GOT symbol at some address in this graph.
     if (!GOTSymbol) {
       for (auto *Sym : G.external_symbols()) {
-        if (Sym->getName() == ELFGOTSymbolName) {
+        if (*Sym->getName() == ELFGOTSymbolName) {
           auto Blocks = G.blocks();
           if (!Blocks.empty()) {
             G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
@@ -333,8 +334,8 @@ class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
   }
 };
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_x86_64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   LLVM_DEBUG({
     dbgs() << "Building jitlink graph for new input "
            << ObjectBuffer.getBufferIdentifier() << "...\n";
@@ -349,7 +350,7 @@ createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
     return Features.takeError();
 
   auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
-  return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(),
+  return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(), std::move(SSP),
                                     ELFObjFile.getELFFile(),
                                     std::move(*Features))
       .buildGraph();
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index 9041dc3a52dcf1..5c109151e6f96a 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -123,7 +123,7 @@ raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) {
      << ", linkage: " << formatv("{0:6}", getLinkageName(Sym.getLinkage()))
      << ", scope: " << formatv("{0:8}", getScopeName(Sym.getScope())) << ", "
      << (Sym.isLive() ? "live" : "dead") << "  -   "
-     << (Sym.hasName() ? Sym.getName() : "<anonymous symbol>");
+     << (Sym.hasName() ? *Sym.getName() : "<anonymous symbol>");
   return OS;
 }
 
@@ -135,7 +135,7 @@ void printEdge(raw_ostream &OS, const Block &B, const Edge &E,
 
   auto &TargetSym = E.getTarget();
   if (TargetSym.hasName())
-    OS << TargetSym.getName();
+    OS << *TargetSym.getName();
   else {
     auto &TargetBlock = TargetSym.getBlock();
     auto &TargetSec = TargetBlock.getSection();
@@ -165,6 +165,16 @@ Section::~Section() {
     B->~Block();
 }
 
+LinkGraph::~LinkGraph() {
+  for (auto *Sym : AbsoluteSymbols) {
+    Sym->~Symbol();
+  }
+  for (auto *Sym : external_symbols()) {
+    Sym->~Symbol();
+  }
+  ExternalSymbols.clear();
+}
+
 std::vector<Block *> LinkGraph::splitBlockImpl(std::vector<Block *> Blocks,
                                                SplitBlockCache *Cache) {
   assert(!Blocks.empty() && "Blocks must at least contain the original block");
@@ -339,7 +349,7 @@ void LinkGraph::dump(raw_ostream &OS) {
             OS << formatv("-{0:x8}", -E.getAddend());
           OS << ", kind = " << getEdgeKindName(E.getKind()) << ", target = ";
           if (E.getTarget().hasName())
-            OS << E.getTarget().getName();
+            OS << *E.getTarget().getName();
           else
             OS << "addressable@"
                << formatv("{0:x16}", E.getTarget().getAddress()) << "+"
@@ -410,7 +420,7 @@ Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
     ErrStream << "In graph " << G.getName() << ", section " << Sec.getName()
               << ": relocation target ";
     if (E.getTarget().hasName()) {
-      ErrStream << "\"" << E.getTarget().getName() << "\"";
+      ErrStream << "\"" << *E.getTarget().getName() << "\"";
     } else
       ErrStream << E.getTarget().getBlock().getSection().getName() << " + "
                 << formatv("{0:x}", E.getOffset());
@@ -427,7 +437,7 @@ Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
         BestSymbolForBlock = Sym;
 
     if (BestSymbolForBlock)
-      ErrStream << BestSymbolForBlock->getName() << ", ";
+      ErrStream << *BestSymbolForBlock->getName() << ", ";
     else
       ErrStream << "<anonymous block> @ ";
 
@@ -479,22 +489,25 @@ PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT) {
 }
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
+                          std::shared_ptr<orc::SymbolStringPool> SSP) {
   auto Magic = identify_magic(ObjectBuffer.getBuffer());
   switch (Magic) {
   case file_magic::macho_object:
-    return createLinkGraphFromMachOObject(ObjectBuffer);
+    return createLinkGraphFromMachOObject(ObjectBuffer, std::move(SSP));
   case file_magic::elf_relocatable:
-    return createLinkGraphFromELFObject(ObjectBuffer);
+    return createLinkGraphFromELFObject(ObjectBuffer, std::move(SSP));
   case file_magic::coff_object:
-    return createLinkGraphFromCOFFObject(ObjectBuffer);
+    return createLinkGraphFromCOFFObject(ObjectBuffer, std::move(SSP));
   default:
     return make_error<JITLinkError>("Unsupported file format");
   };
 }
 
-std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
-                                                    orc::SymbolMap Symbols) {
+std::unique_ptr<LinkGraph>
+absoluteSymbolsLinkGraph(const Triple &TT,
+                         std::shared_ptr<orc::SymbolStringPool> SSP,
+                         orc::SymbolMap Symbols) {
   unsigned PointerSize;
   endianness Endianness =
       TT.isLittleEndian() ? endianness::little : endianness::big;
@@ -516,7 +529,8 @@ std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
   static std::atomic<uint64_t> Counter = {0};
   auto Index = Counter.fetch_add(1, std::memory_order_relaxed);
   auto G = std::make_unique<LinkGraph>(
-      "<Absolute Symbols " + std::to_string(Index) + ">", TT, PointerSize,
+      "<Absolute Symbols " + std::to_string(Index) + ">", std::move(SSP), 
+      TT, PointerSize,
       Endianness, /*GetEdgeKindName=*/nullptr);
   for (auto &[Name, Def] : Symbols) {
     auto &Sym =
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index 254c04b1986129..703031e3331ee0 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -211,8 +211,7 @@ JITLinkContext::LookupMap JITLinkerBase::getExternalSymbolNames() const {
   for (auto *Sym : G->external_symbols()) {
     assert(!Sym->getAddress() &&
            "External has already been assigned an address");
-    assert(Sym->getName() != StringRef() && Sym->getName() != "" &&
-           "Externals must be named");
+    assert(Sym->hasName() && "Externals must be named");
     SymbolLookupFlags LookupFlags =
         Sym->isWeaklyReferenced() ? SymbolLookupFlags::WeaklyReferencedSymbol
                                   : SymbolLookupFlags::RequiredSymbol;
@@ -242,7 +241,7 @@ void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
   LLVM_DEBUG({
     dbgs() << "Externals after applying lookup result:\n";
     for (auto *Sym : G->external_symbols()) {
-      dbgs() << "  " << Sym->getName() << ": "
+      dbgs() << "  " << *Sym->getName() << ": "
              << formatv("{0:x16}", Sym->getAddress().getValue());
       switch (Sym->getLinkage()) {
       case Linkage::Strong:
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
index 42a77a52beef05..7ea9233364f9ad 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp
@@ -155,8 +155,9 @@ void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
       "__---.finalize", "__R--.finalize", "__-W-.finalize", "__RW-.finalize",
       "__--X.finalize", "__R-X.finalize", "__-WX.finalize", "__RWX.finalize"};
 
-  auto G = std::make_unique<LinkGraph>("", Triple(), 0,
-                                       llvm::endianness::native, nullptr);
+  auto G = std::make_unique<LinkGraph>(
+      "", std::shared_ptr<orc::SymbolStringPool>(), Triple(), 0,
+      llvm::endianness::native, nullptr);
   orc::AllocGroupSmallMap<Block *> ContentBlocks;
 
   orc::ExecutorAddr NextAddr(0x100000);
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO.cpp
index f1181b59234e46..d8383f9f325619 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO.cpp
@@ -25,7 +25,8 @@ namespace llvm {
 namespace jitlink {
 
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer) {
+createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer,
+                               std::shared_ptr<orc::SymbolStringPool> SSP) {
   StringRef Data = ObjectBuffer.getBuffer();
   if (Data.size() < 4)
     return make_error<JITLinkError>("Truncated MachO buffer \"" +
@@ -61,9 +62,9 @@ createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer) {
 
     switch (CPUType) {
     case MachO::CPU_TYPE_ARM64:
-      return createLinkGraphFromMachOObject_arm64(ObjectBuffer);
+      return createLinkGraphFromMachOObject_arm64(ObjectBuffer, std::move(SSP));
     case MachO::CPU_TYPE_X86_64:
-      return createLinkGraphFromMachOObject_x86_64(ObjectBuffer);
+      return createLinkGraphFromMachOObject_x86_64(ObjectBuffer, std::move(SSP));
     }
     return make_error<JITLinkError>("MachO-64 CPU type not valid");
   } else
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index 15d679bcbb5df8..c42fd089757214 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -49,10 +49,12 @@ Expected<std::unique_ptr<LinkGraph>> MachOLinkGraphBuilder::buildGraph() {
 }
 
 MachOLinkGraphBuilder::MachOLinkGraphBuilder(
-    const object::MachOObjectFile &Obj, Triple TT, SubtargetFeatures Features,
+    const object::MachOObjectFile &Obj,
+    std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
+    SubtargetFeatures Features,
     LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
     : Obj(Obj),
-      G(std::make_unique<LinkGraph>(std::string(Obj.getFileName()),
+      G(std::make_unique<LinkGraph>(std::string(Obj.getFileName()), std::move(SSP),
                                     std::move(TT), std::move(Features),
                                     getPointerSize(Obj), getEndianness(Obj),
                                     std::move(GetEdgeKindName))) {
@@ -319,9 +321,8 @@ Error MachOLinkGraphBuilder::createNormalizedSymbols() {
       }
     }
 
-    IndexToSymbol[SymbolIndex] =
-        &createNormalizedSymbol(*Name, Value, Type, Sect, Desc,
-                                getLinkage(Desc), getScope(*Name, Type));
+    IndexToSymbol[SymbolIndex] = &createNormalizedSymbol(
+        Name, Value, Type, Sect, Desc, getLinkage(Desc), getScope(*Name, Type));
   }
 
   return Error::success();
@@ -587,7 +588,7 @@ Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,
     if (!NSym.Name)
       dbgs() << "<anonymous symbol>";
     else
-      dbgs() << NSym.Name;
+      dbgs() << *NSym.Name;
     if (IsText)
       dbgs() << " [text]";
     if (IsNoDeadStrip)
@@ -726,7 +727,7 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
         LLVM_DEBUG({
           dbgs() << "      Adding symbol for c-string block " << B.getRange()
                  << ": "
-                 << (Sym.hasName() ? Sym.getName() : "<anonymous symbol>")
+                 << (Sym.hasName() ? *Sym.getName() : "<anonymous symbol>")
                  << " at offset " << formatv("{0:x}", Sym.getOffset()) << "\n";
         });
 
@@ -825,8 +826,8 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
         if (E.getOffset() == 0) {
           LLVM_DEBUG({
             dbgs() << "    Updating compact unwind record at "
-                   << CURec->getAddress() << " to point to "
-                   << (E.getTarget().hasName() ? E.getTarget().getName()
+                   << formatv("{0:x16}", CURec->getAddress()) << " to point to "
+                   << (E.getTarget().hasName() ? *E.getTarget().getName()
                                                : StringRef())
                    << " (at " << E.getTarget().getAddress() << ")\n";
           });
@@ -835,7 +836,7 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
             return make_error<JITLinkError>(
                 "Error adding keep-alive edge for compact unwind record at " +
                 formatv("{0:x}", CURec->getAddress()) + ": target " +
-                E.getTarget().getName() + " is an external symbol");
+                *E.getTarget().getName() + " is an external symbol");
           auto &TgtBlock = E.getTarget().getBlock();
           auto &CURecSym =
               G.addAnonymousSymbol(*CURec, 0, CURecordSize, false, false);
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
index a4ae0ac1ecfc09..33b5cdf7232efe 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
@@ -44,13 +44,13 @@ class MachOLinkGraphBuilder {
           S(S) {
       assert((!Name || !Name->empty()) && "Name must be none or non-empty");
     }
-
+    
   public:
     NormalizedSymbol(const NormalizedSymbol &) = delete;
     NormalizedSymbol &operator=(const NormalizedSymbol &) = delete;
     NormalizedSymbol(NormalizedSymbol &&) = delete;
     NormalizedSymbol &operator=(NormalizedSymbol &&) = delete;
-
+  
     std::optional<StringRef> Name;
     uint64_t Value = 0;
     uint8_t Type = 0;
@@ -83,10 +83,10 @@ class MachOLinkGraphBuilder {
 
   using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
 
-  MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, Triple TT,
+  MachOLinkGraphBuilder(const object::MachOObjectFile &Obj,
+                        std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
                         SubtargetFeatures Features,
                         LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
-
   LinkGraph &getGraph() const { return *G; }
 
   const object::MachOObjectFile &getObject() const { return Obj; }
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
index 6a947828a5e61e..a23de81761027e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
@@ -27,9 +27,10 @@ namespace {
 class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
 public:
   MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj,
+                              std::shared_ptr<orc::SymbolStringPool> SSP,
                               SubtargetFeatures Features)
-      : MachOLinkGraphBuilder(Obj, getObjectTriple(Obj), std::move(Features),
-                              aarch64::getEdgeKindName),
+      : MachOLinkGraphBuilder(Obj, std::move(SSP), getObjectTriple(Obj),
+                              std::move(Features), aarch64::getEdgeKindName),
         NumSymbols(Obj.getSymtabLoadCommand().nsyms) {}
 
 private:
@@ -580,8 +581,8 @@ class MachOJITLinker_arm64 : public JITLinker<MachOJITLinker_arm64> {
   uint64_t NullValue = 0;
 };
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_arm64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer);
   if (!MachOObj)
     return MachOObj.takeError();
@@ -590,7 +591,7 @@ createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) {
   if (!Features)
     return Features.takeError();
 
-  return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(*Features))
+  return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(SSP), std::move(*Features))
       .buildGraph();
 }
 
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
index 2c69d61316a8ad..a9056e4d31232a 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp
@@ -27,8 +27,9 @@ namespace {
 class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
 public:
   MachOLinkGraphBuilder_x86_64(const object::MachOObjectFile &Obj,
+                               std::shared_ptr<orc::SymbolStringPool> SSP,
                                SubtargetFeatures Features)
-      : MachOLinkGraphBuilder(Obj, Triple("x86_64-apple-darwin"),
+      : MachOLinkGraphBuilder(Obj, std::move(SSP), Triple("x86_64-apple-darwin"),
                               std::move(Features), x86_64::getEdgeKindName) {}
 
 private:
@@ -483,8 +484,8 @@ class MachOJITLinker_x86_64 : public JITLinker<MachOJITLinker_x86_64> {
   }
 };
 
-Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer) {
+Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_x86_64(
+    MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
   auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer);
   if (!MachOObj)
     return MachOObj.takeError();
@@ -493,7 +494,7 @@ createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer) {
   if (!Features)
     return Features.takeError();
 
-  return MachOLinkGraphBuilder_x86_64(**MachOObj, std::move(*Features))
+  return MachOLinkGraphBuilder_x86_64(**MachOObj, std::move(SSP), std::move(*Features))
       .buildGraph();
 }
 
diff --git a/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h b/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
index 6e325f92bafbe4..89098c33b30a0c 100644
--- a/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
@@ -76,7 +76,7 @@ class PerGraphGOTAndPLTStubsBuilder {
     if (GOTEntryI == GOTEntries.end()) {
       auto &GOTEntry = impl().createGOTEntry(Target);
       LLVM_DEBUG({
-        dbgs() << "    Created GOT entry for " << Target.getName() << ": "
+        dbgs() << "    Created GOT entry for " << *Target.getName() << ": "
                << GOTEntry << "\n";
       });
       GOTEntryI =
@@ -97,7 +97,7 @@ class PerGraphGOTAndPLTStubsBuilder {
     if (StubI == PLTStubs.end()) {
       auto &StubSymbol = impl().createPLTStub(Target);
       LLVM_DEBUG({
-        dbgs() << "    Created PLT stub for " << Target.getName() << ": "
+        dbgs() << "    Created PLT stub for " << *Target.getName() << ": "
                << StubSymbol << "\n";
       });
       StubI =
@@ -114,8 +114,8 @@ class PerGraphGOTAndPLTStubsBuilder {
 private:
   BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }
 
-  DenseMap<StringRef, Symbol *> GOTEntries;
-  DenseMap<StringRef, Symbol *> PLTStubs;
+  DenseMap<orc::SymbolStringPtr, Symbol *> GOTEntries;
+  DenseMap<orc::SymbolStringPtr, Symbol *> PLTStubs;
 };
 
 } // end namespace jitlink
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index d183498f30a687..0a8aed84244137 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -852,14 +852,14 @@ bool StubsManager_prev7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
 
   Symbol &Target = E.getTarget();
   assert(Target.hasName() && "Edge cannot point to anonymous target");
-  auto [Slot, NewStub] = getStubMapSlot(Target.getName());
+  auto [Slot, NewStub] = getStubMapSlot(*Target.getName());
 
   if (NewStub) {
     if (!StubsSection)
       StubsSection = &G.createSection(getSectionName(),
                                       orc::MemProt::Read | orc::MemProt::Exec);
     LLVM_DEBUG({
-      dbgs() << "    Created stub entry for " << Target.getName() << " in "
+      dbgs() << "    Created stub entry for " << *Target.getName() << " in "
              << StubsSection->getName() << "\n";
     });
     Slot->B = &createStubPrev7(G, *StubsSection, Target);
@@ -896,7 +896,7 @@ bool StubsManager_v7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
 
   Symbol &Target = E.getTarget();
   assert(Target.hasName() && "Edge cannot point to anonymous target");
-  Symbol *&StubSymbol = getStubSymbolSlot(Target.getName(), MakeThumb);
+  Symbol *&StubSymbol = getStubSymbolSlot(*Target.getName(), MakeThumb);
 
   if (!StubSymbol) {
     if (!StubsSection)
@@ -910,7 +910,7 @@ bool StubsManager_v7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
 
     LLVM_DEBUG({
       dbgs() << "    Created " << (MakeThumb ? "Thumb" : "Arm") << " entry for "
-             << Target.getName() << " in " << StubsSection->getName() << ": "
+             << *Target.getName() << " in " << StubsSection->getName() << ": "
              << *StubSymbol << "\n";
     });
   }
diff --git a/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp
index 2176acc5bba807..ed8e6279672ba6 100644
--- a/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/COFFPlatform.cpp
@@ -68,8 +68,8 @@ class COFFHeaderMaterializationUnit : public MaterializationUnit {
     }
 
     auto G = std::make_unique<jitlink::LinkGraph>(
-        "<COFFHeaderMU>", TT, PointerSize, Endianness,
-        jitlink::getGenericEdgeKindName);
+        "<COFFHeaderMU>", CP.getExecutionSession().getSymbolStringPool(), TT,
+        PointerSize, Endianness, jitlink::getGenericEdgeKindName);
     auto &HeaderSection = G->createSection("__header", MemProt::Read);
     auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
 
@@ -792,7 +792,7 @@ Error COFFPlatform::COFFPlatformPlugin::associateJITDylibHeaderSymbol(
     jitlink::LinkGraph &G, MaterializationResponsibility &MR,
     bool IsBootstraping) {
   auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
-    return Sym->getName() == *CP.COFFHeaderStartSymbol;
+    return *Sym->getName() == *CP.COFFHeaderStartSymbol;
   });
   assert(I != G.defined_symbols().end() && "Missing COFF header start symbol");
 
diff --git a/llvm/lib/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.cpp
index e387b06ee9346b..c08e52e943c924 100644
--- a/llvm/lib/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.cpp
@@ -214,8 +214,8 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
 
         Builder.addSymbol("", MachO::N_BNSYM, 1, 0, 0);
         StabSymbols.push_back(
-            {*Sym, Builder.addSymbol(Sym->getName(), SymType, 1, 0, 0),
-             Builder.addSymbol(Sym->getName(), SymType, 0, 0, 0)});
+            {*Sym, Builder.addSymbol(*Sym->getName(), SymType, 1, 0, 0),
+             Builder.addSymbol(*Sym->getName(), SymType, 0, 0, 0)});
         Builder.addSymbol("", MachO::N_ENSYM, 1, 0, 0);
       }
     }
diff --git a/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
index 767115f984c1f0..05294f46e01d34 100644
--- a/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
@@ -86,7 +86,7 @@ constexpr StringRef RegisterPerfImplSymbolName =
 static PerfJITCodeLoadRecord
 getCodeLoadRecord(const Symbol &Sym, std::atomic<uint64_t> &CodeIndex) {
   PerfJITCodeLoadRecord Record;
-  auto Name = Sym.getName();
+  auto Name = *Sym.getName();
   auto Addr = Sym.getAddress();
   auto Size = Sym.getSize();
   Record.Prefix.Id = PerfJITRecordType::JIT_CODE_LOAD;
@@ -117,7 +117,7 @@ getDebugInfoRecord(const Symbol &Sym, DWARFContext &DC) {
   auto Addr = Sym.getAddress();
   auto Size = Sym.getSize();
   auto SAddr = object::SectionedAddress{Addr.getValue(), Section.getOrdinal()};
-  LLVM_DEBUG(dbgs() << "Getting debug info for symbol " << Sym.getName()
+  LLVM_DEBUG(dbgs() << "Getting debug info for symbol " << *Sym.getName()
                     << " at address " << Addr.getValue() << " with size "
                     << Size << "\n"
                     << "Section ordinal: " << Section.getOrdinal() << "\n");
diff --git a/llvm/lib/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.cpp
index de02a20524b9cb..9715a503629bf5 100644
--- a/llvm/lib/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.cpp
@@ -56,7 +56,7 @@ static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
     Method.ParentMI = 0;
     Method.LoadAddr = Sym->getAddress();
     Method.LoadSize = Sym->getSize();
-    Method.NameSI = GetStringIdx(Sym->getName());
+    Method.NameSI = GetStringIdx(*Sym->getName());
     Method.ClassFileSI = 0;
     Method.SourceFileSI = 0;
 
diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
index c48c73769955a1..8746aad471ad24 100644
--- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
@@ -65,9 +65,9 @@ std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(ELFNixPlatform &MOP,
     llvm_unreachable("Unrecognized architecture");
   }
 
-  return std::make_unique<jitlink::LinkGraph>(std::move(Name), TT, PointerSize,
-                                              Endianness,
-                                              jitlink::getGenericEdgeKindName);
+  return std::make_unique<jitlink::LinkGraph>(
+      std::move(Name), MOP.getExecutionSession().getSymbolStringPool(), TT,
+      PointerSize, Endianness, jitlink::getGenericEdgeKindName);
 }
 
 // Creates a Bootstrap-Complete LinkGraph to run deferred actions.
@@ -188,8 +188,8 @@ class DSOHandleMaterializationUnit : public MaterializationUnit {
 
     // void *__dso_handle = &__dso_handle;
     auto G = std::make_unique<jitlink::LinkGraph>(
-        "<DSOHandleMU>", TT, PointerSize, Endianness,
-        jitlink::getGenericEdgeKindName);
+        "<DSOHandleMU>", ENP.getExecutionSession().getSymbolStringPool(), TT,
+        PointerSize, Endianness, jitlink::getGenericEdgeKindName);
     auto &DSOHandleSection =
         G->createSection(".data.__dso_handle", MemProt::Read);
     auto &DSOHandleBlock = G->createContentBlock(
@@ -663,14 +663,14 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::
 
   for (auto *Sym : G.defined_symbols()) {
     for (auto &RTSym : RuntimeSymbols) {
-      if (Sym->hasName() && Sym->getName() == RTSym.first) {
+      if (Sym->hasName() && *Sym->getName() == RTSym.first) {
         if (*RTSym.second)
           return make_error<StringError>(
               "Duplicate " + RTSym.first +
                   " detected during ELFNixPlatform bootstrap",
               inconvertibleErrorCode());
 
-        if (Sym->getName() == *MP.DSOHandleSymbol)
+        if (*Sym->getName() == *MP.DSOHandleSymbol)
           RegisterELFNixHeader = true;
 
         *RTSym.second = Sym->getAddress();
@@ -798,7 +798,7 @@ void ELFNixPlatform::ELFNixPlatformPlugin::addDSOHandleSupportPasses(
   Config.PostAllocationPasses.push_back([this, &JD = MR.getTargetJITDylib()](
                                             jitlink::LinkGraph &G) -> Error {
     auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
-      return Sym->getName() == *MP.DSOHandleSymbol;
+      return Sym->getName() == MP.DSOHandleSymbol;
     });
     assert(I != G.defined_symbols().end() && "Missing DSO handle symbol");
     {
@@ -997,12 +997,17 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
 
 Error ELFNixPlatform::ELFNixPlatformPlugin::fixTLVSectionsAndEdges(
     jitlink::LinkGraph &G, JITDylib &JD) {
-
+  auto TLSGetAddrSymbolName = G.intern("__tls_get_addr");
+  auto TLSDescResolveSymbolName = G.intern("__tlsdesc_resolver");
   for (auto *Sym : G.external_symbols()) {
-    if (Sym->getName() == "__tls_get_addr") {
-      Sym->setName("___orc_rt_elfnix_tls_get_addr");
-    } else if (Sym->getName() == "__tlsdesc_resolver") {
-      Sym->setName("___orc_rt_elfnix_tlsdesc_resolver");
+    if (Sym->getName() == TLSGetAddrSymbolName) {
+      auto TLSGetAddr =
+          MP.getExecutionSession().intern("___orc_rt_elfnix_tls_get_addr");
+      Sym->setName(std::move(TLSGetAddr));
+    } else if (Sym->getName() == TLSDescResolveSymbolName) {
+      auto TLSGetAddr =
+          MP.getExecutionSession().intern("___orc_rt_elfnix_tlsdesc_resolver");
+      Sym->setName(std::move(TLSGetAddr));
     }
   }
 
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index edb49a41ecd120..9d616d1c61902f 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -13,6 +13,7 @@
 #include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
 #include "llvm/ExecutionEngine/Orc/MachO.h"
 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalVariable.h"
@@ -559,8 +560,8 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
     return Endianness.takeError();
 
   auto G = std::make_unique<jitlink::LinkGraph>(
-      "<DLLIMPORT_STUBS>", TT, *PointerSize, *Endianness,
-      jitlink::getGenericEdgeKindName);
+      "<DLLIMPORT_STUBS>", ES.getSymbolStringPool(), TT, *PointerSize,
+      *Endianness, jitlink::getGenericEdgeKindName);
   jitlink::Section &Sec =
       G->createSection(getSectionName(), MemProt::Read | MemProt::Exec);
 
@@ -572,9 +573,8 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
     // Create __imp_ symbol
     jitlink::Symbol &Ptr =
         jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target);
-    auto NameCopy = G->allocateContent(Twine(getImpPrefix()) + *KV.first);
-    StringRef NameCopyRef = StringRef(NameCopy.data(), NameCopy.size());
-    Ptr.setName(NameCopyRef);
+    auto name = getImpPrefix() + *KV.first;
+    Ptr.setName(G->intern((Twine(getImpPrefix()) + *KV.first).str()));
     Ptr.setLinkage(jitlink::Linkage::Strong);
     Ptr.setScope(jitlink::Scope::Default);
 
diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index ee9acf0ab33a40..f927d4d03c7941 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -398,7 +398,7 @@ Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym,
   auto SymSize = Sym.getSize() ? Sym.getSize() : B.getSize() - Sym.getOffset();
   auto Content = ArrayRef(SymStartInBlock, SymSize);
 
-  LLVM_DEBUG(dbgs() << "Adding self-relocations to " << Sym.getName() << "\n");
+  LLVM_DEBUG(dbgs() << "Adding self-relocations to " << *Sym.getName() << "\n");
 
   SmallDenseSet<uintptr_t, 8> ExistingRelocations;
   for (auto &E : B.edges()) {
diff --git a/llvm/lib/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.cpp b/llvm/lib/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.cpp
index 5a08083497d0d4..8dd479a64f1b5e 100644
--- a/llvm/lib/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.cpp
@@ -27,8 +27,8 @@ void JITLinkRedirectableSymbolManager::emitRedirectableSymbols(
   Triple TT = ES.getTargetTriple();
 
   auto G = std::make_unique<jitlink::LinkGraph>(
-      ("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(), TT,
-      TT.isArch64Bit() ? 8 : 4,
+      ("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(),
+      ES.getSymbolStringPool(), TT, TT.isArch64Bit() ? 8 : 4,
       TT.isLittleEndian() ? endianness::little : endianness::big,
       jitlink::getGenericEdgeKindName);
   auto &PointerSection =
@@ -46,10 +46,10 @@ void JITLinkRedirectableSymbolManager::emitRedirectableSymbols(
 
     auto PtrName = ES.intern((*Name + StubSuffix).str());
     auto &Ptr = AnonymousPtrCreator(*G, PointerSection, TargetSym, 0);
-    Ptr.setName(*PtrName);
+    Ptr.setName(PtrName);
     Ptr.setScope(jitlink::Scope::Hidden);
     auto &Stub = PtrJumpStubCreator(*G, StubsSection, Ptr);
-    Stub.setName(*Name);
+    Stub.setName(Name);
     Stub.setScope(jitlink::Scope::Default);
     NewSymbols[std::move(PtrName)] = JITSymbolFlags();
   }
diff --git a/llvm/lib/ExecutionEngine/Orc/LazyObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/LazyObjectLinkingLayer.cpp
index 4dc2f2efd7e47e..1eff9a1bdf08b0 100644
--- a/llvm/lib/ExecutionEngine/Orc/LazyObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LazyObjectLinkingLayer.cpp
@@ -60,10 +60,10 @@ class LazyObjectLinkingLayer::RenamerPlugin
     for (auto *Sym : G.defined_symbols()) {
       if (!Sym->hasName())
         continue;
-      auto I = SymsToRename.find(Sym->getName());
+      auto I = SymsToRename.find(*Sym->getName());
       if (I == SymsToRename.end())
         continue;
-      Sym->setName(G.allocateName(*I->second));
+      Sym->setName(G.intern(G.allocateName(*I->second)));
     }
 
     return Error::success();
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index b4326a17de3b7b..4fb68e0ed97171 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -108,9 +108,9 @@ std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(MachOPlatform &MOP,
     llvm_unreachable("Unrecognized architecture");
   }
 
-  return std::make_unique<jitlink::LinkGraph>(std::move(Name), TT, PointerSize,
-                                              Endianness,
-                                              jitlink::getGenericEdgeKindName);
+  return std::make_unique<jitlink::LinkGraph>(
+      std::move(Name), MOP.getExecutionSession().getSymbolStringPool(), TT,
+      PointerSize, Endianness, jitlink::getGenericEdgeKindName);
 }
 
 // Creates a Bootstrap-Complete LinkGraph to run deferred actions.
@@ -893,14 +893,14 @@ Error MachOPlatform::MachOPlatformPlugin::
 
   for (auto *Sym : G.defined_symbols()) {
     for (auto &RTSym : RuntimeSymbols) {
-      if (Sym->hasName() && Sym->getName() == RTSym.first) {
+      if (Sym->hasName() && *Sym->getName() == RTSym.first) {
         if (*RTSym.second)
           return make_error<StringError>(
               "Duplicate " + RTSym.first +
                   " detected during MachOPlatform bootstrap",
               inconvertibleErrorCode());
 
-        if (Sym->getName() == *MP.MachOHeaderStartSymbol)
+        if (Sym->getName() == MP.MachOHeaderStartSymbol)
           RegisterMachOHeader = true;
 
         *RTSym.second = Sym->getAddress();
@@ -936,7 +936,7 @@ Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(
 Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
     jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
   auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
-    return Sym->getName() == *MP.MachOHeaderStartSymbol;
+    return Sym->getName() == MP.MachOHeaderStartSymbol;
   });
   assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");
 
@@ -1175,11 +1175,13 @@ Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
 
 Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
     jitlink::LinkGraph &G, JITDylib &JD) {
-
+  auto TLVBootStrapSymbolName = G.intern("__tlv_bootstrap");
   // Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
   for (auto *Sym : G.external_symbols())
-    if (Sym->getName() == "__tlv_bootstrap") {
-      Sym->setName("___orc_rt_macho_tlv_get_addr");
+    if (Sym->getName() == TLVBootStrapSymbolName) {
+      auto TLSGetADDR =
+          MP.getExecutionSession().intern("___orc_rt_macho_tlv_get_addr");
+      Sym->setName(std::move(TLSGetADDR));
       break;
     }
 
@@ -1499,19 +1501,19 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
       // Look for an existing __objc_imageinfo symbol.
       jitlink::Symbol *ObjCImageInfoSym = nullptr;
       for (auto *Sym : G.external_symbols())
-        if (Sym->getName() == ObjCImageInfoSymbolName) {
+        if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
           ObjCImageInfoSym = Sym;
           break;
         }
       if (!ObjCImageInfoSym)
         for (auto *Sym : G.absolute_symbols())
-          if (Sym->getName() == ObjCImageInfoSymbolName) {
+          if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
             ObjCImageInfoSym = Sym;
             break;
           }
       if (!ObjCImageInfoSym)
         for (auto *Sym : G.defined_symbols())
-          if (Sym->hasName() && Sym->getName() == ObjCImageInfoSymbolName) {
+          if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
             ObjCImageInfoSym = Sym;
             std::optional<uint32_t> Flags;
             {
@@ -1652,11 +1654,11 @@ Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
       if (!Sym->hasName())
         continue;
 
-      auto I = ExistingStrings.find(Sym->getName());
+      auto I = ExistingStrings.find(*Sym->getName());
       if (I == ExistingStrings.end()) {
         auto &NameBlock = G.createMutableContentBlock(
-            *CStringSec, G.allocateCString(Sym->getName()), orc::ExecutorAddr(),
-            1, 0);
+            *CStringSec, G.allocateCString(*Sym->getName()),
+            orc::ExecutorAddr(), 1, 0);
         auto &SymbolNameSym = G.addAnonymousSymbol(
             NameBlock, 0, NameBlock.getSize(), false, true);
         JITSymTabInfo.push_back({Sym, &SymbolNameSym});
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
index 71221c2d3fce54..0b2cafb0bff13e 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
@@ -129,7 +129,7 @@ getELFObjectFileSymbolInfo(ExecutionSession &ES,
     if (Sym.getBinding() == ELF::STB_GNU_UNIQUE)
       *SymFlags |= JITSymbolFlags::Weak;
 
-    I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
+    I.SymbolFlags[ES.intern(std::move(*Name))] = std::move(*SymFlags);
   }
 
   SymbolStringPtr InitSymbol;
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 592941752805a7..52c1583873f10a 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -98,8 +98,7 @@ class LinkGraphMaterializationUnit : public MaterializationUnit {
         return;
       assert(Sym->hasName() && "Anonymous non-local symbol?");
 
-      LGI.SymbolFlags[ES.intern(Sym->getName())] =
-          getJITSymbolFlagsForSymbol(*Sym);
+      LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym);
     };
 
     for (auto *Sym : G.defined_symbols())
@@ -127,7 +126,7 @@ class LinkGraphMaterializationUnit : public MaterializationUnit {
 
   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
     for (auto *Sym : G->defined_symbols())
-      if (Sym->getName() == *Name) {
+      if (Sym->getName() == Name) {
         assert(Sym->getLinkage() == Linkage::Weak &&
                "Discarding non-weak definition");
         G->makeExternal(*Sym);
@@ -202,7 +201,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
         LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol;
         break;
       }
-      LookupSet.add(ES.intern(KV.first), LookupFlags);
+      LookupSet.add(KV.first, LookupFlags);
     }
 
     // OnResolve -- De-intern the symbols and pass the result to the linker.
@@ -213,7 +212,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
       else {
         AsyncLookupResult LR;
         for (auto &KV : *Result)
-          LR[*KV.first] = KV.second;
+          LR[KV.first] = KV.second;
         LookupContinuation->run(std::move(LR));
       }
     };
@@ -229,7 +228,6 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
   }
 
   Error notifyResolved(LinkGraph &G) override {
-    auto &ES = Layer.getExecutionSession();
 
     SymbolFlagsMap ExtraSymbolsToClaim;
     bool AutoClaim = Layer.AutoClaimObjectSymbols;
@@ -237,27 +235,25 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     SymbolMap InternedResult;
     for (auto *Sym : G.defined_symbols())
       if (Sym->hasName() && Sym->getScope() != Scope::Local) {
-        auto InternedName = ES.intern(Sym->getName());
         auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
         auto Flags = getJITSymbolFlagsForSymbol(*Sym);
-        InternedResult[InternedName] = {Ptr, Flags};
-        if (AutoClaim && !MR->getSymbols().count(InternedName)) {
-          assert(!ExtraSymbolsToClaim.count(InternedName) &&
+        InternedResult[Sym->getName()] = {Ptr, Flags};
+        if (AutoClaim && !MR->getSymbols().count(Sym->getName())) {
+          assert(!ExtraSymbolsToClaim.count(Sym->getName()) &&
                  "Duplicate symbol to claim?");
-          ExtraSymbolsToClaim[InternedName] = Flags;
+          ExtraSymbolsToClaim[Sym->getName()] = Flags;
         }
       }
 
     for (auto *Sym : G.absolute_symbols())
       if (Sym->hasName() && Sym->getScope() != Scope::Local) {
-        auto InternedName = ES.intern(Sym->getName());
         auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
         auto Flags = getJITSymbolFlagsForSymbol(*Sym);
-        InternedResult[InternedName] = {Ptr, Flags};
-        if (AutoClaim && !MR->getSymbols().count(InternedName)) {
-          assert(!ExtraSymbolsToClaim.count(InternedName) &&
+        InternedResult[Sym->getName()] = {Ptr, Flags};
+        if (AutoClaim && !MR->getSymbols().count(Sym->getName())) {
+          assert(!ExtraSymbolsToClaim.count(Sym->getName()) &&
                  "Duplicate symbol to claim?");
-          ExtraSymbolsToClaim[InternedName] = Flags;
+          ExtraSymbolsToClaim[Sym->getName()] = Flags;
         }
       }
 
@@ -379,19 +375,16 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
 
 private:
   Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) {
-    auto &ES = Layer.getExecutionSession();
-
     SymbolFlagsMap NewSymbolsToClaim;
     std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym;
 
     auto ProcessSymbol = [&](Symbol *Sym) {
       if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak &&
           Sym->getScope() != Scope::Local) {
-        auto Name = ES.intern(Sym->getName());
-        if (!MR->getSymbols().count(ES.intern(Sym->getName()))) {
-          NewSymbolsToClaim[Name] =
+        if (!MR->getSymbols().count(Sym->getName())) {
+          NewSymbolsToClaim[Sym->getName()] =
               getJITSymbolFlagsForSymbol(*Sym) | JITSymbolFlags::Weak;
-          NameToSym.push_back(std::make_pair(std::move(Name), Sym));
+          NameToSym.push_back(std::make_pair(Sym->getName(), Sym));
         }
       }
     };
@@ -421,9 +414,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
   }
 
   Error markResponsibilitySymbolsLive(LinkGraph &G) const {
-    auto &ES = Layer.getExecutionSession();
     for (auto *Sym : G.defined_symbols())
-      if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
+      if (Sym->hasName() && MR->getSymbols().count(Sym->getName()))
         Sym->setLive(true);
     return Error::success();
   }
@@ -558,15 +550,6 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     // SymbolDependenceGroups (in the SymbolDepGroups member), ready for use in
     // the upcoming notifyFinalized call.
     auto &TargetJD = MR->getTargetJITDylib();
-    auto &ES = TargetJD.getExecutionSession();
-
-    DenseMap<Symbol *, SymbolStringPtr> InternedNames;
-    auto GetInternedName = [&](Symbol *S) {
-      auto &Name = InternedNames[S];
-      if (!Name)
-        Name = ES.intern(S->getName());
-      return Name;
-    };
 
     for (auto &[B, BI] : BlockInfos) {
       if (!BI.Defs.empty()) {
@@ -574,10 +557,10 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
         auto &SDG = SymbolDepGroups.back();
 
         for (auto *Def : BI.Defs)
-          SDG.Symbols.insert(GetInternedName(Def));
+          SDG.Symbols.insert(Def->getName());
 
         for (auto *Dep : BI.SymbolDeps) {
-          auto DepName = GetInternedName(Dep);
+          auto DepName = Dep->getName();
           if (Dep->isDefined())
             SDG.Dependencies[&TargetJD].insert(std::move(DepName));
           else {
@@ -643,8 +626,8 @@ void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
 
   auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>(
       *this, std::move(R), std::move(O));
-
-  if (auto G = createLinkGraphFromObject(ObjBuffer)) {
+  if (auto G = createLinkGraphFromObject(
+          ObjBuffer, getExecutionSession().getSymbolStringPool())) {
     Ctx->notifyMaterializing(**G);
     link(std::move(*G), std::move(Ctx));
   } else {
diff --git a/llvm/lib/ExecutionEngine/Orc/SectCreate.cpp b/llvm/lib/ExecutionEngine/Orc/SectCreate.cpp
index 4f28b8bda529b9..4ed05ef3573f85 100644
--- a/llvm/lib/ExecutionEngine/Orc/SectCreate.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/SectCreate.cpp
@@ -18,6 +18,7 @@ void SectCreateMaterializationUnit::materialize(
     std::unique_ptr<MaterializationResponsibility> R) {
   auto G = std::make_unique<LinkGraph>(
       "orc_sectcreate_" + SectName,
+      ObjLinkingLayer.getExecutionSession().getSymbolStringPool(),
       ObjLinkingLayer.getExecutionSession().getTargetTriple(),
       getGenericEdgeKindName);
 
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index c4326200b4dd46..0fc05a47648c1d 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -14,6 +14,7 @@
 #include "Targets/RuntimeDyldELFMips.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Endian.h"
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index de7630b9747ea4..24b03a058981a0 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -15,6 +15,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index ccc152dc753bca..b6f50db9d1bf77 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -365,7 +365,7 @@ static raw_ostream &
 operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
   OS << "Symbols:\n";
   for (auto &SKV : SIM)
-    OS << "  \"" << SKV.first() << "\" " << SKV.second << "\n";
+    OS << "  \"" << *(SKV.first) << "\" " << SKV.second << "\n";
   return OS;
 }
 
@@ -416,29 +416,29 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
       continue;
 
     if (Sym->getLinkage() == Linkage::Weak) {
-      if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
-          S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
+      if (!S.CanonicalWeakDefs.count(*Sym->getName()) ||
+          S.CanonicalWeakDefs[*Sym->getName()] != G.getName()) {
         LLVM_DEBUG({
-          dbgs() << "  Externalizing weak symbol " << Sym->getName() << "\n";
+          dbgs() << "  Externalizing weak symbol " << *Sym->getName() << "\n";
         });
         DefinitionsToRemove.push_back(Sym);
       } else {
         LLVM_DEBUG({
-          dbgs() << "  Making weak symbol " << Sym->getName() << " strong\n";
+          dbgs() << "  Making weak symbol " << *Sym->getName() << " strong\n";
         });
-        if (S.HarnessExternals.count(Sym->getName()))
+        if (S.HarnessExternals.count(*Sym->getName()))
           Sym->setScope(Scope::Default);
         else
           Sym->setScope(Scope::Hidden);
         Sym->setLinkage(Linkage::Strong);
       }
-    } else if (S.HarnessExternals.count(Sym->getName())) {
-      LLVM_DEBUG(dbgs() << "  Promoting " << Sym->getName() << "\n");
+    } else if (S.HarnessExternals.count(*Sym->getName())) {
+      LLVM_DEBUG(dbgs() << "  Promoting " << *Sym->getName() << "\n");
       Sym->setScope(Scope::Default);
       Sym->setLive(true);
       continue;
-    } else if (S.HarnessDefinitions.count(Sym->getName())) {
-      LLVM_DEBUG(dbgs() << "  Externalizing " << Sym->getName() << "\n");
+    } else if (S.HarnessDefinitions.count(*Sym->getName())) {
+      LLVM_DEBUG(dbgs() << "  Externalizing " << *Sym->getName() << "\n");
       DefinitionsToRemove.push_back(Sym);
     }
   }
@@ -1306,9 +1306,9 @@ Error Session::FileInfo::registerGOTEntry(
   auto TS = GetSymbolTarget(G, Sym.getBlock());
   if (!TS)
     return TS.takeError();
-  GOTEntryInfos[TS->getName()] = {Sym.getSymbolContent(),
-                                  Sym.getAddress().getValue(),
-                                  Sym.getTargetFlags()};
+  GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),
+                                   Sym.getAddress().getValue(),
+                                   Sym.getTargetFlags()};
   return Error::success();
 }
 
@@ -1322,7 +1322,7 @@ Error Session::FileInfo::registerStubEntry(
   if (!TS)
     return TS.takeError();
 
-  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[TS->getName()];
+  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];
   Entry.insert(Entry.begin(),
                {Sym.getSymbolContent(), Sym.getAddress().getValue(),
                 Sym.getTargetFlags()});
@@ -1340,7 +1340,7 @@ Error Session::FileInfo::registerMultiStubEntry(
   if (!Target)
     return Target.takeError();
 
-  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[Target->getName()];
+  SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];
   Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),
                      Sym.getTargetFlags());
 
@@ -1485,15 +1485,16 @@ Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
   return GOTInfoItr->second;
 }
 
-bool Session::isSymbolRegistered(StringRef SymbolName) {
+bool Session::isSymbolRegistered(const orc::SymbolStringPtr& SymbolName) {
   return SymbolInfos.count(SymbolName);
 }
 
 Expected<Session::MemoryRegionInfo &>
-Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) {
+Session::findSymbolInfo(const orc::SymbolStringPtr& SymbolName,
+                        Twine ErrorMsgStem) {
   auto SymInfoItr = SymbolInfos.find(SymbolName);
   if (SymInfoItr == SymbolInfos.end())
-    return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName +
+    return make_error<StringError>(ErrorMsgStem + ": symbol " + *SymbolName +
                                        " not found",
                                    inconvertibleErrorCode());
   return SymInfoItr->second;
@@ -1719,12 +1720,13 @@ static Error addAbsoluteSymbols(Session &S,
                                          AbsDefStmt + "\"",
                                      inconvertibleErrorCode());
     ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);
-    if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}})))
+    auto InternedName = S.ES.intern(Name);
+    if (auto Err = JD.define(absoluteSymbols({{InternedName, AbsDef}})))
       return Err;
 
     // Register the absolute symbol with the session symbol infos.
-    S.SymbolInfos[Name] = {ArrayRef<char>(), Addr,
-                           AbsDef.getFlags().getTargetFlags()};
+    S.SymbolInfos[InternedName] = {ArrayRef<char>(), Addr,
+                                  AbsDef.getFlags().getTargetFlags()};
   }
 
   return Error::success();
@@ -2330,11 +2332,13 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
   LLVM_DEBUG(dbgs() << "Running checks...\n");
 
   auto IsSymbolValid = [&S](StringRef Symbol) {
-    return S.isSymbolRegistered(Symbol);
+    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
+    return S.isSymbolRegistered(InternedSymbol);
   };
 
   auto GetSymbolInfo = [&S](StringRef Symbol) {
-    return S.findSymbolInfo(Symbol, "Can not get symbol info");
+    auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
+    return S.findSymbolInfo(InternedSymbol, "Can not get symbol info");
   };
 
   auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h
index 40fac2fe6888fe..3163a852c846d9 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h
@@ -78,7 +78,6 @@ struct Session {
     using LinkGraph = jitlink::LinkGraph;
     using GetSymbolTargetFunction =
         unique_function<Expected<Symbol &>(LinkGraph &G, jitlink::Block &)>;
-
     Error registerGOTEntry(LinkGraph &G, Symbol &Sym,
                            GetSymbolTargetFunction GetSymbolTarget);
     Error registerStubEntry(LinkGraph &G, Symbol &Sym,
@@ -88,7 +87,7 @@ struct Session {
   };
 
   using DynLibJDMap = std::map<std::string, orc::JITDylib *, std::less<>>;
-  using SymbolInfoMap = StringMap<MemoryRegionInfo>;
+  using SymbolInfoMap = DenseMap<orc::SymbolStringPtr, MemoryRegionInfo>;
   using FileInfoMap = StringMap<FileInfo>;
 
   Expected<orc::JITDylib *> getOrLoadDynamicLibrary(StringRef LibPath);
@@ -111,8 +110,8 @@ struct Session {
   Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
                                                 StringRef TargetName);
 
-  bool isSymbolRegistered(StringRef Name);
-  Expected<MemoryRegionInfo &> findSymbolInfo(StringRef SymbolName,
+  bool isSymbolRegistered(const orc::SymbolStringPtr& Name);
+  Expected<MemoryRegionInfo &> findSymbolInfo(const orc::SymbolStringPtr& Name,
                                               Twine ErrorMsgStem);
 
   DynLibJDMap DynLibJDs;
diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
index f07ddddd5fe9c6..9c07d215caad8f 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
@@ -6,10 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <llvm/ExecutionEngine/JITLink/aarch32.h>
-
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
+#include <llvm/ExecutionEngine/JITLink/aarch32.h>
 
 using namespace llvm;
 using namespace llvm::jitlink;
@@ -18,7 +18,8 @@ using namespace llvm::support;
 using namespace llvm::support::endian;
 
 constexpr unsigned PointerSize = 4;
-auto G = std::make_unique<LinkGraph>("foo", Triple("armv7-linux-gnueabi"),
+auto G = std::make_unique<LinkGraph>("foo", std::make_shared<orc::SymbolStringPool>(), 
+                                     Triple("armv7-linux-gnueabi"),
                                      PointerSize, endianness::little,
                                      aarch32::getEdgeKindName);
 auto &Sec =
@@ -46,7 +47,8 @@ class AArch32Errors : public testing::Test {
   static void SetUpTestCase() {}
 
   void SetUp() override {
-    G = std::make_unique<LinkGraph>("foo", Triple("armv7-linux-gnueabi"),
+    G = std::make_unique<LinkGraph>("foo", std::make_shared<orc::SymbolStringPool>(), 
+                                    Triple("armv7-linux-gnueabi"),
                                     PointerSize, endianness::little,
                                     aarch32::getEdgeKindName);
     S = &G->createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
diff --git a/llvm/unittests/ExecutionEngine/JITLink/EHFrameSupportTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/EHFrameSupportTests.cpp
index e7e09b3fe40b13..eaf9733b228196 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/EHFrameSupportTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/EHFrameSupportTests.cpp
@@ -172,7 +172,8 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
   // (3) Each FDE has an edge pointing to the CIE at the correct offset.
   // (4) Each function has exactly one FDE pointing at it.
 
-  auto G = cantFail(createLinkGraphFromMachOObject_arm64(TestObject));
+  auto G = cantFail(createLinkGraphFromMachOObject_arm64(
+      TestObject, std::make_shared<orc::SymbolStringPool>()));
   cantFail(createEHFrameSplitterPass_MachO_arm64()(*G));
   cantFail(createEHFrameEdgeFixerPass_MachO_arm64()(*G));
 
@@ -211,7 +212,7 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
       ASSERT_TRUE(!!CFIBI.getPCBeginEdge());
       auto &PCBeginTarget = CFIBI.getPCBeginEdge()->getTarget();
       ASSERT_TRUE(PCBeginTarget.hasName());
-      Targets.insert(PCBeginTarget.getName());
+      Targets.insert(*PCBeginTarget.getName());
 
       // If the FDE points at CIEs[0] (the CIE without a personality) then it
       // should not have an LSDA. If it points to CIEs[1] then it should have
@@ -232,11 +233,12 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
 TEST(EHFrameCFIBlockInspector, ExternalPCBegin) {
   // Check that we don't crash if we transform the target of an FDE into an
   // external symbol before running edge-fixing.
-  auto G = cantFail(createLinkGraphFromMachOObject_arm64(TestObject));
+  auto G = cantFail(createLinkGraphFromMachOObject_arm64(
+      TestObject, std::make_shared<orc::SymbolStringPool>()));
 
   // Make '_a' external.
   for (auto *Sym : G->defined_symbols())
-    if (Sym->hasName() && Sym->getName() == "_a") {
+    if (Sym->hasName() && *Sym->getName() == "_a") {
       G->makeExternal(*Sym);
       break;
     }
diff --git a/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.cpp b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.cpp
index 9a7878edab5045..650b0c611606f7 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestUtils.cpp
@@ -92,9 +92,10 @@ void defaultCtxSetup(MockJITLinkContext &) {}
 TEST(JITLinkMocks, SmokeTest) {
   // Check that the testing infrastructure defaults can "link" a graph
   // successfully.
-  auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
-                                       llvm::endianness::little,
-                                       getGenericEdgeKindName);
+  auto G = std::make_unique<LinkGraph>(
+      "foo",  std::make_shared<orc::SymbolStringPool>(), 
+      Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+      getGenericEdgeKindName);
 
   ArrayRef<char> Content = "hello, world!";
   auto &Sec =
diff --git a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
index 936559f072e052..3b96019766c848 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
@@ -21,7 +21,8 @@ using namespace llvm::jitlink;
 
 TEST(LinkGraphTest, Construction) {
   // Check that LinkGraph construction works as expected.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   EXPECT_EQ(G.getName(), "foo");
   EXPECT_EQ(G.getTargetTriple().str(), "x86_64-apple-darwin");
@@ -35,7 +36,8 @@ TEST(LinkGraphTest, Construction) {
 
 TEST(LinkGraphTest, AddressAccess) {
   // Check that we can get addresses for blocks, symbols, and edges.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
 
   auto &Sec1 =
@@ -54,7 +56,8 @@ TEST(LinkGraphTest, AddressAccess) {
 
 TEST(LinkGraphTest, SectionEmpty) {
   // Check that Section::empty behaves as expected.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec1 =
       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@@ -72,7 +75,8 @@ TEST(LinkGraphTest, SectionEmpty) {
 
 TEST(LinkGraphTest, BlockAndSymbolIteration) {
   // Check that we can iterate over blocks within Sections and across sections.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec1 =
       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@@ -125,7 +129,8 @@ TEST(LinkGraphTest, BlockAndSymbolIteration) {
 
 TEST(LinkGraphTest, ContentAccessAndUpdate) {
   // Check that we can make a defined symbol external.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -214,7 +219,8 @@ TEST(LinkGraphTest, ContentAccessAndUpdate) {
 
 TEST(LinkGraphTest, MakeExternal) {
   // Check that we can make defined and absolute symbols external.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -284,7 +290,8 @@ TEST(LinkGraphTest, MakeExternal) {
 
 TEST(LinkGraphTest, MakeAbsolute) {
   // Check that we can make defined and external symbols absolute.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -353,7 +360,8 @@ TEST(LinkGraphTest, MakeAbsolute) {
 
 TEST(LinkGraphTest, MakeDefined) {
   // Check that we can make an external symbol defined.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -401,7 +409,8 @@ TEST(LinkGraphTest, MakeDefined) {
 
 TEST(LinkGraphTest, TransferDefinedSymbol) {
   // Check that we can transfer a defined symbol from one block to another.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -436,7 +445,8 @@ TEST(LinkGraphTest, TransferDefinedSymbol) {
 TEST(LinkGraphTest, TransferDefinedSymbolAcrossSections) {
   // Check that we can transfer a defined symbol from an existing block in one
   // section to another.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec1 =
       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@@ -470,7 +480,8 @@ TEST(LinkGraphTest, TransferDefinedSymbolAcrossSections) {
 TEST(LinkGraphTest, TransferBlock) {
   // Check that we can transfer a block (and all associated symbols) from one
   // section to another.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec1 =
       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@@ -518,7 +529,8 @@ TEST(LinkGraphTest, TransferBlock) {
 TEST(LinkGraphTest, MergeSections) {
   // Check that we can transfer a block (and all associated symbols) from one
   // section to another.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec1 =
       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@@ -604,7 +616,8 @@ TEST(LinkGraphTest, MergeSections) {
 
 TEST(LinkGraphTest, SplitBlock) {
   // Check that the LinkGraph::splitBlock test works as expected.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -716,7 +729,8 @@ TEST(LinkGraphTest, SplitBlock) {
 }
 
 TEST(LinkGraphTest, GraphAllocationMethods) {
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
 
   // Test allocation of sized, uninitialized buffer.
@@ -737,7 +751,8 @@ TEST(LinkGraphTest, GraphAllocationMethods) {
 
 TEST(LinkGraphTest, IsCStringBlockTest) {
   // Check that the LinkGraph::splitBlock test works as expected.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto &Sec =
       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@@ -761,8 +776,8 @@ TEST(LinkGraphTest, IsCStringBlockTest) {
 }
 
 TEST(LinkGraphTest, BasicLayoutHonorsNoAlloc) {
-  // Check that BasicLayout honors NoAlloc.
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
 
   // Create a regular section and block.
diff --git a/llvm/unittests/ExecutionEngine/JITLink/MachOLinkGraphTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/MachOLinkGraphTests.cpp
index be922275be26f4..d4357ed7516bb2 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/MachOLinkGraphTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/MachOLinkGraphTests.cpp
@@ -11,6 +11,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
 #include "llvm/ExecutionEngine/JITLink/MachO.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
@@ -20,8 +21,9 @@ using namespace llvm::jitlink;
 
 TEST(MachOLinkGraphTest, GetStandardSections) {
   // Check that LinkGraph construction works as expected.
-  LinkGraph G("foo", Triple("arm64-apple-darwin"), 8, llvm::endianness::little,
-              getGenericEdgeKindName);
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(), 
+              Triple("arm64-apple-darwin"), 8,
+              llvm::endianness::little, getGenericEdgeKindName);
 
   auto &Data = getMachODefaultRWDataSection(G);
   EXPECT_TRUE(Data.empty());
diff --git a/llvm/unittests/ExecutionEngine/JITLink/MemoryManagerErrorTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/MemoryManagerErrorTests.cpp
index 2b303f7a8c1a29..d1284ffb2ecf2a 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/MemoryManagerErrorTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/MemoryManagerErrorTests.cpp
@@ -18,9 +18,10 @@ using namespace llvm::jitlink;
 
 TEST(MemoryManagerErrorTest, ErrorOnFirstAllocate) {
   // Check that we can get addresses for blocks, symbols, and edges.
-  auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
-                                       llvm::endianness::little,
-                                       getGenericEdgeKindName);
+  auto G = std::make_unique<LinkGraph>(
+      "foo", std::make_shared<orc::SymbolStringPool>(),
+      Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+      getGenericEdgeKindName);
 
   ArrayRef<char> Content = "hello, world!";
   auto &Sec =
diff --git a/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp
index 6a8f89639a0743..8efbb54f59e848 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/StubsTests.cpp
@@ -57,7 +57,8 @@ GenerateStub(LinkGraph &G, size_t PointerSize, Edge::Kind PointerEdgeKind) {
 TEST(StubsTest, StubsGeneration_x86_64) {
   const char PointerJumpStubContent[6] = {
       static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};
-  LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto [PointerSym, StubSym] = GenerateStub(G, 8U, x86_64::Pointer64);
 
@@ -77,7 +78,8 @@ TEST(StubsTest, StubsGeneration_aarch64) {
       0x10, 0x02, 0x40, (char)0xf9u, // LDR x16, [x16, <imm>@pageoff12]
       0x00, 0x02, 0x1f, (char)0xd6u  // BR  x16
   };
-  LinkGraph G("foo", Triple("aarch64-linux-gnu"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("aarch64-linux-gnu"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto [PointerSym, StubSym] = GenerateStub(G, 8U, aarch64::Pointer64);
 
@@ -97,8 +99,9 @@ TEST(StubsTest, StubsGeneration_aarch64) {
 TEST(StubsTest, StubsGeneration_i386) {
   const char PointerJumpStubContent[6] = {
       static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};
-  LinkGraph G("foo", Triple("i386-unknown-linux-gnu"), 4,
-              llvm::endianness::little, getGenericEdgeKindName);
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("i386-unknown-linux-gnu"), 8, llvm::endianness::little,
+              getGenericEdgeKindName);
   auto [PointerSym, StubSym] = GenerateStub(G, 4U, i386::Pointer32);
 
   EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),
@@ -126,7 +129,8 @@ TEST(StubsTest, StubsGeneration_loongarch32) {
       0x00,
       0x4c // jr $t8
   };
-  LinkGraph G("foo", Triple("loongarch32"), 4, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("loongarch32"), 4, llvm::endianness::little,
               getGenericEdgeKindName);
   auto [PointerSym, StubSym] = GenerateStub(G, 4U, loongarch::Pointer32);
 
@@ -158,7 +162,8 @@ TEST(StubsTest, StubsGeneration_loongarch64) {
       0x00,
       0x4c // jr $t8
   };
-  LinkGraph G("foo", Triple("loongarch64"), 8, llvm::endianness::little,
+  LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
+              Triple("loongarch64"), 8, llvm::endianness::little,
               getGenericEdgeKindName);
   auto [PointerSym, StubSym] = GenerateStub(G, 8U, loongarch::Pointer64);
 
diff --git a/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
index 2e9733cbb039b7..4b8a3efe680f1f 100644
--- a/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/JITLinkRedirectionManagerTest.cpp
@@ -81,8 +81,8 @@ TEST_F(JITLinkRedirectionManagerTest, BasicRedirectionOperation) {
                         JD->getDefaultResourceTracker(),
                         {{RedirectableSymbol, MakeTarget(initialTarget)}}),
                     Succeeded());
-  auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));
 
+  auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));
   auto RTPtr = RTDef.getAddress().toPtr<int (*)()>();
   auto Result = RTPtr();
   EXPECT_EQ(Result, 42) << "Failed to call initial target";
diff --git a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
index bc996711f7ec50..d80cea4d8f1cf8 100644
--- a/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
@@ -44,9 +45,9 @@ class ObjectLinkingLayerTest : public testing::Test {
 };
 
 TEST_F(ObjectLinkingLayerTest, AddLinkGraph) {
-  auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
-                                       llvm::endianness::little,
-                                       x86_64::getEdgeKindName);
+  auto G = std::make_unique<LinkGraph>(
+      "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+      x86_64::getEdgeKindName);
 
   auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
   auto &B1 = G->createContentBlock(Sec1, BlockContent,
@@ -71,9 +72,10 @@ TEST_F(ObjectLinkingLayerTest, ResourceTracker) {
   // may invalidate some iterators internally.
   std::vector<ResourceTrackerSP> Trackers;
   for (unsigned I = 0; I < 64; I++) {
-    auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"),
-                                         8, llvm::endianness::little,
-                                         x86_64::getEdgeKindName);
+    auto G = std::make_unique<LinkGraph>(
+        "foo", ES.getSymbolStringPool(), 
+        Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+        x86_64::getEdgeKindName);
 
     auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
     auto &B1 = G->createContentBlock(Sec1, BlockContent,
@@ -138,10 +140,9 @@ TEST_F(ObjectLinkingLayerTest, ClaimLateDefinedWeakSymbols) {
   };
 
   ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
-
-  auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
-                                       llvm::endianness::little,
-                                       x86_64::getEdgeKindName);
+  auto G = std::make_unique<LinkGraph>(
+      "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+      getGenericEdgeKindName);
 
   auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
   auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
@@ -192,10 +193,10 @@ TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
   ES.setErrorReporter(consumeError);
 
   ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
-
-  auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
-                                       llvm::endianness::little,
-                                       x86_64::getEdgeKindName);
+  auto G = std::make_unique<LinkGraph>(
+      "foo", ES.getSymbolStringPool(), 
+      Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+      getGenericEdgeKindName);
 
   auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
   auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
@@ -247,9 +248,10 @@ TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
   ObjLinkingLayer.addPlugin(P);
 
   {
-    auto G1 = std::make_unique<LinkGraph>("G1", Triple("x86_64-apple-darwin"),
-                                          8, llvm::endianness::little,
-                                          x86_64::getEdgeKindName);
+    auto G1 = std::make_unique<LinkGraph>(
+        "G1", ES.getSymbolStringPool(), 
+        Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+        x86_64::getEdgeKindName);
 
     auto &DataSec = G1->createSection("__data", MemProt::Read | MemProt::Write);
     auto &DataBlock = G1->createContentBlock(DataSec, BlockContent,
@@ -265,9 +267,10 @@ TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
   ObjLinkingLayer.removePlugin(*P);
 
   {
-    auto G2 = std::make_unique<LinkGraph>("G2", Triple("x86_64-apple-darwin"),
-                                          8, llvm::endianness::little,
-                                          x86_64::getEdgeKindName);
+    auto G2 = std::make_unique<LinkGraph>(
+        "G2", ES.getSymbolStringPool(), 
+        Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
+        x86_64::getEdgeKindName);
 
     auto &DataSec = G2->createSection("__data", MemProt::Read | MemProt::Write);
     auto &DataBlock = G2->createContentBlock(DataSec, BlockContent,
@@ -325,8 +328,8 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
 
   auto G = EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
       ES, {}, [&](JITDylib &JD, SymbolMap Syms) {
-        auto G =
-            absoluteSymbolsLinkGraph(ES.getTargetTriple(), std::move(Syms));
+        auto G = absoluteSymbolsLinkGraph(
+            ES.getTargetTriple(), ES.getSymbolStringPool(), std::move(Syms));
         return ObjLinkingLayer.add(JD, std::move(G));
       });
   ASSERT_THAT_EXPECTED(G, Succeeded());
@@ -347,10 +350,10 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
             ADD_FAILURE() << "unexpected unnamed symbol";
             continue;
           }
-          if (Sym->getName() == "_testFunc")
+          if (*Sym->getName() == "_testFunc")
             SawSymbolDef = true;
           else
-            ADD_FAILURE() << "unexpected symbol " << Sym->getName();
+            ADD_FAILURE() << "unexpected symbol " << *Sym->getName();
         }
         EXPECT_EQ(SymCount, 1u);
         return Error::success();

>From 218bad76352a97d61545ca9b3fa42904259f2742 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 15:44:13 +1100
Subject: [PATCH 02/16] Update JITLinkLinker.cpp

---
 bolt/lib/Rewrite/JITLinkLinker.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/bolt/lib/Rewrite/JITLinkLinker.cpp b/bolt/lib/Rewrite/JITLinkLinker.cpp
index 1d6f8428432d72..f5ab9ec15ef3e7 100644
--- a/bolt/lib/Rewrite/JITLinkLinker.cpp
+++ b/bolt/lib/Rewrite/JITLinkLinker.cpp
@@ -167,11 +167,9 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext {
   Error notifyResolved(jitlink::LinkGraph &G) override {
     for (auto *Symbol : G.defined_symbols()) {
       SymbolInfo Info{Symbol->getAddress().getValue(), Symbol->getSize()};
-      auto Name = Symbol->getName();
-      std::string NameStr("");
-      if (Name)
-        NameStr = (*Name).str();
-      Linker.Symtab.insert({NameStr, Info});
+      auto Name =
+        Symbol->hasName() ? (*Symbol->getName()).str() : std::string();
+      Linker.Symtab.insert({std::move(Name), Info});
     }
 
     return Error::success();

>From 02e154cc3a1acfb38e7e76cf7422ab75d2db6f03 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 15:45:13 +1100
Subject: [PATCH 03/16] Fix typo.

---
 llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
index 140dad7b82e002..c4f2c532de7459 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
@@ -24,7 +24,7 @@ namespace jitlink {
 /// its contents. The caller is responsible for ensuring that the object buffer
 /// outlives the graph.
 Expected<std::unique_ptr<LinkGraph>>
-createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffe,
+createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer,
                                     std::shared_ptr<orc::SymbolStringPool> SSP);
 
 /// jit-link the given object buffer, which must be a ELF x86-64 object file.

>From a983fc96d21bf1d6bbcf1ba5d26fbb91e4103360 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 16:47:25 +1100
Subject: [PATCH 04/16] Remove deref.

Should no longer be needed as of 3e11ae69abd.
---
 llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h b/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
index d20c9c94d38067..3d068d97202d6f 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/TableManager.h
@@ -39,7 +39,7 @@ template <typename TableManagerImplT> class TableManager {
       auto &Entry = impl().createEntry(G, Target);
       DEBUG_WITH_TYPE("jitlink", {
         dbgs() << "    Created " << impl().getSectionName() << " entry for "
-               << *Target.getName() << ": " << Entry << "\n";
+               << Target.getName() << ": " << Entry << "\n";
       });
       EntryI = Entries.insert(std::make_pair(Target.getName(), &Entry)).first;
     }

>From 1dd3409054f9388c1511009458ff4746ba39805d Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 16:50:40 +1100
Subject: [PATCH 05/16] Remove SymbolStringPtr derefs in debugging output.

Should no longer be needed as of 3e11ae69abd.
---
 .../ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
index 14df746dcaebf3..e1869420d789db 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
@@ -239,7 +239,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
     if (Sym->isFileRecord())
       LLVM_DEBUG({
         dbgs() << "    " << SymIndex << ": Skipping FileRecord symbol \""
-               << *InternedSymbolName << "\" in "
+               << InternedSymbolName << "\" in "
                << getCOFFSectionName(SectionIndex, Sec, *Sym)
                << " (index: " << SectionIndex << ") \n";
       });
@@ -261,7 +261,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
         LLVM_DEBUG({
           dbgs() << "    " << SymIndex
                  << ": Creating defined graph symbol for COFF symbol \""
-                 << *InternedSymbolName << "\" in "
+                 << InternedSymbolName << "\" in "
                  << getCOFFSectionName(SectionIndex, Sec, *Sym)
                  << " (index: " << SectionIndex << ") \n";
           dbgs() << "      " << *GSym << "\n";
@@ -388,7 +388,7 @@ Symbol *COFFLinkGraphBuilder::createExternalSymbol(
   LLVM_DEBUG({
     dbgs() << "    " << SymIndex
            << ": Creating external graph symbol for COFF symbol \""
-           << *Sym->getName() << "\" in "
+           << Sym->getName() << "\" in "
            << getCOFFSectionName(Symbol.getSectionNumber(), Section, Symbol)
            << " (index: " << Symbol.getSectionNumber() << ") \n";
   });
@@ -501,7 +501,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
       dbgs() << "    " << SymIndex
              << ": Skipping graph symbol since section was not created for "
                 "COFF symbol \""
-             << *SymbolName << "\" in section " << Symbol.getSectionNumber()
+             << SymbolName << "\" in section " << Symbol.getSectionNumber()
              << "\n";
     });
     return nullptr;
@@ -632,7 +632,7 @@ COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
   LLVM_DEBUG({
     dbgs() << "    " << SymIndex
            << ": Exporting COMDAT graph symbol for COFF symbol \""
-           << *SymbolName << "\" in section " << Symbol.getSectionNumber()
+           << SymbolName << "\" in section " << Symbol.getSectionNumber()
            << "\n";
     dbgs() << "      " << *GSym << "\n";
   });

>From 10e98cb33d690c8470785b0722bff3d65a938190 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 16:55:35 +1100
Subject: [PATCH 06/16] Rename imageBaseName -> ImageBaseName, make method
 const.

---
 llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
index 5f2fd1b376a5da..3324adb0a44799 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
@@ -194,7 +194,7 @@ class COFFLinkGraphLowering_x86_64 {
 public:
   COFFLinkGraphLowering_x86_64(std::shared_ptr<orc::SymbolStringPool> SSP)
       : SSP(std::move(SSP)) {
-    imageBaseName = this->SSP->intern("__ImageBase");
+    ImageBaseName = this->SSP->intern("__ImageBase");
   }
   // Lowers COFF x86_64 specific edges to generic x86_64 edges.
   Error lowerCOFFRelocationEdges(LinkGraph &G, JITLinkContext &Ctx) {
@@ -237,7 +237,10 @@ class COFFLinkGraphLowering_x86_64 {
   }
 
 private:
-  orc::SymbolStringPtr & getImageBaseSymbolName() { return this->imageBaseName; }
+  const orc::SymbolStringPtr & getImageBaseSymbolName() const {
+    return this->ImageBaseName;
+  }
+
   orc::ExecutorAddr getSectionStart(Section &Sec) {
     if (!SectionStartCache.count(&Sec)) {
       SectionRange Range(Sec);
@@ -278,7 +281,7 @@ class COFFLinkGraphLowering_x86_64 {
   DenseMap<Section *, orc::ExecutorAddr> SectionStartCache;
   orc::ExecutorAddr ImageBase;
   std::shared_ptr<orc::SymbolStringPool> SSP;
-  orc::SymbolStringPtr imageBaseName = nullptr;
+  orc::SymbolStringPtr ImageBaseName = nullptr;
 };
 
 Error lowerEdges_COFF_x86_64(LinkGraph &G, JITLinkContext *Ctx) {

>From 7e51800aedd505a14f9509643048164c9f4c6826 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 16:57:40 +1100
Subject: [PATCH 07/16] Remove SymbolStringPtr derefs in debugging output.

---
 llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
index c6d29badb3a45e..8b6c88da52eb8f 100644
--- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
@@ -371,7 +371,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
         dbgs() << "      WARNING: Not adding keep-alive edge to FDE at "
                << RecordAddress << ", which points to "
                << ((*PCBegin)->isExternal() ? "external" : "absolute")
-               << " symbol \"" << *(*PCBegin)->getName()
+               << " symbol \"" << (*PCBegin)->getName()
                << "\" -- FDE must be kept alive manually or it will be "
                << "dead stripped.\n";
       });
@@ -524,7 +524,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
                << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
                << FieldName << " at " << EdgeI->second.Target->getAddress();
         if (EdgeI->second.Target->hasName())
-          dbgs() << " (" << *EdgeI->second.Target->getName() << ")";
+          dbgs() << " (" << EdgeI->second.Target->getName() << ")";
         dbgs() << "\n";
       });
       if (auto Err = skipEncodedPointer(PointerEncoding, RecordReader))
@@ -590,7 +590,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
            << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
            << FieldName << " at " << TargetSym->getAddress();
     if (TargetSym->hasName())
-      dbgs() << " (" << *TargetSym->getName() << ")";
+      dbgs() << " (" << TargetSym->getName() << ")";
     dbgs() << "\n";
   });
 

>From 4c066abe68f7c4eff7fc31629ad160d1a3ade37d Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:03:45 +1100
Subject: [PATCH 08/16] Remove SymbolStringPtr derefs in debugging output.

---
 llvm/lib/ExecutionEngine/JITLink/JITLink.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index 5c109151e6f96a..483a9bff356eba 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -123,7 +123,7 @@ raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) {
      << ", linkage: " << formatv("{0:6}", getLinkageName(Sym.getLinkage()))
      << ", scope: " << formatv("{0:8}", getScopeName(Sym.getScope())) << ", "
      << (Sym.isLive() ? "live" : "dead") << "  -   "
-     << (Sym.hasName() ? *Sym.getName() : "<anonymous symbol>");
+     << (Sym.hasName() ? Sym.getName() : "<anonymous symbol>");
   return OS;
 }
 
@@ -135,7 +135,7 @@ void printEdge(raw_ostream &OS, const Block &B, const Edge &E,
 
   auto &TargetSym = E.getTarget();
   if (TargetSym.hasName())
-    OS << *TargetSym.getName();
+    OS << TargetSym.getName();
   else {
     auto &TargetBlock = TargetSym.getBlock();
     auto &TargetSec = TargetBlock.getSection();
@@ -349,7 +349,7 @@ void LinkGraph::dump(raw_ostream &OS) {
             OS << formatv("-{0:x8}", -E.getAddend());
           OS << ", kind = " << getEdgeKindName(E.getKind()) << ", target = ";
           if (E.getTarget().hasName())
-            OS << *E.getTarget().getName();
+            OS << E.getTarget().getName();
           else
             OS << "addressable@"
                << formatv("{0:x16}", E.getTarget().getAddress()) << "+"
@@ -420,7 +420,7 @@ Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
     ErrStream << "In graph " << G.getName() << ", section " << Sec.getName()
               << ": relocation target ";
     if (E.getTarget().hasName()) {
-      ErrStream << "\"" << *E.getTarget().getName() << "\"";
+      ErrStream << "\"" << E.getTarget().getName() << "\"";
     } else
       ErrStream << E.getTarget().getBlock().getSection().getName() << " + "
                 << formatv("{0:x}", E.getOffset());
@@ -437,7 +437,7 @@ Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
         BestSymbolForBlock = Sym;
 
     if (BestSymbolForBlock)
-      ErrStream << *BestSymbolForBlock->getName() << ", ";
+      ErrStream << BestSymbolForBlock->getName() << ", ";
     else
       ErrStream << "<anonymous block> @ ";
 

>From 02336140afaf91541596736cd91a22476b6f8a83 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:06:07 +1100
Subject: [PATCH 09/16] Remove SymbolStringPtr deref operation.

---
 llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index 703031e3331ee0..0a20bab9bfe4b2 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -241,7 +241,7 @@ void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
   LLVM_DEBUG({
     dbgs() << "Externals after applying lookup result:\n";
     for (auto *Sym : G->external_symbols()) {
-      dbgs() << "  " << *Sym->getName() << ": "
+      dbgs() << "  " << Sym->getName() << ": "
              << formatv("{0:x16}", Sym->getAddress().getValue());
       switch (Sym->getLinkage()) {
       case Linkage::Strong:

>From 1b37fef651a7fb5b9c8567a26bd8594280696316 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:14:24 +1100
Subject: [PATCH 10/16] Remove SymbolStringPtr deref in debugging output.

---
 llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index c42fd089757214..c13a1f6d082bc4 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -836,7 +836,7 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
             return make_error<JITLinkError>(
                 "Error adding keep-alive edge for compact unwind record at " +
                 formatv("{0:x}", CURec->getAddress()) + ": target " +
-                *E.getTarget().getName() + " is an external symbol");
+                E.getTarget().getName() + " is an external symbol");
           auto &TgtBlock = E.getTarget().getBlock();
           auto &CURecSym =
               G.addAnonymousSymbol(*CURec, 0, CURecordSize, false, false);

>From 855582c0152a660c28d3bb1816ac5cacf71625e0 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:15:35 +1100
Subject: [PATCH 11/16] Remove redundant formatv.

---
 llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index c13a1f6d082bc4..25cea11dccc248 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -826,7 +826,7 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
         if (E.getOffset() == 0) {
           LLVM_DEBUG({
             dbgs() << "    Updating compact unwind record at "
-                   << formatv("{0:x16}", CURec->getAddress()) << " to point to "
+                   << CURec->getAddress() << " to point to "
                    << (E.getTarget().hasName() ? *E.getTarget().getName()
                                                : StringRef())
                    << " (at " << E.getTarget().getAddress() << ")\n";

>From ce642a6971352669ea34b2ad3f481de5d2ec741d Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:17:08 +1100
Subject: [PATCH 12/16] Remove SymbolStringPtr deref in debugging output.

---
 .../ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h b/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
index 89098c33b30a0c..a073ddcae29499 100644
--- a/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/PerGraphGOTAndPLTStubsBuilder.h
@@ -76,7 +76,7 @@ class PerGraphGOTAndPLTStubsBuilder {
     if (GOTEntryI == GOTEntries.end()) {
       auto &GOTEntry = impl().createGOTEntry(Target);
       LLVM_DEBUG({
-        dbgs() << "    Created GOT entry for " << *Target.getName() << ": "
+        dbgs() << "    Created GOT entry for " << Target.getName() << ": "
                << GOTEntry << "\n";
       });
       GOTEntryI =
@@ -97,7 +97,7 @@ class PerGraphGOTAndPLTStubsBuilder {
     if (StubI == PLTStubs.end()) {
       auto &StubSymbol = impl().createPLTStub(Target);
       LLVM_DEBUG({
-        dbgs() << "    Created PLT stub for " << *Target.getName() << ": "
+        dbgs() << "    Created PLT stub for " << Target.getName() << ": "
                << StubSymbol << "\n";
       });
       StubI =

>From c2f8cd61dfc679bb95e286c3c3920dd4c21b74dc Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:18:27 +1100
Subject: [PATCH 13/16] Remove SymbolStringPtr deref in debugging output.

---
 llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 0a8aed84244137..7b255717f23838 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -859,7 +859,7 @@ bool StubsManager_prev7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
       StubsSection = &G.createSection(getSectionName(),
                                       orc::MemProt::Read | orc::MemProt::Exec);
     LLVM_DEBUG({
-      dbgs() << "    Created stub entry for " << *Target.getName() << " in "
+      dbgs() << "    Created stub entry for " << Target.getName() << " in "
              << StubsSection->getName() << "\n";
     });
     Slot->B = &createStubPrev7(G, *StubsSection, Target);
@@ -910,7 +910,7 @@ bool StubsManager_v7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
 
     LLVM_DEBUG({
       dbgs() << "    Created " << (MakeThumb ? "Thumb" : "Arm") << " entry for "
-             << *Target.getName() << " in " << StubsSection->getName() << ": "
+             << Target.getName() << " in " << StubsSection->getName() << ": "
              << *StubSymbol << "\n";
     });
   }

>From 473c9257d7318ad0f222bfc9758a33b210915811 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:22:09 +1100
Subject: [PATCH 14/16] Remove SymbolStringPtr deref in debugging output.

---
 llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
index 05294f46e01d34..7a970f3cccf461 100644
--- a/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.cpp
@@ -117,7 +117,7 @@ getDebugInfoRecord(const Symbol &Sym, DWARFContext &DC) {
   auto Addr = Sym.getAddress();
   auto Size = Sym.getSize();
   auto SAddr = object::SectionedAddress{Addr.getValue(), Section.getOrdinal()};
-  LLVM_DEBUG(dbgs() << "Getting debug info for symbol " << *Sym.getName()
+  LLVM_DEBUG(dbgs() << "Getting debug info for symbol " << Sym.getName()
                     << " at address " << Addr.getValue() << " with size "
                     << Size << "\n"
                     << "Section ordinal: " << Section.getOrdinal() << "\n");

>From 0de822de55cfd998ee69676f94d996a0ed62db97 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:23:27 +1100
Subject: [PATCH 15/16] Remove SymbolStringPtr deref operation in debugging
 output.

---
 llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index f927d4d03c7941..ee9acf0ab33a40 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -398,7 +398,7 @@ Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym,
   auto SymSize = Sym.getSize() ? Sym.getSize() : B.getSize() - Sym.getOffset();
   auto Content = ArrayRef(SymStartInBlock, SymSize);
 
-  LLVM_DEBUG(dbgs() << "Adding self-relocations to " << *Sym.getName() << "\n");
+  LLVM_DEBUG(dbgs() << "Adding self-relocations to " << Sym.getName() << "\n");
 
   SmallDenseSet<uintptr_t, 8> ExistingRelocations;
   for (auto &E : B.edges()) {

>From a71d319df0f2695fa8b3f41b9b33d9163e950ecb Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 4 Dec 2024 17:26:55 +1100
Subject: [PATCH 16/16] Remove SymbolStringPtr deref in debugging output.

---
 llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index b6f50db9d1bf77..ab8181b0531607 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -365,7 +365,7 @@ static raw_ostream &
 operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
   OS << "Symbols:\n";
   for (auto &SKV : SIM)
-    OS << "  \"" << *(SKV.first) << "\" " << SKV.second << "\n";
+    OS << "  \"" << SKV.first << "\" " << SKV.second << "\n";
   return OS;
 }
 



More information about the llvm-commits mailing list