[llvm] [ORC] Unify symbol mapping and allow custom mapping functions (PR #79616)
Lucas Reis via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 26 08:48:24 PST 2024
https://github.com/lucasreis1 created https://github.com/llvm/llvm-project/pull/79616
This PR provides four changes:
1. Unify symbol mapping into IRLayer and discard the old IRSymbolMapper
class
2. Allow clients to provide their symbol mapper function to
provide custom mappings
3. Skip adding linkonce_odr symbols to the symbol map on the default
mapper (fixes https://github.com/llvm/llvm-project/issues/64907)
4. Create a small FAQ section to explain to users why their LLVM IR symbol might be missing a definition from the JIT as a result of change 3.
>From 1892f8d8df88b80e4a19563a686ae52970b2a5ca Mon Sep 17 00:00:00 2001
From: Lucas <lucas.reis091997 at gmail.com>
Date: Fri, 26 Jan 2024 12:36:36 -0400
Subject: [PATCH 1/2] [ORC] Unify symbol mapping and allow custom mapping
functions
This commit makes three changes:
1. Unify symbol mapping into IRLayer and discard the old IRSymbolMapper
class
2. Allow for clients to provide their own symbol mapper function to
provide custom mappings
3. Skip adding linkonce_odr symbols to the symbol map on the default
mapper (fixes llvm/llvm-project#64907)
---
.../llvm/ExecutionEngine/Orc/CompileUtils.h | 6 +-
.../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 10 +-
llvm/include/llvm/ExecutionEngine/Orc/Layer.h | 107 +++++++++++++++---
.../llvm/ExecutionEngine/Orc/Mangling.h | 23 +---
.../Orc/CompileOnDemandLayer.cpp | 96 ++++++++--------
llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp | 4 +-
llvm/lib/ExecutionEngine/Orc/Layer.cpp | 59 ++++++++--
llvm/lib/ExecutionEngine/Orc/Mangling.cpp | 53 ---------
8 files changed, 204 insertions(+), 154 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index a55aa3d71db2a1..843916f2f001f2 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -27,8 +27,7 @@ class TargetMachine;
namespace orc {
-IRSymbolMapper::ManglingOptions
-irManglingOptionsFromTargetOptions(const TargetOptions &Opts);
+ManglingOptions irManglingOptionsFromTargetOptions(const TargetOptions &Opts);
/// Simple compile functor: Takes a single IR module and returns an ObjectFile.
/// This compiler supports a single compilation thread and LLVMContext only.
@@ -49,8 +48,7 @@ class SimpleCompiler : public IRCompileLayer::IRCompiler {
Expected<CompileResult> operator()(Module &M) override;
private:
- IRSymbolMapper::ManglingOptions
- manglingOptionsForTargetMachine(const TargetMachine &TM);
+ ManglingOptions manglingOptionsForTargetMachine(const TargetMachine &TM);
CompileResult tryToLoadFromObjectCache(const Module &M);
void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer);
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index f493d63a7c8a99..02a18a2072853f 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -32,18 +32,18 @@ class IRCompileLayer : public IRLayer {
public:
class IRCompiler {
public:
- IRCompiler(IRSymbolMapper::ManglingOptions MO) : MO(std::move(MO)) {}
+ IRCompiler(ManglingOptions MO) : MO(std::move(MO)) {}
virtual ~IRCompiler();
- const IRSymbolMapper::ManglingOptions &getManglingOptions() const {
+ const ManglingOptions &getManglingOptions() const {
return MO;
}
virtual Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) = 0;
protected:
- IRSymbolMapper::ManglingOptions &manglingOptions() { return MO; }
+ ManglingOptions &manglingOptions() { return MO; }
private:
- IRSymbolMapper::ManglingOptions MO;
+ ManglingOptions MO;
};
using NotifyCompiledFunction = std::function<void(
@@ -63,7 +63,7 @@ class IRCompileLayer : public IRLayer {
mutable std::mutex IRLayerMutex;
ObjectLayer &BaseLayer;
std::unique_ptr<IRCompiler> Compile;
- const IRSymbolMapper::ManglingOptions *ManglingOpts;
+ const ManglingOptions *ManglingOpts;
NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
};
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
index cfeedc2a0bdaab..083a412119c107 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -16,6 +16,7 @@
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Mangling.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ExtensibleRTTI.h"
@@ -34,8 +35,7 @@ class IRMaterializationUnit : public MaterializationUnit {
/// Create an IRMaterializationLayer. Scans the module to build the
/// SymbolFlags and SymbolToDefinition maps.
- IRMaterializationUnit(ExecutionSession &ES,
- const IRSymbolMapper::ManglingOptions &MO,
+ IRMaterializationUnit(ExecutionSession &ES, const ManglingOptions &MO,
ThreadSafeModule TSM);
/// Create an IRMaterializationLayer from a module, and pre-existing
@@ -52,6 +52,15 @@ class IRMaterializationUnit : public MaterializationUnit {
/// Return a reference to the contained ThreadSafeModule.
const ThreadSafeModule &getModule() const { return TSM; }
+ struct SymbolInfo {
+ public:
+ SymbolInfo(MaterializationUnit::Interface I, SymbolNameToDefinitionMap SMap)
+ : Interface(I), SymbolToDefinition(SMap) {}
+
+ MaterializationUnit::Interface Interface;
+ SymbolNameToDefinitionMap SymbolToDefinition;
+ };
+
protected:
ThreadSafeModule TSM;
SymbolNameToDefinitionMap SymbolToDefinition;
@@ -66,8 +75,76 @@ class IRMaterializationUnit : public MaterializationUnit {
/// Interface for layers that accept LLVM IR.
class IRLayer {
public:
- IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
- : ES(ES), MO(MO) {}
+ using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
+ using IRSymbolMapper = unique_function<void(
+ ArrayRef<GlobalValue *> Gvs, ExecutionSession &ES,
+ const ManglingOptions &MO, SymbolFlagsMap &SymbolFlags,
+ SymbolNameToDefinitionMap *SymbolToDef)>;
+
+ /// Add mangled symbols for the given GlobalValues to SymbolFlags.
+ /// If a SymbolToDefinitionMap pointer is supplied then it will be populated
+ /// with Name-to-GlobalValue* mappings. Note that this mapping is not
+ /// necessarily one-to-one: thread-local GlobalValues, for example, may
+ /// produce more than one symbol, in which case the map will contain duplicate
+ /// values.
+ static void
+ defaultSymbolMapper(ArrayRef<GlobalValue *> GVs, ExecutionSession &ES,
+ const ManglingOptions &MO, SymbolFlagsMap &SymbolFlags,
+ SymbolNameToDefinitionMap *SymbolToDefinition = nullptr) {
+ if (GVs.empty())
+ return;
+
+ MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout());
+ for (auto *G : GVs) {
+ assert(G && "GVs cannot contain null elements");
+ // Follow static linkage behaviour to decide which GVs get a named symbol
+ if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() ||
+ G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage() ||
+ G->hasLinkOnceODRLinkage())
+ continue;
+
+ if (G->isThreadLocal() && MO.EmulatedTLS) {
+ auto *GV = cast<GlobalVariable>(G);
+
+ auto Flags = JITSymbolFlags::fromGlobalValue(*GV);
+
+ auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str());
+ SymbolFlags[EmuTLSV] = Flags;
+ if (SymbolToDefinition)
+ (*SymbolToDefinition)[EmuTLSV] = GV;
+
+ // If this GV has a non-zero initializer we'll need to emit an
+ // __emutls.t symbol too.
+ if (GV->hasInitializer()) {
+ const auto *InitVal = GV->getInitializer();
+
+ // Skip zero-initializers.
+ if (isa<ConstantAggregateZero>(InitVal))
+ continue;
+ const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
+ if (InitIntValue && InitIntValue->isZero())
+ continue;
+
+ auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str());
+ SymbolFlags[EmuTLST] = Flags;
+ if (SymbolToDefinition)
+ (*SymbolToDefinition)[EmuTLST] = GV;
+ }
+ continue;
+ }
+
+ // Otherwise we just need a normal linker mangling.
+ auto MangledName = Mangle(G->getName());
+ SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G);
+ if (G->getComdat() &&
+ G->getComdat()->getSelectionKind() != Comdat::NoDeduplicate)
+ SymbolFlags[MangledName] |= JITSymbolFlags::Weak;
+ if (SymbolToDefinition)
+ (*SymbolToDefinition)[MangledName] = G;
+ }
+ }
+
+ IRLayer(ExecutionSession &ES, const ManglingOptions *&MO) : ES(ES), MO(MO) {}
virtual ~IRLayer();
@@ -75,9 +152,7 @@ class IRLayer {
ExecutionSession &getExecutionSession() { return ES; }
/// Get the mangling options for this layer.
- const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {
- return MO;
- }
+ const ManglingOptions *&getManglingOptions() const { return MO; }
/// Sets the CloneToNewContextOnEmit flag (false by default).
///
@@ -95,12 +170,17 @@ class IRLayer {
/// Returns the current value of the CloneToNewContextOnEmit flag.
bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
- /// Add a MaterializatinoUnit representing the given IR to the JITDylib
+ Expected<IRMaterializationUnit::SymbolInfo>
+ getSymbolInfo(const Module &M, ExecutionSession &ES,
+ const ManglingOptions &MO, IRSymbolMapper &SymMapper);
+
+ /// Adds a MaterializatinoUnit representing the given IR to the JITDylib
/// targeted by the given tracker.
- virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
+ virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM,
+ IRSymbolMapper SymMapper = IRSymbolMapper());
/// Adds a MaterializationUnit representing the given IR to the given
- /// JITDylib. If RT is not specif
+ /// JITDylib. If RT is not specified, use the default tracker for this Dylib.
Error add(JITDylib &JD, ThreadSafeModule TSM) {
return add(JD.getDefaultResourceTracker(), std::move(TSM));
}
@@ -112,16 +192,15 @@ class IRLayer {
private:
bool CloneToNewContextOnEmit = false;
ExecutionSession &ES;
- const IRSymbolMapper::ManglingOptions *&MO;
+ const ManglingOptions *&MO;
};
/// MaterializationUnit that materializes modules by calling the 'emit' method
/// on the given IRLayer.
class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
public:
- BasicIRLayerMaterializationUnit(IRLayer &L,
- const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM);
+ BasicIRLayerMaterializationUnit(IRLayer &L, const ThreadSafeModule TSM,
+ SymbolInfo SymInfo);
private:
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h b/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h
index 77429f4b11eefe..4a3ddfbb93f385 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h
@@ -33,26 +33,9 @@ class MangleAndInterner {
const DataLayout &DL;
};
-/// Maps IR global values to their linker symbol names / flags.
-///
-/// This utility can be used when adding new IR globals in the JIT.
-class IRSymbolMapper {
-public:
- struct ManglingOptions {
- bool EmulatedTLS = false;
- };
-
- using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
-
- /// Add mangled symbols for the given GlobalValues to SymbolFlags.
- /// If a SymbolToDefinitionMap pointer is supplied then it will be populated
- /// with Name-to-GlobalValue* mappings. Note that this mapping is not
- /// necessarily one-to-one: thread-local GlobalValues, for example, may
- /// produce more than one symbol, in which case the map will contain duplicate
- /// values.
- static void add(ExecutionSession &ES, const ManglingOptions &MO,
- ArrayRef<GlobalValue *> GVs, SymbolFlagsMap &SymbolFlags,
- SymbolNameToDefinitionMap *SymbolToDefinition = nullptr);
+// Stores options to guide symbol mapping for IR symbols
+struct ManglingOptions {
+ bool EmulatedTLS = false;
};
} // End namespace orc
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index 6448adaa0ceb36..dcd38ed9625d5d 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
@@ -72,7 +72,7 @@ namespace orc {
class PartitioningIRMaterializationUnit : public IRMaterializationUnit {
public:
PartitioningIRMaterializationUnit(ExecutionSession &ES,
- const IRSymbolMapper::ManglingOptions &MO,
+ const ManglingOptions &MO,
ThreadSafeModule TSM,
CompileOnDemandLayer &Parent)
: IRMaterializationUnit(ES, MO, std::move(TSM)), Parent(Parent) {}
@@ -315,53 +315,53 @@ void CompileOnDemandLayer::emitPartition(
//
// FIXME: We apply this promotion once per partitioning. It's safe, but
// overkill.
- auto ExtractedTSM =
- TSM.withModuleDo([&](Module &M) -> Expected<ThreadSafeModule> {
- auto PromotedGlobals = PromoteSymbols(M);
- if (!PromotedGlobals.empty()) {
-
- MangleAndInterner Mangle(ES, M.getDataLayout());
- SymbolFlagsMap SymbolFlags;
- IRSymbolMapper::add(ES, *getManglingOptions(),
- PromotedGlobals, SymbolFlags);
-
- if (auto Err = R->defineMaterializing(SymbolFlags))
- return std::move(Err);
- }
-
- expandPartition(*GVsToExtract);
-
- // Submodule name is given by hashing the names of the globals.
- std::string SubModuleName;
- {
- std::vector<const GlobalValue*> HashGVs;
- HashGVs.reserve(GVsToExtract->size());
- for (const auto *GV : *GVsToExtract)
- HashGVs.push_back(GV);
- llvm::sort(HashGVs, [](const GlobalValue *LHS, const GlobalValue *RHS) {
- return LHS->getName() < RHS->getName();
- });
- hash_code HC(0);
- for (const auto *GV : HashGVs) {
- assert(GV->hasName() && "All GVs to extract should be named by now");
- auto GVName = GV->getName();
- HC = hash_combine(HC, hash_combine_range(GVName.begin(), GVName.end()));
- }
- raw_string_ostream(SubModuleName)
- << ".submodule."
- << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
- static_cast<size_t>(HC))
- << ".ll";
- }
-
- // Extract the requested partiton (plus any necessary aliases) and
- // put the rest back into the impl dylib.
- auto ShouldExtract = [&](const GlobalValue &GV) -> bool {
- return GVsToExtract->count(&GV);
- };
-
- return extractSubModule(TSM, SubModuleName , ShouldExtract);
+ auto ExtractedTSM = TSM.withModuleDo([&](Module &M)
+ -> Expected<ThreadSafeModule> {
+ auto PromotedGlobals = PromoteSymbols(M);
+ if (!PromotedGlobals.empty()) {
+
+ MangleAndInterner Mangle(ES, M.getDataLayout());
+ SymbolFlagsMap SymbolFlags;
+ IRLayer::defaultSymbolMapper(PromotedGlobals, ES, *getManglingOptions(),
+ SymbolFlags);
+
+ if (auto Err = R->defineMaterializing(SymbolFlags))
+ return std::move(Err);
+ }
+
+ expandPartition(*GVsToExtract);
+
+ // Submodule name is given by hashing the names of the globals.
+ std::string SubModuleName;
+ {
+ std::vector<const GlobalValue *> HashGVs;
+ HashGVs.reserve(GVsToExtract->size());
+ for (const auto *GV : *GVsToExtract)
+ HashGVs.push_back(GV);
+ llvm::sort(HashGVs, [](const GlobalValue *LHS, const GlobalValue *RHS) {
+ return LHS->getName() < RHS->getName();
});
+ hash_code HC(0);
+ for (const auto *GV : HashGVs) {
+ assert(GV->hasName() && "All GVs to extract should be named by now");
+ auto GVName = GV->getName();
+ HC = hash_combine(HC, hash_combine_range(GVName.begin(), GVName.end()));
+ }
+ raw_string_ostream(SubModuleName)
+ << ".submodule."
+ << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
+ static_cast<size_t>(HC))
+ << ".ll";
+ }
+
+ // Extract the requested partiton (plus any necessary aliases) and
+ // put the rest back into the impl dylib.
+ auto ShouldExtract = [&](const GlobalValue &GV) -> bool {
+ return GVsToExtract->count(&GV);
+ };
+
+ return extractSubModule(TSM, SubModuleName, ShouldExtract);
+ });
if (!ExtractedTSM) {
ES.reportError(ExtractedTSM.takeError());
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
index fad7428e1f906c..df9c02264d1035 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
@@ -25,9 +25,9 @@
namespace llvm {
namespace orc {
-IRSymbolMapper::ManglingOptions
+ManglingOptions
irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {
- IRSymbolMapper::ManglingOptions MO;
+ ManglingOptions MO;
MO.EmulatedTLS = Opts.EmulatedTLS;
diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index 3368d3276cb373..2a9b30cefcdba8 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -21,17 +21,59 @@ namespace orc {
IRLayer::~IRLayer() = default;
-Error IRLayer::add(ResourceTrackerSP RT, ThreadSafeModule TSM) {
+Expected<IRMaterializationUnit::SymbolInfo>
+IRLayer::getSymbolInfo(const Module &M, ExecutionSession &ES,
+ const ManglingOptions &MO, IRSymbolMapper &SymMapper) {
+ std::vector<GlobalValue *> GVs;
+
+ for (auto &GV : M.global_values())
+ GVs.push_back(const_cast<GlobalValue *>(&GV));
+
+ SymbolFlagsMap SymbolFlags;
+ SymbolNameToDefinitionMap SymbolToDef;
+ SymMapper(GVs, ES, MO, SymbolFlags, &SymbolToDef);
+
+ SymbolStringPtr InitSymbol;
+ // If we need an init symbol for this module then create one.
+ if (!getStaticInitGVs(const_cast<Module &>(M)).empty()) {
+ size_t Counter = 0;
+
+ do {
+ std::string InitSymbolName;
+ raw_string_ostream(InitSymbolName)
+ << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
+ InitSymbol = ES.intern(InitSymbolName);
+ } while (SymbolFlags.count(InitSymbol));
+
+ SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;
+ }
+
+ return IRMaterializationUnit::SymbolInfo(
+ MaterializationUnit::Interface(SymbolFlags, InitSymbol), SymbolToDef);
+}
+
+Error IRLayer::add(ResourceTrackerSP RT, ThreadSafeModule TSM,
+ IRSymbolMapper SymMapper) {
assert(RT && "RT can not be null");
+ if (!SymMapper)
+ SymMapper = defaultSymbolMapper;
+
auto &JD = RT->getJITDylib();
+ auto SymbolInfoOrErr = TSM.withModuleDo([&](const Module &M) {
+ return getSymbolInfo(M, JD.getExecutionSession(), *getManglingOptions(),
+ SymMapper);
+ });
+ if (auto Err = SymbolInfoOrErr.takeError())
+ return Err;
+
return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
- *this, *getManglingOptions(), std::move(TSM)),
+ *this, std::move(TSM), *SymbolInfoOrErr),
std::move(RT));
}
-IRMaterializationUnit::IRMaterializationUnit(
- ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO,
- ThreadSafeModule TSM)
+IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,
+ const ManglingOptions &MO,
+ ThreadSafeModule TSM)
: MaterializationUnit(Interface()), TSM(std::move(TSM)) {
assert(this->TSM && "Module must not be null");
@@ -133,9 +175,10 @@ void IRMaterializationUnit::discard(const JITDylib &JD,
}
BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
- IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
- : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {
-}
+ IRLayer &L, ThreadSafeModule TSM, SymbolInfo SymInfo)
+ : IRMaterializationUnit(std::move(TSM), SymInfo.Interface,
+ SymInfo.SymbolToDefinition),
+ L(L) {}
void BasicIRLayerMaterializationUnit::materialize(
std::unique_ptr<MaterializationResponsibility> R) {
diff --git a/llvm/lib/ExecutionEngine/Orc/Mangling.cpp b/llvm/lib/ExecutionEngine/Orc/Mangling.cpp
index 9c243c9bf1d298..2ffa856435b04f 100644
--- a/llvm/lib/ExecutionEngine/Orc/Mangling.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Mangling.cpp
@@ -27,58 +27,5 @@ SymbolStringPtr MangleAndInterner::operator()(StringRef Name) {
}
return ES.intern(MangledName);
}
-
-void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO,
- ArrayRef<GlobalValue *> GVs,
- SymbolFlagsMap &SymbolFlags,
- SymbolNameToDefinitionMap *SymbolToDefinition) {
- if (GVs.empty())
- return;
-
- MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout());
- for (auto *G : GVs) {
- assert(G && "GVs cannot contain null elements");
- if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() ||
- G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage())
- continue;
-
- if (G->isThreadLocal() && MO.EmulatedTLS) {
- auto *GV = cast<GlobalVariable>(G);
-
- auto Flags = JITSymbolFlags::fromGlobalValue(*GV);
-
- auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str());
- SymbolFlags[EmuTLSV] = Flags;
- if (SymbolToDefinition)
- (*SymbolToDefinition)[EmuTLSV] = GV;
-
- // If this GV has a non-zero initializer we'll need to emit an
- // __emutls.t symbol too.
- if (GV->hasInitializer()) {
- const auto *InitVal = GV->getInitializer();
-
- // Skip zero-initializers.
- if (isa<ConstantAggregateZero>(InitVal))
- continue;
- const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
- if (InitIntValue && InitIntValue->isZero())
- continue;
-
- auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str());
- SymbolFlags[EmuTLST] = Flags;
- if (SymbolToDefinition)
- (*SymbolToDefinition)[EmuTLST] = GV;
- }
- continue;
- }
-
- // Otherwise we just need a normal linker mangling.
- auto MangledName = Mangle(G->getName());
- SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G);
- if (SymbolToDefinition)
- (*SymbolToDefinition)[MangledName] = G;
- }
-}
-
} // End namespace orc.
} // End namespace llvm.
>From 77ce76b17c282a08a054294e3788d93940c0912f Mon Sep 17 00:00:00 2001
From: Lucas <lucas.reis091997 at gmail.com>
Date: Fri, 26 Jan 2024 12:44:26 -0400
Subject: [PATCH 2/2] [ORC] Add a FAQ section to Orc docs
Populate a small FAQ section with its first question related to missing symbols from IR to prepare for the new changes to symbol mapping
---
llvm/docs/ORCv2.rst | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/llvm/docs/ORCv2.rst b/llvm/docs/ORCv2.rst
index add05e05a80e5f..b5e818585caba7 100644
--- a/llvm/docs/ORCv2.rst
+++ b/llvm/docs/ORCv2.rst
@@ -972,3 +972,32 @@ Further Future Work
multiple dylibs provide a weak definition of a symbol then each will end
up with its own definition (similar to how weak definitions are handled
in Windows DLLs). This will be fixed in the future.
+
+Frequently Asked Questions (FAQ)
+================================
+
+Here are some frequently asked questions about Orc's JIT API.
+
+Why can't I find this symbol defined in my LLVM IR?
+---------------------------------------------------
+
+If you are faced with a ``MissingSymbolsDefinitions`` error for a symbol you have defined in your LLVM IR, it may be a symbol that Orc does not map into a ``Materialization Unit``. Symbols with linkage types such as ``linkonce_odr`` are common cases of this issue. This is the intended behaviour from the perspective of the linker interface, which is the goal of Orc-oriented JITs.
+
+While this is the standard behaviour for symbol mapping on the ``IRLayer``, you are free to provide your own custom symbol mapping function to map symbols in the way that suits your necessities:
+
+.. code-block:: c++
+
+ static void
+ mySymbolMapper(ArrayRef<GlobalValue *> GVs, ExecutionSession &ES,
+ const ManglingOptions &MO, SymbolFlagsMap &SymbolFlags,
+ SymbolNameToDefinitionMap *SymbolToDefinition = nullptr) {
+ // decide which symbols you want to map to a possible MaterializationUnit
+ }
+
+ // ...
+
+ auto RT = JD.getDefaultResourceTracker();
+ // Add a ThreadSafeModule to an IRLayer
+ MyLayer.add(RT, TSM, mySymbolMapper);
+
+More info on how symbol mapping is usually done can be seen on ``defaultSymbolMapper`` at ``llvm/include/llvm/ExecutionEngine/Orc/Layer.h``.
More information about the llvm-commits
mailing list