Taints the non-acquire RMW's store address with the load part
[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       return *this;
110     }
111
112     JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
113       if (Name.endswith("$stub_ptr") && !ExportedSymbolsOnly) {
114         assert(!ExportedSymbolsOnly && "Stubs are never exported");
115         return StubsMgr->findPointer(Name.drop_back(9));
116       }
117       return StubsMgr->findStub(Name, ExportedSymbolsOnly);
118     }
119
120   };
121
122   struct LogicalDylibResources {
123     typedef std::function<RuntimeDyld::SymbolInfo(const std::string&)>
124       SymbolResolverFtor;
125
126     typedef std::function<typename BaseLayerT::ModuleSetHandleT(
127                             BaseLayerT&,
128                             std::unique_ptr<Module>,
129                             std::unique_ptr<RuntimeDyld::SymbolResolver>)>
130       ModuleAdderFtor;
131
132     LogicalDylibResources() = default;
133
134     // Explicit move constructor to make MSVC happy.
135     LogicalDylibResources(LogicalDylibResources &&Other)
136       : ExternalSymbolResolver(std::move(Other.ExternalSymbolResolver)),
137         MemMgr(std::move(Other.MemMgr)),
138         ModuleAdder(std::move(Other.ModuleAdder)) {}
139
140     // Explicit move assignment operator to make MSVC happy.
141     LogicalDylibResources& operator=(LogicalDylibResources &&Other) {
142       ExternalSymbolResolver = std::move(Other.ExternalSymbolResolver);
143       MemMgr = std::move(Other.MemMgr);
144       ModuleAdder = std::move(Other.ModuleAdder);
145       return *this;
146     }
147
148     SymbolResolverFtor ExternalSymbolResolver;
149     std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
150     ModuleAdderFtor ModuleAdder;
151   };
152
153   typedef LogicalDylib<BaseLayerT, LogicalModuleResources,
154                        LogicalDylibResources> CODLogicalDylib;
155
156   typedef typename CODLogicalDylib::LogicalModuleHandle LogicalModuleHandle;
157   typedef std::list<CODLogicalDylib> LogicalDylibList;
158
159 public:
160
161   /// @brief Handle to a set of loaded modules.
162   typedef typename LogicalDylibList::iterator ModuleSetHandleT;
163
164   /// @brief Module partitioning functor.
165   typedef std::function<std::set<Function*>(Function&)> PartitioningFtor;
166
167   /// @brief Builder for IndirectStubsManagers.
168   typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
169     IndirectStubsManagerBuilderT;
170
171   /// @brief Construct a compile-on-demand layer instance.
172   CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
173                        CompileCallbackMgrT &CallbackMgr,
174                        IndirectStubsManagerBuilderT CreateIndirectStubsManager,
175                        bool CloneStubsIntoPartitions = true)
176       : BaseLayer(BaseLayer),  Partition(Partition),
177         CompileCallbackMgr(CallbackMgr),
178         CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
179         CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
180
181   /// @brief Add a module to the compile-on-demand layer.
182   template <typename ModuleSetT, typename MemoryManagerPtrT,
183             typename SymbolResolverPtrT>
184   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
185                                 MemoryManagerPtrT MemMgr,
186                                 SymbolResolverPtrT Resolver) {
187
188     LogicalDylibs.push_back(CODLogicalDylib(BaseLayer));
189     auto &LDResources = LogicalDylibs.back().getDylibResources();
190
191     LDResources.ExternalSymbolResolver =
192       [Resolver](const std::string &Name) {
193         return Resolver->findSymbol(Name);
194       };
195
196     auto &MemMgrRef = *MemMgr;
197     LDResources.MemMgr =
198       wrapOwnership<RuntimeDyld::MemoryManager>(std::move(MemMgr));
199
200     LDResources.ModuleAdder =
201       [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
202                    std::unique_ptr<RuntimeDyld::SymbolResolver> R) {
203         std::vector<std::unique_ptr<Module>> Ms;
204         Ms.push_back(std::move(M));
205         return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
206       };
207
208     // Process each of the modules in this module set.
209     for (auto &M : Ms)
210       addLogicalModule(LogicalDylibs.back(), std::move(M));
211
212     return std::prev(LogicalDylibs.end());
213   }
214
215   /// @brief Remove the module represented by the given handle.
216   ///
217   ///   This will remove all modules in the layers below that were derived from
218   /// the module represented by H.
219   void removeModuleSet(ModuleSetHandleT H) {
220     LogicalDylibs.erase(H);
221   }
222
223   /// @brief Search for the given named symbol.
224   /// @param Name The name of the symbol to search for.
225   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
226   /// @return A handle for the given named symbol, if it exists.
227   JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
228     for (auto LDI = LogicalDylibs.begin(), LDE = LogicalDylibs.end();
229          LDI != LDE; ++LDI)
230       if (auto Symbol = findSymbolIn(LDI, Name, ExportedSymbolsOnly))
231         return Symbol;
232     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
233   }
234
235   /// @brief Get the address of a symbol provided by this layer, or some layer
236   ///        below this one.
237   JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
238                          bool ExportedSymbolsOnly) {
239     return H->findSymbol(Name, ExportedSymbolsOnly);
240   }
241
242 private:
243
244   template <typename ModulePtrT>
245   void addLogicalModule(CODLogicalDylib &LD, ModulePtrT SrcMPtr) {
246
247     // Bump the linkage and rename any anonymous/privote members in SrcM to
248     // ensure that everything will resolve properly after we partition SrcM.
249     makeAllSymbolsExternallyAccessible(*SrcMPtr);
250
251     // Create a logical module handle for SrcM within the logical dylib.
252     auto LMH = LD.createLogicalModule();
253     auto &LMResources =  LD.getLogicalModuleResources(LMH);
254
255     LMResources.SourceModule = wrapOwnership<Module>(std::move(SrcMPtr));
256
257     Module &SrcM = LMResources.SourceModule->getResource();
258
259     // Create the GlobalValues module.
260     const DataLayout &DL = SrcM.getDataLayout();
261     auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
262                                           SrcM.getContext());
263     GVsM->setDataLayout(DL);
264
265     // Create function stubs.
266     ValueToValueMapTy VMap;
267     {
268       typename IndirectStubsMgrT::StubInitsMap StubInits;
269       for (auto &F : SrcM) {
270         // Skip declarations.
271         if (F.isDeclaration())
272           continue;
273
274         // Record all functions defined by this module.
275         if (CloneStubsIntoPartitions)
276           LMResources.StubsToClone.insert(&F);
277
278         // Create a callback, associate it with the stub for the function,
279         // and set the compile action to compile the partition containing the
280         // function.
281         auto CCInfo = CompileCallbackMgr.getCompileCallback();
282         StubInits[mangle(F.getName(), DL)] =
283           std::make_pair(CCInfo.getAddress(),
284                          JITSymbolBase::flagsFromGlobalValue(F));
285         CCInfo.setCompileAction([this, &LD, LMH, &F]() {
286           return this->extractAndCompile(LD, LMH, F);
287         });
288       }
289
290       LMResources.StubsMgr = CreateIndirectStubsManager();
291       auto EC = LMResources.StubsMgr->createStubs(StubInits);
292       (void)EC;
293       // FIXME: This should be propagated back to the user. Stub creation may
294       //        fail for remote JITs.
295       assert(!EC && "Error generating stubs");
296     }
297
298     // Clone global variable decls.
299     for (auto &GV : SrcM.globals())
300       if (!GV.isDeclaration() && !VMap.count(&GV))
301         cloneGlobalVariableDecl(*GVsM, GV, &VMap);
302
303     // And the aliases.
304     for (auto &A : SrcM.aliases())
305       if (!VMap.count(&A))
306         cloneGlobalAliasDecl(*GVsM, A, VMap);
307
308     // Now we need to clone the GV and alias initializers.
309
310     // Initializers may refer to functions declared (but not defined) in this
311     // module. Build a materializer to clone decls on demand.
312     auto Materializer = createLambdaMaterializer(
313       [this, &GVsM, &LMResources](Value *V) -> Value* {
314         if (auto *F = dyn_cast<Function>(V)) {
315           // Decls in the original module just get cloned.
316           if (F->isDeclaration())
317             return cloneFunctionDecl(*GVsM, *F);
318
319           // Definitions in the original module (which we have emitted stubs
320           // for at this point) get turned into a constant alias to the stub
321           // instead.
322           const DataLayout &DL = GVsM->getDataLayout();
323           std::string FName = mangle(F->getName(), DL);
324           auto StubSym = LMResources.StubsMgr->findStub(FName, false);
325           unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
326           ConstantInt *StubAddr =
327             ConstantInt::get(GVsM->getContext(),
328                              APInt(PtrBitWidth, StubSym.getAddress()));
329           Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
330                                                  StubAddr, F->getType());
331           return GlobalAlias::create(F->getFunctionType(),
332                                      F->getType()->getAddressSpace(),
333                                      F->getLinkage(), F->getName(),
334                                      Init, GVsM.get());
335         }
336         // else....
337         return nullptr;
338       });
339
340     // Clone the global variable initializers.
341     for (auto &GV : SrcM.globals())
342       if (!GV.isDeclaration())
343         moveGlobalVariableInitializer(GV, VMap, &Materializer);
344
345     // Clone the global alias initializers.
346     for (auto &A : SrcM.aliases()) {
347       auto *NewA = cast<GlobalAlias>(VMap[&A]);
348       assert(NewA && "Alias not cloned?");
349       Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
350                              &Materializer);
351       NewA->setAliasee(cast<Constant>(Init));
352     }
353
354     // Build a resolver for the globals module and add it to the base layer.
355     auto GVsResolver = createLambdaResolver(
356         [&LD, LMH](const std::string &Name) {
357           auto &LMResources = LD.getLogicalModuleResources(LMH);
358           if (auto Sym = LMResources.StubsMgr->findStub(Name, false))
359             return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
360           return LD.getDylibResources().ExternalSymbolResolver(Name);
361         },
362         [](const std::string &Name) {
363           return RuntimeDyld::SymbolInfo(nullptr);
364         });
365
366     auto GVsH =
367       LD.getDylibResources().ModuleAdder(BaseLayer, std::move(GVsM),
368                                          std::move(GVsResolver));
369     LD.addToLogicalModule(LMH, GVsH);
370   }
371
372   static std::string mangle(StringRef Name, const DataLayout &DL) {
373     std::string MangledName;
374     {
375       raw_string_ostream MangledNameStream(MangledName);
376       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
377     }
378     return MangledName;
379   }
380
381   TargetAddress extractAndCompile(CODLogicalDylib &LD,
382                                   LogicalModuleHandle LMH,
383                                   Function &F) {
384     auto &LMResources = LD.getLogicalModuleResources(LMH);
385     Module &SrcM = LMResources.SourceModule->getResource();
386
387     // If F is a declaration we must already have compiled it.
388     if (F.isDeclaration())
389       return 0;
390
391     // Grab the name of the function being called here.
392     std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
393
394     auto Part = Partition(F);
395     auto PartH = emitPartition(LD, LMH, Part);
396
397     TargetAddress CalledAddr = 0;
398     for (auto *SubF : Part) {
399       std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
400       auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
401       assert(FnBodySym && "Couldn't find function body.");
402
403       TargetAddress FnBodyAddr = FnBodySym.getAddress();
404
405       // If this is the function we're calling record the address so we can
406       // return it from this function.
407       if (SubF == &F)
408         CalledAddr = FnBodyAddr;
409
410       // Update the function body pointer for the stub.
411       if (auto EC = LMResources.StubsMgr->updatePointer(FnName, FnBodyAddr))
412         return 0;
413     }
414
415     return CalledAddr;
416   }
417
418   template <typename PartitionT>
419   BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
420                                           LogicalModuleHandle LMH,
421                                           const PartitionT &Part) {
422     auto &LMResources = LD.getLogicalModuleResources(LMH);
423     Module &SrcM = LMResources.SourceModule->getResource();
424
425     // Create the module.
426     std::string NewName = SrcM.getName();
427     for (auto *F : Part) {
428       NewName += ".";
429       NewName += F->getName();
430     }
431
432     auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
433     M->setDataLayout(SrcM.getDataLayout());
434     ValueToValueMapTy VMap;
435
436     auto Materializer = createLambdaMaterializer([this, &LMResources, &M,
437                                                   &VMap](Value *V) -> Value * {
438       if (auto *GV = dyn_cast<GlobalVariable>(V))
439         return cloneGlobalVariableDecl(*M, *GV);
440
441       if (auto *F = dyn_cast<Function>(V)) {
442         // Check whether we want to clone an available_externally definition.
443         if (!LMResources.StubsToClone.count(F))
444           return cloneFunctionDecl(*M, *F);
445
446         // Ok - we want an inlinable stub. For that to work we need a decl
447         // for the stub pointer.
448         auto *StubPtr = createImplPointer(*F->getType(), *M,
449                                           F->getName() + "$stub_ptr", nullptr);
450         auto *ClonedF = cloneFunctionDecl(*M, *F);
451         makeStub(*ClonedF, *StubPtr);
452         ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
453         ClonedF->addFnAttr(Attribute::AlwaysInline);
454         return ClonedF;
455       }
456
457       if (auto *A = dyn_cast<GlobalAlias>(V)) {
458         auto *Ty = A->getValueType();
459         if (Ty->isFunctionTy())
460           return Function::Create(cast<FunctionType>(Ty),
461                                   GlobalValue::ExternalLinkage, A->getName(),
462                                   M.get());
463
464         return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
465                                   nullptr, A->getName(), nullptr,
466                                   GlobalValue::NotThreadLocal,
467                                   A->getType()->getAddressSpace());
468       }
469
470       return nullptr;
471     });
472
473     // Create decls in the new module.
474     for (auto *F : Part)
475       cloneFunctionDecl(*M, *F, &VMap);
476
477     // Move the function bodies.
478     for (auto *F : Part)
479       moveFunctionBody(*F, VMap, &Materializer);
480
481     // Create memory manager and symbol resolver.
482     auto Resolver = createLambdaResolver(
483         [this, &LD, LMH](const std::string &Name) {
484           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
485             return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
486                                            Symbol.getFlags());
487           return LD.getDylibResources().ExternalSymbolResolver(Name);
488         },
489         [this, &LD, LMH](const std::string &Name) {
490           if (auto Symbol = LD.findSymbolInternally(LMH, Name))
491             return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
492                                            Symbol.getFlags());
493           return RuntimeDyld::SymbolInfo(nullptr);
494         });
495
496     return LD.getDylibResources().ModuleAdder(BaseLayer, std::move(M),
497                                               std::move(Resolver));
498   }
499
500   BaseLayerT &BaseLayer;
501   PartitioningFtor Partition;
502   CompileCallbackMgrT &CompileCallbackMgr;
503   IndirectStubsManagerBuilderT CreateIndirectStubsManager;
504
505   LogicalDylibList LogicalDylibs;
506   bool CloneStubsIntoPartitions;
507 };
508
509 } // End namespace orc.
510 } // End namespace llvm.
511
512 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H