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

View File

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