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