LLVM  14.0.0git
ObjectLinkingLayer.cpp
Go to the documentation of this file.
1 //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===//
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 
10 #include "llvm/ADT/Optional.h"
14 #include <string>
15 #include <vector>
16 
17 #define DEBUG_TYPE "orc"
18 
19 using namespace llvm;
20 using namespace llvm::jitlink;
21 using namespace llvm::orc;
22 
23 namespace {
24 
25 class LinkGraphMaterializationUnit : public MaterializationUnit {
26 private:
27  struct LinkGraphInterface {
29  SymbolStringPtr InitSymbol;
30  };
31 
32 public:
33  static std::unique_ptr<LinkGraphMaterializationUnit>
34  Create(ObjectLinkingLayer &ObjLinkingLayer, std::unique_ptr<LinkGraph> G) {
35  auto LGI = scanLinkGraph(ObjLinkingLayer.getExecutionSession(), *G);
36  return std::unique_ptr<LinkGraphMaterializationUnit>(
37  new LinkGraphMaterializationUnit(ObjLinkingLayer, std::move(G),
38  std::move(LGI)));
39  }
40 
41  StringRef getName() const override { return G->getName(); }
42  void materialize(std::unique_ptr<MaterializationResponsibility> MR) override {
43  ObjLinkingLayer.emit(std::move(MR), std::move(G));
44  }
45 
46 private:
47  static LinkGraphInterface scanLinkGraph(ExecutionSession &ES, LinkGraph &G) {
48 
49  LinkGraphInterface LGI;
50 
51  for (auto *Sym : G.defined_symbols()) {
52  // Skip local symbols.
53  if (Sym->getScope() == Scope::Local)
54  continue;
55  assert(Sym->hasName() && "Anonymous non-local symbol?");
56 
57  JITSymbolFlags Flags;
58  if (Sym->getScope() == Scope::Default)
59  Flags |= JITSymbolFlags::Exported;
60 
61  if (Sym->isCallable())
62  Flags |= JITSymbolFlags::Callable;
63 
64  LGI.SymbolFlags[ES.intern(Sym->getName())] = Flags;
65  }
66 
67  if (G.getTargetTriple().isOSBinFormatMachO())
68  if (hasMachOInitSection(G))
69  LGI.InitSymbol = makeInitSymbol(ES, G);
70 
71  return LGI;
72  }
73 
74  static bool hasMachOInitSection(LinkGraph &G) {
75  for (auto &Sec : G.sections())
76  if (Sec.getName() == "__DATA,__obj_selrefs" ||
77  Sec.getName() == "__DATA,__objc_classlist" ||
78  Sec.getName() == "__TEXT,__swift5_protos" ||
79  Sec.getName() == "__TEXT,__swift5_proto" ||
80  Sec.getName() == "__DATA,__mod_init_func")
81  return true;
82  return false;
83  }
84 
85  static SymbolStringPtr makeInitSymbol(ExecutionSession &ES, LinkGraph &G) {
86  std::string InitSymString;
87  raw_string_ostream(InitSymString)
88  << "$." << G.getName() << ".__inits" << Counter++;
89  return ES.intern(InitSymString);
90  }
91 
92  LinkGraphMaterializationUnit(ObjectLinkingLayer &ObjLinkingLayer,
93  std::unique_ptr<LinkGraph> G,
94  LinkGraphInterface LGI)
95  : MaterializationUnit(std::move(LGI.SymbolFlags),
96  std::move(LGI.InitSymbol)),
97  ObjLinkingLayer(ObjLinkingLayer), G(std::move(G)) {}
98 
99  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
100  for (auto *Sym : G->defined_symbols())
101  if (Sym->getName() == *Name) {
102  assert(Sym->getLinkage() == Linkage::Weak &&
103  "Discarding non-weak definition");
104  G->makeExternal(*Sym);
105  break;
106  }
107  }
108 
109  ObjectLinkingLayer &ObjLinkingLayer;
110  std::unique_ptr<LinkGraph> G;
111  static std::atomic<uint64_t> Counter;
112 };
113 
114 std::atomic<uint64_t> LinkGraphMaterializationUnit::Counter{0};
115 
116 } // end anonymous namespace
117 
118 namespace llvm {
119 namespace orc {
120 
122 public:
124  ObjectLinkingLayer &Layer,
125  std::unique_ptr<MaterializationResponsibility> MR,
126  std::unique_ptr<MemoryBuffer> ObjBuffer)
127  : JITLinkContext(&MR->getTargetJITDylib()), Layer(Layer),
128  MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
129 
131  // If there is an object buffer return function then use it to
132  // return ownership of the buffer.
133  if (Layer.ReturnObjectBuffer && ObjBuffer)
134  Layer.ReturnObjectBuffer(std::move(ObjBuffer));
135  }
136 
137  JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
138 
140  for (auto &P : Layer.Plugins)
141  P->notifyMaterializing(*MR, G, *this,
142  ObjBuffer ? ObjBuffer->getMemBufferRef()
143  : MemoryBufferRef());
144  }
145 
146  void notifyFailed(Error Err) override {
147  for (auto &P : Layer.Plugins)
148  Err = joinErrors(std::move(Err), P->notifyFailed(*MR));
149  Layer.getExecutionSession().reportError(std::move(Err));
150  MR->failMaterialization();
151  }
152 
153  void lookup(const LookupMap &Symbols,
154  std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
155 
156  JITDylibSearchOrder LinkOrder;
157  MR->getTargetJITDylib().withLinkOrderDo(
158  [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
159 
160  auto &ES = Layer.getExecutionSession();
161 
162  SymbolLookupSet LookupSet;
163  for (auto &KV : Symbols) {
164  orc::SymbolLookupFlags LookupFlags;
165  switch (KV.second) {
168  break;
171  break;
172  }
173  LookupSet.add(ES.intern(KV.first), LookupFlags);
174  }
175 
176  // OnResolve -- De-intern the symbols and pass the result to the linker.
177  auto OnResolve = [LookupContinuation =
178  std::move(LC)](Expected<SymbolMap> Result) mutable {
179  if (!Result)
180  LookupContinuation->run(Result.takeError());
181  else {
183  for (auto &KV : *Result)
184  LR[*KV.first] = KV.second;
185  LookupContinuation->run(std::move(LR));
186  }
187  };
188 
189  for (auto &KV : InternalNamedSymbolDeps) {
190  SymbolDependenceMap InternalDeps;
191  InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second);
192  MR->addDependencies(KV.first, InternalDeps);
193  }
194 
195  ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet),
196  SymbolState::Resolved, std::move(OnResolve),
197  [this](const SymbolDependenceMap &Deps) {
198  registerDependencies(Deps);
199  });
200  }
201 
203  auto &ES = Layer.getExecutionSession();
204 
205  SymbolFlagsMap ExtraSymbolsToClaim;
206  bool AutoClaim = Layer.AutoClaimObjectSymbols;
207 
208  SymbolMap InternedResult;
209  for (auto *Sym : G.defined_symbols())
210  if (Sym->hasName() && Sym->getScope() != Scope::Local) {
211  auto InternedName = ES.intern(Sym->getName());
212  JITSymbolFlags Flags;
213 
214  if (Sym->isCallable())
215  Flags |= JITSymbolFlags::Callable;
216  if (Sym->getScope() == Scope::Default)
217  Flags |= JITSymbolFlags::Exported;
218 
219  InternedResult[InternedName] =
220  JITEvaluatedSymbol(Sym->getAddress(), Flags);
221  if (AutoClaim && !MR->getSymbols().count(InternedName)) {
222  assert(!ExtraSymbolsToClaim.count(InternedName) &&
223  "Duplicate symbol to claim?");
224  ExtraSymbolsToClaim[InternedName] = Flags;
225  }
226  }
227 
228  for (auto *Sym : G.absolute_symbols())
229  if (Sym->hasName()) {
230  auto InternedName = ES.intern(Sym->getName());
231  JITSymbolFlags Flags;
232  Flags |= JITSymbolFlags::Absolute;
233  if (Sym->isCallable())
234  Flags |= JITSymbolFlags::Callable;
235  if (Sym->getLinkage() == Linkage::Weak)
236  Flags |= JITSymbolFlags::Weak;
237  InternedResult[InternedName] =
238  JITEvaluatedSymbol(Sym->getAddress(), Flags);
239  if (AutoClaim && !MR->getSymbols().count(InternedName)) {
240  assert(!ExtraSymbolsToClaim.count(InternedName) &&
241  "Duplicate symbol to claim?");
242  ExtraSymbolsToClaim[InternedName] = Flags;
243  }
244  }
245 
246  if (!ExtraSymbolsToClaim.empty())
247  if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim))
248  return Err;
249 
250  {
251 
252  // Check that InternedResult matches up with MR->getSymbols().
253  // This guards against faulty transformations / compilers / object caches.
254 
255  // First check that there aren't any missing symbols.
256  size_t NumMaterializationSideEffectsOnlySymbols = 0;
257  SymbolNameVector ExtraSymbols;
258  SymbolNameVector MissingSymbols;
259  for (auto &KV : MR->getSymbols()) {
260 
261  // If this is a materialization-side-effects only symbol then bump
262  // the counter and make sure it's *not* defined, otherwise make
263  // sure that it is defined.
264  if (KV.second.hasMaterializationSideEffectsOnly()) {
265  ++NumMaterializationSideEffectsOnlySymbols;
266  if (InternedResult.count(KV.first))
267  ExtraSymbols.push_back(KV.first);
268  continue;
269  } else if (!InternedResult.count(KV.first))
270  MissingSymbols.push_back(KV.first);
271  }
272 
273  // If there were missing symbols then report the error.
274  if (!MissingSymbols.empty())
275  return make_error<MissingSymbolDefinitions>(G.getName(),
276  std::move(MissingSymbols));
277 
278  // If there are more definitions than expected, add them to the
279  // ExtraSymbols vector.
280  if (InternedResult.size() >
281  MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
282  for (auto &KV : InternedResult)
283  if (!MR->getSymbols().count(KV.first))
284  ExtraSymbols.push_back(KV.first);
285  }
286 
287  // If there were extra definitions then report the error.
288  if (!ExtraSymbols.empty())
289  return make_error<UnexpectedSymbolDefinitions>(G.getName(),
290  std::move(ExtraSymbols));
291  }
292 
293  if (auto Err = MR->notifyResolved(InternedResult))
294  return Err;
295 
296  Layer.notifyLoaded(*MR);
297  return Error::success();
298  }
299 
301  std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
302  if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
303  Layer.getExecutionSession().reportError(std::move(Err));
304  MR->failMaterialization();
305  return;
306  }
307  if (auto Err = MR->notifyEmitted()) {
308  Layer.getExecutionSession().reportError(std::move(Err));
309  MR->failMaterialization();
310  }
311  }
312 
313  LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override {
314  return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); };
315  }
316 
318  // Add passes to mark duplicate defs as should-discard, and to walk the
319  // link graph to build the symbol dependence graph.
320  Config.PrePrunePasses.push_back([this](LinkGraph &G) {
321  return claimOrExternalizeWeakAndCommonSymbols(G);
322  });
323 
324  Layer.modifyPassConfig(*MR, LG, Config);
325 
326  Config.PostPrunePasses.push_back(
327  [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
328 
329  return Error::success();
330  }
331 
332 private:
333  // Symbol name dependencies:
334  // Internal: Defined in this graph.
335  // External: Defined externally.
336  struct BlockSymbolDependencies {
337  SymbolNameSet Internal, External;
338  };
339 
340  // Lazily populated map of blocks to BlockSymbolDependencies values.
341  class BlockDependenciesMap {
342  public:
343  BlockDependenciesMap(ExecutionSession &ES,
344  DenseMap<const Block *, DenseSet<Block *>> BlockDeps)
345  : ES(ES), BlockDeps(std::move(BlockDeps)) {}
346 
347  const BlockSymbolDependencies &operator[](const Block &B) {
348  // Check the cache first.
349  auto I = BlockTransitiveDepsCache.find(&B);
350  if (I != BlockTransitiveDepsCache.end())
351  return I->second;
352 
353  // No value. Populate the cache.
354  BlockSymbolDependencies BTDCacheVal;
355  auto BDI = BlockDeps.find(&B);
356  assert(BDI != BlockDeps.end() && "No block dependencies");
357 
358  for (auto *BDep : BDI->second) {
359  auto &BID = getBlockImmediateDeps(*BDep);
360  for (auto &ExternalDep : BID.External)
361  BTDCacheVal.External.insert(ExternalDep);
362  for (auto &InternalDep : BID.Internal)
363  BTDCacheVal.Internal.insert(InternalDep);
364  }
365 
366  return BlockTransitiveDepsCache
367  .insert(std::make_pair(&B, std::move(BTDCacheVal)))
368  .first->second;
369  }
370 
371  SymbolStringPtr &getInternedName(Symbol &Sym) {
372  auto I = NameCache.find(&Sym);
373  if (I != NameCache.end())
374  return I->second;
375 
376  return NameCache.insert(std::make_pair(&Sym, ES.intern(Sym.getName())))
377  .first->second;
378  }
379 
380  private:
381  BlockSymbolDependencies &getBlockImmediateDeps(Block &B) {
382  // Check the cache first.
383  auto I = BlockImmediateDepsCache.find(&B);
384  if (I != BlockImmediateDepsCache.end())
385  return I->second;
386 
387  BlockSymbolDependencies BIDCacheVal;
388  for (auto &E : B.edges()) {
389  auto &Tgt = E.getTarget();
390  if (Tgt.getScope() != Scope::Local) {
391  if (Tgt.isExternal())
392  BIDCacheVal.External.insert(getInternedName(Tgt));
393  else
394  BIDCacheVal.Internal.insert(getInternedName(Tgt));
395  }
396  }
397 
398  return BlockImmediateDepsCache
399  .insert(std::make_pair(&B, std::move(BIDCacheVal)))
400  .first->second;
401  }
402 
403  ExecutionSession &ES;
406  DenseMap<const Block *, BlockSymbolDependencies> BlockImmediateDepsCache;
407  DenseMap<const Block *, BlockSymbolDependencies> BlockTransitiveDepsCache;
408  };
409 
410  Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) {
411  auto &ES = Layer.getExecutionSession();
412 
413  SymbolFlagsMap NewSymbolsToClaim;
414  std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym;
415 
416  auto ProcessSymbol = [&](Symbol *Sym) {
417  if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
418  auto Name = ES.intern(Sym->getName());
419  if (!MR->getSymbols().count(ES.intern(Sym->getName()))) {
421  if (Sym->getScope() == Scope::Default)
423  NewSymbolsToClaim[Name] = SF;
424  NameToSym.push_back(std::make_pair(std::move(Name), Sym));
425  }
426  }
427  };
428 
429  for (auto *Sym : G.defined_symbols())
430  ProcessSymbol(Sym);
431  for (auto *Sym : G.absolute_symbols())
432  ProcessSymbol(Sym);
433 
434  // Attempt to claim all weak defs that we're not already responsible for.
435  // This cannot fail -- any clashes will just result in rejection of our
436  // claim, at which point we'll externalize that symbol.
437  cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim)));
438 
439  for (auto &KV : NameToSym)
440  if (!MR->getSymbols().count(KV.first))
441  G.makeExternal(*KV.second);
442 
443  return Error::success();
444  }
445 
446  Error markResponsibilitySymbolsLive(LinkGraph &G) const {
447  auto &ES = Layer.getExecutionSession();
448  for (auto *Sym : G.defined_symbols())
449  if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
450  Sym->setLive(true);
451  return Error::success();
452  }
453 
454  Error computeNamedSymbolDependencies(LinkGraph &G) {
455  auto &ES = MR->getTargetJITDylib().getExecutionSession();
456  auto BlockDeps = computeBlockNonLocalDeps(G);
457 
458  // Compute dependencies for symbols defined in the JITLink graph.
459  for (auto *Sym : G.defined_symbols()) {
460 
461  // Skip local symbols: we do not track dependencies for these.
462  if (Sym->getScope() == Scope::Local)
463  continue;
464  assert(Sym->hasName() &&
465  "Defined non-local jitlink::Symbol should have a name");
466 
467  auto &SymDeps = BlockDeps[Sym->getBlock()];
468  if (SymDeps.External.empty() && SymDeps.Internal.empty())
469  continue;
470 
471  auto SymName = ES.intern(Sym->getName());
472  if (!SymDeps.External.empty())
473  ExternalNamedSymbolDeps[SymName] = SymDeps.External;
474  if (!SymDeps.Internal.empty())
475  InternalNamedSymbolDeps[SymName] = SymDeps.Internal;
476  }
477 
478  for (auto &P : Layer.Plugins) {
479  auto SynthDeps = P->getSyntheticSymbolDependencies(*MR);
480  if (SynthDeps.empty())
481  continue;
482 
483  DenseSet<Block *> BlockVisited;
484  for (auto &KV : SynthDeps) {
485  auto &Name = KV.first;
486  auto &DepsForName = KV.second;
487  for (auto *Sym : DepsForName) {
488  if (Sym->getScope() == Scope::Local) {
489  auto &BDeps = BlockDeps[Sym->getBlock()];
490  for (auto &S : BDeps.Internal)
491  InternalNamedSymbolDeps[Name].insert(S);
492  for (auto &S : BDeps.External)
493  ExternalNamedSymbolDeps[Name].insert(S);
494  } else {
495  if (Sym->isExternal())
496  ExternalNamedSymbolDeps[Name].insert(
497  BlockDeps.getInternedName(*Sym));
498  else
499  InternalNamedSymbolDeps[Name].insert(
500  BlockDeps.getInternedName(*Sym));
501  }
502  }
503  }
504  }
505 
506  return Error::success();
507  }
508 
509  BlockDependenciesMap computeBlockNonLocalDeps(LinkGraph &G) {
510  // First calculate the reachable-via-non-local-symbol blocks for each block.
511  struct BlockInfo {
512  DenseSet<Block *> Dependencies;
513  DenseSet<Block *> Dependants;
514  bool DependenciesChanged = true;
515  };
516  DenseMap<Block *, BlockInfo> BlockInfos;
517  SmallVector<Block *> WorkList;
518 
519  // Pre-allocate map entries. This prevents any iterator/reference
520  // invalidation in the next loop.
521  for (auto *B : G.blocks())
522  (void)BlockInfos[B];
523 
524  // Build initial worklist, record block dependencies/dependants and
525  // non-local symbol dependencies.
526  for (auto *B : G.blocks()) {
527  auto &BI = BlockInfos[B];
528  for (auto &E : B->edges()) {
529  if (E.getTarget().getScope() == Scope::Local) {
530  auto &TgtB = E.getTarget().getBlock();
531  if (&TgtB != B) {
532  BI.Dependencies.insert(&TgtB);
533  BlockInfos[&TgtB].Dependants.insert(B);
534  }
535  }
536  }
537 
538  // If this node has both dependants and dependencies then add it to the
539  // worklist to propagate the dependencies to the dependants.
540  if (!BI.Dependants.empty() && !BI.Dependencies.empty())
541  WorkList.push_back(B);
542  }
543 
544  // Propagate block-level dependencies through the block-dependence graph.
545  while (!WorkList.empty()) {
546  auto *B = WorkList.back();
547  WorkList.pop_back();
548 
549  auto &BI = BlockInfos[B];
550  assert(BI.DependenciesChanged &&
551  "Block in worklist has unchanged dependencies");
552  BI.DependenciesChanged = false;
553  for (auto *Dependant : BI.Dependants) {
554  auto &DependantBI = BlockInfos[Dependant];
555  for (auto *Dependency : BI.Dependencies) {
556  if (Dependant != Dependency &&
557  DependantBI.Dependencies.insert(Dependency).second)
558  if (!DependantBI.DependenciesChanged) {
559  DependantBI.DependenciesChanged = true;
560  WorkList.push_back(Dependant);
561  }
562  }
563  }
564  }
565 
567  for (auto &KV : BlockInfos)
568  BlockDeps[KV.first] = std::move(KV.second.Dependencies);
569 
570  return BlockDependenciesMap(Layer.getExecutionSession(),
571  std::move(BlockDeps));
572  }
573 
574  void registerDependencies(const SymbolDependenceMap &QueryDeps) {
575  for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) {
576  auto &Name = NamedDepsEntry.first;
577  auto &NameDeps = NamedDepsEntry.second;
578  SymbolDependenceMap SymbolDeps;
579 
580  for (const auto &QueryDepsEntry : QueryDeps) {
581  JITDylib &SourceJD = *QueryDepsEntry.first;
582  const SymbolNameSet &Symbols = QueryDepsEntry.second;
583  auto &DepsForJD = SymbolDeps[&SourceJD];
584 
585  for (const auto &S : Symbols)
586  if (NameDeps.count(S))
587  DepsForJD.insert(S);
588 
589  if (DepsForJD.empty())
590  SymbolDeps.erase(&SourceJD);
591  }
592 
593  MR->addDependencies(Name, SymbolDeps);
594  }
595  }
596 
597  ObjectLinkingLayer &Layer;
598  std::unique_ptr<MaterializationResponsibility> MR;
599  std::unique_ptr<MemoryBuffer> ObjBuffer;
600  DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
601  DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
602 };
603 
604 ObjectLinkingLayer::Plugin::~Plugin() {}
605 
607 
609 
610 ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES)
611  : BaseT(ES), MemMgr(ES.getExecutorProcessControl().getMemMgr()) {
612  ES.registerResourceManager(*this);
613 }
614 
616  JITLinkMemoryManager &MemMgr)
617  : BaseT(ES), MemMgr(MemMgr) {
618  ES.registerResourceManager(*this);
619 }
620 
622  ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr)
623  : BaseT(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) {
624  ES.registerResourceManager(*this);
625 }
626 
628  assert(Allocs.empty() && "Layer destroyed with resources still attached");
629  getExecutionSession().deregisterResourceManager(*this);
630 }
631 
633  std::unique_ptr<LinkGraph> G) {
634  auto &JD = RT->getJITDylib();
635  return JD.define(LinkGraphMaterializationUnit::Create(*this, std::move(G)),
636  std::move(RT));
637 }
638 
639 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
640  std::unique_ptr<MemoryBuffer> O) {
641  assert(O && "Object must not be null");
642  MemoryBufferRef ObjBuffer = O->getMemBufferRef();
643 
644  auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>(
645  *this, std::move(R), std::move(O));
646  if (auto G = createLinkGraphFromObject(ObjBuffer)) {
647  Ctx->notifyMaterializing(**G);
648  link(std::move(*G), std::move(Ctx));
649  } else {
650  Ctx->notifyFailed(G.takeError());
651  }
652 }
653 
654 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
655  std::unique_ptr<LinkGraph> G) {
656  auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>(
657  *this, std::move(R), nullptr);
658  Ctx->notifyMaterializing(*G);
659  link(std::move(G), std::move(Ctx));
660 }
661 
662 void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
663  LinkGraph &G,
664  PassConfiguration &PassConfig) {
665  for (auto &P : Plugins)
666  P->modifyPassConfig(MR, G, PassConfig);
667 }
668 
669 void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
670  for (auto &P : Plugins)
671  P->notifyLoaded(MR);
672 }
673 
674 Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
675  AllocPtr Alloc) {
676  Error Err = Error::success();
677  for (auto &P : Plugins)
678  Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
679 
680  if (Err)
681  return Err;
682 
683  return MR.withResourceKeyDo(
684  [&](ResourceKey K) { Allocs[K].push_back(std::move(Alloc)); });
685 }
686 
687 Error ObjectLinkingLayer::handleRemoveResources(ResourceKey K) {
688 
689  Error Err = Error::success();
690 
691  for (auto &P : Plugins)
692  Err = joinErrors(std::move(Err), P->notifyRemovingResources(K));
693 
694  std::vector<AllocPtr> AllocsToRemove;
695  getExecutionSession().runSessionLocked([&] {
696  auto I = Allocs.find(K);
697  if (I != Allocs.end()) {
698  std::swap(AllocsToRemove, I->second);
699  Allocs.erase(I);
700  }
701  });
702 
703  while (!AllocsToRemove.empty()) {
704  Err = joinErrors(std::move(Err), AllocsToRemove.back()->deallocate());
705  AllocsToRemove.pop_back();
706  }
707 
708  return Err;
709 }
710 
711 void ObjectLinkingLayer::handleTransferResources(ResourceKey DstKey,
712  ResourceKey SrcKey) {
713  auto I = Allocs.find(SrcKey);
714  if (I != Allocs.end()) {
715  auto &SrcAllocs = I->second;
716  auto &DstAllocs = Allocs[DstKey];
717  DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size());
718  for (auto &Alloc : SrcAllocs)
719  DstAllocs.push_back(std::move(Alloc));
720 
721  // Erase SrcKey entry using value rather than iterator I: I may have been
722  // invalidated when we looked up DstKey.
723  Allocs.erase(SrcKey);
724  }
725 
726  for (auto &P : Plugins)
727  P->notifyTransferringResources(DstKey, SrcKey);
728 }
729 
731  ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar)
732  : ES(ES), Registrar(std::move(Registrar)) {}
733 
736  PassConfiguration &PassConfig) {
737 
738  PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass(
739  G.getTargetTriple(), [this, &MR](JITTargetAddress Addr, size_t Size) {
740  if (Addr) {
741  std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
742  assert(!InProcessLinks.count(&MR) &&
743  "Link for MR already being tracked?");
744  InProcessLinks[&MR] = {Addr, Size};
745  }
746  }));
747 }
748 
749 Error EHFrameRegistrationPlugin::notifyEmitted(
751 
752  EHFrameRange EmittedRange;
753  {
754  std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
755 
756  auto EHFrameRangeItr = InProcessLinks.find(&MR);
757  if (EHFrameRangeItr == InProcessLinks.end())
758  return Error::success();
759 
760  EmittedRange = EHFrameRangeItr->second;
761  assert(EmittedRange.Addr && "eh-frame addr to register can not be null");
762  InProcessLinks.erase(EHFrameRangeItr);
763  }
764 
765  if (auto Err = MR.withResourceKeyDo(
766  [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
767  return Err;
768 
769  return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size);
770 }
771 
772 Error EHFrameRegistrationPlugin::notifyFailed(
774  std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
775  InProcessLinks.erase(&MR);
776  return Error::success();
777 }
778 
779 Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
780  std::vector<EHFrameRange> RangesToRemove;
781 
782  ES.runSessionLocked([&] {
783  auto I = EHFrameRanges.find(K);
784  if (I != EHFrameRanges.end()) {
785  RangesToRemove = std::move(I->second);
786  EHFrameRanges.erase(I);
787  }
788  });
789 
790  Error Err = Error::success();
791  while (!RangesToRemove.empty()) {
792  auto RangeToRemove = RangesToRemove.back();
793  RangesToRemove.pop_back();
794  assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null");
795  Err = joinErrors(
796  std::move(Err),
797  Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size));
798  }
799 
800  return Err;
801 }
802 
803 void EHFrameRegistrationPlugin::notifyTransferringResources(
804  ResourceKey DstKey, ResourceKey SrcKey) {
805  auto SI = EHFrameRanges.find(SrcKey);
806  if (SI == EHFrameRanges.end())
807  return;
808 
809  auto DI = EHFrameRanges.find(DstKey);
810  if (DI != EHFrameRanges.end()) {
811  auto &SrcRanges = SI->second;
812  auto &DstRanges = DI->second;
813  DstRanges.reserve(DstRanges.size() + SrcRanges.size());
814  for (auto &SrcRange : SrcRanges)
815  DstRanges.push_back(std::move(SrcRange));
816  EHFrameRanges.erase(SI);
817  } else {
818  // We need to move SrcKey's ranges over without invalidating the SI
819  // iterator.
820  auto Tmp = std::move(SI->second);
821  EHFrameRanges.erase(SI);
822  EHFrameRanges[DstKey] = std::move(Tmp);
823  }
824 }
825 
826 } // End namespace orc.
827 } // End namespace llvm.
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ResourceKey
uintptr_t ResourceKey
Definition: Core.h:50
MemoryBuffer.h
llvm::orc::ObjectLinkingLayer::emit
void emit(std::unique_ptr< MaterializationResponsibility > R, std::unique_ptr< MemoryBuffer > O) override
Emit an object file.
Definition: ObjectLinkingLayer.cpp:639
llvm::orc::MaterializationResponsibility
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:506
llvm::AArch64CC::LO
@ LO
Definition: AArch64BaseInfo.h:258
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::orc::JITDylib
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:908
llvm::orc::EHFrameRegistrationPlugin::EHFrameRegistrationPlugin
EHFrameRegistrationPlugin(ExecutionSession &ES, std::unique_ptr< jitlink::EHFrameRegistrar > Registrar)
Definition: ObjectLinkingLayer.cpp:730
Optional.h
llvm::orc::ObjectLinkingLayerJITLinkContext::ObjectLinkingLayerJITLinkContext
ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, std::unique_ptr< MaterializationResponsibility > MR, std::unique_ptr< MemoryBuffer > ObjBuffer)
Definition: ObjectLinkingLayer.cpp:123
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:623
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::orc::SymbolLookupSet
A set of symbols to look up, each associated with a SymbolLookupFlags value.
Definition: Core.h:175
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
llvm::orc::ObjectLinkingLayerJITLinkContext::~ObjectLinkingLayerJITLinkContext
~ObjectLinkingLayerJITLinkContext()
Definition: ObjectLinkingLayer.cpp:130
llvm::orc::ExecutionSession::registerResourceManager
void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
Definition: Core.cpp:1830
llvm::DenseMapBase::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
llvm::orc::EHFrameRegistrationPlugin::modifyPassConfig
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &PassConfig) override
Definition: ObjectLinkingLayer.cpp:734
llvm::orc::ObjectLinkingLayerJITLinkContext::getMarkLivePass
LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override
Returns the mark-live pass to be used for this link.
Definition: ObjectLinkingLayer.cpp:313
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::ObjectLinkingLayer::~ObjectLinkingLayer
~ObjectLinkingLayer()
Destruct an ObjectLinkingLayer.
Definition: ObjectLinkingLayer.cpp:627
llvm::JITSymbolFlags
Flags for symbols in the JIT.
Definition: JITSymbol.h:74
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::MachO::SymbolFlags
SymbolFlags
Symbol flags.
Definition: Symbol.h:25
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:650
llvm::orc::ObjectLinkingLayer::add
Error add(ResourceTrackerSP, std::unique_ptr< jitlink::LinkGraph > G)
Add a LinkGraph to the JITDylib targeted by the given tracker.
llvm::JITEvaluatedSymbol
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:229
llvm::orc::ObjectLinkingLayerJITLinkContext::notifyResolved
Error notifyResolved(LinkGraph &G) override
Called by JITLink once all defined symbols in the graph have been assigned their final memory locatio...
Definition: ObjectLinkingLayer.cpp:202
EHFrameSupport.h
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::orc::SymbolLookupFlags
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
Definition: Core.h:137
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::orc
Definition: CompileOnDemandLayer.h:57
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::orc::ExecutionSession::intern
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1314
llvm::orc::ExecutionSession::runSessionLocked
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1324
llvm::orc::SymbolLookupSet::add
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
Definition: Core.h:236
llvm::orc::ObjectLinkingLayerJITLinkContext::modifyPassConfig
Error modifyPassConfig(LinkGraph &LG, PassConfiguration &Config) override
Called by JITLink to modify the pass pipeline prior to linking.
Definition: ObjectLinkingLayer.cpp:317
llvm::RTTIExtends< ObjectLinkingLayer, ObjectLayer >
llvm::orc::SymbolLookupFlags::WeaklyReferencedSymbol
@ WeaklyReferencedSymbol
llvm::orc::ObjectLinkingLayerJITLinkContext::notifyMaterializing
void notifyMaterializing(LinkGraph &G)
Definition: ObjectLinkingLayer.cpp:139
llvm::orc::MaterializationResponsibility::withResourceKeyDo
Error withResourceKeyDo(Func &&F) const
Returns the ResourceTracker for this instance.
Definition: Core.h:1680
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::DenseSet< SymbolStringPtr >
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:179
llvm::orc::ObjectLinkingLayerJITLinkContext::lookup
void lookup(const LookupMap &Symbols, std::unique_ptr< JITLinkAsyncLookupContinuation > LC) override
Called by JITLink to resolve external symbols.
Definition: ObjectLinkingLayer.cpp:153
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::orc::ObjectLinkingLayerJITLinkContext::getMemoryManager
JITLinkMemoryManager & getMemoryManager() override
Return the MemoryManager to be used for this link.
Definition: ObjectLinkingLayer.cpp:137
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap< SymbolStringPtr, JITSymbolFlags >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::JITSymbolFlags::Callable
@ Callable
Definition: JITSymbol.h:86
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:428
llvm::orc::ObjectLinkingLayer::ObjectLinkingLayer
ObjectLinkingLayer(ExecutionSession &ES)
Construct an ObjectLinkingLayer using the ExecutorProcessControl instance's memory manager.
Definition: ObjectLinkingLayer.cpp:610
llvm::orc::ResourceTrackerSP
uint8_t IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
Definition: Core.h:47
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1605
SI
StandardInstrumentations SI(Debug, VerifyEach)
DebugObjectManagerPlugin.h
llvm::orc::JITDylibSearchOrder
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
Definition: Core.h:154
llvm::JITSymbolFlags::Absolute
@ Absolute
Definition: JITSymbol.h:84
llvm::JITSymbolFlags::Weak
@ Weak
Definition: JITSymbol.h:82
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::Reloc::Static
@ Static
Definition: CodeGen.h:22
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::orc::ObjectLinkingLayer
An ObjectLayer implementation built on JITLink.
Definition: ObjectLinkingLayer.h:54
llvm::DenseMapBase::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:97
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1276
llvm::DenseMapBase::size
unsigned size() const
Definition: DenseMap.h:100
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
llvm::orc::ObjectLinkingLayerJITLinkContext::notifyFinalized
void notifyFinalized(std::unique_ptr< JITLinkMemoryManager::Allocation > A) override
Called by JITLink to notify the context that the object has been finalized (i.e.
Definition: ObjectLinkingLayer.cpp:300
llvm::DenseMapBase::reserve
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition: DenseMap.h:104
llvm::orc::ObjectLinkingLayerJITLinkContext
Definition: ObjectLinkingLayer.cpp:121
ObjectLinkingLayer.h
llvm::orc::SymbolLookupFlags::RequiredSymbol
@ RequiredSymbol
llvm::orc::SymbolNameVector
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
Definition: Core.h:109
llvm::JITSymbolFlags::Exported
@ Exported
Definition: JITSymbol.h:85
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
llvm::orc::ObjectLinkingLayerJITLinkContext::notifyFailed
void notifyFailed(Error Err) override
Notify this context that linking failed.
Definition: ObjectLinkingLayer.cpp:146