From 1e6a98aff9dbe105c403b1a6b5c7cc5508fdc96f Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 15 Mar 2018 00:30:14 +0000 Subject: [PATCH] [ORC] Re-apply r327566 with a fix for test-global-ctors.ll. Also clang-formats the patch, which I should have done the first time around. llvm-svn: 327594 --- .../BuildingAJIT/Chapter2/KaleidoscopeJIT.h | 6 +- .../BuildingAJIT/Chapter3/KaleidoscopeJIT.h | 6 +- .../BuildingAJIT/Chapter4/KaleidoscopeJIT.h | 6 +- .../BuildingAJIT/Chapter5/KaleidoscopeJIT.h | 6 +- include/llvm-c/OrcBindings.h | 34 +-------- .../Orc/CompileOnDemandLayer.h | 12 ++- .../llvm/ExecutionEngine/Orc/ExecutionUtils.h | 8 +- .../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 24 +++++- .../ExecutionEngine/Orc/IRTransformLayer.h | 2 +- .../ExecutionEngine/Orc/LazyEmittingLayer.h | 6 +- lib/ExecutionEngine/Orc/ExecutionUtils.cpp | 2 +- lib/ExecutionEngine/Orc/OrcCBindings.cpp | 24 ++---- lib/ExecutionEngine/Orc/OrcCBindingsStack.h | 8 +- .../Orc/OrcMCJITReplacement.cpp | 9 ++- lib/ExecutionEngine/Orc/OrcMCJITReplacement.h | 73 +++++++++++++------ tools/lli/OrcLazyJIT.cpp | 39 +++++----- tools/lli/OrcLazyJIT.h | 4 +- .../Orc/ObjectTransformLayerTest.cpp | 3 +- unittests/ExecutionEngine/Orc/OrcCAPITest.cpp | 13 +--- 19 files changed, 140 insertions(+), 145 deletions(-) diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h index b6323b8963b..679d72e2050 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h @@ -51,7 +51,7 @@ private: IRCompileLayer CompileLayer; using OptimizeFunction = - std::function(std::shared_ptr)>; + std::function(std::unique_ptr)>; IRTransformLayer OptimizeLayer; @@ -77,7 +77,7 @@ public: std::make_shared(), Resolver}; }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), - OptimizeLayer(CompileLayer, [this](std::shared_ptr M) { + OptimizeLayer(CompileLayer, [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }) { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); @@ -104,7 +104,7 @@ public: } private: - std::shared_ptr optimizeModule(std::shared_ptr M) { + std::unique_ptr optimizeModule(std::unique_ptr M) { // Create a function pass manager. auto FPM = llvm::make_unique(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h index d6d31870002..cca82293018 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h @@ -55,7 +55,7 @@ private: IRCompileLayer CompileLayer; using OptimizeFunction = - std::function(std::shared_ptr)>; + std::function(std::unique_ptr)>; IRTransformLayer OptimizeLayer; @@ -73,7 +73,7 @@ public: }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::shared_ptr M) { + [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }), CompileCallbackManager( @@ -127,7 +127,7 @@ public: } private: - std::shared_ptr optimizeModule(std::shared_ptr M) { + std::unique_ptr optimizeModule(std::unique_ptr M) { // Create a function pass manager. auto FPM = llvm::make_unique(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h index f3878918065..6378dd61e29 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h @@ -81,7 +81,7 @@ private: IRCompileLayer CompileLayer; using OptimizeFunction = - std::function(std::shared_ptr)>; + std::function(std::unique_ptr)>; IRTransformLayer OptimizeLayer; @@ -113,7 +113,7 @@ public: }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::shared_ptr M) { + [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }), CompileCallbackMgr( @@ -207,7 +207,7 @@ private: return MangledNameStream.str(); } - std::shared_ptr optimizeModule(std::shared_ptr M) { + std::unique_ptr optimizeModule(std::unique_ptr M) { // Create a function pass manager. auto FPM = llvm::make_unique(M.get()); diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h index 46638c1f720..acb4090b5eb 100644 --- a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h +++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h @@ -86,7 +86,7 @@ private: IRCompileLayer CompileLayer; using OptimizeFunction = - std::function(std::shared_ptr)>; + std::function(std::unique_ptr)>; IRTransformLayer OptimizeLayer; @@ -121,7 +121,7 @@ public: }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)), OptimizeLayer(CompileLayer, - [this](std::shared_ptr M) { + [this](std::unique_ptr M) { return optimizeModule(std::move(M)); }), Remote(Remote) { @@ -223,7 +223,7 @@ private: return MangledNameStream.str(); } - std::shared_ptr optimizeModule(std::shared_ptr M) { + std::unique_ptr optimizeModule(std::unique_ptr M) { // Create a function pass manager. auto FPM = llvm::make_unique(M.get()); diff --git a/include/llvm-c/OrcBindings.h b/include/llvm-c/OrcBindings.h index 95bdef81593..d2e2e7de4d3 100644 --- a/include/llvm-c/OrcBindings.h +++ b/include/llvm-c/OrcBindings.h @@ -29,7 +29,6 @@ extern "C" { #endif -typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef; typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef; typedef uint64_t LLVMOrcModuleHandle; typedef uint64_t LLVMOrcTargetAddress; @@ -39,33 +38,6 @@ 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); - /** * Create an ORC JIT stack. * @@ -125,8 +97,7 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, */ LLVMOrcErrorCode LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMSharedModuleRef Mod, + LLVMOrcModuleHandle *RetHandle, LLVMModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); @@ -135,8 +106,7 @@ LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, */ LLVMOrcErrorCode LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMSharedModuleRef Mod, + LLVMOrcModuleHandle *RetHandle, LLVMModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index f0e9be9fd28..a64a6dd86a2 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -138,7 +138,7 @@ private: struct LogicalDylib { struct SourceModuleEntry { - std::shared_ptr SourceMod; + std::unique_ptr SourceMod; std::set StubsToClone; }; @@ -152,8 +152,7 @@ private: : K(std::move(K)), BackingResolver(std::move(BackingResolver)), StubsMgr(std::move(StubsMgr)) {} - SourceModuleHandle - addSourceModule(std::shared_ptr M) { + SourceModuleHandle addSourceModule(std::unique_ptr M) { SourceModuleHandle H = SourceModules.size(); SourceModules.push_back(SourceModuleEntry()); SourceModules.back().SourceMod = std::move(M); @@ -232,7 +231,7 @@ public: } /// @brief Add a module to the compile-on-demand layer. - Error addModule(VModuleKey K, std::shared_ptr M) { + Error addModule(VModuleKey K, std::unique_ptr M) { assert(!LogicalDylibs.count(K) && "VModuleKey K already in use"); auto I = LogicalDylibs.insert( @@ -244,7 +243,7 @@ public: } /// @brief Add extra modules to an existing logical module. - Error addExtraModule(VModuleKey K, std::shared_ptr M) { + Error addExtraModule(VModuleKey K, std::unique_ptr M) { return addLogicalModule(LogicalDylibs[K], std::move(M)); } @@ -310,8 +309,7 @@ public: } private: - - Error addLogicalModule(LogicalDylib &LD, std::shared_ptr SrcMPtr) { + Error addLogicalModule(LogicalDylib &LD, std::unique_ptr SrcMPtr) { // Rename all static functions / globals to $static.X : // This will unique the names across all modules in the logical dylib, diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index 074ec8bf248..d466df8b0d5 100644 --- a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -105,20 +105,14 @@ public: using CtorDtorTy = void (*)(); for (const auto &CtorDtorName : CtorDtorNames) { - dbgs() << "Searching for ctor/dtor: " << CtorDtorName << "..."; if (auto CtorDtorSym = JITLayer.findSymbolIn(K, 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 { - dbgs() << " failed materialization!\n"; + } else return AddrOrErr.takeError(); - } } else { - dbgs() << " failed to find symbol..."; if (auto Err = CtorDtorSym.takeError()) return Err; else diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index 045dfc16b74..a7f94164758 100644 --- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -35,19 +35,34 @@ namespace orc { template class IRCompileLayer { public: + /// @brief Callback type for notifications when modules are compiled. + using NotifyCompiledCallback = + std::function)>; /// @brief Construct an IRCompileLayer with the given BaseLayer, which must /// implement the ObjectLayer concept. - IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile) - : BaseLayer(BaseLayer), Compile(std::move(Compile)) {} + IRCompileLayer( + BaseLayerT &BaseLayer, CompileFtor Compile, + NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()) + : BaseLayer(BaseLayer), Compile(std::move(Compile)), + NotifyCompiled(std::move(NotifyCompiled)) {} /// @brief Get a reference to the compiler functor. CompileFtor& getCompiler() { return Compile; } + /// @brief (Re)set the NotifyCompiled callback. + void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) { + this->NotifyCompiled = std::move(NotifyCompiled); + } + /// @brief Compile the module, and add the resulting object to the base layer /// along with the given memory manager and symbol resolver. - Error addModule(VModuleKey K, std::shared_ptr M) { - return BaseLayer.addObject(std::move(K), Compile(*M)); + Error addModule(VModuleKey K, std::unique_ptr M) { + if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M))) + return Err; + if (NotifyCompiled) + NotifyCompiled(std::move(K), std::move(M)); + return Error::success(); } /// @brief Remove the module associated with the VModuleKey K. @@ -82,6 +97,7 @@ public: private: BaseLayerT &BaseLayer; CompileFtor Compile; + NotifyCompiledCallback NotifyCompiled; }; } // end namespace orc diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 2158ca9ac4c..4f1fe7ba0f5 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -40,7 +40,7 @@ public: /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. - Error addModule(VModuleKey K, std::shared_ptr M) { + Error addModule(VModuleKey K, std::unique_ptr M) { return BaseLayer.addModule(std::move(K), Transform(std::move(M))); } diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 35792eab6f9..4117a9226ee 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -43,7 +43,7 @@ template class LazyEmittingLayer { private: class EmissionDeferredModule { public: - EmissionDeferredModule(VModuleKey K, std::shared_ptr M) + EmissionDeferredModule(VModuleKey K, std::unique_ptr M) : K(std::move(K)), M(std::move(M)) {} JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { @@ -187,7 +187,7 @@ private: enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted; VModuleKey K; - std::shared_ptr M; + std::unique_ptr M; mutable std::unique_ptr> MangledSymbols; }; @@ -200,7 +200,7 @@ public: LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} /// @brief Add the given module to the lazy emitting layer. - Error addModule(VModuleKey K, std::shared_ptr M) { + Error addModule(VModuleKey K, std::unique_ptr M) { assert(!ModuleMap.count(K) && "VModuleKey K already in use"); ModuleMap[K] = llvm::make_unique(std::move(K), std::move(M)); diff --git a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index b7220dba88e..f6e6ed66ef9 100644 --- a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -67,7 +67,7 @@ CtorDtorIterator::Element CtorDtorIterator::operator*() const { } ConstantInt *Priority = dyn_cast(CS->getOperand(0)); - Value *Data = CS->getOperand(2); + Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; return Element(Priority->getZExtValue(), Func, Data); } diff --git a/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/lib/ExecutionEngine/Orc/OrcCBindings.cpp index f945acaf95e..0ea7a663989 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ b/lib/ExecutionEngine/Orc/OrcCBindings.cpp @@ -12,14 +12,6 @@ using namespace llvm; -LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod) { - return wrap(new std::shared_ptr(unwrap(Mod))); -} - -void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod) { - delete unwrap(SharedMod); -} - LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) { TargetMachine *TM2(unwrap(TM)); @@ -75,24 +67,24 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, LLVMOrcErrorCode LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMSharedModuleRef Mod, + LLVMOrcModuleHandle *RetHandle, LLVMModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx) { OrcCBindingsStack &J = *unwrap(JITStack); - std::shared_ptr *M(unwrap(Mod)); - return J.addIRModuleEager(*RetHandle, *M, SymbolResolver, SymbolResolverCtx); + std::unique_ptr M(unwrap(Mod)); + return J.addIRModuleEager(*RetHandle, std::move(M), SymbolResolver, + SymbolResolverCtx); } LLVMOrcErrorCode LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMSharedModuleRef Mod, + LLVMOrcModuleHandle *RetHandle, LLVMModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx) { OrcCBindingsStack &J = *unwrap(JITStack); - std::shared_ptr *M(unwrap(Mod)); - return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx); + std::unique_ptr M(unwrap(Mod)); + return J.addIRModuleLazy(*RetHandle, std::move(M), SymbolResolver, + SymbolResolverCtx); } LLVMOrcErrorCode diff --git a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index 382b9a32e09..a9621172d30 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -43,8 +43,6 @@ namespace llvm { class OrcCBindingsStack; -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr, - LLVMSharedModuleRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) @@ -284,7 +282,7 @@ public: } template LLVMOrcErrorCode - addIRModule(orc::VModuleKey &RetKey, LayerT &Layer, std::shared_ptr M, + addIRModule(orc::VModuleKey &RetKey, LayerT &Layer, std::unique_ptr M, std::unique_ptr MemMgr, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { @@ -323,7 +321,7 @@ public: } LLVMOrcErrorCode addIRModuleEager(orc::VModuleKey &RetKey, - std::shared_ptr M, + std::unique_ptr M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { return addIRModule(RetKey, CompileLayer, std::move(M), @@ -332,7 +330,7 @@ public: } LLVMOrcErrorCode addIRModuleLazy(orc::VModuleKey &RetKey, - std::shared_ptr M, + std::unique_ptr M, LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { return addIRModule(RetKey, CODLayer, std::move(M), diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp index f89f21adff4..4def579e709 100644 --- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp +++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp @@ -125,8 +125,13 @@ OrcMCJITReplacement::runFunction(Function *F, } void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) { - for (auto &M : LocalModules) - ExecutionEngine::runStaticConstructorsDestructors(*M, isDtors); + auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors; + + for (auto &KV : CtorDtorsMap) + cantFail(CtorDtorRunner(std::move(KV.second), KV.first) + .runViaLayer(LazyEmitLayer)); + + CtorDtorsMap.clear(); } } // End namespace orc. diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 0a067501170..bdb4d07b132 100644 --- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -21,6 +21,7 @@ #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" @@ -54,6 +55,7 @@ class ObjectCache; namespace orc { class OrcMCJITReplacement : public ExecutionEngine { + // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are // expecting - see finalizeMemory. @@ -235,7 +237,10 @@ public: return ObjectLayerT::Resources{this->MemMgr, this->Resolver}; }, NotifyObjectLoaded, NotifyFinalized), - CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)), + CompileLayer(ObjectLayer, SimpleCompiler(*this->TM), + [this](VModuleKey K, std::unique_ptr M) { + Modules.push_back(std::move(M)); + }), LazyEmitLayer(CompileLayer) {} static void Register() { @@ -250,16 +255,36 @@ public: } else { assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"); } - auto *MPtr = M.release(); - ShouldDelete[MPtr] = true; - auto Deleter = [this](Module *Mod) { - auto I = ShouldDelete.find(Mod); - if (I != ShouldDelete.end() && I->second) - delete Mod; - }; - LocalModules.push_back(std::shared_ptr(MPtr, std::move(Deleter))); - cantFail( - LazyEmitLayer.addModule(ES.allocateVModule(), LocalModules.back())); + + // Rename, bump linkage and record static constructors and destructors. + // We have to do this before we hand over ownership of the module to the + // JIT. + std::vector CtorNames, DtorNames; + { + unsigned CtorId = 0, DtorId = 0; + 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(); + dbgs() << "Found dtor: " << NewDtorName << "\n"; + Dtor.Func->setName(NewDtorName); + Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); + Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); + DtorNames.push_back(mangle(NewDtorName)); + } + } + + auto K = ES.allocateVModule(); + + UnexecutedConstructors[K] = std::move(CtorNames); + UnexecutedDestructors[K] = std::move(DtorNames); + + cantFail(LazyEmitLayer.addModule(K, std::move(M))); } void addObjectFile(std::unique_ptr O) override { @@ -277,16 +302,16 @@ public: void addArchive(object::OwningBinary A) override { Archives.push_back(std::move(A)); } - + bool removeModule(Module *M) override { - for (auto I = LocalModules.begin(), E = LocalModules.end(); I != E; ++I) { - if (I->get() == M) { - ShouldDelete[M] = false; - LocalModules.erase(I); - return true; - } - } - return false; + auto I = Modules.begin(); + for (auto E = Modules.end(); I != E; ++I) + if (I->get() == M) + break; + if (I == Modules.end()) + return false; + Modules.erase(I); + return true; } uint64_t getSymbolAddress(StringRef Name) { @@ -294,7 +319,7 @@ public: } JITSymbol findSymbol(StringRef Name) { - return findMangledSymbol(Mangle(Name)); + return findMangledSymbol(mangle(Name)); } void finalizeObject() override { @@ -412,7 +437,7 @@ private: OrcMCJITReplacement &M; }; - std::string Mangle(StringRef Name) { + std::string mangle(StringRef Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); @@ -438,7 +463,6 @@ private: // delete blocks in LocalModules refer to the ShouldDelete map, so // LocalModules needs to be destructed before ShouldDelete. std::map ShouldDelete; - std::vector> LocalModules; NotifyObjectLoadedT NotifyObjectLoaded; NotifyFinalizedT NotifyFinalized; @@ -447,6 +471,9 @@ private: CompileLayerT CompileLayer; LazyEmitLayerT LazyEmitLayer; + std::map> UnexecutedConstructors; + std::map> UnexecutedDestructors; + // We need to store ObjLayerT::ObjSetHandles for each of the object sets // that have been emitted but not yet finalized so that we can forward the // mapSectionAddress calls appropriately. diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp index f1a752e0790..a7f0e338b9c 100644 --- a/tools/lli/OrcLazyJIT.cpp +++ b/tools/lli/OrcLazyJIT.cpp @@ -54,10 +54,10 @@ static cl::opt OrcInlineStubs("orc-lazy-inline-stubs", OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { switch (OrcDumpKind) { case DumpKind::NoDump: - return [](std::shared_ptr M) { return M; }; + return [](std::unique_ptr M) { return M; }; case DumpKind::DumpFuncsToStdOut: - return [](std::shared_ptr M) { + return [](std::unique_ptr M) { printf("[ "); for (const auto &F : *M) { @@ -76,26 +76,25 @@ OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() { }; case DumpKind::DumpModsToStdOut: - return [](std::shared_ptr M) { - outs() << "----- Module Start -----\n" << *M - << "----- Module End -----\n"; + return [](std::unique_ptr M) { + outs() << "----- Module Start -----\n" + << *M << "----- Module End -----\n"; - return M; - }; + return M; + }; case DumpKind::DumpModsToDisk: - return [](std::shared_ptr M) { - std::error_code EC; - raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, - sys::fs::F_Text); - if (EC) { - errs() << "Couldn't open " << M->getModuleIdentifier() - << " for dumping.\nError:" << EC.message() << "\n"; - exit(1); - } - Out << *M; - return M; - }; + return [](std::unique_ptr M) { + std::error_code EC; + raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, sys::fs::F_Text); + if (EC) { + errs() << "Couldn't open " << M->getModuleIdentifier() + << " for dumping.\nError:" << EC.message() << "\n"; + exit(1); + } + Out << *M; + return M; + }; } llvm_unreachable("Unknown DumpKind"); } @@ -148,7 +147,7 @@ int llvm::runOrcLazyJIT(std::vector> Ms, // Add the module, look up main and run it. for (auto &M : Ms) - cantFail(J.addModule(std::shared_ptr(std::move(M)))); + cantFail(J.addModule(std::move(M))); if (auto MainSym = J.findSymbol("main")) { typedef int (*MainFnPtr)(int, const char*[]); diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h index 6b057c4d293..42b063fc697 100644 --- a/tools/lli/OrcLazyJIT.h +++ b/tools/lli/OrcLazyJIT.h @@ -51,7 +51,7 @@ public: using ObjLayerT = orc::RTDyldObjectLinkingLayer; using CompileLayerT = orc::IRCompileLayer; using TransformFtor = - std::function(std::shared_ptr)>; + std::function(std::unique_ptr)>; using IRDumpLayerT = orc::IRTransformLayer; using CODLayerT = orc::CompileOnDemandLayer; using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; @@ -106,7 +106,7 @@ public: } } - Error addModule(std::shared_ptr M) { + Error addModule(std::unique_ptr M) { if (M->getDataLayout().isDefault()) M->setDataLayout(DL); diff --git a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp index 3d0ee365f1c..eacd3e0b0f9 100644 --- a/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ b/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -14,6 +14,7 @@ #include "llvm/ExecutionEngine/Orc/NullResolver.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/IR/Module.h" #include "llvm/Object/ObjectFile.h" #include "gtest/gtest.h" @@ -302,7 +303,7 @@ TEST(ObjectTransformLayerTest, Main) { // Make sure that the calls from IRCompileLayer to ObjectTransformLayer // compile. cantFail(CompileLayer.addModule(ES.allocateVModule(), - std::shared_ptr())); + std::unique_ptr())); // 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 ca445b4d4e1..f053407a478 100644 --- a/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp +++ b/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -73,9 +73,8 @@ protected: CompileContext *CCtx = static_cast(Ctx); auto *ET = CCtx->APIExecTest; CCtx->M = ET->createTestModule(ET->TM->getTargetTriple()); - LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(CCtx->M.release())); - LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, SM, myResolver, nullptr); - LLVMOrcDisposeSharedModuleRef(SM); + LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, wrap(CCtx->M.release()), + myResolver, nullptr); CCtx->Compiled = true; LLVMOrcTargetAddress MainAddr; LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main"); @@ -97,10 +96,8 @@ TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) { LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); - LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release())); LLVMOrcModuleHandle H; - LLVMOrcAddEagerlyCompiledIR(JIT, &H, SM, myResolver, nullptr); - LLVMOrcDisposeSharedModuleRef(SM); + LLVMOrcAddEagerlyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr); LLVMOrcTargetAddress MainAddr; LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main"); MainFnTy MainFn = (MainFnTy)MainAddr; @@ -125,10 +122,8 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) { LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc"); - LLVMSharedModuleRef SM = LLVMOrcMakeSharedModule(wrap(M.release())); LLVMOrcModuleHandle H; - LLVMOrcAddLazilyCompiledIR(JIT, &H, SM, myResolver, nullptr); - LLVMOrcDisposeSharedModuleRef(SM); + LLVMOrcAddLazilyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr); LLVMOrcTargetAddress MainAddr; LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main"); MainFnTy MainFn = (MainFnTy)MainAddr;