summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2018-06-26 21:35:48 +0000
committerLang Hames <lhames@gmail.com>2018-06-26 21:35:48 +0000
commit6a94134b1167d1245058ce65b3c8c33956d37ec3 (patch)
tree9bc0185702953f139e731e6018d0861c3604d9a5 /llvm/lib/ExecutionEngine
parent777477705a7b00450d17504d08fa9ec7d2ba4ebb (diff)
downloadbcm5719-llvm-6a94134b1167d1245058ce65b3c8c33956d37ec3.tar.gz
bcm5719-llvm-6a94134b1167d1245058ce65b3c8c33956d37ec3.zip
[ORC] Add LLJIT and LLLazyJIT, and replace OrcLazyJIT in LLI with LLLazyJIT.
LLJIT is a prefabricated ORC based JIT class that is meant to be the go-to replacement for MCJIT. Unlike OrcMCJITReplacement (which will continue to be supported) it is not API or bug-for-bug compatible, but targets the same use cases: Simple, non-lazy compilation and execution of LLVM IR. LLLazyJIT extends LLJIT with support for function-at-a-time lazy compilation, similar to what was provided by LLVM's original (now long deprecated) JIT APIs. This commit also contains some simple utility classes (CtorDtorRunner2, LocalCXXRuntimeOverrides2, JITTargetMachineBuilder) to support LLJIT and LLLazyJIT. Both of these classes are works in progress. Feedback from JIT clients is very welcome! llvm-svn: 335670
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CMakeLists.txt1
-rw-r--r--llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp56
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Core.cpp35
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp150
-rw-r--r--llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/LLJIT.cpp171
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Layer.cpp6
7 files changed, 402 insertions, 19 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
index 9af5f211e90..2725fdfd14a 100644
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -7,6 +7,7 @@ add_llvm_library(LLVMOrcJIT
IRTransformLayer.cpp
Legacy.cpp
Layer.cpp
+ LLJIT.cpp
NullResolver.cpp
ObjectTransformLayer.cpp
OrcABISupport.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index 584f990976a..27a4ad68f59 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -35,12 +35,42 @@ createLambdaValueMaterializer(MaterializerFtor M) {
}
} // namespace
+static void extractAliases(MaterializationResponsibility &R, Module &M,
+ MangleAndInterner &Mangle) {
+ SymbolAliasMap Aliases;
+
+ std::vector<GlobalAlias *> ModAliases;
+ for (auto &A : M.aliases())
+ ModAliases.push_back(&A);
+
+ for (auto *A : ModAliases) {
+ Constant *Aliasee = A->getAliasee();
+ assert(A->hasName() && "Anonymous alias?");
+ assert(Aliasee->hasName() && "Anonymous aliasee");
+ std::string AliasName = A->getName();
+
+ Aliases[Mangle(AliasName)] = SymbolAliasMapEntry(
+ {Mangle(Aliasee->getName()), JITSymbolFlags::fromGlobalValue(*A)});
+
+ if (isa<Function>(Aliasee)) {
+ auto *F = cloneFunctionDecl(M, *cast<Function>(Aliasee));
+ A->replaceAllUsesWith(F);
+ A->eraseFromParent();
+ F->setName(AliasName);
+ } else if (isa<GlobalValue>(Aliasee)) {
+ auto *G = cloneGlobalVariableDecl(M, *cast<GlobalVariable>(Aliasee));
+ A->replaceAllUsesWith(G);
+ A->eraseFromParent();
+ G->setName(AliasName);
+ }
+ }
+
+ R.delegate(symbolAliases(std::move(Aliases)));
+}
+
static std::unique_ptr<Module> extractGlobals(Module &M) {
// FIXME: Add alias support.
- if (M.global_empty() && M.alias_empty() && !M.getModuleFlagsMetadata())
- return nullptr;
-
auto GlobalsModule = llvm::make_unique<Module>(
(M.getName() + ".globals").str(), M.getContext());
GlobalsModule->setDataLayout(M.getDataLayout());
@@ -161,7 +191,6 @@ CompileOnDemandLayer2::CompileOnDemandLayer2(
Error CompileOnDemandLayer2::add(VSO &V, VModuleKey K,
std::unique_ptr<Module> M) {
- makeAllSymbolsExternallyAccessible(*M);
return IRLayer::add(V, K, std::move(M));
}
@@ -174,10 +203,12 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
if (GV.hasWeakLinkage())
GV.setLinkage(GlobalValue::ExternalLinkage);
- auto GlobalsModule = extractGlobals(*M);
-
MangleAndInterner Mangle(ES, M->getDataLayout());
+ extractAliases(R, *M, Mangle);
+
+ auto GlobalsModule = extractGlobals(*M);
+
// Delete the bodies of any available externally functions, rename the
// rest, and build the compile callbacks.
std::map<SymbolStringPtr, std::pair<JITTargetAddress, JITSymbolFlags>>
@@ -194,8 +225,12 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
}
assert(F.hasName() && "Function should have a name");
- auto StubName = Mangle(F.getName());
+ std::string StubUnmangledName = F.getName();
F.setName(F.getName() + "$body");
+ auto StubDecl = cloneFunctionDecl(*M, F);
+ StubDecl->setName(StubUnmangledName);
+ F.replaceAllUsesWith(StubDecl);
+ auto StubName = Mangle(StubUnmangledName);
auto BodyName = Mangle(F.getName());
if (auto CallbackAddr = CCMgr.getCompileCallback(
[BodyName, &TargetVSO, &ES]() -> JITTargetAddress {
@@ -223,14 +258,19 @@ void CompileOnDemandLayer2::emit(MaterializationResponsibility R, VModuleKey K,
StubInits[*KV.first] = KV.second;
// Build the function-body-extracting materialization unit.
+ auto SR = GetSymbolResolver(K);
if (auto Err = R.getTargetVSO().define(
llvm::make_unique<ExtractingIRMaterializationUnit>(
- ES, *this, std::move(M), GetSymbolResolver(K)))) {
+ ES, *this, std::move(M), SR))) {
ES.reportError(std::move(Err));
R.failMaterialization();
return;
}
+ // Replace the fallback symbol resolver: We will re-use M's VModuleKey for
+ // the GlobalsModule.
+ SetSymbolResolver(K, SR);
+
// Build the stubs.
// FIXME: Remove function bodies materialization unit if stub creation fails.
auto &StubsMgr = getStubsManager(TargetVSO);
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index 53e4a853b35..717f2f085fe 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -725,6 +725,25 @@ void VSO::notifyFailed(const SymbolNameSet &FailedSymbols) {
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
}
+void VSO::runOutstandingMUs() {
+ while (1) {
+ std::unique_ptr<MaterializationUnit> MU;
+
+ {
+ std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+ if (!OutstandingMUs.empty()) {
+ MU = std::move(OutstandingMUs.back());
+ OutstandingMUs.pop_back();
+ }
+ }
+
+ if (MU)
+ ES.dispatchMaterialization(*this, std::move(MU));
+ else
+ break;
+ }
+}
+
SymbolNameSet VSO::lookupFlags(SymbolFlagsMap &Flags,
const SymbolNameSet &Names) {
return ES.runSessionLocked([&, this]() {
@@ -767,6 +786,8 @@ SymbolNameSet VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
SymbolNameSet Names) {
assert(Q && "Query can not be null");
+ runOutstandingMUs();
+
LookupImplActionFlags ActionFlags = None;
std::vector<std::unique_ptr<MaterializationUnit>> MUs;
@@ -796,9 +817,19 @@ SymbolNameSet VSO::lookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
if (ActionFlags & NotifyFullyReady)
Q->handleFullyReady();
+ // FIXME: Swap back to the old code below once RuntimeDyld works with
+ // callbacks from asynchronous queries.
+ // Add MUs to the OutstandingMUs list.
+ {
+ std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
+ for (auto &MU : MUs)
+ OutstandingMUs.push_back(std::move(MU));
+ }
+ runOutstandingMUs();
+
// Dispatch any required MaterializationUnits for materialization.
- for (auto &MU : MUs)
- ES.dispatchMaterialization(*this, std::move(MU));
+ // for (auto &MU : MUs)
+ // ES.dispatchMaterialization(*this, std::move(MU));
return Unresolved;
}
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index f6e6ed66ef9..1389c2c723e 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -13,10 +13,51 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Target/TargetMachine.h"
namespace llvm {
namespace orc {
+JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
+ : TT(std::move(TT)) {}
+
+Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
+ return JITTargetMachineBuilder(Triple(sys::getProcessTriple()));
+}
+
+Expected<std::unique_ptr<TargetMachine>>
+JITTargetMachineBuilder::createTargetMachine() {
+ if (!Arch.empty()) {
+ Triple::ArchType Type = Triple::getArchTypeForLLVMName(Arch);
+
+ if (Type == Triple::UnknownArch)
+ return make_error<StringError>(std::string("Unknown arch: ") + Arch,
+ inconvertibleErrorCode());
+ }
+
+ std::string ErrMsg;
+ auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
+ if (!TheTarget)
+ return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
+
+ auto *TM =
+ TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
+ Options, RM, CM, OptLevel, /*JIT*/ true);
+ if (!TM)
+ return make_error<StringError>("Could not allocate target machine",
+ inconvertibleErrorCode());
+
+ return std::unique_ptr<TargetMachine>(TM);
+}
+
+JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
+ const std::vector<std::string> &FeatureVec) {
+ for (const auto &F : FeatureVec)
+ Features.AddFeature(F);
+ return *this;
+}
+
CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
: InitList(
GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
@@ -68,6 +109,8 @@ CtorDtorIterator::Element CtorDtorIterator::operator*() const {
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr;
+ if (!isa<GlobalValue>(Data))
+ Data = nullptr;
return Element(Priority->getZExtValue(), Func, Data);
}
@@ -83,20 +126,121 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M) {
CtorDtorIterator(DtorsList, true));
}
-void LocalCXXRuntimeOverrides::runDestructors() {
+void CtorDtorRunner2::add(iterator_range<CtorDtorIterator> CtorDtors) {
+ if (CtorDtors.begin() == CtorDtors.end())
+ return;
+
+ MangleAndInterner Mangle(
+ V.getExecutionSession(),
+ (*CtorDtors.begin()).Func->getParent()->getDataLayout());
+
+ for (const auto &CtorDtor : CtorDtors) {
+ assert(CtorDtor.Func && CtorDtor.Func->hasName() &&
+ "Ctor/Dtor function must be named to be runnable under the JIT");
+
+ if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) {
+ dbgs() << " Skipping because why now?\n";
+ continue;
+ }
+
+ CtorDtorsByPriority[CtorDtor.Priority].push_back(
+ Mangle(CtorDtor.Func->getName()));
+ }
+}
+
+Error CtorDtorRunner2::run() {
+ using CtorDtorTy = void (*)();
+
+ SymbolNameSet Names;
+
+ for (auto &KV : CtorDtorsByPriority) {
+ for (auto &Name : KV.second) {
+ auto Added = Names.insert(Name).second;
+ (void)Added;
+ assert(Added && "Ctor/Dtor names clashed");
+ }
+ }
+
+ if (auto CtorDtorMap = lookup({&V}, std::move(Names))) {
+ for (auto &KV : CtorDtorsByPriority) {
+ for (auto &Name : KV.second) {
+ assert(CtorDtorMap->count(Name) && "No entry for Name");
+ auto CtorDtor = reinterpret_cast<CtorDtorTy>(
+ static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress()));
+ CtorDtor();
+ }
+ }
+ return Error::success();
+ } else
+ return CtorDtorMap.takeError();
+
+ CtorDtorsByPriority.clear();
+}
+
+void LocalCXXRuntimeOverridesBase::runDestructors() {
auto& CXXDestructorDataPairs = DSOHandleOverride;
for (auto &P : CXXDestructorDataPairs)
P.first(P.second);
CXXDestructorDataPairs.clear();
}
-int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor,
- void *Arg, void *DSOHandle) {
+int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor,
+ void *Arg,
+ void *DSOHandle) {
auto& CXXDestructorDataPairs =
*reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
return 0;
}
+Error LocalCXXRuntimeOverrides2::enable(VSO &V, MangleAndInterner &Mangle) {
+ SymbolMap RuntimeInterposes(
+ {{Mangle("__dso_handle"),
+ JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride),
+ JITSymbolFlags::Exported)},
+ {Mangle("__cxa_atexit"),
+ JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride),
+ JITSymbolFlags::Exported)}});
+
+ return V.define(absoluteSymbols(std::move(RuntimeInterposes)));
+}
+
+DynamicLibraryFallbackGenerator::DynamicLibraryFallbackGenerator(
+ sys::DynamicLibrary Dylib, const DataLayout &DL, SymbolPredicate Allow)
+ : Dylib(std::move(Dylib)), Allow(std::move(Allow)),
+ GlobalPrefix(DL.getGlobalPrefix()) {}
+
+SymbolNameSet DynamicLibraryFallbackGenerator::
+operator()(VSO &V, const SymbolNameSet &Names) {
+ orc::SymbolNameSet Added;
+ orc::SymbolMap NewSymbols;
+
+ bool HasGlobalPrefix = (GlobalPrefix != '\0');
+
+ for (auto &Name : Names) {
+ if (!Allow(Name) || (*Name).empty())
+ continue;
+
+ if (HasGlobalPrefix && (*Name).front() != GlobalPrefix)
+ continue;
+
+ std::string Tmp((*Name).data() + (HasGlobalPrefix ? 1 : 0), (*Name).size());
+ if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) {
+ Added.insert(Name);
+ NewSymbols[Name] = JITEvaluatedSymbol(
+ static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)),
+ JITSymbolFlags::Exported);
+ }
+ }
+
+ // Add any new symbols to V. Since the fallback generator is only called for
+ // symbols that are not already defined, this will never trigger a duplicate
+ // definition error, so we can wrap this call in a 'cantFail'.
+ if (!NewSymbols.empty())
+ cantFail(V.define(absoluteSymbols(std::move(NewSymbols))));
+
+ return Added;
+}
+
} // End namespace orc.
} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index c2dfaa1a5f6..dc9628f183e 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -265,7 +265,6 @@ void makeAllSymbolsExternallyAccessible(Module &M) {
Function* cloneFunctionDecl(Module &Dst, const Function &F,
ValueToValueMapTy *VMap) {
- assert(F.getParent() != &Dst && "Can't copy decl over existing function.");
Function *NewF =
Function::Create(cast<FunctionType>(F.getValueType()),
F.getLinkage(), F.getName(), &Dst);
@@ -303,7 +302,6 @@ void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
ValueToValueMapTy *VMap) {
- assert(GV.getParent() != &Dst && "Can't copy decl over existing global var.");
GlobalVariable *NewGV = new GlobalVariable(
Dst, GV.getValueType(), GV.isConstant(),
GV.getLinkage(), nullptr, GV.getName(), nullptr,
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
new file mode 100644
index 00000000000..059fba23d57
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -0,0 +1,171 @@
+//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/IR/Mangler.h"
+
+namespace llvm {
+namespace orc {
+
+Expected<std::unique_ptr<LLJIT>>
+LLJIT::Create(std::unique_ptr<ExecutionSession> ES,
+ std::unique_ptr<TargetMachine> TM, DataLayout DL) {
+ return std::unique_ptr<LLJIT>(
+ new LLJIT(std::move(ES), std::move(TM), std::move(DL)));
+}
+
+Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
+ auto InternedName = ES->getSymbolStringPool().intern(Name);
+ SymbolMap Symbols({{InternedName, Sym}});
+ return Main.define(absoluteSymbols(std::move(Symbols)));
+}
+
+Error LLJIT::addIRModule(VSO &V, std::unique_ptr<Module> M) {
+ assert(M && "Can not add null module");
+
+ if (auto Err = applyDataLayout(*M))
+ return Err;
+
+ auto K = ES->allocateVModule();
+ Resolvers[K] = createResolverFor(V);
+ return CompileLayer.add(V, K, std::move(M));
+}
+
+Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V,
+ StringRef Name) {
+ return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name));
+}
+
+LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
+ std::unique_ptr<TargetMachine> TM, DataLayout DL)
+ : ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)),
+ DL(std::move(DL)),
+ ObjLinkingLayer(*this->ES,
+ [this](VModuleKey K) { return getRTDyldResources(K); }),
+ CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),
+ CtorRunner(Main), DtorRunner(Main) {
+ VSOLookupOrder[&Main] = VSOList({&Main});
+}
+
+std::shared_ptr<SymbolResolver> LLJIT::takeSymbolResolver(VModuleKey K) {
+ auto ResolverI = Resolvers.find(K);
+ assert(ResolverI != Resolvers.end() && "Missing resolver");
+ auto Resolver = std::move(ResolverI->second);
+ Resolvers.erase(ResolverI);
+ return Resolver;
+}
+
+RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) {
+ return orc::RTDyldObjectLinkingLayer2::Resources(
+ {llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)});
+}
+
+std::string LLJIT::mangle(StringRef UnmangledName) {
+ std::string MangledName;
+ {
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
+ }
+ return MangledName;
+}
+
+std::unique_ptr<SymbolResolver> LLJIT::createResolverFor(VSO &V) {
+ return createSymbolResolver(
+ [&](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) {
+ return V.lookupFlags(Flags, Symbols);
+ },
+ [&, this](std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Symbols) {
+ assert(VSOLookupOrder.count(&V) && "No VSO lookup order for V");
+ SymbolNameSet Unresolved = std::move(Symbols);
+ for (auto *LV : VSOLookupOrder[&V])
+ Unresolved = LV->lookup(Q, std::move(Unresolved));
+ return Unresolved;
+ });
+}
+
+Error LLJIT::applyDataLayout(Module &M) {
+ if (M.getDataLayout().isDefault())
+ M.setDataLayout(DL);
+
+ if (M.getDataLayout() != DL)
+ return make_error<StringError>(
+ "Added modules have incompatible data layouts",
+ inconvertibleErrorCode());
+
+ return Error::success();
+}
+
+void LLJIT::recordCtorDtors(Module &M) {
+ CtorRunner.add(getConstructors(M));
+ DtorRunner.add(getDestructors(M));
+}
+
+Expected<std::unique_ptr<LLLazyJIT>>
+LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES,
+ std::unique_ptr<TargetMachine> TM, DataLayout DL,
+ LLVMContext &Ctx) {
+ const Triple &TT = TM->getTargetTriple();
+
+ auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);
+ if (!CCMgr)
+ return make_error<StringError>(
+ std::string("No callback manager available for ") + TT.str(),
+ inconvertibleErrorCode());
+
+ auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
+ if (!ISMBuilder)
+ return make_error<StringError>(
+ std::string("No indirect stubs manager builder for ") + TT.str(),
+ inconvertibleErrorCode());
+
+ return std::unique_ptr<LLLazyJIT>(
+ new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx,
+ std::move(CCMgr), std::move(ISMBuilder)));
+}
+
+Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) {
+ assert(M && "Can not add null module");
+
+ if (auto Err = applyDataLayout(*M))
+ return Err;
+
+ makeAllSymbolsExternallyAccessible(*M);
+
+ recordCtorDtors(*M);
+
+ auto K = ES->allocateVModule();
+ setSymbolResolver(K, createResolverFor(V));
+ return CODLayer.add(V, K, std::move(M));
+}
+
+LLLazyJIT::LLLazyJIT(
+ std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
+ DataLayout DL, LLVMContext &Ctx,
+ std::unique_ptr<JITCompileCallbackManager> CCMgr,
+ std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
+ : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
+ CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),
+ CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder),
+ [this](VModuleKey K) { return takeSymbolResolver(K); },
+ [this](VModuleKey K, std::shared_ptr<SymbolResolver> R) {
+ setSymbolResolver(K, std::move(R));
+ },
+ [&]() -> LLVMContext & { return Ctx; }) {}
+
+void LLLazyJIT::setSymbolResolver(VModuleKey K,
+ std::shared_ptr<SymbolResolver> R) {
+ assert(!Resolvers.count(K) && "Resolver already present for VModule K");
+ Resolvers[K] = std::move(R);
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
index 76255f56fd4..b9da3b7fb8d 100644
--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/Layer.h"
-#include "llvm/IR/Mangler.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -29,9 +28,8 @@ IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,
MangleAndInterner Mangle(ES, this->M->getDataLayout());
for (auto &G : this->M->global_values()) {
- if (G.hasName() && !G.isDeclaration() &&
- !G.hasLocalLinkage() &&
- !G.hasAvailableExternallyLinkage()) {
+ if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() &&
+ !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) {
auto MangledName = Mangle(G.getName());
SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);
SymbolToDefinition[MangledName] = &G;
OpenPOWER on IntegriCloud