X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FExecutionEngine%2FOrc%2FCompileOnDemandLayer.h;h=07914e386ad213f311231a59e8b7eecfb5ed3613;hp=a72805d2af9633b634f301eecc2fd7e53534ee1f;hb=0b6b9ceae3f1ea6b29769fa7d2a461d65ee301c5;hpb=e61c7b5220cd118c005cba94fc14e2598b68f59e diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index a72805d2af9..07914e386ad 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -62,18 +62,48 @@ private: typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT; + class ModuleOwner { + public: + ModuleOwner() = default; + ModuleOwner(const ModuleOwner&) = delete; + ModuleOwner& operator=(const ModuleOwner&) = delete; + virtual ~ModuleOwner() { } + virtual Module& getModule() const = 0; + }; + + template + class ModuleOwnerImpl : public ModuleOwner { + public: + ModuleOwnerImpl(ModulePtrT ModulePtr) : ModulePtr(std::move(ModulePtr)) {} + Module& getModule() const override { return *ModulePtr; } + private: + ModulePtrT ModulePtr; + }; + + template + std::unique_ptr wrapOwnership(ModulePtrT ModulePtr) { + return llvm::make_unique>(std::move(ModulePtr)); + } + struct LogicalModuleResources { - std::shared_ptr SourceModule; + std::unique_ptr SourceModuleOwner; std::set StubsToClone; std::unique_ptr StubsMgr; - LogicalModuleResources() {} + LogicalModuleResources() = default; // Explicit move constructor to make MSVC happy. - LogicalModuleResources(LogicalModuleResources &&Other) = default; + LogicalModuleResources(LogicalModuleResources &&Other) + : SourceModuleOwner(std::move(Other.SourceModuleOwner)), + StubsToClone(std::move(Other.StubsToClone)), + StubsMgr(std::move(Other.StubsMgr)) {} // Explicit move assignment to make MSVC happy. - LogicalModuleResources& operator=(LogicalModuleResources &&Other) = default; + LogicalModuleResources& operator=(LogicalModuleResources &&Other) { + SourceModuleOwner = std::move(Other.SourceModuleOwner); + StubsToClone = std::move(Other.StubsToClone); + StubsMgr = std::move(Other.StubsMgr); + } JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { if (Name.endswith("$stub_ptr") && !ExportedSymbolsOnly) { @@ -85,6 +115,8 @@ private: }; + + struct LogicalDylibResources { typedef std::function SymbolResolverFtor; @@ -139,8 +171,7 @@ public: // Process each of the modules in this module set. for (auto &M : Ms) - addLogicalModule(LogicalDylibs.back(), - std::shared_ptr(std::move(M))); + addLogicalModule(LogicalDylibs.back(), std::move(M)); return std::prev(LogicalDylibs.end()); } @@ -162,7 +193,7 @@ public: LDI != LDE; ++LDI) if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly)) return Symbol; - return nullptr; + return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } /// @brief Get the address of a symbol provided by this layer, or some layer @@ -174,29 +205,32 @@ public: private: - void addLogicalModule(CODLogicalDylib &LD, std::shared_ptr SrcM) { + template + void addLogicalModule(CODLogicalDylib &LD, ModulePtrT SrcMPtr) { // Bump the linkage and rename any anonymous/privote members in SrcM to // ensure that everything will resolve properly after we partition SrcM. - makeAllSymbolsExternallyAccessible(*SrcM); + makeAllSymbolsExternallyAccessible(*SrcMPtr); // Create a logical module handle for SrcM within the logical dylib. auto LMH = LD.createLogicalModule(); auto &LMResources = LD.getLogicalModuleResources(LMH); - LMResources.SourceModule = SrcM; + LMResources.SourceModuleOwner = wrapOwnership(std::move(SrcMPtr)); + + Module &SrcM = LMResources.SourceModuleOwner->getModule(); // Create the GlobalValues module. - const DataLayout &DL = SrcM->getDataLayout(); - auto GVsM = llvm::make_unique((SrcM->getName() + ".globals").str(), - SrcM->getContext()); + const DataLayout &DL = SrcM.getDataLayout(); + auto GVsM = llvm::make_unique((SrcM.getName() + ".globals").str(), + SrcM.getContext()); GVsM->setDataLayout(DL); // Create function stubs. ValueToValueMapTy VMap; { typename IndirectStubsMgrT::StubInitsMap StubInits; - for (auto &F : *SrcM) { + for (auto &F : SrcM) { // Skip declarations. if (F.isDeclaration()) continue; @@ -208,18 +242,17 @@ private: // Create a callback, associate it with the stub for the function, // and set the compile action to compile the partition containing the // function. - auto CCInfo = CompileCallbackMgr.getCompileCallback(SrcM->getContext()); + auto CCInfo = CompileCallbackMgr.getCompileCallback(SrcM.getContext()); StubInits[mangle(F.getName(), DL)] = std::make_pair(CCInfo.getAddress(), JITSymbolBase::flagsFromGlobalValue(F)); - CCInfo.setCompileAction( - [this, &LD, LMH, &F]() { - return this->extractAndCompile(LD, LMH, F); - }); + CCInfo.setCompileAction([this, &LD, LMH, &F]() { + return this->extractAndCompile(LD, LMH, F); + }); } LMResources.StubsMgr = CreateIndirectStubsManager(); - auto EC = LMResources.StubsMgr->init(StubInits); + auto EC = LMResources.StubsMgr->createStubs(StubInits); (void)EC; // FIXME: This should be propagated back to the user. Stub creation may // fail for remote JITs. @@ -227,12 +260,12 @@ private: } // Clone global variable decls. - for (auto &GV : SrcM->globals()) + for (auto &GV : SrcM.globals()) if (!GV.isDeclaration() && !VMap.count(&GV)) cloneGlobalVariableDecl(*GVsM, GV, &VMap); // And the aliases. - for (auto &A : SrcM->aliases()) + for (auto &A : SrcM.aliases()) if (!VMap.count(&A)) cloneGlobalAliasDecl(*GVsM, A, VMap); @@ -269,12 +302,12 @@ private: }); // Clone the global variable initializers. - for (auto &GV : SrcM->globals()) + for (auto &GV : SrcM.globals()) if (!GV.isDeclaration()) moveGlobalVariableInitializer(GV, VMap, &Materializer); // Clone the global alias initializers. - for (auto &A : SrcM->aliases()) { + for (auto &A : SrcM.aliases()) { auto *NewA = cast(VMap[&A]); assert(NewA && "Alias not cloned?"); Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr, @@ -305,10 +338,7 @@ private: static std::string mangle(StringRef Name, const DataLayout &DL) { std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, DL); - } + Mangler::getNameWithPrefix(raw_string_ostream(MangledName), Name, DL); return MangledName; } @@ -316,7 +346,7 @@ private: LogicalModuleHandle LMH, Function &F) { auto &LMResources = LD.getLogicalModuleResources(LMH); - Module &SrcM = *LMResources.SourceModule; + Module &SrcM = LMResources.SourceModuleOwner->getModule(); // If F is a declaration we must already have compiled it. if (F.isDeclaration()) @@ -354,7 +384,7 @@ private: LogicalModuleHandle LMH, const PartitionT &Part) { auto &LMResources = LD.getLogicalModuleResources(LMH); - Module &SrcM = *LMResources.SourceModule; + Module &SrcM = LMResources.SourceModuleOwner->getModule(); // Create the module. std::string NewName = SrcM.getName(); @@ -367,42 +397,42 @@ private: M->setDataLayout(SrcM.getDataLayout()); ValueToValueMapTy VMap; - auto Materializer = createLambdaMaterializer( - [this, &LMResources, &M, &VMap](Value *V) -> Value* { - if (auto *GV = dyn_cast(V)) { - return cloneGlobalVariableDecl(*M, *GV); - } else if (auto *F = dyn_cast(V)) { - // Check whether we want to clone an available_externally definition. - if (LMResources.StubsToClone.count(F)) { - // Ok - we want an inlinable stub. For that to work we need a decl - // for the stub pointer. - auto *StubPtr = createImplPointer(*F->getType(), *M, - F->getName() + "$stub_ptr", - nullptr); - auto *ClonedF = cloneFunctionDecl(*M, *F); - makeStub(*ClonedF, *StubPtr); - ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage); - ClonedF->addFnAttr(Attribute::AlwaysInline); - return ClonedF; - } + auto Materializer = createLambdaMaterializer([this, &LMResources, &M, + &VMap](Value *V) -> Value * { + if (auto *GV = dyn_cast(V)) + return cloneGlobalVariableDecl(*M, *GV); + if (auto *F = dyn_cast(V)) { + // Check whether we want to clone an available_externally definition. + if (!LMResources.StubsToClone.count(F)) return cloneFunctionDecl(*M, *F); - } else if (auto *A = dyn_cast(V)) { - auto *PTy = cast(A->getType()); - if (PTy->getElementType()->isFunctionTy()) - return Function::Create(cast(PTy->getElementType()), - GlobalValue::ExternalLinkage, - A->getName(), M.get()); - // else - return new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalLinkage, - nullptr, A->getName(), nullptr, - GlobalValue::NotThreadLocal, - PTy->getAddressSpace()); - } - // Else. - return nullptr; - }); + + // Ok - we want an inlinable stub. For that to work we need a decl + // for the stub pointer. + auto *StubPtr = createImplPointer(*F->getType(), *M, + F->getName() + "$stub_ptr", nullptr); + auto *ClonedF = cloneFunctionDecl(*M, *F); + makeStub(*ClonedF, *StubPtr); + ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage); + ClonedF->addFnAttr(Attribute::AlwaysInline); + return ClonedF; + } + + if (auto *A = dyn_cast(V)) { + auto *Ty = A->getValueType(); + if (Ty->isFunctionTy()) + return Function::Create(cast(Ty), + GlobalValue::ExternalLinkage, A->getName(), + M.get()); + + return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, + nullptr, A->getName(), nullptr, + GlobalValue::NotThreadLocal, + A->getType()->getAddressSpace()); + } + + return nullptr; + }); // Create decls in the new module. for (auto *F : Part)