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.h346
1 files changed, 222 insertions, 124 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index a961992c2147..8bd21a0e3dd6 100644
--- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -22,6 +22,8 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/Layer.h"
+#include "llvm/ExecutionEngine/Orc/Legacy.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
@@ -56,7 +58,47 @@ class Value;
namespace orc {
-/// @brief Compile-on-demand layer.
+class ExtractingIRMaterializationUnit;
+
+class CompileOnDemandLayer2 : public IRLayer {
+ friend class ExtractingIRMaterializationUnit;
+
+public:
+ /// Builder for IndirectStubsManagers.
+ using IndirectStubsManagerBuilder =
+ std::function<std::unique_ptr<IndirectStubsManager>()>;
+
+ using GetAvailableContextFunction = std::function<LLVMContext &()>;
+
+ CompileOnDemandLayer2(ExecutionSession &ES, IRLayer &BaseLayer,
+ JITCompileCallbackManager &CCMgr,
+ IndirectStubsManagerBuilder BuildIndirectStubsManager,
+ GetAvailableContextFunction GetAvailableContext);
+
+ Error add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) override;
+
+ void emit(MaterializationResponsibility R, VModuleKey K,
+ std::unique_ptr<Module> M) override;
+
+private:
+ using StubManagersMap =
+ std::map<const VSO *, std::unique_ptr<IndirectStubsManager>>;
+
+ IndirectStubsManager &getStubsManager(const VSO &V);
+
+ void emitExtractedFunctionsModule(MaterializationResponsibility R,
+ std::unique_ptr<Module> M);
+
+ mutable std::mutex CODLayerMutex;
+
+ IRLayer &BaseLayer;
+ JITCompileCallbackManager &CCMgr;
+ IndirectStubsManagerBuilder BuildIndirectStubsManager;
+ StubManagersMap StubsMgrs;
+ GetAvailableContextFunction GetAvailableContext;
+};
+
+/// Compile-on-demand layer.
///
/// When a module is added to this layer a stub is created for each of its
/// function definitions. The stubs and other global values are immediately
@@ -85,8 +127,6 @@ private:
return LambdaMaterializer<MaterializerFtor>(std::move(M));
}
- using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT;
-
// Provide type-erasure for the Modules and MemoryManagers.
template <typename ResourceT>
class ResourceOwner {
@@ -138,18 +178,22 @@ private:
};
struct LogicalDylib {
- using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>;
-
struct SourceModuleEntry {
- std::shared_ptr<Module> SourceMod;
+ std::unique_ptr<Module> SourceMod;
std::set<Function*> StubsToClone;
};
using SourceModulesList = std::vector<SourceModuleEntry>;
using SourceModuleHandle = typename SourceModulesList::size_type;
- SourceModuleHandle
- addSourceModule(std::shared_ptr<Module> M) {
+ LogicalDylib() = default;
+
+ LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
+ std::unique_ptr<IndirectStubsMgrT> StubsMgr)
+ : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
+ StubsMgr(std::move(StubsMgr)) {}
+
+ SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
SourceModuleHandle H = SourceModules.size();
SourceModules.push_back(SourceModuleEntry());
SourceModules.back().SourceMod = std::move(M);
@@ -168,8 +212,8 @@ private:
bool ExportedSymbolsOnly) {
if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
- for (auto BLH : BaseLayerHandles)
- if (auto Sym = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
+ for (auto BLK : BaseLayerVModuleKeys)
+ if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
@@ -177,91 +221,94 @@ private:
}
Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
- for (auto &BLH : BaseLayerHandles)
- if (auto Err = BaseLayer.removeModule(BLH))
+ for (auto &BLK : BaseLayerVModuleKeys)
+ if (auto Err = BaseLayer.removeModule(BLK))
return Err;
return Error::success();
}
- std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
+ VModuleKey K;
+ std::shared_ptr<SymbolResolver> BackingResolver;
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
StaticGlobalRenamer StaticRenamer;
SourceModulesList SourceModules;
- std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
+ std::vector<VModuleKey> BaseLayerVModuleKeys;
};
- using LogicalDylibList = std::list<LogicalDylib>;
-
public:
- /// @brief Handle to loaded module.
- using ModuleHandleT = typename LogicalDylibList::iterator;
-
- /// @brief Module partitioning functor.
+ /// Module partitioning functor.
using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
- /// @brief Builder for IndirectStubsManagers.
+ /// Builder for IndirectStubsManagers.
using IndirectStubsManagerBuilderT =
std::function<std::unique_ptr<IndirectStubsMgrT>()>;
- /// @brief Construct a compile-on-demand layer instance.
- CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
+ using SymbolResolverGetter =
+ std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
+
+ using SymbolResolverSetter =
+ std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
+
+ /// Construct a compile-on-demand layer instance.
+ CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
+ SymbolResolverGetter GetSymbolResolver,
+ SymbolResolverSetter SetSymbolResolver,
+ PartitioningFtor Partition,
CompileCallbackMgrT &CallbackMgr,
IndirectStubsManagerBuilderT CreateIndirectStubsManager,
bool CloneStubsIntoPartitions = true)
- : BaseLayer(BaseLayer), Partition(std::move(Partition)),
- CompileCallbackMgr(CallbackMgr),
+ : ES(ES), BaseLayer(BaseLayer),
+ GetSymbolResolver(std::move(GetSymbolResolver)),
+ SetSymbolResolver(std::move(SetSymbolResolver)),
+ Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
~CompileOnDemandLayer() {
// FIXME: Report error on log.
while (!LogicalDylibs.empty())
- consumeError(removeModule(LogicalDylibs.begin()));
+ consumeError(removeModule(LogicalDylibs.begin()->first));
}
- /// @brief Add a module to the compile-on-demand layer.
- Expected<ModuleHandleT>
- addModule(std::shared_ptr<Module> M,
- std::shared_ptr<JITSymbolResolver> Resolver) {
+ /// Add a module to the compile-on-demand layer.
+ Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
- LogicalDylibs.push_back(LogicalDylib());
- auto &LD = LogicalDylibs.back();
- LD.ExternalSymbolResolver = std::move(Resolver);
- LD.StubsMgr = CreateIndirectStubsManager();
+ assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
+ auto I = LogicalDylibs.insert(
+ LogicalDylibs.end(),
+ std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
+ CreateIndirectStubsManager())));
- // Process each of the modules in this module set.
- if (auto Err = addLogicalModule(LD, std::move(M)))
- return std::move(Err);
-
- return std::prev(LogicalDylibs.end());
+ return addLogicalModule(I->second, std::move(M));
}
- /// @brief Add extra modules to an existing logical module.
- Error addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
- return addLogicalModule(*H, std::move(M));
+ /// Add extra modules to an existing logical module.
+ Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
+ return addLogicalModule(LogicalDylibs[K], std::move(M));
}
- /// @brief Remove the module represented by the given handle.
+ /// Remove the module represented by the given key.
///
/// This will remove all modules in the layers below that were derived from
- /// the module represented by H.
- Error removeModule(ModuleHandleT H) {
- auto Err = H->removeModulesFromBaseLayer(BaseLayer);
- LogicalDylibs.erase(H);
+ /// the module represented by K.
+ Error removeModule(VModuleKey K) {
+ auto I = LogicalDylibs.find(K);
+ assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
+ auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
+ LogicalDylibs.erase(I);
return Err;
}
- /// @brief Search for the given named symbol.
+ /// Search for the given named symbol.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
- for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
- LDI != LDE; ++LDI) {
- if (auto Sym = LDI->StubsMgr->findStub(Name, ExportedSymbolsOnly))
+ for (auto &KV : LogicalDylibs) {
+ if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
- if (auto Sym = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
+ if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
@@ -269,14 +316,15 @@ public:
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
- /// @brief Get the address of a symbol provided by this layer, or some layer
+ /// Get the address of a symbol provided by this layer, or some layer
/// below this one.
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
+ JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
bool ExportedSymbolsOnly) {
- return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
+ assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
+ return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
}
- /// @brief Update the stub for the given function to point at FnBodyAddr.
+ /// Update the stub for the given function to point at FnBodyAddr.
/// This can be used to support re-optimization.
/// @return true if the function exists and the stub is updated, false
/// otherwise.
@@ -302,15 +350,14 @@ public:
}
private:
-
- Error addLogicalModule(LogicalDylib &LD, std::shared_ptr<Module> SrcMPtr) {
+ Error addLogicalModule(LogicalDylib &LD, std::unique_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.
LD.StaticRenamer.rename(*SrcMPtr);
- // Bump the linkage and rename any anonymous/privote members in SrcM to
+ // Bump the linkage and rename any anonymous/private members in SrcM to
// ensure that everything will resolve properly after we partition SrcM.
makeAllSymbolsExternallyAccessible(*SrcMPtr);
@@ -343,22 +390,21 @@ private:
// Create a callback, associate it with the stub for the function,
// and set the compile action to compile the partition containing the
// function.
- if (auto CCInfoOrErr = CompileCallbackMgr.getCompileCallback()) {
- auto &CCInfo = *CCInfoOrErr;
+ auto CompileAction = [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;
+ }
+ };
+ if (auto CCAddr =
+ CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
StubInits[MangledName] =
- std::make_pair(CCInfo.getAddress(),
- JITSymbolFlags::fromGlobalValue(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;
- }
- });
- } else
- return CCInfoOrErr.takeError();
+ std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
+ else
+ return CCAddr.takeError();
}
if (auto Err = LD.StubsMgr->createStubs(StubInits))
@@ -396,9 +442,8 @@ 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, &MaterializerErrors](Value *V) -> Value* {
+ [&LD, &GVsM](Value *V) -> Value* {
if (auto *F = dyn_cast<Function>(V)) {
// Decls in the original module just get cloned.
if (F->isDeclaration())
@@ -410,18 +455,8 @@ private:
const DataLayout &DL = GVsM->getDataLayout();
std::string FName = mangle(F->getName(), DL);
unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
- 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());
- }
+ JITTargetAddress StubAddr =
+ LD.StubsMgr->findStub(FName, false).getAddress();
ConstantInt *StubAddrCI =
ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
@@ -450,29 +485,58 @@ 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) -> 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);
+ auto LegacyLookup = [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 nullptr;
+ };
+
+ auto GVsResolver = createSymbolResolver(
+ [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
+ auto SymbolFlags = lookupFlagsWithLegacyFn(Symbols, LegacyLookup);
+
+ if (!SymbolFlags) {
+ logAllUnhandledErrors(SymbolFlags.takeError(), errs(),
+ "CODLayer/GVsResolver flags lookup failed: ");
+ return SymbolFlagsMap();
+ }
+
+ if (SymbolFlags->size() == Symbols.size())
+ return *SymbolFlags;
+
+ SymbolNameSet NotFoundViaLegacyLookup;
+ for (auto &S : Symbols)
+ if (!SymbolFlags->count(S))
+ NotFoundViaLegacyLookup.insert(S);
+ auto SymbolFlags2 =
+ LD.BackingResolver->lookupFlags(NotFoundViaLegacyLookup);
+
+ for (auto &KV : SymbolFlags2)
+ (*SymbolFlags)[KV.first] = std::move(KV.second);
+
+ return *SymbolFlags;
},
- [&LD](const std::string &Name) {
- return LD.ExternalSymbolResolver->findSymbol(Name);
+ [this, &LD,
+ LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
+ SymbolNameSet Symbols) {
+ auto NotFoundViaLegacyLookup =
+ lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
+ return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
});
- if (auto GVsHOrErr =
- BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver)))
- LD.BaseLayerHandles.push_back(*GVsHOrErr);
- else
- return GVsHOrErr.takeError();
+ SetSymbolResolver(LD.K, std::move(GVsResolver));
+
+ if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
+ return Err;
+
+ LD.BaseLayerVModuleKeys.push_back(LD.K);
return Error::success();
}
@@ -501,11 +565,11 @@ private:
JITTargetAddress CalledAddr = 0;
auto Part = Partition(F);
- if (auto PartHOrErr = emitPartition(LD, LMId, Part)) {
- auto &PartH = *PartHOrErr;
+ if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
+ auto &PartKey = *PartKeyOrErr;
for (auto *SubF : Part) {
std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
- if (auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false)) {
+ if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
@@ -526,15 +590,15 @@ private:
llvm_unreachable("Function not emitted for partition");
}
- LD.BaseLayerHandles.push_back(PartH);
+ LD.BaseLayerVModuleKeys.push_back(PartKey);
} else
- return PartHOrErr.takeError();
+ return PartKeyOrErr.takeError();
return CalledAddr;
}
template <typename PartitionT>
- Expected<BaseLayerModuleHandleT>
+ Expected<VModuleKey>
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
@@ -596,28 +660,62 @@ private:
for (auto *F : Part)
moveFunctionBody(*F, VMap, &Materializer);
+ auto K = ES.allocateVModule();
+
+ auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
+ return LD.findSymbol(BaseLayer, Name, false);
+ };
+
// Create memory manager and symbol resolver.
- auto Resolver = createLambdaResolver(
- [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);
+ auto Resolver = createSymbolResolver(
+ [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
+ auto SymbolFlags = lookupFlagsWithLegacyFn(Symbols, LegacyLookup);
+ if (!SymbolFlags) {
+ logAllUnhandledErrors(SymbolFlags.takeError(), errs(),
+ "CODLayer/SubResolver flags lookup failed: ");
+ return SymbolFlagsMap();
+ }
+
+ if (SymbolFlags->size() == Symbols.size())
+ return *SymbolFlags;
+
+ SymbolNameSet NotFoundViaLegacyLookup;
+ for (auto &S : Symbols)
+ if (!SymbolFlags->count(S))
+ NotFoundViaLegacyLookup.insert(S);
+
+ auto SymbolFlags2 =
+ LD.BackingResolver->lookupFlags(NotFoundViaLegacyLookup);
+
+ for (auto &KV : SymbolFlags2)
+ (*SymbolFlags)[KV.first] = std::move(KV.second);
+
+ return *SymbolFlags;
},
- [&LD](const std::string &Name) {
- return LD.ExternalSymbolResolver->findSymbol(Name);
+ [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
+ SymbolNameSet Symbols) {
+ auto NotFoundViaLegacyLookup =
+ lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
+ return LD.BackingResolver->lookup(Q,
+ std::move(NotFoundViaLegacyLookup));
});
+ SetSymbolResolver(K, std::move(Resolver));
+
+ if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
+ return std::move(Err);
- return BaseLayer.addModule(std::move(M), std::move(Resolver));
+ return K;
}
+ ExecutionSession &ES;
BaseLayerT &BaseLayer;
+ SymbolResolverGetter GetSymbolResolver;
+ SymbolResolverSetter SetSymbolResolver;
PartitioningFtor Partition;
CompileCallbackMgrT &CompileCallbackMgr;
IndirectStubsManagerBuilderT CreateIndirectStubsManager;
- LogicalDylibList LogicalDylibs;
+ std::map<VModuleKey, LogicalDylib> LogicalDylibs;
bool CloneStubsIntoPartitions;
};