Orc: Drop some else-after-return, reflow a few spots, and avoid use of pointee types
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / CompileOnDemandLayer.h
index a72805d2af9633b634f301eecc2fd7e53534ee1f..07914e386ad213f311231a59e8b7eecfb5ed3613 100644 (file)
@@ -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 <typename ModulePtrT>
+  class ModuleOwnerImpl : public ModuleOwner {
+  public:
+    ModuleOwnerImpl(ModulePtrT ModulePtr) : ModulePtr(std::move(ModulePtr)) {}
+    Module& getModule() const override { return *ModulePtr; }
+  private:
+    ModulePtrT ModulePtr;
+  };
+
+  template <typename ModulePtrT>
+  std::unique_ptr<ModuleOwner> wrapOwnership(ModulePtrT ModulePtr) {
+    return llvm::make_unique<ModuleOwnerImpl<ModulePtrT>>(std::move(ModulePtr));
+  }
+
   struct LogicalModuleResources {
-    std::shared_ptr<Module> SourceModule;
+    std::unique_ptr<ModuleOwner> SourceModuleOwner;
     std::set<const Function*> StubsToClone;
     std::unique_ptr<IndirectStubsMgrT> 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<RuntimeDyld::SymbolInfo(const std::string&)>
       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<Module>(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<Module> SrcM) {
+  template <typename ModulePtrT>
+  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<Module>((SrcM->getName() + ".globals").str(),
-                                          SrcM->getContext());
+    const DataLayout &DL = SrcM.getDataLayout();
+    auto GVsM = llvm::make_unique<Module>((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<GlobalAlias>(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<GlobalVariable>(V)) {
-          return cloneGlobalVariableDecl(*M, *GV);
-        } else if (auto *F = dyn_cast<Function>(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<GlobalVariable>(V))
+        return cloneGlobalVariableDecl(*M, *GV);
 
+      if (auto *F = dyn_cast<Function>(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<GlobalAlias>(V)) {
-          auto *PTy = cast<PointerType>(A->getType());
-          if (PTy->getElementType()->isFunctionTy())
-            return Function::Create(cast<FunctionType>(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<GlobalAlias>(V)) {
+        auto *Ty = A->getValueType();
+        if (Ty->isFunctionTy())
+          return Function::Create(cast<FunctionType>(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)