diff options
author | Lang Hames <lhames@gmail.com> | 2017-06-23 21:45:29 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2017-06-23 21:45:29 +0000 |
commit | a5b199883c2f629345eee4fbbf2bd842a1bbca1b (patch) | |
tree | a13a39b879df3e80f8558341934d97978db1eb3f | |
parent | 48d560bf0c66dd8eeb26bc7985f2be9adef9112a (diff) | |
download | llvm-a5b199883c2f629345eee4fbbf2bd842a1bbca1b.tar.gz |
[ORC] Move ORC IR layer interface from addModuleSet to addModule and fix the
module type as std::shared_ptr<Module>.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306166 91177308-0d34-0410-b5e6-96231b3b80d8
21 files changed, 370 insertions, 331 deletions
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h index 3274433178b..f99722f60e9 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h @@ -44,7 +44,7 @@ private: IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; public: - using ModuleHandle = decltype(CompileLayer)::ModuleSetHandleT; + using ModuleHandle = decltype(CompileLayer)::ModuleHandleT; KaleidoscopeJIT() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), @@ -72,15 +72,11 @@ public: return JITSymbol(nullptr); }); - // Build a singleton module set to hold our module. - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - // Add the set to the JIT with the resolver we created above and a newly // created SectionMemoryManager. - return CompileLayer.addModuleSet(std::move(Ms), - make_unique<SectionMemoryManager>(), - std::move(Resolver)); + return CompileLayer.addModule(std::move(M), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); } JITSymbol findSymbol(const std::string Name) { @@ -91,7 +87,7 @@ public: } void removeModule(ModuleHandle H) { - CompileLayer.removeModuleSet(H); + CompileLayer.removeModule(H); } }; diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h index f71b322bff7..2cd4ed79aaf 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h @@ -48,18 +48,18 @@ private: IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; using OptimizeFunction = - std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>; + std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>; IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; public: - using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT; + using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT; KaleidoscopeJIT() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::unique_ptr<Module> M) { + [this](std::shared_ptr<Module> M) { return optimizeModule(std::move(M)); }) { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); @@ -85,15 +85,11 @@ public: return JITSymbol(nullptr); }); - // Build a singleton module set to hold our module. - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - // Add the set to the JIT with the resolver we created above and a newly // created SectionMemoryManager. - return OptimizeLayer.addModuleSet(std::move(Ms), - make_unique<SectionMemoryManager>(), - std::move(Resolver)); + return OptimizeLayer.addModule(std::move(M), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); } JITSymbol findSymbol(const std::string Name) { @@ -104,11 +100,11 @@ public: } void removeModule(ModuleHandle H) { - OptimizeLayer.removeModuleSet(H); + OptimizeLayer.removeModule(H); } private: - std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { + std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) { // Create a function pass manager. auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h index c851b609779..f6fb3071d52 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h @@ -51,7 +51,7 @@ private: IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; using OptimizeFunction = - std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>; + std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>; IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; @@ -59,13 +59,13 @@ private: CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer; public: - using ModuleHandle = decltype(CODLayer)::ModuleSetHandleT; + using ModuleHandle = decltype(CODLayer)::ModuleHandleT; KaleidoscopeJIT() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::unique_ptr<Module> M) { + [this](std::shared_ptr<Module> M) { return optimizeModule(std::move(M)); }), CompileCallbackManager( @@ -98,15 +98,11 @@ public: return JITSymbol(nullptr); }); - // Build a singleton module set to hold our module. - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - // Add the set to the JIT with the resolver we created above and a newly // created SectionMemoryManager. - return CODLayer.addModuleSet(std::move(Ms), - make_unique<SectionMemoryManager>(), - std::move(Resolver)); + return CODLayer.addModule(std::move(M), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); } JITSymbol findSymbol(const std::string Name) { @@ -117,11 +113,11 @@ public: } void removeModule(ModuleHandle H) { - CODLayer.removeModuleSet(H); + CODLayer.removeModule(H); } private: - std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { + std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) { // Create a function pass manager. auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h index 58642237d4f..d45874e9a69 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h @@ -77,7 +77,7 @@ private: IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; using OptimizeFunction = - std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>; + std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>; IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; @@ -85,14 +85,14 @@ private: std::unique_ptr<IndirectStubsManager> IndirectStubsMgr; public: - using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT; + using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT; KaleidoscopeJIT() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::unique_ptr<Module> M) { + [this](std::shared_ptr<Module> M) { return optimizeModule(std::move(M)); }), CompileCallbackMgr( @@ -125,15 +125,11 @@ public: return JITSymbol(nullptr); }); - // Build a singleton module set to hold our module. - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - // Add the set to the JIT with the resolver we created above and a newly // created SectionMemoryManager. - return OptimizeLayer.addModuleSet(std::move(Ms), - make_unique<SectionMemoryManager>(), - std::move(Resolver)); + return OptimizeLayer.addModule(std::move(M), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); } Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) { @@ -199,7 +195,7 @@ public: } void removeModule(ModuleHandle H) { - OptimizeLayer.removeModuleSet(H); + OptimizeLayer.removeModule(H); } private: @@ -210,7 +206,7 @@ private: return MangledNameStream.str(); } - std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { + std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) { // Create a function pass manager. auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h index 84916b8f2b8..e889c6d3432 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h @@ -82,7 +82,7 @@ private: IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer; using OptimizeFunction = - std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>; + std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>; IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; @@ -91,7 +91,7 @@ private: MyRemote &Remote; public: - using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT; + using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT; KaleidoscopeJIT(MyRemote &Remote) : TM(EngineBuilder().selectTarget(Triple(Remote.getTargetTriple()), "", @@ -99,7 +99,7 @@ public: DL(TM->createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::unique_ptr<Module> M) { + [this](std::shared_ptr<Module> M) { return optimizeModule(std::move(M)); }), Remote(Remote) { @@ -153,15 +153,11 @@ public: exit(1); } - // Build a singleton module set to hold our module. - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - // Add the set to the JIT with the resolver we created above and a newly // created SectionMemoryManager. - return OptimizeLayer.addModuleSet(std::move(Ms), - std::move(MemMgr), - std::move(Resolver)); + return OptimizeLayer.addModule(std::move(M), + std::move(MemMgr), + std::move(Resolver)); } Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) { @@ -231,7 +227,7 @@ public: } void removeModule(ModuleHandle H) { - OptimizeLayer.removeModuleSet(H); + OptimizeLayer.removeModule(H); } private: @@ -242,7 +238,7 @@ private: return MangledNameStream.str(); } - std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { + std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) { // Create a function pass manager. auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); diff --git a/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/examples/Kaleidoscope/include/KaleidoscopeJIT.h index 1e2d567c057..fe73d717976 100644 --- a/examples/Kaleidoscope/include/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/include/KaleidoscopeJIT.h @@ -41,7 +41,7 @@ class KaleidoscopeJIT { public: using ObjLayerT = RTDyldObjectLinkingLayer; using CompileLayerT = IRCompileLayer<ObjLayerT, SimpleCompiler>; - using ModuleHandleT = CompileLayerT::ModuleSetHandleT; + using ModuleHandleT = CompileLayerT::ModuleHandleT; KaleidoscopeJIT() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), @@ -62,9 +62,9 @@ public: return JITSymbol(nullptr); }, [](const std::string &S) { return nullptr; }); - auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)), - make_unique<SectionMemoryManager>(), - std::move(Resolver)); + auto H = CompileLayer.addModule(std::move(M), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); ModuleHandles.push_back(H); return H; @@ -72,7 +72,7 @@ public: void removeModule(ModuleHandleT H) { ModuleHandles.erase(find(ModuleHandles, H)); - CompileLayer.removeModuleSet(H); + CompileLayer.removeModule(H); } JITSymbol findSymbol(const std::string Name) { @@ -89,12 +89,6 @@ private: return MangledName; } - template <typename T> static std::vector<T> singletonSet(T t) { - std::vector<T> Vec; - Vec.push_back(std::move(t)); - return Vec; - } - JITSymbol findMangledSymbol(const std::string &Name) { #ifdef LLVM_ON_WIN32 // The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported diff --git a/include/llvm-c/OrcBindings.h b/include/llvm-c/OrcBindings.h index de2969ab1c9..d86ea880888 100644 --- a/include/llvm-c/OrcBindings.h +++ b/include/llvm-c/OrcBindings.h @@ -29,6 +29,8 @@ extern "C" { #endif +typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef; +typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef; typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef; typedef uint32_t LLVMOrcModuleHandle; typedef uint64_t LLVMOrcTargetAddress; @@ -39,6 +41,45 @@ typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, typedef enum { LLVMOrcErrSuccess = 0, LLVMOrcErrGeneric } LLVMOrcErrorCode; /** + * Turn an LLVMModuleRef into an LLVMSharedModuleRef. + * + * The JIT uses shared ownership for LLVM modules, since it is generally + * difficult to know when the JIT will be finished with a module (and the JIT + * has no way of knowing when a user may be finished with one). + * + * Calling this method with an LLVMModuleRef creates a shared-pointer to the + * module, and returns a reference to this shared pointer. + * + * The shared module should be disposed when finished with by calling + * LLVMOrcDisposeSharedModule (not LLVMDisposeModule). The Module will be + * deleted when the last shared pointer owner relinquishes it. + */ + +LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod); + +/** + * Dispose of a shared module. + * + * The module should not be accessed after this call. The module will be + * deleted once all clients (including the JIT itself) have released their + * shared pointers. + */ + +void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod); + +/** + * Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef. + */ +LLVMSharedObjectBufferRef +LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer); + +/** + * Dispose of a shared object buffer. + */ +void +LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer); + +/** * Create an ORC JIT stack. * * The client owns the resulting stack, and must call OrcDisposeInstance(...) @@ -95,7 +136,8 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, * Add module to be eagerly compiled. */ LLVMOrcModuleHandle -LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); @@ -103,7 +145,8 @@ LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, * Add module to be lazily compiled one function at a time. */ LLVMOrcModuleHandle -LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); @@ -111,7 +154,7 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, * Add an object file. */ LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, - LLVMObjectFileRef Obj, + LLVMSharedObjectBufferRef Obj, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index f2dc13be10f..8ac1b6bca0a 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -84,7 +84,7 @@ private: return LambdaMaterializer<MaterializerFtor>(std::move(M)); } - using BaseLayerModuleSetHandleT = typename BaseLayerT::ModuleSetHandleT; + using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT; // Provide type-erasure for the Modules and MemoryManagers. template <typename ResourceT> @@ -139,9 +139,11 @@ private: struct LogicalDylib { using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>; - using ModuleAdderFtor = std::function<typename BaseLayerT::ModuleSetHandleT( - BaseLayerT &, std::unique_ptr<Module>, - std::unique_ptr<JITSymbolResolver>)>; + using ModuleAdderFtor = + std::function<typename BaseLayerT::ModuleHandleT( + BaseLayerT&, + std::unique_ptr<Module>, + std::unique_ptr<JITSymbolResolver>)>; struct SourceModuleEntry { std::unique_ptr<ResourceOwner<Module>> SourceMod; @@ -179,7 +181,7 @@ private: void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { for (auto &BLH : BaseLayerHandles) - BaseLayer.removeModuleSet(BLH); + BaseLayer.removeModule(BLH); } std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver; @@ -188,14 +190,14 @@ private: StaticGlobalRenamer StaticRenamer; ModuleAdderFtor ModuleAdder; SourceModulesList SourceModules; - std::vector<BaseLayerModuleSetHandleT> BaseLayerHandles; + std::vector<BaseLayerModuleHandleT> BaseLayerHandles; }; using LogicalDylibList = std::list<LogicalDylib>; public: - /// @brief Handle to a set of loaded modules. - using ModuleSetHandleT = typename LogicalDylibList::iterator; + /// @brief Handle to loaded module. + using ModuleHandleT = typename LogicalDylibList::iterator; /// @brief Module partitioning functor. using PartitioningFtor = std::function<std::set<Function*>(Function&)>; @@ -216,15 +218,15 @@ public: ~CompileOnDemandLayer() { while (!LogicalDylibs.empty()) - removeModuleSet(LogicalDylibs.begin()); + removeModule(LogicalDylibs.begin()); } - + /// @brief Add a module to the compile-on-demand layer. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + LogicalDylibs.push_back(LogicalDylib()); auto &LD = LogicalDylibs.back(); LD.ExternalSymbolResolver = std::move(Resolver); @@ -236,23 +238,25 @@ public: LD.ModuleAdder = [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M, std::unique_ptr<JITSymbolResolver> R) { - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R)); + return B.addModule(std::move(M), &MemMgrRef, std::move(R)); }; // Process each of the modules in this module set. - for (auto &M : Ms) - addLogicalModule(LogicalDylibs.back(), std::move(M)); + addLogicalModule(LogicalDylibs.back(), std::move(M)); return std::prev(LogicalDylibs.end()); } + /// @brief Add extra modules to an existing logical module. + void addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) { + addLogicalModule(*H, std::move(M)); + } + /// @brief Remove the module represented by the given handle. /// /// This will remove all modules in the layers below that were derived from /// the module represented by H. - void removeModuleSet(ModuleSetHandleT H) { + void removeModule(ModuleHandleT H) { H->removeModulesFromBaseLayer(BaseLayer); LogicalDylibs.erase(H); } @@ -274,7 +278,7 @@ public: /// @brief Get the address of a symbol provided by this layer, or some layer /// below this one. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly); } @@ -498,7 +502,7 @@ private: } template <typename PartitionT> - BaseLayerModuleSetHandleT + BaseLayerModuleHandleT emitPartition(LogicalDylib &LD, typename LogicalDylib::SourceModuleHandle LMId, const PartitionT &Part) { diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index 36a41891614..bf8cca40684 100644 --- a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -94,7 +94,7 @@ public: /// @brief Construct a CtorDtorRunner for the given range using the given /// name mangling function. CtorDtorRunner(std::vector<std::string> CtorDtorNames, - typename JITLayerT::ModuleSetHandleT H) + typename JITLayerT::ModuleHandleT H) : CtorDtorNames(std::move(CtorDtorNames)), H(H) {} /// @brief Run the recorded constructors/destructors through the given JIT @@ -116,7 +116,7 @@ public: private: std::vector<std::string> CtorDtorNames; - typename JITLayerT::ModuleSetHandleT H; + typename JITLayerT::ModuleHandleT H; }; /// @brief Support class for static dtor execution. For hosted (in-process) JITs diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index fc1db346af6..99ccd4d221a 100644 --- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -28,15 +28,15 @@ namespace orc { /// @brief Eager IR compiling layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It -/// immediately compiles each IR module to an object file (each IR Module is -/// compiled separately). The resulting set of object files is then added to -/// the layer below, which must implement the object layer concept. +/// This layer immediately compiles each IR module added via addModule to an +/// object file and adds this module file to the layer below, which must +/// implement the object layer concept. template <typename BaseLayerT, typename CompileFtor> class IRCompileLayer { public: - /// @brief Handle to a set of compiled modules. - using ModuleSetHandleT = typename BaseLayerT::ObjHandleT; + + /// @brief Handle to a compiled module. + using ModuleHandleT = typename BaseLayerT::ObjHandleT; /// @brief Construct an IRCompileLayer with the given BaseLayer, which must /// implement the ObjectLayer concept. @@ -46,25 +46,22 @@ public: /// @brief Get a reference to the compiler functor. CompileFtor& getCompiler() { return Compile; } - /// @brief Compile each module in the given module set, then add the resulting - /// set of objects to the base layer along with the memory manager and - /// symbol resolver. + /// @brief Compile the module, and add the resulting object to the base layer + /// along with the given memory manager and symbol resolver. /// - /// @return A handle for the added modules. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - assert(Ms.size() == 1); - using CompileResult = decltype(Compile(*Ms.front())); - auto Obj = std::make_shared<CompileResult>(Compile(*Ms.front())); + /// @return A handle for the added module. + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + using CompileResult = decltype(Compile(*M)); + auto Obj = std::make_shared<CompileResult>(Compile(*M)); return BaseLayer.addObject(std::move(Obj), std::move(MemMgr), std::move(Resolver)); } - /// @brief Remove the module set associated with the handle H. - void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObject(H); } + /// @brief Remove the module associated with the handle H. + void removeModule(ModuleHandleT H) { BaseLayer.removeObject(H); } /// @brief Search for the given named symbol. /// @param Name The name of the symbol to search for. @@ -74,23 +71,23 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the set of - /// compiled modules represented by the handle H. This call is - /// forwarded to the base layer's implementation. - /// @param H The handle for the module set to search in. + /// @brief Get the address of the given symbol in compiled module represented + /// by the handle H. This call is forwarded to the base layer's + /// implementation. + /// @param H The handle for the module to search in. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the - /// given module set. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + /// given module. + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the moduleOB set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { BaseLayer.emitAndFinalize(H); } diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 057309ee09b..8e9be6b6f4f 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -22,39 +22,34 @@ namespace orc { /// @brief IR mutating layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It -/// immediately applies the user supplied functor to each module, then adds -/// the set of transformed modules to the layer below. +/// This layer applies a user supplied transform to each module that is added, +/// then adds the transformed module to the layer below. template <typename BaseLayerT, typename TransformFtor> class IRTransformLayer { public: + /// @brief Handle to a set of added modules. - using ModuleSetHandleT = typename BaseLayerT::ModuleSetHandleT; + using ModuleHandleT = typename BaseLayerT::ModuleHandleT; /// @brief Construct an IRTransformLayer with the given BaseLayer IRTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform = TransformFtor()) : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - /// @brief Apply the transform functor to each module in the module set, then - /// add the resulting set of modules to the base layer, along with the - /// memory manager and symbol resolver. + /// @brief Apply the transform functor to the module, then add the module to + /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I) - *I = Transform(std::move(*I)); - - return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr), - std::move(Resolver)); + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return BaseLayer.addModule(Transform(std::move(M)), std::move(MemMgr), + std::move(Resolver)); } - /// @brief Remove the module set associated with the handle H. - void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); } + /// @brief Remove the module associated with the handle H. + void removeModule(ModuleHandleT H) { BaseLayer.removeModule(H); } /// @brief Search for the given named symbol. /// @param Name The name of the symbol to search for. @@ -64,23 +59,23 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the set of - /// modules represented by the handle H. This call is forwarded to the - /// base layer's implementation. - /// @param H The handle for the module set to search in. + /// @brief Get the address of the given symbol in the context of the module + /// represented by the handle H. This call is forwarded to the base + /// layer's implementation. + /// @param H The handle for the module to search in. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the - /// given module set. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + /// given module. + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the module set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { BaseLayer.emitAndFinalize(H); } diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index b44e69d1412..38769aac12a 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -34,19 +34,20 @@ namespace orc { /// @brief Lazy-emitting IR layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does -/// not immediately emit them the layer below. Instead, emissing to the base -/// layer is deferred until the first time the client requests the address -/// (via JITSymbol::getAddress) for a symbol contained in this layer. +/// This layer accepts LLVM IR Modules (via addModule), but does not +/// immediately emit them the layer below. Instead, emissing to the base layer +/// is deferred until the first time the client requests the address (via +/// JITSymbol::getAddress) for a symbol contained in this layer. template <typename BaseLayerT> class LazyEmittingLayer { public: - using BaseLayerHandleT = typename BaseLayerT::ModuleSetHandleT; + + using BaseLayerHandleT = typename BaseLayerT::ModuleHandleT; private: - class EmissionDeferredSet { + class EmissionDeferredModule { public: - EmissionDeferredSet() = default; - virtual ~EmissionDeferredSet() = default; + EmissionDeferredModule() = default; + virtual ~EmissionDeferredModule() = default; JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { @@ -84,9 +85,9 @@ private: llvm_unreachable("Invalid emit-state."); } - void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { + void removeModuleFromBaseLayer(BaseLayerT &BaseLayer) { if (EmitState != NotEmitted) - BaseLayer.removeModuleSet(Handle); + BaseLayer.removeModule(Handle); } void emitAndFinalize(BaseLayerT &BaseLayer) { @@ -100,10 +101,9 @@ private: BaseLayer.emitAndFinalize(Handle); } - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - static std::unique_ptr<EmissionDeferredSet> - create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr, + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + static std::unique_ptr<EmissionDeferredModule> + create(BaseLayerT &B, std::shared_ptr<Module> M, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver); protected: @@ -116,14 +116,13 @@ private: BaseLayerHandleT Handle; }; - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - class EmissionDeferredSetImpl : public EmissionDeferredSet { + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + class EmissionDeferredModuleImpl : public EmissionDeferredModule { public: - EmissionDeferredSetImpl(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) - : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)), + EmissionDeferredModuleImpl(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) + : M(std::move(M)), MemMgr(std::move(MemMgr)), Resolver(std::move(Resolver)) {} protected: @@ -154,8 +153,8 @@ 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.addModuleSet(std::move(Ms), std::move(MemMgr), - std::move(Resolver)); + return BaseLayer.addModule(std::move(M), std::move(MemMgr), + std::move(Resolver)); } private: @@ -197,56 +196,54 @@ private: auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>(); - for (const auto &M : Ms) { - Mangler Mang; + Mangler Mang; - for (const auto &GO : M->global_objects()) + for (const auto &GO : M->global_objects()) if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName, ExportedSymbolsOnly)) return GV; - } MangledSymbols = std::move(Symbols); return nullptr; } - ModuleSetT Ms; + std::shared_ptr<Module> M; MemoryManagerPtrT MemMgr; SymbolResolverPtrT Resolver; mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols; }; - using ModuleSetListT = std::list<std::unique_ptr<EmissionDeferredSet>>; + using ModuleListT = std::list<std::unique_ptr<EmissionDeferredModule>>; BaseLayerT &BaseLayer; - ModuleSetListT ModuleSetList; + ModuleListT ModuleList; public: - /// @brief Handle to a set of loaded modules. - using ModuleSetHandleT = typename ModuleSetListT::iterator; + /// @brief Handle to a loaded module. + using ModuleHandleT = typename ModuleListT::iterator; /// @brief Construct a lazy emitting layer. LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} - /// @brief Add the given set of modules to the lazy emitting layer. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - return ModuleSetList.insert( - ModuleSetList.end(), - EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr), - std::move(Resolver))); + /// @brief Add the given module to the lazy emitting layer. + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return ModuleList.insert( + ModuleList.end(), + EmissionDeferredModule::create(BaseLayer, std::move(M), + std::move(MemMgr), + std::move(Resolver))); } - /// @brief Remove the module set represented by the given handle. + /// @brief Remove the module represented by the given handle. /// - /// This method will free the memory associated with the given module set, - /// both in this layer, and the base layer. - void removeModuleSet(ModuleSetHandleT H) { - (*H)->removeModulesFromBaseLayer(BaseLayer); - ModuleSetList.erase(H); + /// This method will free the memory associated with the given module, both + /// in this layer, and the base layer. + void removeModule(ModuleHandleT H) { + (*H)->removeModuleFromBaseLayer(BaseLayer); + ModuleList.erase(H); } /// @brief Search for the given named symbol. @@ -258,42 +255,40 @@ public: if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly)) return Symbol; - // If not found then search the deferred sets. If any of these contain a + // If not found then search the deferred modules. If any of these contain a // definition of 'Name' then they will return a JITSymbol that will emit // the corresponding module when the symbol address is requested. - for (auto &DeferredSet : ModuleSetList) - if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer)) + for (auto &DeferredMod : ModuleList) + if (auto Symbol = DeferredMod->find(Name, ExportedSymbolsOnly, BaseLayer)) return Symbol; // If no definition found anywhere return a null symbol. return nullptr; } - /// @brief Get the address of the given symbol in the context of the set of + /// @brief Get the address of the given symbol in the context of the of /// compiled modules represented by the handle H. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer); } - /// @brief Immediately emit and finalize the moduleOB set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { (*H)->emitAndFinalize(BaseLayer); } }; template <typename BaseLayerT> -template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> -std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet> -LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create( - BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr, +template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> +std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredModule> +LazyEmittingLayer<BaseLayerT>::EmissionDeferredModule::create( + BaseLayerT &B, std::shared_ptr<Module> M, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) { - using EDS = EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, - SymbolResolverPtrT>; - return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr), + using EDS = EmissionDeferredModuleImpl<MemoryManagerPtrT, SymbolResolverPtrT>; + return llvm::make_unique<EDS>(std::move(M), std::move(MemMgr), std::move(Resolver)); } diff --git a/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/lib/ExecutionEngine/Orc/OrcCBindings.cpp index 8dcd49aaab5..5fe259f80b6 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ b/lib/ExecutionEngine/Orc/OrcCBindings.cpp @@ -12,6 +12,24 @@ using namespace llvm; +LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod) { + return wrap(new std::shared_ptr<Module>(unwrap(Mod))); +} + +void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod) { + delete unwrap(SharedMod); +} + +LLVMSharedObjectBufferRef +LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer) { + return wrap(new std::shared_ptr<MemoryBuffer>(unwrap(ObjBuffer))); +} + +void +LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer) { + delete unwrap(SharedObjBuffer); +} + LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) { TargetMachine *TM2(unwrap(TM)); @@ -65,21 +83,23 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, } LLVMOrcModuleHandle -LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx) { OrcCBindingsStack &J = *unwrap(JITStack); - Module *M(unwrap(Mod)); - return J.addIRModuleEager(M, SymbolResolver, SymbolResolverCtx); + std::shared_ptr<Module> *M(unwrap(Mod)); + return J.addIRModuleEager(*M, SymbolResolver, SymbolResolverCtx); } LLVMOrcModuleHandle -LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx) { OrcCBindingsStack &J = *unwrap(JITStack); - Module *M(unwrap(Mod)); - return J.addIRModuleLazy(M, SymbolResolver, SymbolResolverCtx); + std::shared_ptr<Module> *M(unwrap(Mod)); + return J.addIRModuleLazy(*M, SymbolResolver, SymbolResolverCtx); } void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H) { diff --git a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index 96bd15eb091..b9a2d517c3a 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -42,6 +42,10 @@ namespace llvm { class OrcCBindingsStack; +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>, + LLVMSharedModuleRef); +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<MemoryBuffer>, + LLVMSharedObjectBufferRef); DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) @@ -71,7 +75,7 @@ private: template <typename LayerT> class GenericHandleImpl : public GenericHandle { public: - GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) + GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleHandleT Handle) : Layer(Layer), Handle(std::move(Handle)) {} JITSymbol findSymbolIn(const std::string &Name, @@ -79,24 +83,21 @@ private: return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly); } - void removeModule() override { return Layer.removeModuleSet(Handle); } + void removeModule() override { return Layer.removeModule(Handle); } private: LayerT &Layer; - typename LayerT::ModuleSetHandleT Handle; + typename LayerT::ModuleHandleT Handle; }; template <typename LayerT> std::unique_ptr<GenericHandleImpl<LayerT>> - createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) { + createGenericHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) { return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer, std::move(Handle)); } public: - // We need a 'ModuleSetHandleT' to conform to the layer concept. - using ModuleSetHandleT = unsigned; - using ModuleHandleT = unsigned; OrcCBindingsStack(TargetMachine &TM, @@ -183,7 +184,7 @@ public: } template <typename LayerT> - ModuleHandleT addIRModule(LayerT &Layer, Module *M, + ModuleHandleT addIRModule(LayerT &Layer, std::shared_ptr<Module> M, std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { @@ -203,11 +204,8 @@ public: auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx); // Add the module to the JIT. - std::vector<Module *> S; - S.push_back(std::move(M)); - - auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr), - std::move(Resolver)); + auto LH = Layer.addModule(std::move(M), std::move(MemMgr), + std::move(Resolver)); ModuleHandleT H = createHandle(Layer, LH); // Run the static constructors, and save the static destructor runner for @@ -220,7 +218,7 @@ public: return H; } - ModuleHandleT addIRModuleEager(Module *M, + ModuleHandleT addIRModuleEager(std::shared_ptr<Module> M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { return addIRModule(CompileLayer, std::move(M), @@ -228,7 +226,7 @@ public: std::move(ExternalResolver), ExternalResolverCtx); } - ModuleHandleT addIRModuleLazy(Module *M, + ModuleHandleT addIRModuleLazy(std::shared_ptr<Module> M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { return addIRModule(CODLayer, std::move(M), @@ -257,8 +255,7 @@ public: private: template <typename LayerT> - unsigned createHandle(LayerT &Layer, - typename LayerT::ModuleSetHandleT Handle) { + unsigned createHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) { unsigned NewHandle; if (!FreeHandleIndexes.empty()) { NewHandle = FreeHandleIndexes.back(); diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 000ab0006ba..944eba7bc89 100644 --- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -191,10 +191,15 @@ public: } else { assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"); } - Modules.push_back(std::move(M)); - std::vector<Module *> Ms; - Ms.push_back(&*Modules.back()); - LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver); + auto *MPtr = M.release(); + Retain[MPtr] = false; + auto Deleter = + [this](Module *Mod) { + if (!Retain[Mod]) + delete Mod; + }; + LocalModules.push_back(std::shared_ptr<Module>(MPtr, std::move(Deleter))); + LazyEmitLayer.addModule(LocalModules.back(), &MemMgr, &Resolver); } void addObjectFile(std::unique_ptr<object::ObjectFile> O) override { @@ -381,6 +386,8 @@ private: std::map<ObjectLayerT::ObjHandleT, SectionAddrSet, ObjHandleCompare> UnfinalizedSections; + std::map<Module*, bool> Retain; + std::vector<std::shared_ptr<Module>> LocalModules; std::vector<object::OwningBinary<object::Archive>> Archives; }; diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp index 899a7acdb1c..2e15894152f 100644 --- a/tools/lli/OrcLazyJIT.cpp +++ b/tools/lli/OrcLazyJIT.cpp @@ -54,10 +54,10 @@ static cl::opt<bool> OrcInlineStubs("orc-lazy-inline-stubs", OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { switch (OrcDumpKind) { case DumpKind::NoDump: - return [](std::unique_ptr<Module> M) { return M; }; + return [](std::shared_ptr<Module> M) { return M; }; case DumpKind::DumpFuncsToStdOut: - return [](std::unique_ptr<Module> M) { + return [](std::shared_ptr<Module> M) { printf("[ "); for (const auto &F : *M) { @@ -76,7 +76,7 @@ OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { }; case DumpKind::DumpModsToStdOut: - return [](std::unique_ptr<Module> M) { + return [](std::shared_ptr<Module> M) { outs() << "----- Module Start -----\n" << *M << "----- Module End -----\n"; @@ -84,7 +84,7 @@ OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { }; case DumpKind::DumpModsToDisk: - return [](std::unique_ptr<Module> M) { + return [](std::shared_ptr<Module> M) { std::error_code EC; raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, sys::fs::F_Text); @@ -147,7 +147,8 @@ int llvm::runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms, OrcInlineStubs); // Add the module, look up main and run it. - J.addModuleSet(std::move(Ms)); + for (auto &M : Ms) + J.addModule(std::shared_ptr<Module>(std::move(M))); auto MainSym = J.findSymbol("main"); if (!MainSym) { diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h index 20551494647..fc02a10b514 100644 --- a/tools/lli/OrcLazyJIT.h +++ b/tools/lli/OrcLazyJIT.h @@ -50,11 +50,11 @@ public: using ObjLayerT = orc::RTDyldObjectLinkingLayer; using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>; using TransformFtor = - std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>; + std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>; using IRDumpLayerT = orc::IRTransformLayer<CompileLayerT, TransformFtor>; using CODLayerT = orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr>; using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; - using ModuleSetHandleT = CODLayerT::ModuleSetHandleT; + using ModuleHandleT = CODLayerT::ModuleHandleT; OrcLazyJIT(std::unique_ptr<TargetMachine> TM, std::unique_ptr<CompileCallbackMgr> CCMgr, @@ -77,11 +77,9 @@ public: DtorRunner.runViaLayer(CODLayer); } - ModuleSetHandleT addModuleSet(std::vector<std::unique_ptr<Module>> Ms) { - // Attach a data-layouts if they aren't already present. - for (auto &M : Ms) - if (M->getDataLayout().isDefault()) - M->setDataLayout(DL); + void addModule(std::shared_ptr<Module> M) { + if (M->getDataLayout().isDefault()) + M->setDataLayout(DL); // Rename, bump linkage and record static constructors and destructors. // We have to do this before we hand over ownership of the module to the @@ -89,21 +87,19 @@ public: std::vector<std::string> CtorNames, DtorNames; { unsigned CtorId = 0, DtorId = 0; - for (auto &M : Ms) { - for (auto Ctor : orc::getConstructors(*M)) { - std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str(); - Ctor.Func->setName(NewCtorName); - Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); - Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); - CtorNames.push_back(mangle(NewCtorName)); - } - for (auto Dtor : orc::getDestructors(*M)) { - std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str(); - Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); - Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); - DtorNames.push_back(mangle(Dtor.Func->getName())); - Dtor.Func->setName(NewDtorName); - } + for (auto Ctor : orc::getConstructors(*M)) { + std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str(); + Ctor.Func->setName(NewCtorName); + Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); + Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); + CtorNames.push_back(mangle(NewCtorName)); + } + for (auto Dtor : orc::getDestructors(*M)) { + std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str(); + Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); + Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); + DtorNames.push_back(mangle(Dtor.Func->getName())); + Dtor.Func->setName(NewDtorName); } } @@ -111,41 +107,45 @@ public: // 1) Search the JIT symbols. // 2) Check for C++ runtime overrides. // 3) Search the host process (LLI)'s symbol table. - auto Resolver = - orc::createLambdaResolver( - [this](const std::string &Name) -> JITSymbol { - if (auto Sym = CODLayer.findSymbol(Name, true)) - return Sym; - return CXXRuntimeOverrides.searchOverrides(Name); - }, - [](const std::string &Name) { - if (auto Addr = - RTDyldMemoryManager::getSymbolAddressInProcess(Name)) - return JITSymbol(Addr, JITSymbolFlags::Exported); - return JITSymbol(nullptr); - } - ); - - // Add the module to the JIT. - auto H = CODLayer.addModuleSet(std::move(Ms), - llvm::make_unique<SectionMemoryManager>(), - std::move(Resolver)); + if (ModulesHandle == CODLayerT::ModuleHandleT()) { + auto Resolver = + orc::createLambdaResolver( + [this](const std::string &Name) -> JITSymbol { + if (auto Sym = CODLayer.findSymbol(Name, true)) + return Sym; + return CXXRuntimeOverrides.searchOverrides(Name); + }, + [](const std::string &Name) { + if (auto Addr = + RTDyldMemoryManager::getSymbolAddressInProcess(Name)) + return JITSymbol(Addr, JITSymbolFlags::Exported); + return JITSymbol(nullptr); + } + ); + + // Add the module to the JIT. + ModulesHandle = + CODLayer.addModule(std::move(M), + llvm::make_unique<SectionMemoryManager>(), + std::move(Resolver)); + } else + CODLayer.addExtraModule(ModulesHandle, std::move(M)); // Run the static constructors, and save the static destructor runner for // execution when the JIT is torn down. - orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), H); + orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), + ModulesHandle); CtorRunner.runViaLayer(CODLayer); - IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H); - - return H; + IRStaticDestructorRunners.emplace_back(std::move(DtorNames), + ModulesHandle); } JITSymbol findSymbol(const std::string &Name) { return CODLayer.findSymbol(mangle(Name), true); } - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name) { + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) { return CODLayer.findSymbolIn(H, mangle(Name), true); } @@ -179,6 +179,7 @@ private: orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners; + CODLayerT::ModuleHandleT ModulesHandle; }; int runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms, diff --git a/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp index 213c460aa67..f65dc0cd609 100644 --- a/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp +++ b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp @@ -14,9 +14,9 @@ namespace { struct MockBaseLayer { - typedef int ModuleSetHandleT; - ModuleSetHandleT addModuleSet( - std::list<std::unique_ptr<llvm::Module>>, + 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); @@ -27,7 +27,7 @@ struct MockBaseLayer { TEST(LazyEmittingLayerTest, Empty) { MockBaseLayer M; llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M); - L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr, nullptr); + L.addModule(std::unique_ptr<llvm::Module>(), nullptr, nullptr); } } diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp index 6da2894ae0e..2fdf9e8b737 100644 --- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -314,7 +314,7 @@ TEST(ObjectTransformLayerTest, Main) { // compile. NullResolver Resolver; NullManager Manager; - CompileLayer.addModuleSet(std::vector<llvm::Module *>(), &Manager, &Resolver); + CompileLayer.addModule(std::shared_ptr<llvm::Module>(), &Manager, &Resolver); // Make sure that the calls from ObjectTransformLayer to ObjectLinkingLayer // compile. diff --git a/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp index e8ba16a472b..2900a9c9276 100644 --- a/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp +++ b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -65,8 +65,9 @@ protected: CompileContext *CCtx = static_cast<CompileContext*>(Ctx); auto *ET = CCtx->APIExecTest; CCtx->M = ET->createTestModule(ET->TM->getTargetTriple()); - CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()), - myResolver, nullptr); + LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release())); + CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, SM, myResolver, nullptr); + LLVMOrcDisposeSharedModuleRef(SM); CCtx->Compiled = true; LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main"); LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr); @@ -87,8 +88,10 @@ TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) { LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release())); LLVMOrcModuleHandle H = - LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr); + LLVMOrcAddEagerlyCompiledIR(JIT, SM, myResolver, nullptr); + LLVMOrcDisposeSharedModuleRef(SM); MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main"); int Result = MainFn(); EXPECT_EQ(Result, 42) @@ -111,8 +114,10 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) { LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); + LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release())); LLVMOrcModuleHandle H = - LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr); + LLVMOrcAddLazilyCompiledIR(JIT, SM, myResolver, nullptr); + LLVMOrcDisposeSharedModuleRef(SM); MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main"); int Result = MainFn(); EXPECT_EQ(Result, 42) diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h index 24320034a17..d7049ef00e6 100644 --- a/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -106,65 +106,65 @@ public: }; template <typename HandleT, - typename AddModuleSetFtor, - typename RemoveModuleSetFtor, + typename AddModuleFtor, + typename RemoveModuleFtor, typename FindSymbolFtor, typename FindSymbolInFtor> class MockBaseLayer { public: - typedef HandleT ModuleSetHandleT; + typedef HandleT ModuleHandleT; - MockBaseLayer(AddModuleSetFtor &&AddModuleSet, - RemoveModuleSetFtor &&RemoveModuleSet, + MockBaseLayer(AddModuleFtor &&AddModule, + RemoveModuleFtor &&RemoveModule, FindSymbolFtor &&FindSymbol, FindSymbolInFtor &&FindSymbolIn) - : AddModuleSet(AddModuleSet), RemoveModuleSet(RemoveModuleSet), + : AddModule(AddModule), RemoveModule(RemoveModule), FindSymbol(FindSymbol), FindSymbolIn(FindSymbolIn) {} - template <typename ModuleSetT, typename MemoryManagerPtrT, + template <typename ModuleT, typename MemoryManagerPtrT, typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - return AddModuleSet(std::move(Ms), std::move(MemMgr), std::move(Resolver)); + ModuleHandleT addModule(ModuleT Ms, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return AddModule(std::move(Ms), std::move(MemMgr), std::move(Resolver)); } - void removeModuleSet(ModuleSetHandleT H) { - RemoveModuleSet(H); + void removeModule(ModuleHandleT H) { + RemoveModule(H); } JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { return FindSymbol(Name, ExportedSymbolsOnly); } - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return FindSymbolIn(H, Name, ExportedSymbolsOnly); } private: - AddModuleSetFtor AddModuleSet; - RemoveModuleSetFtor RemoveModuleSet; + AddModuleFtor AddModule; + RemoveModuleFtor RemoveModule; FindSymbolFtor FindSymbol; FindSymbolInFtor FindSymbolIn; }; -template <typename ModuleSetHandleT, - typename AddModuleSetFtor, - typename RemoveModuleSetFtor, +template <typename ModuleHandleT, + typename AddModuleFtor, + typename RemoveModuleFtor, typename FindSymbolFtor, typename FindSymbolInFtor> -MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor, +MockBaseLayer<ModuleHandleT, AddModuleFtor, RemoveModuleFtor, FindSymbolFtor, FindSymbolInFtor> -createMockBaseLayer(AddModuleSetFtor &&AddModuleSet, - RemoveModuleSetFtor &&RemoveModuleSet, +createMockBaseLayer(AddModuleFtor &&AddModule, + RemoveModuleFtor &&RemoveModule, FindSymbolFtor &&FindSymbol, FindSymbolInFtor &&FindSymbolIn) { - return MockBaseLayer<ModuleSetHandleT, AddModuleSetFtor, RemoveModuleSetFtor, + return MockBaseLayer<ModuleHandleT, AddModuleFtor, RemoveModuleFtor, FindSymbolFtor, FindSymbolInFtor>( - std::forward<AddModuleSetFtor>(AddModuleSet), - std::forward<RemoveModuleSetFtor>(RemoveModuleSet), + std::forward<AddModuleFtor>(AddModule), + std::forward<RemoveModuleFtor>(RemoveModule), std::forward<FindSymbolFtor>(FindSymbol), std::forward<FindSymbolInFtor>(FindSymbolIn)); } |