[llvm] [ORC] Unify symbol mapping logic to IRLayer (PR #67624)
Lucas Reis via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 17:33:29 PDT 2023
https://github.com/lucasreis1 created https://github.com/llvm/llvm-project/pull/67624
Remove the old `IRSymbolMapper` and unifies symbol mapping logic to `IRLayer`. Allows clients to provide their own version of an `IRSymbolMapper` function for custom mappings.
>From e781ef956a3c46be5041d3cb57ad67b7653a88ee Mon Sep 17 00:00:00 2001
From: Lucas Reis <lucas.reis091997 at gmail.com>
Date: Wed, 27 Sep 2023 20:12:16 -0400
Subject: [PATCH] [ORC] Unify symbol mapping logic to IRLayer. Prepare for
possible custom mapping logic for clients.
---
.../llvm/ExecutionEngine/Orc/CompileUtils.h | 6 +-
.../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 12 +-
llvm/include/llvm/ExecutionEngine/Orc/Layer.h | 104 +++++++++++++++---
.../llvm/ExecutionEngine/Orc/Mangling.h | 23 +---
.../Orc/CompileOnDemandLayer.cpp | 94 ++++++++--------
llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp | 5 +-
llvm/lib/ExecutionEngine/Orc/Layer.cpp | 68 ++++++++++--
llvm/lib/ExecutionEngine/Orc/Mangling.cpp | 53 ---------
8 files changed, 210 insertions(+), 155 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index a55aa3d71db2a14..843916f2f001f26 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 f493d63a7c8a991..22f9c46e4ae3703 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -32,18 +32,16 @@ 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 {
- return MO;
- }
+ 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 +61,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 cfeedc2a0bdaab7..2f0590fa2371abe 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,73 @@ 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");
+ if (!willYieldSymbol(G))
+ 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 +149,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 +167,17 @@ class IRLayer {
/// Returns the current value of the CloneToNewContextOnEmit flag.
bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
+ Expected<IRMaterializationUnit::SymbolInfo>
+ getSymbolInfo(const Module &M, ExecutionSession &ES,
+ const ManglingOptions &MO, IRSymbolMapper &SymMapper);
+
/// Add 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));
}
@@ -110,18 +187,19 @@ class IRLayer {
ThreadSafeModule TSM) = 0;
private:
+ static bool willYieldSymbol(GlobalValue *GV);
+
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, 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 77429f4b11eefe4..c95193348bb7056 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 sybmol 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 6448adaa0ceb36f..06311ee2161dbc6 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -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 fad7428e1f906c6..6d9a4b0b615be6e 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
@@ -25,9 +25,8 @@
namespace llvm {
namespace orc {
-IRSymbolMapper::ManglingOptions
-irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {
- IRSymbolMapper::ManglingOptions MO;
+ManglingOptions irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {
+ ManglingOptions MO;
MO.EmulatedTLS = Opts.EmulatedTLS;
diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index 3368d3276cb373c..21142fbf7bded11 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -21,17 +21,68 @@ 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);
+}
+
+bool IRLayer::willYieldSymbol(GlobalValue *GV) {
+ if (!GV->hasName() || GV->isDeclaration() || GV->hasLocalLinkage() ||
+ GV->hasAvailableExternallyLinkage() || GV->hasAppendingLinkage())
+ return false;
+
+ // TODO: extend to forbid generating symbols that will be inlined
+ return true;
+}
+
+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 +184,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 9c243c9bf1d298d..2ffa856435b04f4 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.
More information about the llvm-commits
mailing list