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