summaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h177
1 files changed, 108 insertions, 69 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 8ac1b6bca0a7..c1acca386820 100644
--- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -146,7 +146,7 @@ private:
std::unique_ptr<JITSymbolResolver>)>;
struct SourceModuleEntry {
- std::unique_ptr<ResourceOwner<Module>> SourceMod;
+ std::shared_ptr<Module> SourceMod;
std::set<Function*> StubsToClone;
};
@@ -154,7 +154,7 @@ private:
using SourceModuleHandle = typename SourceModulesList::size_type;
SourceModuleHandle
- addSourceModule(std::unique_ptr<ResourceOwner<Module>> M) {
+ addSourceModule(std::shared_ptr<Module> M) {
SourceModuleHandle H = SourceModules.size();
SourceModules.push_back(SourceModuleEntry());
SourceModules.back().SourceMod = std::move(M);
@@ -162,7 +162,7 @@ private:
}
Module& getSourceModule(SourceModuleHandle H) {
- return SourceModules[H].SourceMod->getResource();
+ return *SourceModules[H].SourceMod;
}
std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
@@ -176,19 +176,21 @@ private:
for (auto BLH : BaseLayerHandles)
if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return nullptr;
}
- void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
+ Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
for (auto &BLH : BaseLayerHandles)
- BaseLayer.removeModule(BLH);
+ if (auto Err = BaseLayer.removeModule(BLH))
+ return Err;
+ return Error::success();
}
- std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
- std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
+ std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
StaticGlobalRenamer StaticRenamer;
- ModuleAdderFtor ModuleAdder;
SourceModulesList SourceModules;
std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
};
@@ -196,6 +198,7 @@ private:
using LogicalDylibList = std::list<LogicalDylib>;
public:
+
/// @brief Handle to loaded module.
using ModuleHandleT = typename LogicalDylibList::iterator;
@@ -217,48 +220,41 @@ public:
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
~CompileOnDemandLayer() {
+ // FIXME: Report error on log.
while (!LogicalDylibs.empty())
- removeModule(LogicalDylibs.begin());
+ consumeError(removeModule(LogicalDylibs.begin()));
}
/// @brief Add a module to the compile-on-demand layer.
- template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
- ModuleHandleT addModule(std::shared_ptr<Module> M,
- MemoryManagerPtrT MemMgr,
- SymbolResolverPtrT Resolver) {
+ Expected<ModuleHandleT>
+ addModule(std::shared_ptr<Module> M,
+ std::shared_ptr<JITSymbolResolver> Resolver) {
LogicalDylibs.push_back(LogicalDylib());
auto &LD = LogicalDylibs.back();
LD.ExternalSymbolResolver = std::move(Resolver);
LD.StubsMgr = CreateIndirectStubsManager();
- auto &MemMgrRef = *MemMgr;
- LD.MemMgr = wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
-
- LD.ModuleAdder =
- [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
- std::unique_ptr<JITSymbolResolver> R) {
- return B.addModule(std::move(M), &MemMgrRef, std::move(R));
- };
-
// Process each of the modules in this module set.
- addLogicalModule(LogicalDylibs.back(), std::move(M));
+ if (auto Err = addLogicalModule(LD, std::move(M)))
+ return std::move(Err);
return std::prev(LogicalDylibs.end());
}
/// @brief Add extra modules to an existing logical module.
- void addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
- addLogicalModule(*H, std::move(M));
+ Error addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
+ return addLogicalModule(*H, std::move(M));
}
/// @brief Remove the module represented by the given handle.
///
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
- void removeModule(ModuleHandleT H) {
- H->removeModulesFromBaseLayer(BaseLayer);
+ Error removeModule(ModuleHandleT H) {
+ auto Err = H->removeModulesFromBaseLayer(BaseLayer);
LogicalDylibs.erase(H);
+ return Err;
}
/// @brief Search for the given named symbol.
@@ -272,6 +268,8 @@ public:
return Sym;
if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
}
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
@@ -309,8 +307,9 @@ public:
}
private:
- template <typename ModulePtrT>
- void addLogicalModule(LogicalDylib &LD, ModulePtrT SrcMPtr) {
+
+ Error addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcMPtr) {
+
// Rename all static functions / globals to $static.X :
// This will unique the names across all modules in the logical dylib,
// simplifying symbol lookup.
@@ -322,7 +321,7 @@ private:
// Create a logical module handle for SrcM within the logical dylib.
Module &SrcM = *SrcMPtr;
- auto LMId = LD.addSourceModule(wrapOwnership<Module>(std::move(SrcMPtr)));
+ auto LMId = LD.addSourceModule(std::move(SrcMPtr));
// Create stub functions.
const DataLayout &DL = SrcM.getDataLayout();
@@ -335,9 +334,12 @@ private:
// Skip weak functions for which we already have definitions.
auto MangledName = mangle(F.getName(), DL);
- if (F.hasWeakLinkage() || F.hasLinkOnceLinkage())
+ if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
continue;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ }
// Record all functions defined by this module.
if (CloneStubsIntoPartitions)
@@ -350,9 +352,15 @@ private:
StubInits[MangledName] =
std::make_pair(CCInfo.getAddress(),
JITSymbolFlags::fromGlobalValue(F));
- CCInfo.setCompileAction([this, &LD, LMId, &F]() {
- return this->extractAndCompile(LD, LMId, F);
- });
+ CCInfo.setCompileAction([this, &LD, LMId, &F]() -> JITTargetAddress {
+ if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
+ return *FnImplAddrOrErr;
+ else {
+ // FIXME: Report error, return to 'abort' or something similar.
+ consumeError(FnImplAddrOrErr.takeError());
+ return 0;
+ }
+ });
}
auto EC = LD.StubsMgr->createStubs(StubInits);
@@ -367,7 +375,7 @@ private:
// empty globals module.
if (SrcM.global_empty() && SrcM.alias_empty() &&
!SrcM.getModuleFlagsMetadata())
- return;
+ return Error::success();
// Create the GlobalValues module.
auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
@@ -393,8 +401,9 @@ private:
// Initializers may refer to functions declared (but not defined) in this
// module. Build a materializer to clone decls on demand.
+ Error MaterializerErrors = Error::success();
auto Materializer = createLambdaMaterializer(
- [&LD, &GVsM](Value *V) -> Value* {
+ [&LD, &GVsM, &MaterializerErrors](Value *V) -> Value* {
if (auto *F = dyn_cast<Function>(V)) {
// Decls in the original module just get cloned.
if (F->isDeclaration())
@@ -405,13 +414,24 @@ private:
// instead.
const DataLayout &DL = GVsM->getDataLayout();
std::string FName = mangle(F->getName(), DL);
- auto StubSym = LD.StubsMgr->findStub(FName, false);
unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
- ConstantInt *StubAddr =
- ConstantInt::get(GVsM->getContext(),
- APInt(PtrBitWidth, StubSym.getAddress()));
+ JITTargetAddress StubAddr = 0;
+
+ // Get the address for the stub. If we encounter an error while
+ // doing so, stash it in the MaterializerErrors variable and use a
+ // null address as a placeholder.
+ if (auto StubSym = LD.StubsMgr->findStub(FName, false)) {
+ if (auto StubAddrOrErr = StubSym.getAddress())
+ StubAddr = *StubAddrOrErr;
+ else
+ MaterializerErrors = joinErrors(std::move(MaterializerErrors),
+ StubAddrOrErr.takeError());
+ }
+
+ ConstantInt *StubAddrCI =
+ ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
- StubAddr, F->getType());
+ StubAddrCI, F->getType());
return GlobalAlias::create(F->getFunctionType(),
F->getType()->getAddressSpace(),
F->getLinkage(), F->getName(),
@@ -435,22 +455,31 @@ private:
NewA->setAliasee(cast<Constant>(Init));
}
+ if (MaterializerErrors)
+ return MaterializerErrors;
+
// Build a resolver for the globals module and add it to the base layer.
auto GVsResolver = createLambdaResolver(
- [this, &LD](const std::string &Name) {
+ [this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.StubsMgr->findStub(Name, false))
return Sym;
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
[&LD](const std::string &Name) {
return LD.ExternalSymbolResolver->findSymbol(Name);
});
- auto GVsH = LD.ModuleAdder(BaseLayer, std::move(GVsM),
- std::move(GVsResolver));
- LD.BaseLayerHandles.push_back(GVsH);
+ if (auto GVsHOrErr =
+ BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver)))
+ LD.BaseLayerHandles.push_back(*GVsHOrErr);
+ else
+ return GVsHOrErr.takeError();
+
+ return Error::success();
}
static std::string mangle(StringRef Name, const DataLayout &DL) {
@@ -462,7 +491,7 @@ private:
return MangledName;
}
- JITTargetAddress
+ Expected<JITTargetAddress>
extractAndCompile(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
Function &F) {
@@ -475,34 +504,42 @@ private:
// Grab the name of the function being called here.
std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
- auto Part = Partition(F);
- auto PartH = emitPartition(LD, LMId, Part);
-
JITTargetAddress CalledAddr = 0;
- for (auto *SubF : Part) {
- std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
- auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
- assert(FnBodySym && "Couldn't find function body.");
-
- JITTargetAddress FnBodyAddr = FnBodySym.getAddress();
-
- // If this is the function we're calling record the address so we can
- // return it from this function.
- if (SubF == &F)
- CalledAddr = FnBodyAddr;
-
- // Update the function body pointer for the stub.
- if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
- return 0;
- }
+ auto Part = Partition(F);
+ if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
+ auto &PartH = *PartHOrErr;
+ for (auto *SubF : Part) {
+ std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
+ if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
+ if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
+ JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
+
+ // If this is the function we're calling record the address so we can
+ // return it from this function.
+ if (SubF == &F)
+ CalledAddr = FnBodyAddr;
+
+ // Update the function body pointer for the stub.
+ if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
+ return 0;
+
+ } else
+ return FnBodyAddrOrErr.takeError();
+ } else if (auto Err = FnBodySym.takeError())
+ return std::move(Err);
+ else
+ llvm_unreachable("Function not emitted for partition");
+ }
- LD.BaseLayerHandles.push_back(PartH);
+ LD.BaseLayerHandles.push_back(PartH);
+ } else
+ return PartHOrErr.takeError();
return CalledAddr;
}
template <typename PartitionT>
- BaseLayerModuleHandleT
+ Expected<BaseLayerModuleHandleT>
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
@@ -566,16 +603,18 @@ private:
// Create memory manager and symbol resolver.
auto Resolver = createLambdaResolver(
- [this, &LD](const std::string &Name) {
+ [this, &LD](const std::string &Name) -> JITSymbol {
if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
return Sym;
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
return LD.ExternalSymbolResolver->findSymbolInLogicalDylib(Name);
},
[&LD](const std::string &Name) {
return LD.ExternalSymbolResolver->findSymbol(Name);
});
- return LD.ModuleAdder(BaseLayer, std::move(M), std::move(Resolver));
+ return BaseLayer.addModule(std::move(M), std::move(Resolver));
}
BaseLayerT &BaseLayer;