diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt index 657a14be87d0..72c9668f7d3a 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h index ab675e3f7422..91709433d937 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h @@ -38,6 +38,9 @@ namespace orc { class KaleidoscopeJIT { private: + SymbolStringPool SSP; + ExecutionSession ES; + std::shared_ptr Resolver; std::unique_ptr 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(); }), + : 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(); }, + [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 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) { diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt index ea5bc05fa00a..ba6abd72d428 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h index 9a295f1566cb..4b7549391b9c 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h @@ -42,6 +42,9 @@ namespace orc { class KaleidoscopeJIT { private: + SymbolStringPool SSP; + ExecutionSession ES; + std::shared_ptr Resolver; std::unique_ptr 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(); }), + : 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(); }, + [this](VModuleKey K) { return Resolver; }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), - OptimizeLayer(CompileLayer, - [this](std::shared_ptr M) { - return optimizeModule(std::move(M)); - }) { + OptimizeLayer(CompileLayer, [this](std::shared_ptr M) { + return optimizeModule(std::move(M)); + }) { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); } TargetMachine &getTargetMachine() { return *TM; } ModuleHandle addModule(std::unique_ptr 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) { diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h index a03f5ce5e238..43de6d9ef567 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h @@ -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 +#include #include #include #include @@ -45,6 +46,9 @@ namespace orc { class KaleidoscopeJIT { private: + SymbolStringPool SSP; + ExecutionSession ES; + std::map> Resolvers; std::unique_ptr 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(); }), + : ES(SSP), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), + ObjectLayer( + ES, + [](VModuleKey) { return std::make_shared(); }, + [&](orc::VModuleKey K) { return Resolvers[K]; }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, [this](std::shared_ptr M) { @@ -71,37 +78,40 @@ public: }), CompileCallbackManager( orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)), - CODLayer(OptimizeLayer, - [](Function &F) { return std::set({&F}); }, + CODLayer(ES, OptimizeLayer, + [&](orc::VModuleKey K) { return Resolvers[K]; }, + [&](orc::VModuleKey K, std::shared_ptr R) { + Resolvers[K] = std::move(R); + }, + [](Function &F) { return std::set({&F}); }, *CompileCallbackManager, orc::createLocalIndirectStubsManagerBuilder( - TM->getTargetTriple())) { + TM->getTargetTriple())) { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); } TargetMachine &getTargetMachine() { return *TM; } ModuleHandle addModule(std::unique_ptr 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) { diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h index 841ea74fb98a..a95efd4ba822 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h @@ -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 #include #include +#include #include #include #include @@ -71,6 +72,9 @@ namespace orc { class KaleidoscopeJIT { private: + SymbolStringPool SSP; + ExecutionSession ES; + std::shared_ptr Resolver; std::unique_ptr 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(); }), + : 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(); }, + [&](VModuleKey K) { return Resolver; }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, [this](std::shared_ptr M) { @@ -107,29 +128,9 @@ public: TargetMachine &getTargetMachine() { return *TM; } ModuleHandle addModule(std::unique_ptr 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 FnAST) { diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h index 8990a67feb72..2e9f5c3b37f0 100644 --- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h @@ -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 #include #include +#include #include #include #include @@ -76,6 +77,9 @@ using MyRemote = remote::OrcRemoteTargetClient; class KaleidoscopeJIT { private: + SymbolStringPool SSP; + ExecutionSession ES; + std::shared_ptr Resolver; std::unique_ptr 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())), 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 M) { @@ -120,33 +140,9 @@ public: TargetMachine &getTargetMachine() { return *TM; } ModuleHandle addModule(std::unique_ptr 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 FnAST) { diff --git a/llvm/examples/Kaleidoscope/Chapter4/CMakeLists.txt b/llvm/examples/Kaleidoscope/Chapter4/CMakeLists.txt index 89feed143adc..fdc083e07681 100644 --- a/llvm/examples/Kaleidoscope/Chapter4/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/Chapter4/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/Chapter5/CMakeLists.txt b/llvm/examples/Kaleidoscope/Chapter5/CMakeLists.txt index c0ae70654c36..757d901ef525 100644 --- a/llvm/examples/Kaleidoscope/Chapter5/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/Chapter5/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/Chapter6/CMakeLists.txt b/llvm/examples/Kaleidoscope/Chapter6/CMakeLists.txt index 49627f07ddf0..ad50928a346c 100644 --- a/llvm/examples/Kaleidoscope/Chapter6/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/Chapter6/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/Chapter7/CMakeLists.txt b/llvm/examples/Kaleidoscope/Chapter7/CMakeLists.txt index 69e78be6a620..03220358ab71 100644 --- a/llvm/examples/Kaleidoscope/Chapter7/CMakeLists.txt +++ b/llvm/examples/Kaleidoscope/Chapter7/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ExecutionEngine InstCombine Object + OrcJIT RuntimeDyld ScalarOpts Support diff --git a/llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h index 215ce03af99b..a1cbe0267bab 100644 --- a/llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h +++ b/llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h @@ -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 +#include #include #include #include @@ -44,8 +45,17 @@ public: using ModuleHandleT = CompileLayerT::ModuleHandleT; KaleidoscopeJIT() - : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), - ObjectLayer([]() { return std::make_shared(); }), + : 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(); }, + [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 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 Resolver; std::unique_ptr TM; const DataLayout DL; ObjLayerT ObjectLayer; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 3281c354676c..1daff438b685 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -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; - struct SourceModuleEntry { std::shared_ptr SourceMod; std::set StubsToClone; @@ -183,7 +182,8 @@ private: return Error::success(); } - std::shared_ptr ExternalSymbolResolver; + VModuleKey K; + std::shared_ptr BackingResolver; std::unique_ptr StubsMgr; StaticGlobalRenamer StaticRenamer; SourceModulesList SourceModules; @@ -204,13 +204,24 @@ public: using IndirectStubsManagerBuilderT = std::function()>; + using SymbolResolverGetter = + std::function(VModuleKey K)>; + + using SymbolResolverSetter = + std::function 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 - addModule(std::shared_ptr M, - std::shared_ptr Resolver) { + Expected addModule(VModuleKey K, std::shared_ptr 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; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index d9b45c6a1e29..22071ff0cb04 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -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(static_cast(*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(CtorDtorName); } + } return Error::success(); } diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index fadd334bed0f..94a3086a4eea 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -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 #include @@ -50,12 +51,10 @@ public: /// along with the given memory manager and symbol resolver. /// /// @return A handle for the added module. - Expected - addModule(std::shared_ptr M, - std::shared_ptr Resolver) { + Expected addModule(VModuleKey K, std::shared_ptr M) { using CompileResult = decltype(Compile(*M)); auto Obj = std::make_shared(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. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 476061afda59..31de6f1cd5cb 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include #include @@ -42,10 +43,8 @@ public: /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. - Expected - addModule(std::shared_ptr M, - std::shared_ptr Resolver) { - return BaseLayer.addModule(Transform(std::move(M)), std::move(Resolver)); + Expected addModule(VModuleKey K, std::shared_ptr M) { + return BaseLayer.addModule(std::move(K), Transform(std::move(M))); } /// @brief Remove the module associated with the handle H. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index b7e462e85d9d..0da6e0135b77 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.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 M, - std::shared_ptr Resolver) - : M(std::move(M)), Resolver(std::move(Resolver)) {} + EmissionDeferredModule(VModuleKey K, std::shared_ptr 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 M; - std::shared_ptr Resolver; mutable std::unique_ptr> MangledSymbols; }; @@ -212,13 +212,10 @@ public: LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} /// @brief Add the given module to the lazy emitting layer. - Expected - addModule(std::shared_ptr M, - std::shared_ptr Resolver) { + Expected addModule(VModuleKey K, std::shared_ptr M) { return ModuleList.insert( ModuleList.end(), - llvm::make_unique(std::move(M), - std::move(Resolver))); + llvm::make_unique(std::move(K), std::move(M))); } /// @brief Remove the module represented by the given handle. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h index e04ef93a9629..ab495c6cebd3 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h @@ -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 +class LegacyLookupFnResolver final : public SymbolResolver { +public: + using ErrorReporter = std::function; + + 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 +std::shared_ptr> +createLegacyLookupResolver(LegacyLookupFn LegacyLookup, + std::function ErrorReporter) { + return std::make_shared>( + std::move(LegacyLookup), std::move(ErrorReporter)); +}; + } // End namespace orc } // End namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h index e946b909eff3..982bd868e763 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h @@ -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 { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index cb47e7520b1a..46bf21437c94 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -15,6 +15,7 @@ #define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Core.h" #include #include #include @@ -44,9 +45,8 @@ public: /// /// @return A handle for the added objects. template - Expected addObject(ObjectPtr Obj, - std::shared_ptr Resolver) { - return BaseLayer.addObject(Transform(std::move(Obj)), std::move(Resolver)); + Expected 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. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 246c57341f35..073d48e09d5d 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.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; private: - - - template + template class ConcreteLinkedObject : public LinkedObject { public: - ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) - : MemMgr(std::move(MemMgr)), - PFC(llvm::make_unique(std::move(Obj), - std::move(Resolver), - std::move(Finalizer), - ProcessAllSections)) { + ConcreteLinkedObject(ExecutionSession &ES, ObjectPtr Obj, + MemoryManagerPtrT MemMgr, + std::shared_ptr Resolver, + FinalizerFtor Finalizer, bool ProcessAllSections) + : MemMgr(std::move(MemMgr)), + PFC(llvm::make_unique( + 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 { + // 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 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 Resolver; FinalizerFtor Finalizer; bool ProcessAllSections; ObjHandleT Handle; @@ -212,17 +212,14 @@ private: std::unique_ptr PFC; }; - template - std::unique_ptr< - ConcreteLinkedObject> - createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) { - using LOS = ConcreteLinkedObject; - return llvm::make_unique(std::move(Obj), std::move(MemMgr), + template + std::unique_ptr> + createLinkedObject(ExecutionSession &ES, ObjectPtr Obj, + MemoryManagerPtrT MemMgr, + std::shared_ptr Resolver, + FinalizerFtor Finalizer, bool ProcessAllSections) { + using LOS = ConcreteLinkedObject; + return llvm::make_unique(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::function(VModuleKey)>; + + using ResolverGetter = + std::function(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 addObject(ObjectPtr Obj, - std::shared_ptr Resolver) { + Expected addObject(VModuleKey K, ObjectPtr Obj) { auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld, const ObjectPtr &ObjToLoad, - std::function LOSHandleLoad) { + std::function LOSHandleLoad) -> Error { std::unique_ptr Info = RTDyld.loadObject(*ObjToLoad->getBinary()); @@ -273,14 +274,19 @@ public: RTDyld.finalizeWithMemoryManagerLocking(); + if (RTDyld.hasError()) + return make_error(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; diff --git a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp index 7a11b94c7cf0..240e0f8ba1dd 100644 --- a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp @@ -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("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(ErrorMsg, inconvertibleErrorCode())); + } if (Err) return std::move(Err); diff --git a/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp b/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp index 6bb94f788416..59f7414df71d 100644 --- a/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp +++ b/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp @@ -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"); } diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index 05b1f47eb5bb..7128bd343809 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -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 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 std::unique_ptr> - createGenericHandle(LayerT &Layer, HandleT Handle) { - return llvm::make_unique>(Layer, - std::move(Handle)); + createGenericHandle(LayerT &Layer, HandleT Handle, orc::VModuleKey K) { + return llvm::make_unique>( + Layer, std::move(Handle), std::move(K)); } } // end namespace detail @@ -126,20 +140,113 @@ private: using OwningObject = object::OwningBinary; + 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 CCMgr, IndirectStubsManagerBuilder IndirectStubsMgrBuilder) - : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()), - CCMgr(std::move(CCMgr)), - ObjectLayer( - []() { - return std::make_shared(); - }), + : ES(SSP), DL(TM.createDataLayout()), + IndirectStubsMgr(IndirectStubsMgrBuilder()), CCMgr(std::move(CCMgr)), + ObjectLayer(ES, + [](orc::VModuleKey K) { + return std::make_shared(); + }, + [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 Resolver) { + assert(!Resolvers.count(K) && "Resolver already present"); + Resolvers[K] = std::move(Resolver); + }, [](Function &F) { return std::set({&F}); }, *this->CCMgr, std::move(IndirectStubsMgrBuilder), false), CXXRuntimeOverrides( @@ -195,38 +302,6 @@ public: JITTargetAddress Addr) { return mapError(IndirectStubsMgr->updatePointer(Name, Addr)); } - - std::shared_ptr - 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 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(*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(std::move(Obj), std::move(ObjBuffer)); - // Create the resolver. - auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx); + orc::VModuleKey K = ES.allocateVModule(); + Resolvers[K] = std::make_shared( + *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 - 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> IRStaticDestructorRunners; std::string ErrMsg; + + std::map> Resolvers; }; } // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 166d1369c724..cc5a8a5c1cec 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -138,18 +138,67 @@ class OrcMCJITReplacement : public ExecutionEngine { std::shared_ptr 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 MemMgr, std::shared_ptr ClientResolver, std::unique_ptr TM) - : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)), + : ExecutionEngine(TM->createDataLayout()), ES(SSP), TM(std::move(TM)), MemMgr( std::make_shared(*this, std::move(MemMgr))), - Resolver(std::make_shared(*this)), + Resolver(std::make_shared(*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(MPtr, std::move(Deleter))); - cantFail(LazyEmitLayer.addModule(LocalModules.back(), Resolver)); + cantFail( + LazyEmitLayer.addModule(ES.allocateVModule(), LocalModules.back())); } void addObjectFile(std::unique_ptr O) override { auto Obj = std::make_shared>(std::move(O), nullptr); - cantFail(ObjectLayer.addObject(std::move(Obj), Resolver)); + cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(Obj))); } void addObjectFile(object::OwningBinary O) override { auto Obj = std::make_shared>(std::move(O)); - cantFail(ObjectLayer.addObject(std::move(Obj), Resolver)); + cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(Obj))); } void addArchive(object::OwningBinary A) override { @@ -322,7 +377,7 @@ private: auto Obj = std::make_shared>( 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; using LazyEmitLayerT = LazyEmittingLayer; + SymbolStringPool SSP; + ExecutionSession ES; + std::unique_ptr TM; std::shared_ptr MemMgr; - std::shared_ptr Resolver; + std::shared_ptr Resolver; std::shared_ptr ClientResolver; Mangler Mang; diff --git a/llvm/tools/lli/OrcLazyJIT.h b/llvm/tools/lli/OrcLazyJIT.h index a5cc804bb045..66c5c5b63f2d 100644 --- a/llvm/tools/lli/OrcLazyJIT.h +++ b/llvm/tools/lli/OrcLazyJIT.h @@ -61,13 +61,38 @@ public: std::unique_ptr 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(); }), + ObjectLayer(ES, + [](orc::VModuleKey) { + return std::make_shared(); + }, + [&](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 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> Resolvers; + std::unique_ptr TM; DataLayout DL; SectionMemoryManager CCMgrMemMgr; diff --git a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp index 61ce310e6311..4501b53c3c04 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp @@ -59,9 +59,22 @@ TEST(CompileOnDemandLayerTest, FindSymbol) { DummyCallbackManager CallbackMgr; + SymbolStringPool SSP; + ExecutionSession ES(SSP); + + auto GetResolver = + [](orc::VModuleKey) -> std::shared_ptr { + llvm_unreachable("Should never be called"); + }; + + auto SetResolver = [](orc::VModuleKey, std::shared_ptr) { + llvm_unreachable("Should never be called"); + }; + llvm::orc::CompileOnDemandLayer COD( - TestBaseLayer, [](Function &F) { return std::set{&F}; }, - CallbackMgr, [] { return llvm::make_unique(); }, true); + ES, TestBaseLayer, GetResolver, SetResolver, + [](Function &F) { return std::set{&F}; }, CallbackMgr, + [] { return llvm::make_unique(); }, true); auto Sym = COD.findSymbol("foo", true); diff --git a/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp index 0dba66d47535..3801fa918db7 100644 --- a/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp @@ -15,11 +15,8 @@ namespace { struct MockBaseLayer { typedef int ModuleHandleT; - ModuleHandleT addModule( - std::shared_ptr, - std::unique_ptr MemMgr, - std::unique_ptr Resolver) { - EXPECT_FALSE(MemMgr); + ModuleHandleT addModule(llvm::orc::VModuleKey, + std::shared_ptr) { return 42; } }; @@ -27,7 +24,8 @@ struct MockBaseLayer { TEST(LazyEmittingLayerTest, Empty) { MockBaseLayer M; llvm::orc::LazyEmittingLayer L(M); - cantFail(L.addModule(std::unique_ptr(), nullptr)); + cantFail( + L.addModule(llvm::orc::VModuleKey(), std::unique_ptr())); } } diff --git a/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp index 2aa2b48d761e..9de1c22e45f6 100644 --- a/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -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 - llvm::Expected - addObject(ObjPtrT Obj, - std::shared_ptr Resolver) { - EXPECT_EQ(MockResolver, Resolver) << "Resolver should pass through"; + llvm::Expected 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 - void expectAddObject(ObjPtrT Obj, - std::shared_ptr Resolver) { - MockResolver = Resolver; + template 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 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 T1(M); @@ -205,16 +203,17 @@ TEST(ObjectTransformLayerTest, Main) { }); // Test addObject with T1 (allocating) + auto K1 = ES.allocateVModule(); auto Obj1 = std::make_shared(211); - auto SR = std::make_shared(); - 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(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(); - }); + ES, + [](VModuleKey) { return std::make_shared(); }, + [](VModuleKey) -> std::shared_ptr { + llvm_unreachable("Should never be called"); + }); auto IdentityTransform = [](std::shared_ptr> @@ -311,8 +312,8 @@ TEST(ObjectTransformLayerTest, Main) { // Make sure that the calls from IRCompileLayer to ObjectTransformLayer // compile. - auto Resolver = std::make_shared(); - cantFail(CompileLayer.addModule(std::shared_ptr(), Resolver)); + cantFail(CompileLayer.addModule(ES.allocateVModule(), + std::shared_ptr())); // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer // compile. diff --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp index 8b25ede78bc8..3e7d3f6db39c 100644 --- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp @@ -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(DebugSectionSeen); - RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; }); + SymbolStringPool SSP; + ExecutionSession ES(SSP); + + RTDyldObjectLinkingLayer ObjLayer( + ES, [&MM](VModuleKey) { return MM; }, + [](orc::VModuleKey) { return std::make_shared(); }); LLVMContext Context; auto M = llvm::make_unique("", Context); @@ -92,18 +98,9 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) { std::make_shared>( 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(); - RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; }); + std::map> 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>( 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(); + 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(); - RTDyldObjectLinkingLayer ObjLayer([&MM]() { return MM; }); + RTDyldObjectLinkingLayer ObjLayer( + ES, [&MM](VModuleKey) { return MM; }, + [](VModuleKey) { return std::make_shared(); }); SimpleCompiler Compile(*TM); // Create a pair of unrelated modules: @@ -243,9 +264,8 @@ TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) { std::make_shared>( Compile(*MB2.getModule())); - auto NR = std::make_shared(); - 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(); }, [](RTDyldObjectLinkingLayer::ObjHandleT, const RTDyldObjectLinkingLayer::ObjectPtr &obj, const RuntimeDyld::LoadedObjectInfo &info) {});