LLVM  8.0.1
CompileOnDemandLayer.h
Go to the documentation of this file.
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 "llvm/ADT/APInt.h"
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/Twine.h"
31 #include "llvm/IR/Attributes.h"
32 #include "llvm/IR/Constant.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/DataLayout.h"
35 #include "llvm/IR/Function.h"
36 #include "llvm/IR/GlobalAlias.h"
37 #include "llvm/IR/GlobalValue.h"
38 #include "llvm/IR/GlobalVariable.h"
39 #include "llvm/IR/Instruction.h"
40 #include "llvm/IR/Mangler.h"
41 #include "llvm/IR/Module.h"
42 #include "llvm/IR/Type.h"
43 #include "llvm/Support/Casting.h"
46 #include <algorithm>
47 #include <cassert>
48 #include <functional>
49 #include <iterator>
50 #include <list>
51 #include <memory>
52 #include <set>
53 #include <string>
54 #include <utility>
55 #include <vector>
56 
57 namespace llvm {
58 
59 class Value;
60 
61 namespace orc {
62 
63 class ExtractingIRMaterializationUnit;
64 
65 class CompileOnDemandLayer : public IRLayer {
67 
68 public:
69  /// Builder for IndirectStubsManagers.
71  std::function<std::unique_ptr<IndirectStubsManager>()>;
72 
73  using GlobalValueSet = std::set<const GlobalValue *>;
74 
75  /// Partitioning function.
76  using PartitionFunction =
77  std::function<Optional<GlobalValueSet>(GlobalValueSet Requested)>;
78 
79  /// Off-the-shelf partitioning which compiles all requested symbols (usually
80  /// a single function at a time).
82 
83  /// Off-the-shelf partitioning which compiles whole modules whenever any
84  /// symbol in them is requested.
86 
87  /// Construct a CompileOnDemandLayer.
89  LazyCallThroughManager &LCTMgr,
90  IndirectStubsManagerBuilder BuildIndirectStubsManager);
91 
92  /// Sets the partition function.
94 
95  /// Emits the given module. This should not be called by clients: it will be
96  /// called by the JIT when a definition added via the add method is requested.
98 
99 private:
100  struct PerDylibResources {
101  public:
102  PerDylibResources(JITDylib &ImplD,
103  std::unique_ptr<IndirectStubsManager> ISMgr)
104  : ImplD(ImplD), ISMgr(std::move(ISMgr)) {}
105  JITDylib &getImplDylib() { return ImplD; }
106  IndirectStubsManager &getISManager() { return *ISMgr; }
107 
108  private:
109  JITDylib &ImplD;
110  std::unique_ptr<IndirectStubsManager> ISMgr;
111  };
112 
113  using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;
114 
115  PerDylibResources &getPerDylibResources(JITDylib &TargetD);
116 
117  void cleanUpModule(Module &M);
118 
119  void expandPartition(GlobalValueSet &Partition);
120 
121  void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
123 
124  mutable std::mutex CODLayerMutex;
125 
126  IRLayer &BaseLayer;
127  LazyCallThroughManager &LCTMgr;
128  IndirectStubsManagerBuilder BuildIndirectStubsManager;
129  PerDylibResourcesMap DylibResources;
131  SymbolLinkagePromoter PromoteSymbols;
132 };
133 
134 /// Compile-on-demand layer.
135 ///
136 /// When a module is added to this layer a stub is created for each of its
137 /// function definitions. The stubs and other global values are immediately
138 /// added to the layer below. When a stub is called it triggers the extraction
139 /// of the function body from the original module. The extracted body is then
140 /// compiled and executed.
141 template <typename BaseLayerT,
142  typename CompileCallbackMgrT = JITCompileCallbackManager,
143  typename IndirectStubsMgrT = IndirectStubsManager>
145 private:
146  template <typename MaterializerFtor>
147  class LambdaMaterializer final : public ValueMaterializer {
148  public:
149  LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
150 
151  Value *materialize(Value *V) final { return M(V); }
152 
153  private:
154  MaterializerFtor M;
155  };
156 
157  template <typename MaterializerFtor>
158  LambdaMaterializer<MaterializerFtor>
159  createLambdaMaterializer(MaterializerFtor M) {
160  return LambdaMaterializer<MaterializerFtor>(std::move(M));
161  }
162 
163  // Provide type-erasure for the Modules and MemoryManagers.
164  template <typename ResourceT>
165  class ResourceOwner {
166  public:
167  ResourceOwner() = default;
168  ResourceOwner(const ResourceOwner &) = delete;
169  ResourceOwner &operator=(const ResourceOwner &) = delete;
170  virtual ~ResourceOwner() = default;
171 
172  virtual ResourceT& getResource() const = 0;
173  };
174 
175  template <typename ResourceT, typename ResourcePtrT>
176  class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
177  public:
178  ResourceOwnerImpl(ResourcePtrT ResourcePtr)
179  : ResourcePtr(std::move(ResourcePtr)) {}
180 
181  ResourceT& getResource() const override { return *ResourcePtr; }
182 
183  private:
184  ResourcePtrT ResourcePtr;
185  };
186 
187  template <typename ResourceT, typename ResourcePtrT>
188  std::unique_ptr<ResourceOwner<ResourceT>>
189  wrapOwnership(ResourcePtrT ResourcePtr) {
190  using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
191  return llvm::make_unique<RO>(std::move(ResourcePtr));
192  }
193 
194  struct LogicalDylib {
196  std::unique_ptr<Module> SourceMod;
197  std::set<Function*> StubsToClone;
198  };
199 
200  using SourceModulesList = std::vector<SourceModuleEntry>;
201  using SourceModuleHandle = typename SourceModulesList::size_type;
202 
203  LogicalDylib() = default;
204 
205  LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
206  std::unique_ptr<IndirectStubsMgrT> StubsMgr)
207  : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
208  StubsMgr(std::move(StubsMgr)) {}
209 
210  SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
211  SourceModuleHandle H = SourceModules.size();
212  SourceModules.push_back(SourceModuleEntry());
213  SourceModules.back().SourceMod = std::move(M);
214  return H;
215  }
216 
217  Module& getSourceModule(SourceModuleHandle H) {
218  return *SourceModules[H].SourceMod;
219  }
220 
221  std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
222  return SourceModules[H].StubsToClone;
223  }
224 
225  JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
226  bool ExportedSymbolsOnly) {
227  if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
228  return Sym;
229  for (auto BLK : BaseLayerVModuleKeys)
230  if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
231  return Sym;
232  else if (auto Err = Sym.takeError())
233  return std::move(Err);
234  return nullptr;
235  }
236 
237  Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
238  for (auto &BLK : BaseLayerVModuleKeys)
239  if (auto Err = BaseLayer.removeModule(BLK))
240  return Err;
241  return Error::success();
242  }
243 
244  VModuleKey K;
245  std::shared_ptr<SymbolResolver> BackingResolver;
246  std::unique_ptr<IndirectStubsMgrT> StubsMgr;
247  SymbolLinkagePromoter PromoteSymbols;
248  SourceModulesList SourceModules;
249  std::vector<VModuleKey> BaseLayerVModuleKeys;
250  };
251 
252 public:
253 
254  /// Module partitioning functor.
255  using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
256 
257  /// Builder for IndirectStubsManagers.
259  std::function<std::unique_ptr<IndirectStubsMgrT>()>;
260 
261  using SymbolResolverGetter =
262  std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
263 
264  using SymbolResolverSetter =
265  std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
266 
267  /// Construct a compile-on-demand layer instance.
268  LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
269  SymbolResolverGetter GetSymbolResolver,
270  SymbolResolverSetter SetSymbolResolver,
271  PartitioningFtor Partition,
272  CompileCallbackMgrT &CallbackMgr,
273  IndirectStubsManagerBuilderT CreateIndirectStubsManager,
274  bool CloneStubsIntoPartitions = true)
275  : ES(ES), BaseLayer(BaseLayer),
276  GetSymbolResolver(std::move(GetSymbolResolver)),
277  SetSymbolResolver(std::move(SetSymbolResolver)),
278  Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
279  CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
280  CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
281 
283  // FIXME: Report error on log.
284  while (!LogicalDylibs.empty())
285  consumeError(removeModule(LogicalDylibs.begin()->first));
286  }
287 
288  /// Add a module to the compile-on-demand layer.
289  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
290 
291  assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
292  auto I = LogicalDylibs.insert(
293  LogicalDylibs.end(),
294  std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
295  CreateIndirectStubsManager())));
296 
297  return addLogicalModule(I->second, std::move(M));
298  }
299 
300  /// Add extra modules to an existing logical module.
301  Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
302  return addLogicalModule(LogicalDylibs[K], std::move(M));
303  }
304 
305  /// Remove the module represented by the given key.
306  ///
307  /// This will remove all modules in the layers below that were derived from
308  /// the module represented by K.
310  auto I = LogicalDylibs.find(K);
311  assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
312  auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
313  LogicalDylibs.erase(I);
314  return Err;
315  }
316 
317  /// Search for the given named symbol.
318  /// @param Name The name of the symbol to search for.
319  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
320  /// @return A handle for the given named symbol, if it exists.
321  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
322  for (auto &KV : LogicalDylibs) {
323  if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
324  return Sym;
325  if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
326  return Sym;
327  else if (auto Err = Sym.takeError())
328  return std::move(Err);
329  }
330  return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
331  }
332 
333  /// Get the address of a symbol provided by this layer, or some layer
334  /// below this one.
335  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
336  bool ExportedSymbolsOnly) {
337  assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
338  return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
339  }
340 
341  /// Update the stub for the given function to point at FnBodyAddr.
342  /// This can be used to support re-optimization.
343  /// @return true if the function exists and the stub is updated, false
344  /// otherwise.
345  //
346  // FIXME: We should track and free associated resources (unused compile
347  // callbacks, uncompiled IR, and no-longer-needed/reachable function
348  // implementations).
349  Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
350  //Find out which logical dylib contains our symbol
351  auto LDI = LogicalDylibs.begin();
352  for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
353  if (auto LMResources =
354  LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
355  Module &SrcM = LMResources->SourceModule->getResource();
356  std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
357  if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
358  FnBodyAddr))
359  return Err;
360  return Error::success();
361  }
362  }
363  return make_error<JITSymbolNotFound>(FuncName);
364  }
365 
366 private:
367  Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
368 
369  // Rename anonymous globals and promote linkage to ensure that everything
370  // will resolve properly after we partition SrcM.
371  LD.PromoteSymbols(*SrcMPtr);
372 
373  // Create a logical module handle for SrcM within the logical dylib.
374  Module &SrcM = *SrcMPtr;
375  auto LMId = LD.addSourceModule(std::move(SrcMPtr));
376 
377  // Create stub functions.
378  const DataLayout &DL = SrcM.getDataLayout();
379  {
380  typename IndirectStubsMgrT::StubInitsMap StubInits;
381  for (auto &F : SrcM) {
382  // Skip declarations.
383  if (F.isDeclaration())
384  continue;
385 
386  // Skip weak functions for which we already have definitions.
387  auto MangledName = mangle(F.getName(), DL);
388  if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
389  if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
390  continue;
391  else if (auto Err = Sym.takeError())
392  return std::move(Err);
393  }
394 
395  // Record all functions defined by this module.
396  if (CloneStubsIntoPartitions)
397  LD.getStubsToClone(LMId).insert(&F);
398 
399  // Create a callback, associate it with the stub for the function,
400  // and set the compile action to compile the partition containing the
401  // function.
402  auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
403  if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
404  return *FnImplAddrOrErr;
405  else {
406  // FIXME: Report error, return to 'abort' or something similar.
407  consumeError(FnImplAddrOrErr.takeError());
408  return 0;
409  }
410  };
411  if (auto CCAddr =
412  CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
413  StubInits[MangledName] =
414  std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
415  else
416  return CCAddr.takeError();
417  }
418 
419  if (auto Err = LD.StubsMgr->createStubs(StubInits))
420  return Err;
421  }
422 
423  // If this module doesn't contain any globals, aliases, or module flags then
424  // we can bail out early and avoid the overhead of creating and managing an
425  // empty globals module.
426  if (SrcM.global_empty() && SrcM.alias_empty() &&
427  !SrcM.getModuleFlagsMetadata())
428  return Error::success();
429 
430  // Create the GlobalValues module.
431  auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
432  SrcM.getContext());
433  GVsM->setDataLayout(DL);
434 
435  ValueToValueMapTy VMap;
436 
437  // Clone global variable decls.
438  for (auto &GV : SrcM.globals())
439  if (!GV.isDeclaration() && !VMap.count(&GV))
440  cloneGlobalVariableDecl(*GVsM, GV, &VMap);
441 
442  // And the aliases.
443  for (auto &A : SrcM.aliases())
444  if (!VMap.count(&A))
445  cloneGlobalAliasDecl(*GVsM, A, VMap);
446 
447  // Clone the module flags.
448  cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
449 
450  // Now we need to clone the GV and alias initializers.
451 
452  // Initializers may refer to functions declared (but not defined) in this
453  // module. Build a materializer to clone decls on demand.
454  auto Materializer = createLambdaMaterializer(
455  [&LD, &GVsM](Value *V) -> Value* {
456  if (auto *F = dyn_cast<Function>(V)) {
457  // Decls in the original module just get cloned.
458  if (F->isDeclaration())
459  return cloneFunctionDecl(*GVsM, *F);
460 
461  // Definitions in the original module (which we have emitted stubs
462  // for at this point) get turned into a constant alias to the stub
463  // instead.
464  const DataLayout &DL = GVsM->getDataLayout();
465  std::string FName = mangle(F->getName(), DL);
466  unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
467  JITTargetAddress StubAddr =
468  LD.StubsMgr->findStub(FName, false).getAddress();
469 
470  ConstantInt *StubAddrCI =
471  ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
472  Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
473  StubAddrCI, F->getType());
474  return GlobalAlias::create(F->getFunctionType(),
475  F->getType()->getAddressSpace(),
476  F->getLinkage(), F->getName(),
477  Init, GVsM.get());
478  }
479  // else....
480  return nullptr;
481  });
482 
483  // Clone the global variable initializers.
484  for (auto &GV : SrcM.globals())
485  if (!GV.isDeclaration())
486  moveGlobalVariableInitializer(GV, VMap, &Materializer);
487 
488  // Clone the global alias initializers.
489  for (auto &A : SrcM.aliases()) {
490  auto *NewA = cast<GlobalAlias>(VMap[&A]);
491  assert(NewA && "Alias not cloned?");
492  Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
493  &Materializer);
494  NewA->setAliasee(cast<Constant>(Init));
495  }
496 
497  // Build a resolver for the globals module and add it to the base layer.
498  auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
499  if (auto Sym = LD.StubsMgr->findStub(Name, false))
500  return Sym;
501 
502  if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
503  return Sym;
504  else if (auto Err = Sym.takeError())
505  return std::move(Err);
506 
507  return nullptr;
508  };
509 
510  auto GVsResolver = createSymbolResolver(
511  [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
512  auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
513 
514  if (!RS) {
516  RS.takeError(), errs(),
517  "CODLayer/GVsResolver responsibility set lookup failed: ");
518  return SymbolNameSet();
519  }
520 
521  if (RS->size() == Symbols.size())
522  return *RS;
523 
524  SymbolNameSet NotFoundViaLegacyLookup;
525  for (auto &S : Symbols)
526  if (!RS->count(S))
527  NotFoundViaLegacyLookup.insert(S);
528  auto RS2 =
529  LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
530 
531  for (auto &S : RS2)
532  (*RS).insert(S);
533 
534  return *RS;
535  },
536  [this, &LD,
537  LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
538  SymbolNameSet Symbols) {
539  auto NotFoundViaLegacyLookup =
540  lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
541  return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
542  });
543 
544  SetSymbolResolver(LD.K, std::move(GVsResolver));
545 
546  if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
547  return Err;
548 
549  LD.BaseLayerVModuleKeys.push_back(LD.K);
550 
551  return Error::success();
552  }
553 
554  static std::string mangle(StringRef Name, const DataLayout &DL) {
555  std::string MangledName;
556  {
557  raw_string_ostream MangledNameStream(MangledName);
558  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
559  }
560  return MangledName;
561  }
562 
564  extractAndCompile(LogicalDylib &LD,
565  typename LogicalDylib::SourceModuleHandle LMId,
566  Function &F) {
567  Module &SrcM = LD.getSourceModule(LMId);
568 
569  // If F is a declaration we must already have compiled it.
570  if (F.isDeclaration())
571  return 0;
572 
573  // Grab the name of the function being called here.
574  std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
575 
576  JITTargetAddress CalledAddr = 0;
577  auto Part = Partition(F);
578  if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
579  auto &PartKey = *PartKeyOrErr;
580  for (auto *SubF : Part) {
581  std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
582  if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
583  if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
584  JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
585 
586  // If this is the function we're calling record the address so we can
587  // return it from this function.
588  if (SubF == &F)
589  CalledAddr = FnBodyAddr;
590 
591  // Update the function body pointer for the stub.
592  if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
593  return 0;
594 
595  } else
596  return FnBodyAddrOrErr.takeError();
597  } else if (auto Err = FnBodySym.takeError())
598  return std::move(Err);
599  else
600  llvm_unreachable("Function not emitted for partition");
601  }
602 
603  LD.BaseLayerVModuleKeys.push_back(PartKey);
604  } else
605  return PartKeyOrErr.takeError();
606 
607  return CalledAddr;
608  }
609 
610  template <typename PartitionT>
612  emitPartition(LogicalDylib &LD,
613  typename LogicalDylib::SourceModuleHandle LMId,
614  const PartitionT &Part) {
615  Module &SrcM = LD.getSourceModule(LMId);
616 
617  // Create the module.
618  std::string NewName = SrcM.getName();
619  for (auto *F : Part) {
620  NewName += ".";
621  NewName += F->getName();
622  }
623 
624  auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
625  M->setDataLayout(SrcM.getDataLayout());
626  ValueToValueMapTy VMap;
627 
628  auto Materializer = createLambdaMaterializer([&LD, &LMId,
629  &M](Value *V) -> Value * {
630  if (auto *GV = dyn_cast<GlobalVariable>(V))
631  return cloneGlobalVariableDecl(*M, *GV);
632 
633  if (auto *F = dyn_cast<Function>(V)) {
634  // Check whether we want to clone an available_externally definition.
635  if (!LD.getStubsToClone(LMId).count(F))
636  return cloneFunctionDecl(*M, *F);
637 
638  // Ok - we want an inlinable stub. For that to work we need a decl
639  // for the stub pointer.
640  auto *StubPtr = createImplPointer(*F->getType(), *M,
641  F->getName() + "$stub_ptr", nullptr);
642  auto *ClonedF = cloneFunctionDecl(*M, *F);
643  makeStub(*ClonedF, *StubPtr);
644  ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
645  ClonedF->addFnAttr(Attribute::AlwaysInline);
646  return ClonedF;
647  }
648 
649  if (auto *A = dyn_cast<GlobalAlias>(V)) {
650  auto *Ty = A->getValueType();
651  if (Ty->isFunctionTy())
652  return Function::Create(cast<FunctionType>(Ty),
653  GlobalValue::ExternalLinkage, A->getName(),
654  M.get());
655 
656  return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
657  nullptr, A->getName(), nullptr,
659  A->getType()->getAddressSpace());
660  }
661 
662  return nullptr;
663  });
664 
665  // Create decls in the new module.
666  for (auto *F : Part)
667  cloneFunctionDecl(*M, *F, &VMap);
668 
669  // Move the function bodies.
670  for (auto *F : Part)
671  moveFunctionBody(*F, VMap, &Materializer);
672 
673  auto K = ES.allocateVModule();
674 
675  auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
676  return LD.findSymbol(BaseLayer, Name, false);
677  };
678 
679  // Create memory manager and symbol resolver.
681  [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
682  auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
683  if (!RS) {
685  RS.takeError(), errs(),
686  "CODLayer/SubResolver responsibility set lookup failed: ");
687  return SymbolNameSet();
688  }
689 
690  if (RS->size() == Symbols.size())
691  return *RS;
692 
693  SymbolNameSet NotFoundViaLegacyLookup;
694  for (auto &S : Symbols)
695  if (!RS->count(S))
696  NotFoundViaLegacyLookup.insert(S);
697 
698  auto RS2 =
699  LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
700 
701  for (auto &S : RS2)
702  (*RS).insert(S);
703 
704  return *RS;
705  },
706  [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
707  SymbolNameSet Symbols) {
708  auto NotFoundViaLegacyLookup =
709  lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
710  return LD.BackingResolver->lookup(Q,
711  std::move(NotFoundViaLegacyLookup));
712  });
713  SetSymbolResolver(K, std::move(Resolver));
714 
715  if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
716  return std::move(Err);
717 
718  return K;
719  }
720 
721  ExecutionSession &ES;
722  BaseLayerT &BaseLayer;
723  SymbolResolverGetter GetSymbolResolver;
724  SymbolResolverSetter SetSymbolResolver;
725  PartitioningFtor Partition;
726  CompileCallbackMgrT &CompileCallbackMgr;
727  IndirectStubsManagerBuilderT CreateIndirectStubsManager;
728 
729  std::map<VModuleKey, LogicalDylib> LogicalDylibs;
730  bool CloneStubsIntoPartitions;
731 };
732 
733 } // end namespace orc
734 
735 } // end namespace llvm
736 
737 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Base class for managing collections of named indirect stubs.
Error removeModule(VModuleKey K)
Remove the module represented by the given key.
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Definition: JITSymbol.cpp:22
Represents a symbol in the JIT.
Definition: JITSymbol.h:238
This class represents lattice values for constants.
Definition: AllocatorList.h:24
GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
static Optional< GlobalValueSet > compileRequested(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles all requested symbols (usually a single function at a time)...
void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap)
Clone module flags metadata into the destination module.
Available for inspection, not emission.
Definition: GlobalValue.h:50
bool global_empty() const
Definition: Module.h:582
Externally visible function.
Definition: GlobalValue.h:49
StringRef getName() const
Get a short "name" for the module.
Definition: Module.h:227
F(f)
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
Promotes private symbols to global hidden, and renames to prevent clashes with other promoted symbols...
std::function< std::unique_ptr< IndirectStubsManager >()> IndirectStubsManagerBuilder
Builder for IndirectStubsManagers.
Target-independent base class for compile callback management.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Definition: BitVector.h:938
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:371
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
Definition: DataLayout.cpp:646
std::unique_ptr< LambdaSymbolResolver< typename std::remove_cv< typename std::remove_reference< GetResponsibilitySetFn >::type >::type, typename std::remove_cv< typename std::remove_reference< LookupFn >::type >::type > > createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet, LookupFn &&Lookup)
Creates a SymbolResolver implementation from the pair of supplied function objects.
Definition: Legacy.h:81
GlobalVariable * createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer)
Create a function pointer with the given type, name, and initializer in the given Module...
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
std::function< Optional< GlobalValueSet >(GlobalValueSet Requested)> PartitionFunction
Partitioning function.
This file contains the simple types necessary to represent the attributes associated with functions a...
void moveGlobalVariableInitializer(GlobalVariable &OrigGV, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, GlobalVariable *NewGV=nullptr)
Move global variable GV from its parent module to cloned global declaration in a different module...
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Layer.h:69
JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, bool ExportedSymbolsOnly)
Get the address of a symbol provided by this layer, or some layer below this one. ...
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
This file implements a class to represent arbitrary precision integral constant values and operations...
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:155
Error addModule(VModuleKey K, std::unique_ptr< Module > M)
Add a module to the compile-on-demand layer.
Expected< SymbolNameSet > getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols, FindSymbolFn FindSymbol)
Use the given legacy-style FindSymbol function (i.e.
Definition: Legacy.h:118
Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr)
Update the stub for the given function to point at FnBodyAddr.
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:41
std::function< void(VModuleKey K, std::shared_ptr< SymbolResolver > R)> SymbolResolverSetter
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
bool alias_empty() const
Definition: Module.h:622
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
Definition: Core.h:44
This is a class that can be implemented by clients to materialize Values on demand.
Definition: ValueMapper.h:51
void getModuleFlagsMetadata(SmallVectorImpl< ModuleFlagEntry > &Flags) const
Returns the module flags in the provided vector.
Definition: Module.cpp:292
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:136
This is an important base class in LLVM.
Definition: Constant.h:42
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define H(x, y, z)
Definition: MD5.cpp:57
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:1774
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:188
Error addExtraModule(VModuleKey K, std::unique_ptr< Module > M)
Add extra modules to an existing logical module.
SymbolNameSet lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, const SymbolNameSet &Symbols, FindSymbolFn FindSymbol)
Use the given legacy-style FindSymbol function (i.e.
Definition: Legacy.h:144
std::function< std::shared_ptr< SymbolResolver >(VModuleKey K)> SymbolResolverGetter
An LLVM Module together with a shared ThreadSafeContext.
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:982
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:62
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Look up or compute a value in the value map.
Definition: ValueMapper.h:206
Interface for layers that accept LLVM IR.
Definition: Layer.h:26
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
Module.h This file contains the declarations for the Module class.
size_type size() const
Definition: DenseSet.h:76
static Optional< GlobalValueSet > compileWholeModule(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles whole modules whenever any symbol in them is requested...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:622
An ExecutionSession represents a running JIT program.
Definition: Core.h:697
Class for arbitrary precision integers.
Definition: APInt.h:70
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition: Constants.cpp:1530
CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr, IndirectStubsManagerBuilder BuildIndirectStubsManager)
Construct a CompileOnDemandLayer.
std::function< std::set< Function * >(Function &)> PartitioningFtor
Module partitioning functor.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
void setPartitionFunction(PartitionFunction Partition)
Sets the partition function.
#define I(x, y, z)
Definition: MD5.cpp:58
static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly)
Search for the given named symbol.
LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver, SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, CompileCallbackMgrT &CallbackMgr, IndirectStubsManagerBuilderT CreateIndirectStubsManager, bool CloneStubsIntoPartitions=true)
Construct a compile-on-demand layer instance.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:206
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: ValueMap.h:158
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
LLVM Value Representation.
Definition: Value.h:73
std::function< std::unique_ptr< IndirectStubsMgrT >()> IndirectStubsManagerBuilderT
Builder for IndirectStubsManagers.
Manages a set of &#39;lazy call-through&#39; trampolines.
Definition: LazyReexports.h:37
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable&#39;s name.
Definition: Mangler.cpp:112
iterator_range< global_iterator > globals()
Definition: Module.h:584
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override
Emits the given module.
void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, ValueMaterializer *Materializer=nullptr, Function *NewF=nullptr)
Move the body of function &#39;F&#39; to a cloned function declaration in a different module (See related clo...
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:423
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:274
std::set< const GlobalValue * > GlobalValueSet
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:496
iterator_range< alias_iterator > aliases()
Definition: Module.h:624