mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
[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:
@ -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))
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user