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