[Orc] Refactor the CompileOnDemandLayer to make its addModuleSet method

signature match the other layers.

This makes it possible to compose other layers (e.g. IRTransformLayer) on top
of CompileOnDemandLayer.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235029 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames 2015-04-15 18:26:24 +00:00
parent 9051b7fc69
commit a1c91277c4
2 changed files with 58 additions and 39 deletions

View File

@ -36,7 +36,7 @@ namespace orc {
/// compiled only when it is first called.
template <typename BaseLayerT, typename CompileCallbackMgrT>
class CompileOnDemandLayer {
public:
private:
/// @brief Lookup helper that provides compatibility with the classic
/// static-compilation symbol resolution process.
///
@ -64,6 +64,8 @@ public:
/// @brief Construct a scoped lookup.
CODScopedLookup(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
virtual ~CODScopedLookup() {}
/// @brief Start a new context for a single logical module.
LMHandle createLogicalModule() {
Handles.push_back(SiblingHandlesList());
@ -92,6 +94,10 @@ public:
return nullptr;
}
/// @brief Find an external symbol (via the user supplied SymbolResolver).
virtual RuntimeDyld::SymbolInfo
externalLookup(const std::string &Name) const = 0;
private:
JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) {
@ -105,7 +111,29 @@ public:
PseudoDylibModuleSetHandlesList Handles;
};
private:
template <typename ResolverPtrT>
class CODScopedLookupImpl : public CODScopedLookup {
public:
CODScopedLookupImpl(BaseLayerT &BaseLayer, ResolverPtrT Resolver)
: CODScopedLookup(BaseLayer), Resolver(std::move(Resolver)) {}
RuntimeDyld::SymbolInfo
externalLookup(const std::string &Name) const override {
return Resolver->findSymbol(Name);
}
private:
ResolverPtrT Resolver;
};
template <typename ResolverPtrT>
static std::shared_ptr<CODScopedLookup>
createCODScopedLookup(BaseLayerT &BaseLayer,
ResolverPtrT Resolver) {
typedef CODScopedLookupImpl<ResolverPtrT> Impl;
return std::make_shared<Impl>(BaseLayer, std::move(Resolver));
}
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerModuleSetHandleListT;
@ -138,40 +166,31 @@ public:
/// @brief Handle to a set of loaded modules.
typedef typename ModuleSetInfoListT::iterator ModuleSetHandleT;
// @brief Fallback lookup functor.
typedef std::function<RuntimeDyld::SymbolInfo(const std::string &)> LookupFtor;
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
: BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
/// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT>
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
LookupFtor FallbackLookup = nullptr) {
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
// If the user didn't supply a fallback lookup then just use
// getSymbolAddress.
if (!FallbackLookup)
FallbackLookup =
[=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
if (auto Symbol = findSymbol(Name, true))
return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
Symbol.getFlags());
return nullptr;
};
assert(MemMgr == nullptr &&
"User supplied memory managers not supported with COD yet.");
// Create a lookup context and ModuleSetInfo for this module set.
// For the purposes of symbol resolution the set Ms will be treated as if
// the modules it contained had been linked together as a dylib.
auto DylibLookup = std::make_shared<CODScopedLookup>(BaseLayer);
auto DylibLookup = createCODScopedLookup(BaseLayer, std::move(Resolver));
ModuleSetHandleT H =
ModuleSetInfos.insert(ModuleSetInfos.end(), ModuleSetInfo(DylibLookup));
ModuleSetInfo &MSI = ModuleSetInfos.back();
// Process each of the modules in this module set.
for (auto &M : Ms)
partitionAndAdd(*M, MSI, FallbackLookup);
partitionAndAdd(*M, MSI);
return H;
}
@ -207,8 +226,7 @@ public:
private:
void partitionAndAdd(Module &M, ModuleSetInfo &MSI,
LookupFtor FallbackLookup) {
void partitionAndAdd(Module &M, ModuleSetInfo &MSI) {
const char *AddrSuffix = "$orc_addr";
const char *BodySuffix = "$orc_body";
@ -228,8 +246,7 @@ private:
auto FunctionModules = std::move(PartitionedModule.Functions);
// Emit the commons stright away.
auto CommonHandle = addModule(std::move(CommonsModule), MSI, LogicalModule,
FallbackLookup);
auto CommonHandle = addModule(std::move(CommonsModule), MSI, LogicalModule);
BaseLayer.emitAndFinalize(CommonHandle);
// Map of definition names to callback-info data structures. We'll use
@ -274,7 +291,7 @@ private:
NewStubInfos.push_back(StubInfos.insert(StubInfos.begin(), KV));
}
auto H = addModule(std::move(SubM), MSI, LogicalModule, FallbackLookup);
auto H = addModule(std::move(SubM), MSI, LogicalModule);
// Set the compile actions for this module:
for (auto &KVPair : NewStubInfos) {
@ -292,7 +309,7 @@ private:
// Ok - we've processed all the partitioned modules. Now add the
// stubs/globals module and set the update actions.
auto StubsH =
addModule(std::move(StubsModule), MSI, LogicalModule, FallbackLookup);
addModule(std::move(StubsModule), MSI, LogicalModule);
for (auto &KVPair : StubInfos) {
std::string AddrName = Mangle(KVPair.first + AddrSuffix,
@ -310,8 +327,7 @@ private:
BaseLayerModuleSetHandleT addModule(
std::unique_ptr<Module> M,
ModuleSetInfo &MSI,
typename CODScopedLookup::LMHandle LogicalModule,
LookupFtor FallbackLookup) {
typename CODScopedLookup::LMHandle LogicalModule) {
// Add this module to the JIT with a memory manager that uses the
// DylibLookup to resolve symbols.
@ -325,7 +341,7 @@ private:
if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
Symbol.getFlags());
return FallbackLookup(Name);
return DylibLookup->externalLookup(Name);
},
[=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))

View File

@ -92,25 +92,28 @@ public:
// 1) Search the JIT symbols.
// 2) Check for C++ runtime overrides.
// 3) Search the host process (LLI)'s symbol table.
auto FallbackLookup =
[this](const std::string &Name) {
auto Resolver =
orc::createLambdaResolver(
[this](const std::string &Name) {
if (auto Sym = CODLayer.findSymbol(Name, true))
return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
if (auto Sym = CODLayer.findSymbol(Name, true))
return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
return Sym;
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
return Sym;
if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
return RuntimeDyld::SymbolInfo(nullptr);
};
return RuntimeDyld::SymbolInfo(nullptr);
},
[](const std::string &Name) { return RuntimeDyld::SymbolInfo(nullptr); }
);
// Add the module to the JIT.
std::vector<std::unique_ptr<Module>> S;
S.push_back(std::move(M));
auto H = CODLayer.addModuleSet(std::move(S), std::move(FallbackLookup));
auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver));
// Run the static constructors, and save the static destructor runner for
// execution when the JIT is torn down.