forked from OSchip/llvm-project
[ORC] Start migrating ORC layers to use the new ORC Core.h APIs.
In particular this patch switches RTDyldObjectLinkingLayer to use orc::SymbolResolver and threads the requried changse (ExecutionSession references and VModuleKeys) through the existing layer APIs. The purpose of the new resolver interface is to improve query performance and better support parallelism, both in JIT'd code and within the compiler itself. The most visibile change is switch of the <Layer>::addModule signatures from: Expected<Handle> addModule(std::shared_ptr<ModuleType> Mod, std::shared_ptr<JITSymbolResolver> Resolver) to: Expected<Handle> addModule(VModuleKey K, std::shared_ptr<ModuleType> Mod); Typical usage of addModule will now look like: auto K = ES.allocateVModuleKey(); Resolvers[K] = createSymbolResolver(...); Layer.addModule(K, std::move(Mod)); See the BuildingAJIT tutorial code for example usage. llvm-svn: 324405
This commit is contained in:
parent
ffe72034a6
commit
4b546c9145
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -38,6 +38,9 @@ namespace orc {
|
|||
|
||||
class KaleidoscopeJIT {
|
||||
private:
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
|
@ -47,8 +50,24 @@ public:
|
|||
using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT()
|
||||
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
: ES(SSP),
|
||||
Resolver(createLegacyLookupResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = CompileLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<SectionMemoryManager>(); },
|
||||
[this](VModuleKey K) { return Resolver; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
|
||||
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
||||
}
|
||||
|
@ -56,27 +75,8 @@ public:
|
|||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandle addModule(std::unique_ptr<Module> M) {
|
||||
// Build our symbol resolver:
|
||||
// Lambda 1: Look back into the JIT itself to find symbols that are part of
|
||||
// the same "logical dylib".
|
||||
// Lambda 2: Search for external symbols in the host process.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = CompileLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
|
||||
// Add the set to the JIT with the resolver we created above and a newly
|
||||
// created SectionMemoryManager.
|
||||
return cantFail(CompileLayer.addModule(std::move(M),
|
||||
std::move(Resolver)));
|
||||
// Add the module to the JIT with a new VModuleKey.
|
||||
return cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(const std::string Name) {
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace orc {
|
|||
|
||||
class KaleidoscopeJIT {
|
||||
private:
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
|
@ -56,40 +59,37 @@ public:
|
|||
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT()
|
||||
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
: ES(SSP),
|
||||
Resolver(createLegacyLookupResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<SectionMemoryManager>(); },
|
||||
[this](VModuleKey K) { return Resolver; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
|
||||
OptimizeLayer(CompileLayer,
|
||||
[this](std::shared_ptr<Module> M) {
|
||||
return optimizeModule(std::move(M));
|
||||
}) {
|
||||
OptimizeLayer(CompileLayer, [this](std::shared_ptr<Module> M) {
|
||||
return optimizeModule(std::move(M));
|
||||
}) {
|
||||
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
||||
}
|
||||
|
||||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandle addModule(std::unique_ptr<Module> M) {
|
||||
// Build our symbol resolver:
|
||||
// Lambda 1: Look back into the JIT itself to find symbols that are part of
|
||||
// the same "logical dylib".
|
||||
// Lambda 2: Search for external symbols in the host process.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
|
||||
// Add the set to the JIT with the resolver we created above and a newly
|
||||
// created SectionMemoryManager.
|
||||
return cantFail(OptimizeLayer.addModule(std::move(M),
|
||||
std::move(Resolver)));
|
||||
// Add the module to the JIT with a new VModuleKey.
|
||||
return cantFail(
|
||||
OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(const std::string Name) {
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
@ -45,6 +46,9 @@ namespace orc {
|
|||
|
||||
class KaleidoscopeJIT {
|
||||
private:
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::map<VModuleKey, std::shared_ptr<SymbolResolver>> Resolvers;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
|
@ -62,8 +66,11 @@ public:
|
|||
using ModuleHandle = decltype(CODLayer)::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT()
|
||||
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
: ES(SSP), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<SectionMemoryManager>(); },
|
||||
[&](orc::VModuleKey K) { return Resolvers[K]; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
|
||||
OptimizeLayer(CompileLayer,
|
||||
[this](std::shared_ptr<Module> M) {
|
||||
|
@ -71,37 +78,40 @@ public:
|
|||
}),
|
||||
CompileCallbackManager(
|
||||
orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)),
|
||||
CODLayer(OptimizeLayer,
|
||||
[](Function &F) { return std::set<Function*>({&F}); },
|
||||
CODLayer(ES, OptimizeLayer,
|
||||
[&](orc::VModuleKey K) { return Resolvers[K]; },
|
||||
[&](orc::VModuleKey K, std::shared_ptr<SymbolResolver> R) {
|
||||
Resolvers[K] = std::move(R);
|
||||
},
|
||||
[](Function &F) { return std::set<Function *>({&F}); },
|
||||
*CompileCallbackManager,
|
||||
orc::createLocalIndirectStubsManagerBuilder(
|
||||
TM->getTargetTriple())) {
|
||||
TM->getTargetTriple())) {
|
||||
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
||||
}
|
||||
|
||||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandle addModule(std::unique_ptr<Module> M) {
|
||||
// Build our symbol resolver:
|
||||
// Lambda 1: Look back into the JIT itself to find symbols that are part of
|
||||
// the same "logical dylib".
|
||||
// Lambda 2: Search for external symbols in the host process.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = CODLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
// Create a new VModuleKey.
|
||||
VModuleKey K = ES.allocateVModule();
|
||||
|
||||
// Add the set to the JIT with the resolver we created above and a newly
|
||||
// created SectionMemoryManager.
|
||||
return cantFail(CODLayer.addModule(std::move(M), std::move(Resolver)));
|
||||
// Build a resolver and associate it with the new key.
|
||||
Resolvers[K] = createLegacyLookupResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = CompileLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); });
|
||||
|
||||
// Add the module to the JIT with the new key.
|
||||
return cantFail(CODLayer.addModule(K, std::move(M)));
|
||||
}
|
||||
|
||||
JITSymbol findSymbol(const std::string Name) {
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
|
@ -37,6 +37,7 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -71,6 +72,9 @@ namespace orc {
|
|||
|
||||
class KaleidoscopeJIT {
|
||||
private:
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
|
@ -88,9 +92,26 @@ public:
|
|||
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT()
|
||||
: TM(EngineBuilder().selectTarget()),
|
||||
DL(TM->createDataLayout()),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
: ES(SSP),
|
||||
Resolver(createLegacyLookupResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, false))
|
||||
return Sym;
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<SectionMemoryManager>(); },
|
||||
[&](VModuleKey K) { return Resolver; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
|
||||
OptimizeLayer(CompileLayer,
|
||||
[this](std::shared_ptr<Module> M) {
|
||||
|
@ -107,29 +128,9 @@ public:
|
|||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandle addModule(std::unique_ptr<Module> M) {
|
||||
// Build our symbol resolver:
|
||||
// Lambda 1: Look back into the JIT itself to find symbols that are part of
|
||||
// the same "logical dylib".
|
||||
// Lambda 2: Search for external symbols in the host process.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, false))
|
||||
return Sym;
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
|
||||
// Add the set to the JIT with the resolver we created above and a newly
|
||||
// created SectionMemoryManager.
|
||||
return cantFail(OptimizeLayer.addModule(std::move(M),
|
||||
std::move(Resolver)));
|
||||
// Add the module to the JIT with a new VModuleKey.
|
||||
return cantFail(
|
||||
OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
|
||||
}
|
||||
|
||||
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
|
||||
|
|
|
@ -15,18 +15,18 @@
|
|||
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|
||||
|
||||
#include "RemoteJITUtils.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -76,6 +77,9 @@ using MyRemote = remote::OrcRemoteTargetClient;
|
|||
|
||||
class KaleidoscopeJIT {
|
||||
private:
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
|
@ -94,12 +98,28 @@ public:
|
|||
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT(MyRemote &Remote)
|
||||
: TM(EngineBuilder().selectTarget(Triple(Remote.getTargetTriple()), "",
|
||||
: ES(SSP),
|
||||
Resolver(createLegacyLookupResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, false))
|
||||
return Sym;
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto Addr = cantFail(this->Remote.getSymbolAddress(Name)))
|
||||
return JITSymbol(Addr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget(Triple(Remote.getTargetTriple()), "",
|
||||
"", SmallVector<std::string, 0>())),
|
||||
DL(TM->createDataLayout()),
|
||||
ObjectLayer([&Remote]() {
|
||||
return cantFail(Remote.createRemoteMemoryManager());
|
||||
}),
|
||||
ObjectLayer(ES,
|
||||
[&Remote](VModuleKey) {
|
||||
return cantFail(Remote.createRemoteMemoryManager());
|
||||
},
|
||||
[this](VModuleKey) { return Resolver; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
|
||||
OptimizeLayer(CompileLayer,
|
||||
[this](std::shared_ptr<Module> M) {
|
||||
|
@ -120,33 +140,9 @@ public:
|
|||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandle addModule(std::unique_ptr<Module> M) {
|
||||
// Build our symbol resolver:
|
||||
// Lambda 1: Look back into the JIT itself to find symbols that are part of
|
||||
// the same "logical dylib".
|
||||
// Lambda 2: Search for external symbols in the host process.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, false))
|
||||
return Sym;
|
||||
if (auto Sym = OptimizeLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[&](const std::string &Name) {
|
||||
if (auto AddrOrErr = Remote.getSymbolAddress(Name))
|
||||
return JITSymbol(*AddrOrErr, JITSymbolFlags::Exported);
|
||||
else {
|
||||
logAllUnhandledErrors(AddrOrErr.takeError(), errs(),
|
||||
"Error resolving remote symbol:");
|
||||
exit(1);
|
||||
}
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
|
||||
// Add the set to the JIT with the resolver we created above and a newly
|
||||
// created SectionMemoryManager.
|
||||
return cantFail(OptimizeLayer.addModule(std::move(M),
|
||||
std::move(Resolver)));
|
||||
// Add the module with a new VModuleKey.
|
||||
return cantFail(
|
||||
OptimizeLayer.addModule(ES.allocateVModule(), std::move(M)));
|
||||
}
|
||||
|
||||
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
ExecutionEngine
|
||||
InstCombine
|
||||
Object
|
||||
OrcJIT
|
||||
RuntimeDyld
|
||||
ScalarOpts
|
||||
Support
|
||||
|
|
|
@ -14,22 +14,23 @@
|
|||
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|
||||
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -44,8 +45,17 @@ public:
|
|||
using ModuleHandleT = CompileLayerT::ModuleHandleT;
|
||||
|
||||
KaleidoscopeJIT()
|
||||
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
: ES(SSP),
|
||||
Resolver(createLegacyLookupResolver(
|
||||
[this](const std::string &Name) {
|
||||
return ObjectLayer.findSymbol(Name, true);
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<SectionMemoryManager>(); },
|
||||
[this](VModuleKey) { return Resolver; }),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
|
||||
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
||||
}
|
||||
|
@ -53,19 +63,8 @@ public:
|
|||
TargetMachine &getTargetMachine() { return *TM; }
|
||||
|
||||
ModuleHandleT addModule(std::unique_ptr<Module> M) {
|
||||
// We need a memory manager to allocate memory and resolve symbols for this
|
||||
// new module. Create one that resolves symbols by looking back into the
|
||||
// JIT.
|
||||
auto Resolver = createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = findMangledSymbol(Name))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &S) { return nullptr; });
|
||||
auto H = cantFail(CompileLayer.addModule(std::move(M),
|
||||
std::move(Resolver)));
|
||||
|
||||
auto H =
|
||||
cantFail(CompileLayer.addModule(ES.allocateVModule(), std::move(M)));
|
||||
ModuleHandles.push_back(H);
|
||||
return H;
|
||||
}
|
||||
|
@ -127,6 +126,9 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
ObjLayerT ObjectLayer;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
||||
|
@ -138,8 +139,6 @@ private:
|
|||
};
|
||||
|
||||
struct LogicalDylib {
|
||||
using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>;
|
||||
|
||||
struct SourceModuleEntry {
|
||||
std::shared_ptr<Module> SourceMod;
|
||||
std::set<Function*> StubsToClone;
|
||||
|
@ -183,7 +182,8 @@ private:
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ExternalSymbolResolver;
|
||||
VModuleKey K;
|
||||
std::shared_ptr<SymbolResolver> BackingResolver;
|
||||
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
|
||||
StaticGlobalRenamer StaticRenamer;
|
||||
SourceModulesList SourceModules;
|
||||
|
@ -204,13 +204,24 @@ public:
|
|||
using IndirectStubsManagerBuilderT =
|
||||
std::function<std::unique_ptr<IndirectStubsMgrT>()>;
|
||||
|
||||
using SymbolResolverGetter =
|
||||
std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
|
||||
|
||||
using SymbolResolverSetter =
|
||||
std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
|
||||
|
||||
/// @brief Construct a compile-on-demand layer instance.
|
||||
CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
|
||||
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) {}
|
||||
|
||||
|
@ -221,16 +232,14 @@ public:
|
|||
}
|
||||
|
||||
/// @brief Add a module to the compile-on-demand layer.
|
||||
Expected<ModuleHandleT>
|
||||
addModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
|
||||
Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
|
||||
|
||||
LogicalDylibs.push_back(LogicalDylib());
|
||||
auto &LD = LogicalDylibs.back();
|
||||
LD.ExternalSymbolResolver = std::move(Resolver);
|
||||
LD.K = std::move(K);
|
||||
LD.StubsMgr = CreateIndirectStubsManager();
|
||||
LD.BackingResolver = GetSymbolResolver(LD.K);
|
||||
|
||||
// Process each of the modules in this module set.
|
||||
if (auto Err = addLogicalModule(LD, std::move(M)))
|
||||
return std::move(Err);
|
||||
|
||||
|
@ -454,22 +463,46 @@ private:
|
|||
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;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
|
||||
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(
|
||||
[this, &LD, LegacyLookup](SymbolFlagsMap &SymbolFlags,
|
||||
const SymbolNameSet &Symbols) {
|
||||
auto NotFoundViaLegacyLookup =
|
||||
lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup);
|
||||
|
||||
if (!NotFoundViaLegacyLookup) {
|
||||
logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(),
|
||||
"CODLayer/GVsResolver flags lookup failed: ");
|
||||
SymbolFlags.clear();
|
||||
return SymbolNameSet();
|
||||
}
|
||||
|
||||
return LD.BackingResolver->lookupFlags(SymbolFlags,
|
||||
*NotFoundViaLegacyLookup);
|
||||
},
|
||||
[&LD](const std::string &Name) {
|
||||
return LD.ExternalSymbolResolver->findSymbol(Name);
|
||||
[&LD, LegacyLookup](AsynchronousSymbolQuery &Query,
|
||||
SymbolNameSet Symbols) {
|
||||
auto NotFoundViaLegacyLookup =
|
||||
lookupWithLegacyFn(Query, Symbols, LegacyLookup);
|
||||
return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
|
||||
});
|
||||
|
||||
if (auto GVsHOrErr =
|
||||
BaseLayer.addModule(std::move(GVsM), std::move(GVsResolver)))
|
||||
SetSymbolResolver(LD.K, std::move(GVsResolver));
|
||||
|
||||
if (auto GVsHOrErr = BaseLayer.addModule(LD.K, std::move(GVsM)))
|
||||
LD.BaseLayerHandles.push_back(*GVsHOrErr);
|
||||
else
|
||||
return GVsHOrErr.takeError();
|
||||
|
@ -596,23 +629,42 @@ private:
|
|||
for (auto *F : Part)
|
||||
moveFunctionBody(*F, VMap, &Materializer);
|
||||
|
||||
// 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);
|
||||
},
|
||||
[&LD](const std::string &Name) {
|
||||
return LD.ExternalSymbolResolver->findSymbol(Name);
|
||||
});
|
||||
auto K = ES.allocateVModule();
|
||||
|
||||
return BaseLayer.addModule(std::move(M), std::move(Resolver));
|
||||
auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
|
||||
return LD.findSymbol(BaseLayer, Name, false);
|
||||
};
|
||||
|
||||
// Create memory manager and symbol resolver.
|
||||
auto Resolver = createSymbolResolver(
|
||||
[this, &LD, LegacyLookup](SymbolFlagsMap &SymbolFlags,
|
||||
const SymbolNameSet &Symbols) {
|
||||
auto NotFoundViaLegacyLookup =
|
||||
lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup);
|
||||
if (!NotFoundViaLegacyLookup) {
|
||||
logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(),
|
||||
"CODLayer/SubResolver flags lookup failed: ");
|
||||
SymbolFlags.clear();
|
||||
return SymbolNameSet();
|
||||
}
|
||||
return LD.BackingResolver->lookupFlags(SymbolFlags,
|
||||
*NotFoundViaLegacyLookup);
|
||||
},
|
||||
[&LD, LegacyLookup](AsynchronousSymbolQuery &Q, SymbolNameSet Symbols) {
|
||||
auto NotFoundViaLegacyLookup =
|
||||
lookupWithLegacyFn(Q, Symbols, LegacyLookup);
|
||||
return LD.BackingResolver->lookup(Q,
|
||||
std::move(NotFoundViaLegacyLookup));
|
||||
});
|
||||
SetSymbolResolver(K, std::move(Resolver));
|
||||
|
||||
return BaseLayer.addModule(std::move(K), std::move(M));
|
||||
}
|
||||
|
||||
ExecutionSession &ES;
|
||||
BaseLayerT &BaseLayer;
|
||||
SymbolResolverGetter GetSymbolResolver;
|
||||
SymbolResolverSetter SetSymbolResolver;
|
||||
PartitioningFtor Partition;
|
||||
CompileCallbackMgrT &CompileCallbackMgr;
|
||||
IndirectStubsManagerBuilderT CreateIndirectStubsManager;
|
||||
|
|
|
@ -104,20 +104,27 @@ public:
|
|||
Error runViaLayer(JITLayerT &JITLayer) const {
|
||||
using CtorDtorTy = void (*)();
|
||||
|
||||
for (const auto &CtorDtorName : CtorDtorNames)
|
||||
for (const auto &CtorDtorName : CtorDtorNames) {
|
||||
dbgs() << "Searching for ctor/dtor: " << CtorDtorName << "...";
|
||||
if (auto CtorDtorSym = JITLayer.findSymbolIn(H, CtorDtorName, false)) {
|
||||
dbgs() << " found symbol...";
|
||||
if (auto AddrOrErr = CtorDtorSym.getAddress()) {
|
||||
dbgs() << " at addr " << format("0x%016x", *AddrOrErr) << "\n";
|
||||
CtorDtorTy CtorDtor =
|
||||
reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr));
|
||||
CtorDtor();
|
||||
} else
|
||||
} else {
|
||||
dbgs() << " failed materialization!\n";
|
||||
return AddrOrErr.takeError();
|
||||
}
|
||||
} else {
|
||||
dbgs() << " failed to find symbol...";
|
||||
if (auto Err = CtorDtorSym.takeError())
|
||||
return Err;
|
||||
else
|
||||
return make_error<JITSymbolNotFound>(CtorDtorName);
|
||||
}
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -50,12 +51,10 @@ public:
|
|||
/// along with the given memory manager and symbol resolver.
|
||||
///
|
||||
/// @return A handle for the added module.
|
||||
Expected<ModuleHandleT>
|
||||
addModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
|
||||
using CompileResult = decltype(Compile(*M));
|
||||
auto Obj = std::make_shared<CompileResult>(Compile(*M));
|
||||
return BaseLayer.addObject(std::move(Obj), std::move(Resolver));
|
||||
return BaseLayer.addObject(std::move(K), std::move(Obj));
|
||||
}
|
||||
|
||||
/// @brief Remove the module associated with the handle H.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
@ -42,10 +43,8 @@ public:
|
|||
/// the layer below, along with the memory manager and symbol resolver.
|
||||
///
|
||||
/// @return A handle for the added modules.
|
||||
Expected<ModuleHandleT>
|
||||
addModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver));
|
||||
Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
|
||||
return BaseLayer.addModule(std::move(K), Transform(std::move(M)));
|
||||
}
|
||||
|
||||
/// @brief Remove the module associated with the handle H.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
@ -46,9 +47,8 @@ public:
|
|||
private:
|
||||
class EmissionDeferredModule {
|
||||
public:
|
||||
EmissionDeferredModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver)
|
||||
: M(std::move(M)), Resolver(std::move(Resolver)) {}
|
||||
EmissionDeferredModule(VModuleKey K, std::shared_ptr<Module> M)
|
||||
: K(std::move(K)), M(std::move(M)) {}
|
||||
|
||||
JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
|
||||
switch (EmitState) {
|
||||
|
@ -139,7 +139,7 @@ private:
|
|||
// We don't need the mangled names set any more: Once we've emitted this
|
||||
// to the base layer we'll just look for symbols there.
|
||||
MangledSymbols.reset();
|
||||
return BaseLayer.addModule(std::move(M), std::move(Resolver));
|
||||
return BaseLayer.addModule(std::move(K), std::move(M));
|
||||
}
|
||||
|
||||
// If the mangled name of the given GlobalValue matches the given search
|
||||
|
@ -193,8 +193,8 @@ private:
|
|||
|
||||
enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
|
||||
BaseLayerHandleT Handle;
|
||||
VModuleKey K;
|
||||
std::shared_ptr<Module> M;
|
||||
std::shared_ptr<JITSymbolResolver> Resolver;
|
||||
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
|
||||
};
|
||||
|
||||
|
@ -212,13 +212,10 @@ public:
|
|||
LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
|
||||
|
||||
/// @brief Add the given module to the lazy emitting layer.
|
||||
Expected<ModuleHandleT>
|
||||
addModule(std::shared_ptr<Module> M,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
Expected<ModuleHandleT> addModule(VModuleKey K, std::shared_ptr<Module> M) {
|
||||
return ModuleList.insert(
|
||||
ModuleList.end(),
|
||||
llvm::make_unique<EmissionDeferredModule>(std::move(M),
|
||||
std::move(Resolver)));
|
||||
llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M)));
|
||||
}
|
||||
|
||||
/// @brief Remove the module represented by the given handle.
|
||||
|
|
|
@ -92,6 +92,46 @@ SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query,
|
|||
return SymbolsNotFound;
|
||||
}
|
||||
|
||||
/// @brief An ORC SymbolResolver implementation that uses a legacy
|
||||
/// findSymbol-like function to perform lookup;
|
||||
template <typename LegacyLookupFn>
|
||||
class LegacyLookupFnResolver final : public SymbolResolver {
|
||||
public:
|
||||
using ErrorReporter = std::function<void(Error)>;
|
||||
|
||||
LegacyLookupFnResolver(LegacyLookupFn LegacyLookup, ErrorReporter ReportError)
|
||||
: LegacyLookup(std::move(LegacyLookup)),
|
||||
ReportError(std::move(ReportError)) {}
|
||||
|
||||
SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
|
||||
const SymbolNameSet &Symbols) final {
|
||||
if (auto RemainingSymbols =
|
||||
lookupFlagsWithLegacyFn(Flags, Symbols, LegacyLookup))
|
||||
return std::move(*RemainingSymbols);
|
||||
else {
|
||||
ReportError(RemainingSymbols.takeError());
|
||||
return Symbols;
|
||||
}
|
||||
}
|
||||
|
||||
SymbolNameSet lookup(AsynchronousSymbolQuery &Query,
|
||||
SymbolNameSet Symbols) final {
|
||||
return lookupWithLegacyFn(Query, Symbols, LegacyLookup);
|
||||
}
|
||||
|
||||
private:
|
||||
LegacyLookupFn LegacyLookup;
|
||||
ErrorReporter ReportError;
|
||||
};
|
||||
|
||||
template <typename LegacyLookupFn>
|
||||
std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>>
|
||||
createLegacyLookupResolver(LegacyLookupFn LegacyLookup,
|
||||
std::function<void(Error)> ErrorReporter) {
|
||||
return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>(
|
||||
std::move(LegacyLookup), std::move(ErrorReporter));
|
||||
};
|
||||
|
||||
} // End namespace orc
|
||||
} // End namespace llvm
|
||||
|
||||
|
|
|
@ -15,11 +15,21 @@
|
|||
#ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
class NullResolver : public SymbolResolver {
|
||||
public:
|
||||
SymbolNameSet lookupFlags(SymbolFlagsMap &Flags,
|
||||
const SymbolNameSet &Symbols) override;
|
||||
|
||||
SymbolNameSet lookup(AsynchronousSymbolQuery &Query,
|
||||
SymbolNameSet Symbols) override;
|
||||
};
|
||||
|
||||
/// SymbolResolver impliementation that rejects all resolution requests.
|
||||
/// Useful for clients that have no cross-object fixups.
|
||||
class NullLegacyResolver : public LegacyJITSymbolResolver {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -44,9 +45,8 @@ public:
|
|||
///
|
||||
/// @return A handle for the added objects.
|
||||
template <typename ObjectPtr>
|
||||
Expected<ObjHandleT> addObject(ObjectPtr Obj,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver));
|
||||
Expected<ObjHandleT> addObject(VModuleKey K, ObjectPtr Obj) {
|
||||
return BaseLayer.addObject(std::move(K), Transform(std::move(Obj)));
|
||||
}
|
||||
|
||||
/// @brief Remove the object set associated with the handle H.
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Legacy.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
@ -55,7 +57,7 @@ protected:
|
|||
void operator=(const LinkedObject&) = delete;
|
||||
virtual ~LinkedObject() = default;
|
||||
|
||||
virtual void finalize() = 0;
|
||||
virtual Error finalize() = 0;
|
||||
|
||||
virtual JITSymbol::GetAddressFtor
|
||||
getSymbolMaterializer(std::string Name) = 0;
|
||||
|
@ -107,21 +109,17 @@ public:
|
|||
using NotifyFinalizedFtor = std::function<void(ObjHandleT)>;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
|
||||
typename FinalizerFtor>
|
||||
template <typename MemoryManagerPtrT, typename FinalizerFtor>
|
||||
class ConcreteLinkedObject : public LinkedObject {
|
||||
public:
|
||||
ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
|
||||
SymbolResolverPtrT Resolver,
|
||||
FinalizerFtor Finalizer,
|
||||
bool ProcessAllSections)
|
||||
: MemMgr(std::move(MemMgr)),
|
||||
PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj),
|
||||
std::move(Resolver),
|
||||
std::move(Finalizer),
|
||||
ProcessAllSections)) {
|
||||
ConcreteLinkedObject(ExecutionSession &ES, ObjectPtr Obj,
|
||||
MemoryManagerPtrT MemMgr,
|
||||
std::shared_ptr<SymbolResolver> Resolver,
|
||||
FinalizerFtor Finalizer, bool ProcessAllSections)
|
||||
: MemMgr(std::move(MemMgr)),
|
||||
PFC(llvm::make_unique<PreFinalizeContents>(
|
||||
ES, std::move(Obj), std::move(Resolver), std::move(Finalizer),
|
||||
ProcessAllSections)) {
|
||||
buildInitialSymbolTable(PFC->Obj);
|
||||
}
|
||||
|
||||
|
@ -133,32 +131,32 @@ private:
|
|||
PFC->Handle = H;
|
||||
}
|
||||
|
||||
void finalize() override {
|
||||
Error finalize() override {
|
||||
assert(PFC && "mapSectionAddress called on finalized LinkedObject");
|
||||
|
||||
RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver);
|
||||
JITSymbolResolverAdapter ResolverAdapter(PFC->ES, *PFC->Resolver);
|
||||
RuntimeDyld RTDyld(*MemMgr, ResolverAdapter);
|
||||
RTDyld.setProcessAllSections(PFC->ProcessAllSections);
|
||||
PFC->RTDyld = &RTDyld;
|
||||
|
||||
this->Finalized = true;
|
||||
PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
|
||||
[&]() {
|
||||
this->updateSymbolTable(RTDyld);
|
||||
});
|
||||
auto Err = PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj),
|
||||
[&]() { this->updateSymbolTable(RTDyld); });
|
||||
|
||||
// Release resources.
|
||||
PFC = nullptr;
|
||||
return Err;
|
||||
}
|
||||
|
||||
JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override {
|
||||
return
|
||||
[this, Name]() {
|
||||
// The symbol may be materialized between the creation of this lambda
|
||||
// and its execution, so we need to double check.
|
||||
if (!this->Finalized)
|
||||
this->finalize();
|
||||
return this->getSymbol(Name, false).getAddress();
|
||||
};
|
||||
return [this, Name]() -> Expected<JITTargetAddress> {
|
||||
// The symbol may be materialized between the creation of this lambda
|
||||
// and its execution, so we need to double check.
|
||||
if (!this->Finalized)
|
||||
if (auto Err = this->finalize())
|
||||
return std::move(Err);
|
||||
return this->getSymbol(Name, false).getAddress();
|
||||
};
|
||||
}
|
||||
|
||||
void mapSectionAddress(const void *LocalAddress,
|
||||
|
@ -194,14 +192,16 @@ private:
|
|||
// Contains the information needed prior to finalization: the object files,
|
||||
// memory manager, resolver, and flags needed for RuntimeDyld.
|
||||
struct PreFinalizeContents {
|
||||
PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver,
|
||||
PreFinalizeContents(ExecutionSession &ES, ObjectPtr Obj,
|
||||
std::shared_ptr<SymbolResolver> Resolver,
|
||||
FinalizerFtor Finalizer, bool ProcessAllSections)
|
||||
: Obj(std::move(Obj)), Resolver(std::move(Resolver)),
|
||||
Finalizer(std::move(Finalizer)),
|
||||
ProcessAllSections(ProcessAllSections) {}
|
||||
: ES(ES), Obj(std::move(Obj)), Resolver(std::move(Resolver)),
|
||||
Finalizer(std::move(Finalizer)),
|
||||
ProcessAllSections(ProcessAllSections) {}
|
||||
|
||||
ExecutionSession &ES;
|
||||
ObjectPtr Obj;
|
||||
SymbolResolverPtrT Resolver;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
FinalizerFtor Finalizer;
|
||||
bool ProcessAllSections;
|
||||
ObjHandleT Handle;
|
||||
|
@ -212,17 +212,14 @@ private:
|
|||
std::unique_ptr<PreFinalizeContents> PFC;
|
||||
};
|
||||
|
||||
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT,
|
||||
typename FinalizerFtor>
|
||||
std::unique_ptr<
|
||||
ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>>
|
||||
createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr,
|
||||
SymbolResolverPtrT Resolver,
|
||||
FinalizerFtor Finalizer,
|
||||
bool ProcessAllSections) {
|
||||
using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT,
|
||||
FinalizerFtor>;
|
||||
return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr),
|
||||
template <typename MemoryManagerPtrT, typename FinalizerFtor>
|
||||
std::unique_ptr<ConcreteLinkedObject<MemoryManagerPtrT, FinalizerFtor>>
|
||||
createLinkedObject(ExecutionSession &ES, ObjectPtr Obj,
|
||||
MemoryManagerPtrT MemMgr,
|
||||
std::shared_ptr<SymbolResolver> Resolver,
|
||||
FinalizerFtor Finalizer, bool ProcessAllSections) {
|
||||
using LOS = ConcreteLinkedObject<MemoryManagerPtrT, FinalizerFtor>;
|
||||
return llvm::make_unique<LOS>(ES, std::move(Obj), std::move(MemMgr),
|
||||
std::move(Resolver), std::move(Finalizer),
|
||||
ProcessAllSections);
|
||||
}
|
||||
|
@ -231,18 +228,23 @@ public:
|
|||
|
||||
/// @brief Functor for creating memory managers.
|
||||
using MemoryManagerGetter =
|
||||
std::function<std::shared_ptr<RuntimeDyld::MemoryManager>()>;
|
||||
std::function<std::shared_ptr<RuntimeDyld::MemoryManager>(VModuleKey)>;
|
||||
|
||||
using ResolverGetter =
|
||||
std::function<std::shared_ptr<SymbolResolver>(VModuleKey)>;
|
||||
|
||||
/// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded,
|
||||
/// and NotifyFinalized functors.
|
||||
RTDyldObjectLinkingLayer(
|
||||
MemoryManagerGetter GetMemMgr,
|
||||
ExecutionSession &ES, MemoryManagerGetter GetMemMgr,
|
||||
ResolverGetter GetResolver,
|
||||
NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(),
|
||||
NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor())
|
||||
: GetMemMgr(GetMemMgr),
|
||||
: ES(ES), GetMemMgr(std::move(GetMemMgr)),
|
||||
GetResolver(std::move(GetResolver)),
|
||||
NotifyLoaded(std::move(NotifyLoaded)),
|
||||
NotifyFinalized(std::move(NotifyFinalized)),
|
||||
ProcessAllSections(false) {}
|
||||
NotifyFinalized(std::move(NotifyFinalized)), ProcessAllSections(false) {
|
||||
}
|
||||
|
||||
/// @brief Set the 'ProcessAllSections' flag.
|
||||
///
|
||||
|
@ -258,11 +260,10 @@ public:
|
|||
///
|
||||
/// @return A handle that can be used to refer to the loaded object (for
|
||||
/// symbol searching, finalization, freeing memory, etc.).
|
||||
Expected<ObjHandleT> addObject(ObjectPtr Obj,
|
||||
std::shared_ptr<JITSymbolResolver> Resolver) {
|
||||
Expected<ObjHandleT> addObject(VModuleKey K, ObjectPtr Obj) {
|
||||
auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld,
|
||||
const ObjectPtr &ObjToLoad,
|
||||
std::function<void()> LOSHandleLoad) {
|
||||
std::function<void()> LOSHandleLoad) -> Error {
|
||||
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info =
|
||||
RTDyld.loadObject(*ObjToLoad->getBinary());
|
||||
|
||||
|
@ -273,14 +274,19 @@ public:
|
|||
|
||||
RTDyld.finalizeWithMemoryManagerLocking();
|
||||
|
||||
if (RTDyld.hasError())
|
||||
return make_error<StringError>(RTDyld.getErrorString(),
|
||||
inconvertibleErrorCode());
|
||||
|
||||
if (this->NotifyFinalized)
|
||||
this->NotifyFinalized(H);
|
||||
|
||||
return Error::success();
|
||||
};
|
||||
|
||||
auto LO =
|
||||
createLinkedObject(std::move(Obj), GetMemMgr(),
|
||||
std::move(Resolver), std::move(Finalizer),
|
||||
ProcessAllSections);
|
||||
createLinkedObject(ES, std::move(Obj), GetMemMgr(K), GetResolver(K),
|
||||
std::move(Finalizer), ProcessAllSections);
|
||||
// LOS is an owning-ptr. Keep a non-owning one so that we can set the handle
|
||||
// below.
|
||||
auto *LOPtr = LO.get();
|
||||
|
@ -339,15 +345,13 @@ public:
|
|||
/// @brief Immediately emit and finalize the object represented by the given
|
||||
/// handle.
|
||||
/// @param H Handle for object to emit/finalize.
|
||||
Error emitAndFinalize(ObjHandleT H) {
|
||||
(*H)->finalize();
|
||||
return Error::success();
|
||||
}
|
||||
Error emitAndFinalize(ObjHandleT H) { return (*H)->finalize(); }
|
||||
|
||||
private:
|
||||
|
||||
ExecutionSession &ES;
|
||||
LinkedObjectListT LinkedObjList;
|
||||
MemoryManagerGetter GetMemMgr;
|
||||
ResolverGetter GetResolver;
|
||||
NotifyLoadedFtor NotifyLoaded;
|
||||
NotifyFinalizedFtor NotifyFinalized;
|
||||
bool ProcessAllSections = false;
|
||||
|
|
|
@ -45,10 +45,21 @@ JITSymbolResolverAdapter::lookup(const LookupSet &Symbols) {
|
|||
|
||||
auto UnresolvedSymbols = R.lookup(Query, InternedSymbols);
|
||||
|
||||
if (!UnresolvedSymbols.empty())
|
||||
Err = joinErrors(std::move(Err),
|
||||
make_error<StringError>("Unresolved symbols",
|
||||
inconvertibleErrorCode()));
|
||||
if (!UnresolvedSymbols.empty()) {
|
||||
std::string ErrorMsg = "Unresolved symbols: ";
|
||||
|
||||
ErrorMsg += **UnresolvedSymbols.begin();
|
||||
for (auto I = std::next(UnresolvedSymbols.begin()),
|
||||
E = UnresolvedSymbols.end();
|
||||
I != E; ++I) {
|
||||
ErrorMsg += ", ";
|
||||
ErrorMsg += **I;
|
||||
}
|
||||
|
||||
Err =
|
||||
joinErrors(std::move(Err),
|
||||
make_error<StringError>(ErrorMsg, inconvertibleErrorCode()));
|
||||
}
|
||||
|
||||
if (Err)
|
||||
return std::move(Err);
|
||||
|
|
|
@ -14,6 +14,17 @@
|
|||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
SymbolNameSet NullResolver::lookupFlags(SymbolFlagsMap &Flags,
|
||||
const SymbolNameSet &Symbols) {
|
||||
return Symbols;
|
||||
}
|
||||
|
||||
SymbolNameSet NullResolver::lookup(AsynchronousSymbolQuery &Query,
|
||||
SymbolNameSet Symbols) {
|
||||
assert(Symbols.empty() && "Null resolver: Symbols must be empty");
|
||||
return Symbols;
|
||||
}
|
||||
|
||||
JITSymbol NullLegacyResolver::findSymbol(const std::string &Name) {
|
||||
llvm_unreachable("Unexpected cross-object symbol reference");
|
||||
}
|
||||
|
|
|
@ -52,24 +52,34 @@ namespace detail {
|
|||
|
||||
class GenericHandle {
|
||||
public:
|
||||
GenericHandle(orc::VModuleKey K) : K(K) {}
|
||||
|
||||
virtual ~GenericHandle() = default;
|
||||
|
||||
virtual JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) = 0;
|
||||
virtual Error removeModule() = 0;
|
||||
virtual Error removeModule(orc::ExecutionSession &ES) = 0;
|
||||
|
||||
orc::VModuleKey K;
|
||||
};
|
||||
|
||||
template <typename LayerT> class GenericHandleImpl : public GenericHandle {
|
||||
public:
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle,
|
||||
orc::VModuleKey K)
|
||||
: GenericHandle(std::move(K)), Layer(Layer), Handle(std::move(Handle)) {
|
||||
}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeModule(Handle); }
|
||||
Error removeModule(orc::ExecutionSession &ES) override {
|
||||
auto Err = Layer.removeModule(Handle);
|
||||
ES.releaseVModule(K);
|
||||
return Err;
|
||||
}
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
|
@ -82,28 +92,32 @@ namespace detail {
|
|||
private:
|
||||
using LayerT = orc::RTDyldObjectLinkingLayer;
|
||||
public:
|
||||
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle,
|
||||
orc::VModuleKey K)
|
||||
: GenericHandle(std::move(K)), Layer(Layer), Handle(std::move(Handle)) {
|
||||
}
|
||||
|
||||
JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
Error removeModule() override { return Layer.removeObject(Handle); }
|
||||
Error removeModule(orc::ExecutionSession &ES) override {
|
||||
auto Err = Layer.removeObject(Handle);
|
||||
ES.releaseVModule(K);
|
||||
return Err;
|
||||
}
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ObjHandleT Handle;
|
||||
};
|
||||
|
||||
|
||||
template <typename LayerT, typename HandleT>
|
||||
std::unique_ptr<GenericHandleImpl<LayerT>>
|
||||
createGenericHandle(LayerT &Layer, HandleT Handle) {
|
||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
||||
std::move(Handle));
|
||||
createGenericHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) {
|
||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(
|
||||
Layer, std::move(Handle), std::move(K));
|
||||
}
|
||||
|
||||
} // end namespace detail
|
||||
|
@ -126,20 +140,113 @@ private:
|
|||
|
||||
using OwningObject = object::OwningBinary<object::ObjectFile>;
|
||||
|
||||
class CBindingsResolver : public orc::SymbolResolver {
|
||||
public:
|
||||
CBindingsResolver(OrcCBindingsStack &Stack,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx)
|
||||
: Stack(Stack), ExternalResolver(std::move(ExternalResolver)),
|
||||
ExternalResolverCtx(std::move(ExternalResolverCtx)) {}
|
||||
|
||||
orc::SymbolNameSet lookupFlags(orc::SymbolFlagsMap &SymbolFlags,
|
||||
const orc::SymbolNameSet &Symbols) override {
|
||||
orc::SymbolNameSet SymbolsNotFound;
|
||||
|
||||
for (auto &S : Symbols) {
|
||||
if (auto Sym = findSymbol(*S))
|
||||
SymbolFlags[S] = Sym.getFlags();
|
||||
else if (auto Err = Sym.takeError()) {
|
||||
Stack.reportError(std::move(Err));
|
||||
return {};
|
||||
} else
|
||||
SymbolsNotFound.insert(S);
|
||||
}
|
||||
|
||||
return SymbolsNotFound;
|
||||
}
|
||||
|
||||
orc::SymbolNameSet lookup(orc::AsynchronousSymbolQuery &Query,
|
||||
orc::SymbolNameSet Symbols) override {
|
||||
orc::SymbolNameSet UnresolvedSymbols;
|
||||
|
||||
for (auto &S : Symbols) {
|
||||
if (auto Sym = findSymbol(*S)) {
|
||||
if (auto Addr = Sym.getAddress())
|
||||
Query.setDefinition(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
|
||||
else {
|
||||
Query.setFailed(Addr.takeError());
|
||||
return {};
|
||||
}
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
Query.setFailed(std::move(Err));
|
||||
return {};
|
||||
} else
|
||||
UnresolvedSymbols.insert(S);
|
||||
}
|
||||
|
||||
return UnresolvedSymbols;
|
||||
}
|
||||
|
||||
private:
|
||||
JITSymbol findSymbol(const std::string &Name) {
|
||||
// Search order:
|
||||
// 1. JIT'd symbols.
|
||||
// 2. Runtime overrides.
|
||||
// 3. External resolver (if present).
|
||||
|
||||
if (auto Sym = Stack.CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return Sym.takeError();
|
||||
|
||||
if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name))
|
||||
return Sym;
|
||||
|
||||
if (ExternalResolver)
|
||||
return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx),
|
||||
JITSymbolFlags::Exported);
|
||||
|
||||
return JITSymbol(nullptr);
|
||||
}
|
||||
|
||||
OrcCBindingsStack &Stack;
|
||||
LLVMOrcSymbolResolverFn ExternalResolver;
|
||||
void *ExternalResolverCtx = nullptr;
|
||||
};
|
||||
|
||||
public:
|
||||
using ModuleHandleT = unsigned;
|
||||
|
||||
OrcCBindingsStack(TargetMachine &TM,
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
|
||||
: DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()),
|
||||
CCMgr(std::move(CCMgr)),
|
||||
ObjectLayer(
|
||||
[]() {
|
||||
return std::make_shared<SectionMemoryManager>();
|
||||
}),
|
||||
: ES(SSP), DL(TM.createDataLayout()),
|
||||
IndirectStubsMgr(IndirectStubsMgrBuilder()), CCMgr(std::move(CCMgr)),
|
||||
ObjectLayer(ES,
|
||||
[](orc::VModuleKey K) {
|
||||
return std::make_shared<SectionMemoryManager>();
|
||||
},
|
||||
[this](orc::VModuleKey K) {
|
||||
auto ResolverI = Resolvers.find(K);
|
||||
assert(ResolverI != Resolvers.end() &&
|
||||
"No resolver for module K");
|
||||
auto Resolver = std::move(ResolverI->second);
|
||||
Resolvers.erase(ResolverI);
|
||||
return Resolver;
|
||||
}),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
|
||||
CODLayer(CompileLayer,
|
||||
CODLayer(ES, CompileLayer,
|
||||
[this](orc::VModuleKey K) {
|
||||
auto ResolverI = Resolvers.find(K);
|
||||
assert(ResolverI != Resolvers.end() &&
|
||||
"No resolver for module K");
|
||||
return ResolverI->second;
|
||||
},
|
||||
[this](orc::VModuleKey K,
|
||||
std::shared_ptr<orc::SymbolResolver> Resolver) {
|
||||
assert(!Resolvers.count(K) && "Resolver already present");
|
||||
Resolvers[K] = std::move(Resolver);
|
||||
},
|
||||
[](Function &F) { return std::set<Function *>({&F}); },
|
||||
*this->CCMgr, std::move(IndirectStubsMgrBuilder), false),
|
||||
CXXRuntimeOverrides(
|
||||
|
@ -195,38 +302,6 @@ public:
|
|||
JITTargetAddress Addr) {
|
||||
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
|
||||
}
|
||||
|
||||
std::shared_ptr<LegacyJITSymbolResolver>
|
||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return orc::createLambdaResolver(
|
||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name)
|
||||
-> JITSymbol {
|
||||
// Search order:
|
||||
// 1. JIT'd symbols.
|
||||
// 2. Runtime overrides.
|
||||
// 3. External resolver (if present).
|
||||
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return Sym.takeError();
|
||||
|
||||
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
||||
return Sym;
|
||||
|
||||
if (ExternalResolver)
|
||||
return JITSymbol(
|
||||
ExternalResolver(Name.c_str(), ExternalResolverCtx),
|
||||
JITSymbolFlags::Exported);
|
||||
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) -> JITSymbol {
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename LayerT>
|
||||
LLVMOrcErrorCode
|
||||
addIRModule(ModuleHandleT &RetHandle, LayerT &Layer,
|
||||
|
@ -247,13 +322,13 @@ public:
|
|||
for (auto Dtor : orc::getDestructors(*M))
|
||||
DtorNames.push_back(mangle(Dtor.Func->getName()));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
// Add the module to the JIT.
|
||||
ModuleHandleT H;
|
||||
if (auto LHOrErr = Layer.addModule(std::move(M), std::move(Resolver)))
|
||||
H = createHandle(Layer, *LHOrErr);
|
||||
orc::VModuleKey K = ES.allocateVModule();
|
||||
Resolvers[K] = std::make_shared<CBindingsResolver>(*this, ExternalResolver,
|
||||
ExternalResolverCtx);
|
||||
if (auto LHOrErr = Layer.addModule(K, std::move(M)))
|
||||
H = createHandle(Layer, *LHOrErr, K);
|
||||
else
|
||||
return mapError(LHOrErr.takeError());
|
||||
|
||||
|
@ -288,7 +363,7 @@ public:
|
|||
}
|
||||
|
||||
LLVMOrcErrorCode removeModule(ModuleHandleT H) {
|
||||
if (auto Err = GenericHandles[H]->removeModule())
|
||||
if (auto Err = GenericHandles[H]->removeModule(ES))
|
||||
return mapError(std::move(Err));
|
||||
GenericHandles[H] = nullptr;
|
||||
FreeHandleIndexes.push_back(H);
|
||||
|
@ -305,13 +380,13 @@ public:
|
|||
auto OwningObj =
|
||||
std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
orc::VModuleKey K = ES.allocateVModule();
|
||||
Resolvers[K] = std::make_shared<CBindingsResolver>(
|
||||
*this, ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
ModuleHandleT H;
|
||||
if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
|
||||
std::move(Resolver)))
|
||||
H = createHandle(ObjectLayer, *HOrErr);
|
||||
if (auto HOrErr = ObjectLayer.addObject(K, std::move(OwningObj)))
|
||||
H = createHandle(ObjectLayer, *HOrErr, K);
|
||||
else
|
||||
return mapError(HOrErr.takeError());
|
||||
|
||||
|
@ -358,18 +433,18 @@ public:
|
|||
|
||||
private:
|
||||
template <typename LayerT, typename HandleT>
|
||||
unsigned createHandle(LayerT &Layer, HandleT Handle) {
|
||||
unsigned createHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) {
|
||||
unsigned NewHandle;
|
||||
if (!FreeHandleIndexes.empty()) {
|
||||
NewHandle = FreeHandleIndexes.back();
|
||||
FreeHandleIndexes.pop_back();
|
||||
GenericHandles[NewHandle] =
|
||||
detail::createGenericHandle(Layer, std::move(Handle));
|
||||
detail::createGenericHandle(Layer, std::move(Handle), std::move(K));
|
||||
return NewHandle;
|
||||
} else {
|
||||
NewHandle = GenericHandles.size();
|
||||
GenericHandles.push_back(
|
||||
detail::createGenericHandle(Layer, std::move(Handle)));
|
||||
detail::createGenericHandle(Layer, std::move(Handle), std::move(K)));
|
||||
}
|
||||
return NewHandle;
|
||||
}
|
||||
|
@ -386,6 +461,14 @@ private:
|
|||
return Result;
|
||||
}
|
||||
|
||||
void reportError(Error Err) {
|
||||
// FIXME: Report errors on the execution session.
|
||||
logAllUnhandledErrors(std::move(Err), errs(), "ORC error: ");
|
||||
};
|
||||
|
||||
orc::SymbolStringPool SSP;
|
||||
orc::ExecutionSession ES;
|
||||
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
|
@ -402,6 +485,8 @@ private:
|
|||
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
||||
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
|
||||
std::string ErrMsg;
|
||||
|
||||
std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -138,18 +138,67 @@ class OrcMCJITReplacement : public ExecutionEngine {
|
|||
std::shared_ptr<MCJITMemoryManager> ClientMM;
|
||||
};
|
||||
|
||||
class LinkingResolver : public LegacyJITSymbolResolver {
|
||||
class LinkingORCResolver : public orc::SymbolResolver {
|
||||
public:
|
||||
LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
|
||||
LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {}
|
||||
|
||||
JITSymbol findSymbol(const std::string &Name) override {
|
||||
return M.ClientResolver->findSymbol(Name);
|
||||
SymbolNameSet lookupFlags(SymbolFlagsMap &SymbolFlags,
|
||||
const SymbolNameSet &Symbols) override {
|
||||
SymbolNameSet UnresolvedSymbols;
|
||||
|
||||
for (auto &S : Symbols) {
|
||||
if (auto Sym = M.findMangledSymbol(*S)) {
|
||||
SymbolFlags[S] = Sym.getFlags();
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
M.reportError(std::move(Err));
|
||||
return SymbolNameSet();
|
||||
} else {
|
||||
if (auto Sym2 = M.ClientResolver->findSymbolInLogicalDylib(*S)) {
|
||||
SymbolFlags[S] = Sym2.getFlags();
|
||||
} else if (auto Err = Sym2.takeError()) {
|
||||
M.reportError(std::move(Err));
|
||||
return SymbolNameSet();
|
||||
} else
|
||||
UnresolvedSymbols.insert(S);
|
||||
}
|
||||
}
|
||||
|
||||
return UnresolvedSymbols;
|
||||
}
|
||||
|
||||
JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
|
||||
if (auto Sym = M.findMangledSymbol(Name))
|
||||
return Sym;
|
||||
return M.ClientResolver->findSymbolInLogicalDylib(Name);
|
||||
SymbolNameSet lookup(AsynchronousSymbolQuery &Query,
|
||||
SymbolNameSet Symbols) override {
|
||||
SymbolNameSet UnresolvedSymbols;
|
||||
|
||||
for (auto &S : Symbols) {
|
||||
if (auto Sym = M.findMangledSymbol(*S)) {
|
||||
if (auto Addr = Sym.getAddress())
|
||||
Query.setDefinition(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
|
||||
else {
|
||||
Query.setFailed(Addr.takeError());
|
||||
return SymbolNameSet();
|
||||
}
|
||||
} else if (auto Err = Sym.takeError()) {
|
||||
Query.setFailed(std::move(Err));
|
||||
return SymbolNameSet();
|
||||
} else {
|
||||
if (auto Sym2 = M.ClientResolver->findSymbol(*S)) {
|
||||
if (auto Addr = Sym2.getAddress())
|
||||
Query.setDefinition(S,
|
||||
JITEvaluatedSymbol(*Addr, Sym2.getFlags()));
|
||||
else {
|
||||
Query.setFailed(Addr.takeError());
|
||||
return SymbolNameSet();
|
||||
}
|
||||
} else if (auto Err = Sym2.takeError()) {
|
||||
Query.setFailed(std::move(Err));
|
||||
return SymbolNameSet();
|
||||
} else
|
||||
UnresolvedSymbols.insert(S);
|
||||
}
|
||||
}
|
||||
|
||||
return UnresolvedSymbols;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -166,18 +215,23 @@ private:
|
|||
std::move(TM));
|
||||
}
|
||||
|
||||
void reportError(Error Err) {
|
||||
logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: ");
|
||||
}
|
||||
|
||||
public:
|
||||
OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
|
||||
std::unique_ptr<TargetMachine> TM)
|
||||
: ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
|
||||
: ExecutionEngine(TM->createDataLayout()), ES(SSP), TM(std::move(TM)),
|
||||
MemMgr(
|
||||
std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
|
||||
Resolver(std::make_shared<LinkingResolver>(*this)),
|
||||
Resolver(std::make_shared<LinkingORCResolver>(*this)),
|
||||
ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
|
||||
NotifyFinalized(*this),
|
||||
ObjectLayer([this]() { return this->MemMgr; }, NotifyObjectLoaded,
|
||||
NotifyFinalized),
|
||||
ObjectLayer(ES, [this](VModuleKey K) { return this->MemMgr; },
|
||||
[this](VModuleKey K) { return this->Resolver; },
|
||||
NotifyObjectLoaded, NotifyFinalized),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
|
||||
LazyEmitLayer(CompileLayer) {}
|
||||
|
||||
|
@ -201,20 +255,21 @@ public:
|
|||
delete Mod;
|
||||
};
|
||||
LocalModules.push_back(std::shared_ptr<Module>(MPtr, std::move(Deleter)));
|
||||
cantFail(LazyEmitLayer.addModule(LocalModules.back(), Resolver));
|
||||
cantFail(
|
||||
LazyEmitLayer.addModule(ES.allocateVModule(), LocalModules.back()));
|
||||
}
|
||||
|
||||
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
|
||||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O),
|
||||
nullptr);
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(Obj)));
|
||||
}
|
||||
|
||||
void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
|
||||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(std::move(O));
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(Obj)));
|
||||
}
|
||||
|
||||
void addArchive(object::OwningBinary<object::Archive> A) override {
|
||||
|
@ -322,7 +377,7 @@ private:
|
|||
auto Obj =
|
||||
std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||
std::move(ChildObj), nullptr);
|
||||
cantFail(ObjectLayer.addObject(std::move(Obj), Resolver));
|
||||
cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(Obj)));
|
||||
if (auto Sym = ObjectLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
}
|
||||
|
@ -374,9 +429,12 @@ private:
|
|||
using CompileLayerT = IRCompileLayer<ObjectLayerT, orc::SimpleCompiler>;
|
||||
using LazyEmitLayerT = LazyEmittingLayer<CompileLayerT>;
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES;
|
||||
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
|
||||
std::shared_ptr<LinkingResolver> Resolver;
|
||||
std::shared_ptr<LinkingORCResolver> Resolver;
|
||||
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
|
||||
Mangler Mang;
|
||||
|
||||
|
|
|
@ -61,13 +61,38 @@ public:
|
|||
std::unique_ptr<CompileCallbackMgr> CCMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder,
|
||||
bool InlineStubs)
|
||||
: TM(std::move(TM)), DL(this->TM->createDataLayout()),
|
||||
: ES(SSP), TM(std::move(TM)), DL(this->TM->createDataLayout()),
|
||||
CCMgr(std::move(CCMgr)),
|
||||
ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
|
||||
ObjectLayer(ES,
|
||||
[](orc::VModuleKey) {
|
||||
return std::make_shared<SectionMemoryManager>();
|
||||
},
|
||||
[&](orc::VModuleKey K) {
|
||||
auto ResolverI = Resolvers.find(K);
|
||||
assert(ResolverI != Resolvers.end() &&
|
||||
"Missing resolver for module K");
|
||||
auto Resolver = std::move(ResolverI->second);
|
||||
Resolvers.erase(ResolverI);
|
||||
return Resolver;
|
||||
}),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
|
||||
IRDumpLayer(CompileLayer, createDebugDumper()),
|
||||
CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr,
|
||||
std::move(IndirectStubsMgrBuilder), InlineStubs),
|
||||
CODLayer(
|
||||
ES, IRDumpLayer,
|
||||
[&](orc::VModuleKey K) {
|
||||
auto ResolverI = Resolvers.find(K);
|
||||
assert(ResolverI != Resolvers.end() &&
|
||||
"Missing resolver for module K");
|
||||
auto Resolver = std::move(ResolverI->second);
|
||||
Resolvers.erase(ResolverI);
|
||||
return Resolver;
|
||||
},
|
||||
[&](orc::VModuleKey K, std::shared_ptr<orc::SymbolResolver> R) {
|
||||
assert(!Resolvers.count(K) && "Resolver already present");
|
||||
Resolvers[K] = std::move(R);
|
||||
},
|
||||
extractSingleFunction, *this->CCMgr,
|
||||
std::move(IndirectStubsMgrBuilder), InlineStubs),
|
||||
CXXRuntimeOverrides(
|
||||
[this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
|
@ -114,24 +139,50 @@ public:
|
|||
// 2) Check for C++ runtime overrides.
|
||||
// 3) Search the host process (LLI)'s symbol table.
|
||||
if (!ModulesHandle) {
|
||||
auto Resolver =
|
||||
orc::createLambdaResolver(
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
return CXXRuntimeOverrides.searchOverrides(Name);
|
||||
auto LegacyLookupInDylib = [this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
return CXXRuntimeOverrides.searchOverrides(Name);
|
||||
};
|
||||
|
||||
auto LegacyLookup =
|
||||
[this, LegacyLookupInDylib](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = LegacyLookupInDylib(Name))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
|
||||
if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(Addr, JITSymbolFlags::Exported);
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
auto K = ES.allocateVModule();
|
||||
assert(!Resolvers.count(K) && "Resolver already present");
|
||||
Resolvers[K] = orc::createSymbolResolver(
|
||||
[this, LegacyLookupInDylib](orc::SymbolFlagsMap &SymbolFlags,
|
||||
const orc::SymbolNameSet &Symbols) {
|
||||
auto NotFoundViaLegacyLookup = lookupFlagsWithLegacyFn(
|
||||
SymbolFlags, Symbols, LegacyLookupInDylib);
|
||||
if (!NotFoundViaLegacyLookup) {
|
||||
logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(),
|
||||
"OrcLazyJIT lookupFlags error: ");
|
||||
SymbolFlags.clear();
|
||||
return orc::SymbolNameSet();
|
||||
}
|
||||
return std::move(*NotFoundViaLegacyLookup);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
if (auto Addr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(Addr, JITSymbolFlags::Exported);
|
||||
return JITSymbol(nullptr);
|
||||
}
|
||||
);
|
||||
[LegacyLookup](orc::AsynchronousSymbolQuery &Query,
|
||||
orc::SymbolNameSet Symbols) {
|
||||
return lookupWithLegacyFn(Query, Symbols, LegacyLookup);
|
||||
});
|
||||
|
||||
// Add the module to the JIT.
|
||||
if (auto ModulesHandleOrErr =
|
||||
CODLayer.addModule(std::move(M), std::move(Resolver)))
|
||||
CODLayer.addModule(std::move(K), std::move(M)))
|
||||
ModulesHandle = std::move(*ModulesHandleOrErr);
|
||||
else
|
||||
return ModulesHandleOrErr.takeError();
|
||||
|
@ -178,6 +229,11 @@ private:
|
|||
|
||||
static TransformFtor createDebugDumper();
|
||||
|
||||
orc::SymbolStringPool SSP;
|
||||
orc::ExecutionSession ES;
|
||||
|
||||
std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
|
||||
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
|
|
@ -59,9 +59,22 @@ TEST(CompileOnDemandLayerTest, FindSymbol) {
|
|||
|
||||
DummyCallbackManager CallbackMgr;
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
|
||||
auto GetResolver =
|
||||
[](orc::VModuleKey) -> std::shared_ptr<llvm::orc::SymbolResolver> {
|
||||
llvm_unreachable("Should never be called");
|
||||
};
|
||||
|
||||
auto SetResolver = [](orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>) {
|
||||
llvm_unreachable("Should never be called");
|
||||
};
|
||||
|
||||
llvm::orc::CompileOnDemandLayer<decltype(TestBaseLayer)> COD(
|
||||
TestBaseLayer, [](Function &F) { return std::set<Function *>{&F}; },
|
||||
CallbackMgr, [] { return llvm::make_unique<DummyStubsManager>(); }, true);
|
||||
ES, TestBaseLayer, GetResolver, SetResolver,
|
||||
[](Function &F) { return std::set<Function *>{&F}; }, CallbackMgr,
|
||||
[] { return llvm::make_unique<DummyStubsManager>(); }, true);
|
||||
|
||||
auto Sym = COD.findSymbol("foo", true);
|
||||
|
||||
|
|
|
@ -15,11 +15,8 @@ namespace {
|
|||
|
||||
struct MockBaseLayer {
|
||||
typedef int ModuleHandleT;
|
||||
ModuleHandleT addModule(
|
||||
std::shared_ptr<llvm::Module>,
|
||||
std::unique_ptr<llvm::RuntimeDyld::MemoryManager> MemMgr,
|
||||
std::unique_ptr<llvm::JITSymbolResolver> Resolver) {
|
||||
EXPECT_FALSE(MemMgr);
|
||||
ModuleHandleT addModule(llvm::orc::VModuleKey,
|
||||
std::shared_ptr<llvm::Module>) {
|
||||
return 42;
|
||||
}
|
||||
};
|
||||
|
@ -27,7 +24,8 @@ struct MockBaseLayer {
|
|||
TEST(LazyEmittingLayerTest, Empty) {
|
||||
MockBaseLayer M;
|
||||
llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
|
||||
cantFail(L.addModule(std::unique_ptr<llvm::Module>(), nullptr));
|
||||
cantFail(
|
||||
L.addModule(llvm::orc::VModuleKey(), std::unique_ptr<llvm::Module>()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
@ -49,20 +48,16 @@ public:
|
|||
MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
|
||||
|
||||
template <typename ObjPtrT>
|
||||
llvm::Expected<ObjHandleT>
|
||||
addObject(ObjPtrT Obj,
|
||||
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
|
||||
EXPECT_EQ(MockResolver, Resolver) << "Resolver should pass through";
|
||||
llvm::Expected<ObjHandleT> addObject(VModuleKey K, ObjPtrT Obj) {
|
||||
EXPECT_EQ(MockKey, K) << "Key should pass through";
|
||||
EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
|
||||
LastCalled = "addObject";
|
||||
MockObjHandle = 111;
|
||||
return MockObjHandle;
|
||||
}
|
||||
|
||||
template <typename ObjPtrT>
|
||||
void expectAddObject(ObjPtrT Obj,
|
||||
std::shared_ptr<llvm::JITSymbolResolver> Resolver) {
|
||||
MockResolver = Resolver;
|
||||
template <typename ObjPtrT> void expectAddObject(VModuleKey K, ObjPtrT Obj) {
|
||||
MockKey = K;
|
||||
MockObject = *Obj;
|
||||
}
|
||||
|
||||
|
@ -162,7 +157,7 @@ public:
|
|||
private:
|
||||
// Backing fields for remembering parameter/return values
|
||||
std::string LastCalled;
|
||||
std::shared_ptr<llvm::JITSymbolResolver> MockResolver;
|
||||
VModuleKey MockKey;
|
||||
MockObjectFile MockObject;
|
||||
ObjHandleT MockObjHandle;
|
||||
std::string MockName;
|
||||
|
@ -175,7 +170,7 @@ private:
|
|||
// Clear remembered parameters between calls
|
||||
void resetExpectations() {
|
||||
LastCalled = "nothing";
|
||||
MockResolver = nullptr;
|
||||
MockKey = 0;
|
||||
MockObject = 0;
|
||||
MockObjHandle = 0;
|
||||
MockName = "bogus";
|
||||
|
@ -190,6 +185,9 @@ private:
|
|||
TEST(ObjectTransformLayerTest, Main) {
|
||||
MockBaseLayer M;
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
|
||||
// Create one object transform layer using a transform (as a functor)
|
||||
// that allocates new objects, and deals in unique pointers.
|
||||
ObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
|
||||
|
@ -205,16 +203,17 @@ TEST(ObjectTransformLayerTest, Main) {
|
|||
});
|
||||
|
||||
// Test addObject with T1 (allocating)
|
||||
auto K1 = ES.allocateVModule();
|
||||
auto Obj1 = std::make_shared<MockObjectFile>(211);
|
||||
auto SR = std::make_shared<NullLegacyResolver>();
|
||||
M.expectAddObject(Obj1, SR);
|
||||
auto H = cantFail(T1.addObject(std::move(Obj1), SR));
|
||||
M.expectAddObject(K1, Obj1);
|
||||
auto H = cantFail(T1.addObject(K1, std::move(Obj1)));
|
||||
M.verifyAddObject(H);
|
||||
|
||||
// Test addObjectSet with T2 (mutating)
|
||||
auto K2 = ES.allocateVModule();
|
||||
auto Obj2 = std::make_shared<MockObjectFile>(222);
|
||||
M.expectAddObject(Obj2, SR);
|
||||
H = cantFail(T2.addObject(Obj2, SR));
|
||||
M.expectAddObject(K2, Obj2);
|
||||
H = cantFail(T2.addObject(K2, Obj2));
|
||||
M.verifyAddObject(H);
|
||||
EXPECT_EQ(223, *Obj2) << "Expected mutation";
|
||||
|
||||
|
@ -291,9 +290,11 @@ TEST(ObjectTransformLayerTest, Main) {
|
|||
|
||||
// Construct the jit layers.
|
||||
RTDyldObjectLinkingLayer BaseLayer(
|
||||
[]() {
|
||||
return std::make_shared<llvm::SectionMemoryManager>();
|
||||
});
|
||||
ES,
|
||||
[](VModuleKey) { return std::make_shared<llvm::SectionMemoryManager>(); },
|
||||
[](VModuleKey) -> std::shared_ptr<SymbolResolver> {
|
||||
llvm_unreachable("Should never be called");
|
||||
});
|
||||
|
||||
auto IdentityTransform =
|
||||
[](std::shared_ptr<llvm::object::OwningBinary<llvm::object::ObjectFile>>
|
||||
|
@ -311,8 +312,8 @@ TEST(ObjectTransformLayerTest, Main) {
|
|||
|
||||
// Make sure that the calls from IRCompileLayer to ObjectTransformLayer
|
||||
// compile.
|
||||
auto Resolver = std::make_shared<NullLegacyResolver>();
|
||||
cantFail(CompileLayer.addModule(std::shared_ptr<llvm::Module>(), Resolver));
|
||||
cantFail(CompileLayer.addModule(ES.allocateVModule(),
|
||||
std::shared_ptr<llvm::Module>()));
|
||||
|
||||
// Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer
|
||||
// compile.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Legacy.h"
|
||||
#include "llvm/ExecutionEngine/Orc/NullResolver.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
|
@ -66,7 +67,12 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
|
|||
bool DebugSectionSeen = false;
|
||||
auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen);
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer(
|
||||
ES, [&MM](VModuleKey) { return MM; },
|
||||
[](orc::VModuleKey) { return std::make_shared<NullResolver>(); });
|
||||
|
||||
LLVMContext Context;
|
||||
auto M = llvm::make_unique<Module>("", Context);
|
||||
|
@ -92,18 +98,9 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
|
|||
std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||
SimpleCompiler(*TM)(*M));
|
||||
|
||||
auto Resolver =
|
||||
createLambdaResolver(
|
||||
[](const std::string &Name) {
|
||||
return JITSymbol(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
return JITSymbol(nullptr);
|
||||
});
|
||||
|
||||
{
|
||||
// Test with ProcessAllSections = false (the default).
|
||||
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
|
||||
auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
|
||||
cantFail(ObjLayer.emitAndFinalize(H));
|
||||
EXPECT_EQ(DebugSectionSeen, false)
|
||||
<< "Unexpected debug info section";
|
||||
|
@ -113,7 +110,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
|
|||
{
|
||||
// Test with ProcessAllSections = true.
|
||||
ObjLayer.setProcessAllSections(true);
|
||||
auto H = cantFail(ObjLayer.addObject(Obj, Resolver));
|
||||
auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), Obj));
|
||||
cantFail(ObjLayer.emitAndFinalize(H));
|
||||
EXPECT_EQ(DebugSectionSeen, true)
|
||||
<< "Expected debug info section not seen";
|
||||
|
@ -125,9 +122,22 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
|
|||
if (!TM)
|
||||
return;
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
|
||||
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
|
||||
std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) { return MM; },
|
||||
[&](VModuleKey K) {
|
||||
auto I = Resolvers.find(K);
|
||||
assert(I != Resolvers.end() &&
|
||||
"Missing resolver");
|
||||
auto R = std::move(I->second);
|
||||
Resolvers.erase(I);
|
||||
return R;
|
||||
});
|
||||
SimpleCompiler Compile(*TM);
|
||||
|
||||
// Create a pair of modules that will trigger recursive finalization:
|
||||
|
@ -170,19 +180,25 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
|
|||
std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||
Compile(*MB2.getModule()));
|
||||
|
||||
auto Resolver =
|
||||
createLambdaResolver(
|
||||
[&](const std::string &Name) {
|
||||
if (auto Sym = ObjLayer.findSymbol(Name, true))
|
||||
return Sym;
|
||||
return JITSymbol(nullptr);
|
||||
auto K1 = ES.allocateVModule();
|
||||
Resolvers[K1] = std::make_shared<NullResolver>();
|
||||
cantFail(ObjLayer.addObject(K1, std::move(Obj1)));
|
||||
|
||||
auto K2 = ES.allocateVModule();
|
||||
auto LegacyLookup = [&](const std::string &Name) {
|
||||
return ObjLayer.findSymbol(Name, true);
|
||||
};
|
||||
|
||||
Resolvers[K2] = createSymbolResolver(
|
||||
[&](SymbolFlagsMap &SymbolFlags, const SymbolNameSet &Symbols) {
|
||||
return cantFail(
|
||||
lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup));
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
return JITSymbol(nullptr);
|
||||
[&](AsynchronousSymbolQuery &Query, const SymbolNameSet &Symbols) {
|
||||
return lookupWithLegacyFn(Query, Symbols, LegacyLookup);
|
||||
});
|
||||
|
||||
cantFail(ObjLayer.addObject(std::move(Obj1), Resolver));
|
||||
auto H = cantFail(ObjLayer.addObject(std::move(Obj2), Resolver));
|
||||
auto H = cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
|
||||
cantFail(ObjLayer.emitAndFinalize(H));
|
||||
cantFail(ObjLayer.removeObject(H));
|
||||
|
||||
|
@ -196,9 +212,14 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
|
|||
if (!TM)
|
||||
return;
|
||||
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
|
||||
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; });
|
||||
RTDyldObjectLinkingLayer ObjLayer(
|
||||
ES, [&MM](VModuleKey) { return MM; },
|
||||
[](VModuleKey) { return std::make_shared<NullResolver>(); });
|
||||
SimpleCompiler Compile(*TM);
|
||||
|
||||
// Create a pair of unrelated modules:
|
||||
|
@ -243,9 +264,8 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
|
|||
std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||
Compile(*MB2.getModule()));
|
||||
|
||||
auto NR = std::make_shared<NullLegacyResolver>();
|
||||
auto H = cantFail(ObjLayer.addObject(std::move(Obj1), NR));
|
||||
cantFail(ObjLayer.addObject(std::move(Obj2), NR));
|
||||
auto H = cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj1)));
|
||||
cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
|
||||
cantFail(ObjLayer.emitAndFinalize(H));
|
||||
cantFail(ObjLayer.removeObject(H));
|
||||
|
||||
|
@ -256,8 +276,11 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
|
|||
}
|
||||
|
||||
TEST_F(RTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
|
||||
SymbolStringPool SSP;
|
||||
ExecutionSession ES(SSP);
|
||||
RTDyldObjectLinkingLayer ObjLayer(
|
||||
[]() { return nullptr; },
|
||||
ES, [](VModuleKey) { return nullptr; },
|
||||
[](VModuleKey) { return std::make_shared<NullResolver>(); },
|
||||
[](RTDyldObjectLinkingLayer::ObjHandleT,
|
||||
const RTDyldObjectLinkingLayer::ObjectPtr &obj,
|
||||
const RuntimeDyld::LoadedObjectInfo &info) {});
|
||||
|
|
Loading…
Reference in New Issue