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