[Orc] Enable user-supplied memory managers in the CompileOnDemand layer.
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / CompileOnDemandLayer.h
1 //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // JIT layer for breaking up modules and inserting callbacks to allow
11 // individual functions to be compiled on demand.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
16 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
17
18 #include "IndirectionUtils.h"
19 #include "LambdaResolver.h"
20 #include "LogicalDylib.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Transforms/Utils/Cloning.h"
23 #include <list>
24 #include <memory>
25 #include <set>
26
27 #include "llvm/Support/Debug.h"
28
29 namespace llvm {
30 namespace orc {
31
32 /// @brief Compile-on-demand layer.
33 ///
34 ///   When a module is added to this layer a stub is created for each of its
35 /// function definitions. The stubs and other global values are immediately
36 /// added to the layer below. When a stub is called it triggers the extraction
37 /// of the function body from the original module. The extracted body is then
38 /// compiled and executed.
39 template <typename BaseLayerT,
40           typename CompileCallbackMgrT = JITCompileCallbackManager,
41           typename IndirectStubsMgrT = IndirectStubsManager>
42 class CompileOnDemandLayer {
43 private:
44
45   template <typename MaterializerFtor>
46   class LambdaMaterializer final : public ValueMaterializer {
47   public:
48     LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
49     Value *materializeDeclFor(Value *V) final { return M(V); }
50
51   private:
52     MaterializerFtor M;
53   };
54
55   template <typename MaterializerFtor>
56   LambdaMaterializer<MaterializerFtor>
57   createLambdaMaterializer(MaterializerFtor M) {
58     return LambdaMaterializer<MaterializerFtor>(std::move(M));
59   }
60
61   typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
62
63   // Provide type-erasure for the Modules and MemoryManagers.
64   template <typename ResourceT>
65   class ResourceOwner {
66   public:
67     ResourceOwner() = default;
68     ResourceOwner(const ResourceOwner&) = delete;
69     ResourceOwner& operator=(const ResourceOwner&) = delete;
70     virtual ~ResourceOwner() { }
71     virtual ResourceT& getResource() const = 0;
72   };
73
74   template <typename ResourceT, typename ResourcePtrT>
75   class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
76   public:
77     ResourceOwnerImpl(ResourcePtrT ResourcePtr)
78       : ResourcePtr(std::move(ResourcePtr)) {}
79     ResourceT& getResource() const override { return *ResourcePtr; }
80   private:
81     ResourcePtrT ResourcePtr;
82   };
83
84   template <typename ResourceT, typename ResourcePtrT>
85   std::unique_ptr<ResourceOwner<ResourceT>>
86   wrapOwnership(ResourcePtrT ResourcePtr) {
87     typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO;
88     return llvm::make_unique<RO>(std::move(ResourcePtr));
89   }
90
91   struct LogicalModuleResources {
92     std::unique_ptr<ResourceOwner<Module>> SourceModule;
93     std::set<const Function*> StubsToClone;
94     std::unique_ptr<IndirectStubsMgrT> StubsMgr;
95
96     LogicalModuleResources() = default;
97
98     // Explicit move constructor to make MSVC happy.
99     LogicalModuleResources(LogicalModuleResources &&Other)
100         : SourceModule(std::move(Other.SourceModule)),
101           StubsToClone(std::move(Other.StubsToClone)),
102           StubsMgr(std::move(Other.StubsMgr)) {}
103
104     // Explicit move assignment to make MSVC happy.
105     LogicalModuleResources& operator=(LogicalModuleResources &&Other) {
106       SourceModule = std::move(Other.SourceModule);
107       StubsToClone = std::move(Other.StubsToClone);
108       StubsMgr = std::move(Other.StubsMgr);
109     }
110
111     JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
112       if (Name.endswith("$stub_ptr") && !ExportedSymbolsOnly) {
113         assert(!ExportedSymbolsOnly && "Stubs are never exported");
114         return StubsMgr->findPointer(Name.drop_back(9));
115       }
116       return StubsMgr->findStub(Name, ExportedSymbolsOnly);
117     }
118
119   };
120
121   struct LogicalDylibResources {
122     typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
123       SymbolResolverFtor;
124
125     typedef std::function<typename BaseLayerT::ModuleSetHandleT(
126                             BaseLayerT&,
127                             std::unique_ptr<Module>,
128                             std::unique_ptr<RuntimeDyld::SymbolResolver>)>
129       ModuleAdderFtor;
130
131     SymbolResolverFtor ExternalSymbolResolver;
132     std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
133     ModuleAdderFtor ModuleAdder;
134   };
135
136   typedef LogicalDylib<BaseLayerT, LogicalModuleResources,
137                        LogicalDylibResources> CODLogicalDylib;
138
139   typedef typename CODLogicalDylib::LogicalModuleHandle LogicalModuleHandle;
140   typedef std::list<CODLogicalDylib> LogicalDylibList;
141
142 public:
143
144   /// @brief Handle to a set of loaded modules.
145   typedef typename LogicalDylibList::iterator ModuleSetHandleT;
146
147   /// @brief Module partitioning functor.
148   typedef std::function<std::set<Function*>(Function&)> PartitioningFtor;
149
150   /// @brief Builder for IndirectStubsManagers.
151   typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
152     IndirectStubsManagerBuilderT;
153
154   /// @brief Construct a compile-on-demand layer instance.
155   CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
156                        CompileCallbackMgrT &CallbackMgr,
157                        IndirectStubsManagerBuilderT CreateIndirectStubsManager,
158                        bool CloneStubsIntoPartitions = true)
159       : BaseLayer(BaseLayer),  Partition(Partition),
160         CompileCallbackMgr(CallbackMgr),
161         CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
162         CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
163
164   /// @brief Add a module to the compile-on-demand layer.
165   template <typename ModuleSetT, typename MemoryManagerPtrT,
166             typename SymbolResolverPtrT>
167   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
168                                 MemoryManagerPtrT MemMgr,
169                                 SymbolResolverPtrT Resolver) {
170
171     LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
172     auto &LDResources = LogicalDylibs.back().getDylibResources();
173
174     LDResources.ExternalSymbolResolver =
175       [Resolver](const std::string &Name) {
176         return Resolver->findSymbol(Name);
177       };
178
179     auto &MemMgrRef = *MemMgr;
180     LDResources.MemMgr =
181       wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
182
183     LDResources.ModuleAdder =
184       [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
185                    std::unique_ptr<RuntimeDyld::SymbolResolver> R) {
186         std::vector<std::unique_ptr<Module>> Ms;
187         Ms.push_back(std::move(M));
188         return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
189       };
190
191     // Process each of the modules in this module set.
192     for (auto &M : Ms)
193       addLogicalModule(LogicalDylibs.back(), std::move(M));
194
195     return std::prev(LogicalDylibs.end());
196   }
197
198   /// @brief Remove the module represented by the given handle.
199   ///
200   ///   This will remove all modules in the layers below that were derived from
201   /// the module represented by H.
202   void removeModuleSet(ModuleSetHandleT H) {
203     LogicalDylibs.erase(H);
204   }
205
206   /// @brief Search for the given named symbol.
207   /// @param Name The name of the symbol to search for.
208   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
209   /// @return A handle for the given named symbol, if it exists.
210   JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
211     for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
212          LDI != LDE; ++LDI)
213       if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
214         return Symbol;
215     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
216   }
217
218   /// @brief Get the address of a symbol provided by this layer, or some layer
219   ///        below this one.
220   JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
221                          bool ExportedSymbolsOnly) {
222     return H->findSymbol(Name, ExportedSymbolsOnly);
223   }
224
225 private:
226
227   template <typename ModulePtrT>
228   void addLogicalModule(CODLogicalDylib &LD, ModulePtrT SrcMPtr) {
229
230     // Bump the linkage and rename any anonymous/privote members in SrcM to
231     // ensure that everything will resolve properly after we partition SrcM.
232     makeAllSymbolsExternallyAccessible(*SrcMPtr);
233
234     // Create a logical module handle for SrcM within the logical dylib.
235     auto LMH = LD.createLogicalModule();
236     auto &LMResources =  LD.getLogicalModuleResources(LMH);
237
238     LMResources.SourceModule = wrapOwnership<Module>(std::move(SrcMPtr));
239
240     Module &SrcM = LMResources.SourceModule->getResource();
241
242     // Create the GlobalValues module.
243     const DataLayout &DL = SrcM.getDataLayout();
244     auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
245                                           SrcM.getContext());
246     GVsM->setDataLayout(DL);
247
248     // Create function stubs.
249     ValueToValueMapTy VMap;
250     {
251       typename IndirectStubsMgrT::StubInitsMap StubInits;
252       for (auto &F : SrcM) {
253         // Skip declarations.
254         if (F.isDeclaration())
255           continue;
256
257         // Record all functions defined by this module.
258         if (CloneStubsIntoPartitions)
259           LMResources.StubsToClone.insert(&F);
260
261         // Create a callback, associate it with the stub for the function,
262         // and set the compile action to compile the partition containing the
263         // function.
264         auto CCInfo = CompileCallbackMgr.getCompileCallback();
265         StubInits[mangle(F.getName(), DL)] =
266           std::make_pair(CCInfo.getAddress(),
267                          JITSymbolBase::flagsFromGlobalValue(F));
268         CCInfo.setCompileAction([this, &LD, LMH, &F]() {
269           return this->extractAndCompile(LD, LMH, F);
270         });
271       }
272
273       LMResources.StubsMgr = CreateIndirectStubsManager();
274       auto EC = LMResources.StubsMgr->createStubs(StubInits);
275       (void)EC;
276       // FIXME: This should be propagated back to the user. Stub creation may
277       //        fail for remote JITs.
278       assert(!EC && "Error generating stubs");
279     }
280
281     // Clone global variable decls.
282     for (auto &GV : SrcM.globals())
283       if (!GV.isDeclaration() && !VMap.count(&GV))
284         cloneGlobalVariableDecl(*GVsM, GV, &VMap);
285
286     // And the aliases.
287     for (auto &A : SrcM.aliases())
288       if (!VMap.count(&A))
289         cloneGlobalAliasDecl(*GVsM, A, VMap);
290
291     // Now we need to clone the GV and alias initializers.
292
293     // Initializers may refer to functions declared (but not defined) in this
294     // module. Build a materializer to clone decls on demand.
295     auto Materializer = createLambdaMaterializer(
296       [this, &GVsM, &LMResources](Value *V) -> Value* {
297         if (auto *F = dyn_cast<Function>(V)) {
298           // Decls in the original module just get cloned.
299           if (F->isDeclaration())
300             return cloneFunctionDecl(*GVsM, *F);
301
302           // Definitions in the original module (which we have emitted stubs
303           // for at this point) get turned into a constant alias to the stub
304           // instead.
305           const DataLayout &DL = GVsM->getDataLayout();
306           std::string FName = mangle(F->getName(), DL);
307           auto StubSym = LMResources.StubsMgr->findStub(FName, false);
308           unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
309           ConstantInt *StubAddr =
310             ConstantInt::get(GVsM->getContext(),
311                              APInt(PtrBitWidth, StubSym.getAddress()));
312           Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
313                                                  StubAddr, F->getType());
314           return GlobalAlias::create(F->getFunctionType(),
315                                      F->getType()->getAddressSpace(),
316                                      F->getLinkage(), F->getName(),
317                                      Init, GVsM.get());
318         }
319         // else....
320         return nullptr;
321       });
322
323     // Clone the global variable initializers.
324     for (auto &GV : SrcM.globals())
325       if (!GV.isDeclaration())
326         moveGlobalVariableInitializer(GV, VMap, &Materializer);
327
328     // Clone the global alias initializers.
329     for (auto &A : SrcM.aliases()) {
330       auto *NewA = cast<GlobalAlias>(VMap[&A]);
331       assert(NewA && "Alias not cloned?");
332       Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
333                              &Materializer);
334       NewA->setAliasee(cast<Constant>(Init));
335     }
336
337     // Build a resolver for the globals module and add it to the base layer.
338     auto GVsResolver = createLambdaResolver(
339         [&LD, LMH](const std::string &Name) {
340           auto &LMResources = LD.getLogicalModuleResources(LMH);
341           if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
342             return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
343           return LD.getDylibResources().ExternalSymbolResolver(Name);
344         },
345         [](const std::string &Name) {
346           return RuntimeDyld::SymbolInfo(nullptr);
347         });
348
349     auto GVsH =
350       LD.getDylibResources().ModuleAdder(BaseLayer, std::move(GVsM),
351                                          std::move(GVsResolver));
352     LD.addToLogicalModule(LMH, GVsH);
353   }
354
355   static std::string mangle(StringRef Name, const DataLayout &DL) {
356     std::string MangledName;
357     {
358       raw_string_ostream MangledNameStream(MangledName);
359       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
360     }
361     return MangledName;
362   }
363
364   TargetAddress extractAndCompile(CODLogicalDylib &LD,
365                                   LogicalModuleHandle LMH,
366                                   Function &F) {
367     auto &LMResources = LD.getLogicalModuleResources(LMH);
368     Module &SrcM = LMResources.SourceModule->getResource();
369
370     // If F is a declaration we must already have compiled it.
371     if (F.isDeclaration())
372       return 0;
373
374     // Grab the name of the function being called here.
375     std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
376
377     auto Part = Partition(F);
378     auto PartH = emitPartition(LD, LMH, Part);
379
380     TargetAddress CalledAddr = 0;
381     for (auto *SubF : Part) {
382       std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
383       auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
384       assert(FnBodySym && "Couldn't find function body.");
385
386       TargetAddress FnBodyAddr = FnBodySym.getAddress();
387
388       // If this is the function we're calling record the address so we can
389       // return it from this function.
390       if (SubF == &F)
391         CalledAddr = FnBodyAddr;
392
393       // Update the function body pointer for the stub.
394       if (auto EC = LMResources.StubsMgr->updatePointer(FnName, FnBodyAddr))
395         return 0;
396     }
397
398     return CalledAddr;
399   }
400
401   template <typename PartitionT>
402   BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
403                                           LogicalModuleHandle LMH,
404                                           const PartitionT &Part) {
405     auto &LMResources = LD.getLogicalModuleResources(LMH);
406     Module &SrcM = LMResources.SourceModule->getResource();
407
408     // Create the module.
409     std::string NewName = SrcM.getName();
410     for (auto *F : Part) {
411       NewName += ".";
412       NewName += F->getName();
413     }
414
415     auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
416     M->setDataLayout(SrcM.getDataLayout());
417     ValueToValueMapTy VMap;
418
419     auto Materializer = createLambdaMaterializer([this, &LMResources, &M,
420                                                   &VMap](Value *V) -> Value * {
421       if (auto *GV = dyn_cast<GlobalVariable>(V))
422         return cloneGlobalVariableDecl(*M, *GV);
423
424       if (auto *F = dyn_cast<Function>(V)) {
425         // Check whether we want to clone an available_externally definition.
426         if (!LMResources.StubsToClone.count(F))
427           return cloneFunctionDecl(*M, *F);
428
429         // Ok - we want an inlinable stub. For that to work we need a decl
430         // for the stub pointer.
431         auto *StubPtr = createImplPointer(*F->getType(), *M,
432                                           F->getName() + "$stub_ptr", nullptr);
433         auto *ClonedF = cloneFunctionDecl(*M, *F);
434         makeStub(*ClonedF, *StubPtr);
435         ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
436         ClonedF->addFnAttr(Attribute::AlwaysInline);
437         return ClonedF;
438       }
439
440       if (auto *A = dyn_cast<GlobalAlias>(V)) {
441         auto *Ty = A->getValueType();
442         if (Ty->isFunctionTy())
443           return Function::Create(cast<FunctionType>(Ty),
444                                   GlobalValue::ExternalLinkage, A->getName(),
445                                   M.get());
446
447         return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
448                                   nullptr, A->getName(), nullptr,
449                                   GlobalValue::NotThreadLocal,
450                                   A->getType()->getAddressSpace());
451       }
452
453       return nullptr;
454     });
455
456     // Create decls in the new module.
457     for (auto *F : Part)
458       cloneFunctionDecl(*M, *F, &VMap);
459
460     // Move the function bodies.
461     for (auto *F : Part)
462       moveFunctionBody(*F, VMap, &Materializer);
463
464     // Create memory manager and symbol resolver.
465     auto Resolver = createLambdaResolver(
466         [this, &LD, LMH](const std::string &Name) {
467           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
468             return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
469                                            Symbol.getFlags());
470           return LD.getDylibResources().ExternalSymbolResolver(Name);
471         },
472         [this, &LD, LMH](const std::string &Name) {
473           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
474             return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
475                                            Symbol.getFlags());
476           return RuntimeDyld::SymbolInfo(nullptr);
477         });
478
479     return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
480                                               std::move(Resolver));
481   }
482
483   BaseLayerT &BaseLayer;
484   PartitioningFtor Partition;
485   CompileCallbackMgrT &CompileCallbackMgr;
486   IndirectStubsManagerBuilderT CreateIndirectStubsManager;
487
488   LogicalDylibList LogicalDylibs;
489   bool CloneStubsIntoPartitions;
490 };
491
492 } // End namespace orc.
493 } // End namespace llvm.
494
495 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H