[Orc] Enable user-supplied memory managers in the CompileOnDemand layer.
authorLang Hames <lhames@gmail.com>
Sat, 9 Jan 2016 20:55:18 +0000 (20:55 +0000)
committerLang Hames <lhames@gmail.com>
Sat, 9 Jan 2016 20:55:18 +0000 (20:55 +0000)
Previously the CompileOnDemand layer was hard-coded to use a new
SectionMemoryManager for each function when it was called.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257265 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
lib/ExecutionEngine/Orc/OrcCBindingsStack.h
tools/lli/OrcLazyJIT.h

index 7dab5d1bc67f0d33a0f4564319e3f056f7f8ad5d..0eb8693df42e77770b84a52e35f4205be788b30a 100644 (file)
@@ -19,7 +19,6 @@
 #include "LambdaResolver.h"
 #include "LogicalDylib.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include <list>
 #include <memory>
@@ -61,31 +60,36 @@ private:
 
   typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
 
-  class ModuleOwner {
+  // Provide type-erasure for the Modules and MemoryManagers.
+  template <typename ResourceT>
+  class ResourceOwner {
   public:
-    ModuleOwner() = default;
-    ModuleOwner(const ModuleOwner&) = delete;
-    ModuleOwner& operator=(const ModuleOwner&) = delete;
-    virtual ~ModuleOwner() { }
-    virtual Module& getModule() const = 0;
+    ResourceOwner() = default;
+    ResourceOwner(const ResourceOwner&) = delete;
+    ResourceOwner& operator=(const ResourceOwner&) = delete;
+    virtual ~ResourceOwner() { }
+    virtual ResourceT& getResource() const = 0;
   };
 
-  template <typename ModulePtrT>
-  class ModuleOwnerImpl : public ModuleOwner {
+  template <typename ResourceT, typename ResourcePtrT>
+  class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
   public:
-    ModuleOwnerImpl(ModulePtrT ModulePtr) : ModulePtr(std::move(ModulePtr)) {}
-    Module& getModule() const override { return *ModulePtr; }
+    ResourceOwnerImpl(ResourcePtrT ResourcePtr)
+      : ResourcePtr(std::move(ResourcePtr)) {}
+    ResourceT& getResource() const override { return *ResourcePtr; }
   private:
-    ModulePtrT ModulePtr;
+    ResourcePtrT ResourcePtr;
   };
 
-  template <typename ModulePtrT>
-  std::unique_ptr<ModuleOwner> wrapOwnership(ModulePtrT ModulePtr) {
-    return llvm::make_unique<ModuleOwnerImpl<ModulePtrT>>(std::move(ModulePtr));
+  template <typename ResourceT, typename ResourcePtrT>
+  std::unique_ptr<ResourceOwner<ResourceT>>
+  wrapOwnership(ResourcePtrT ResourcePtr) {
+    typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO;
+    return llvm::make_unique<RO>(std::move(ResourcePtr));
   }
 
   struct LogicalModuleResources {
-    std::unique_ptr<ModuleOwner> SourceModuleOwner;
+    std::unique_ptr<ResourceOwner<Module>> SourceModule;
     std::set<const Function*> StubsToClone;
     std::unique_ptr<IndirectStubsMgrT> StubsMgr;
 
@@ -93,13 +97,13 @@ private:
 
     // Explicit move constructor to make MSVC happy.
     LogicalModuleResources(LogicalModuleResources &&Other)
-        : SourceModuleOwner(std::move(Other.SourceModuleOwner)),
+        : SourceModule(std::move(Other.SourceModule)),
           StubsToClone(std::move(Other.StubsToClone)),
           StubsMgr(std::move(Other.StubsMgr)) {}
 
     // Explicit move assignment to make MSVC happy.
     LogicalModuleResources& operator=(LogicalModuleResources &&Other) {
-      SourceModuleOwner = std::move(Other.SourceModuleOwner);
+      SourceModule = std::move(Other.SourceModule);
       StubsToClone = std::move(Other.StubsToClone);
       StubsMgr = std::move(Other.StubsMgr);
     }
@@ -114,12 +118,19 @@ private:
 
   };
 
-
-
   struct LogicalDylibResources {
     typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
       SymbolResolverFtor;
+
+    typedef std::function<typename BaseLayerT::ModuleSetHandleT(
+                            BaseLayerT&,
+                            std::unique_ptr<Module>,
+                            std::unique_ptr<RuntimeDyld::SymbolResolver>)>
+      ModuleAdderFtor;
+
     SymbolResolverFtor ExternalSymbolResolver;
+    std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
+    ModuleAdderFtor ModuleAdder;
   };
 
   typedef LogicalDylib<BaseLayerT, LogicalModuleResources,
@@ -157,9 +168,6 @@ public:
                                 MemoryManagerPtrT MemMgr,
                                 SymbolResolverPtrT Resolver) {
 
-    assert(MemMgr == nullptr &&
-           "User supplied memory managers not supported with COD yet.");
-
     LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
     auto &LDResources = LogicalDylibs.back().getDylibResources();
 
@@ -168,6 +176,18 @@ public:
         return Resolver->findSymbol(Name);
       };
 
+    auto &MemMgrRef = *MemMgr;
+    LDResources.MemMgr =
+      wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
+
+    LDResources.ModuleAdder =
+      [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
+                   std::unique_ptr<RuntimeDyld::SymbolResolver> R) {
+        std::vector<std::unique_ptr<Module>> Ms;
+        Ms.push_back(std::move(M));
+        return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
+      };
+
     // Process each of the modules in this module set.
     for (auto &M : Ms)
       addLogicalModule(LogicalDylibs.back(), std::move(M));
@@ -215,9 +235,9 @@ private:
     auto LMH = LD.createLogicalModule();
     auto &LMResources =  LD.getLogicalModuleResources(LMH);
 
-    LMResources.SourceModuleOwner = wrapOwnership(std::move(SrcMPtr));
+    LMResources.SourceModule = wrapOwnership<Module>(std::move(SrcMPtr));
 
-    Module &SrcM = LMResources.SourceModuleOwner->getModule();
+    Module &SrcM = LMResources.SourceModule->getResource();
 
     // Create the GlobalValues module.
     const DataLayout &DL = SrcM.getDataLayout();
@@ -326,12 +346,9 @@ private:
           return RuntimeDyld::SymbolInfo(nullptr);
         });
 
-    std::vector<std::unique_ptr<Module>> GVsMSet;
-    GVsMSet.push_back(std::move(GVsM));
     auto GVsH =
-      BaseLayer.addModuleSet(std::move(GVsMSet),
-                             llvm::make_unique<SectionMemoryManager>(),
-                             std::move(GVsResolver));
+      LD.getDylibResources().ModuleAdder(BaseLayer, std::move(GVsM),
+                                        std::move(GVsResolver));
     LD.addToLogicalModule(LMH, GVsH);
   }
 
@@ -348,7 +365,7 @@ private:
                                   LogicalModuleHandle LMH,
                                   Function &F) {
     auto &LMResources = LD.getLogicalModuleResources(LMH);
-    Module &SrcM = LMResources.SourceModuleOwner->getModule();
+    Module &SrcM = LMResources.SourceModule->getResource();
 
     // If F is a declaration we must already have compiled it.
     if (F.isDeclaration())
@@ -386,7 +403,7 @@ private:
                                           LogicalModuleHandle LMH,
                                           const PartitionT &Part) {
     auto &LMResources = LD.getLogicalModuleResources(LMH);
-    Module &SrcM = LMResources.SourceModuleOwner->getModule();
+    Module &SrcM = LMResources.SourceModule->getResource();
 
     // Create the module.
     std::string NewName = SrcM.getName();
@@ -445,7 +462,6 @@ private:
       moveFunctionBody(*F, VMap, &Materializer);
 
     // Create memory manager and symbol resolver.
-    auto MemMgr = llvm::make_unique<SectionMemoryManager>();
     auto Resolver = createLambdaResolver(
         [this, &LD, LMH](const std::string &Name) {
           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
@@ -459,10 +475,9 @@ private:
                                            Symbol.getFlags());
           return RuntimeDyld::SymbolInfo(nullptr);
         });
-    std::vector<std::unique_ptr<Module>> PartMSet;
-    PartMSet.push_back(std::move(M));
-    return BaseLayer.addModuleSet(std::move(PartMSet), std::move(MemMgr),
-                                  std::move(Resolver));
+
+    return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
+                                             std::move(Resolver));
   }
 
   BaseLayerT &BaseLayer;
index 2e17624ff4740759c54a7c41eb5c96024c93b969..aae6a99432bc5c48e591cbace2bec6a4c90a494a 100644 (file)
@@ -221,7 +221,8 @@ public:
   ModuleHandleT addIRModuleLazy(Module* M,
                                 LLVMOrcSymbolResolverFn ExternalResolver,
                                 void *ExternalResolverCtx) {
-    return addIRModule(CODLayer, std::move(M), nullptr,
+    return addIRModule(CODLayer, std::move(M),
+                      llvm::make_unique<SectionMemoryManager>(),
                        std::move(ExternalResolver), ExternalResolverCtx);
   }
 
index bb4da33ea9b6d9669d679f5602d0db4c9e7bbdbe..2a5b31d1bfb8e9810d11a08391bad8deef9d0e6d 100644 (file)
@@ -105,7 +105,9 @@ public:
     // Add the module to the JIT.
     std::vector<std::unique_ptr<Module>> S;
     S.push_back(std::move(M));
-    auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver));
+    auto H = CODLayer.addModuleSet(std::move(S),
+                                  llvm::make_unique<SectionMemoryManager>(),
+                                  std::move(Resolver));
 
     // Run the static constructors, and save the static destructor runner for
     // execution when the JIT is torn down.