LLVM  14.0.0git
Core.cpp
Go to the documentation of this file.
1 //===--- Core.cpp - Core ORC APIs (MaterializationUnit, JITDylib, etc.) ---===//
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 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/Config/llvm-config.h"
17 
18 #include <condition_variable>
19 #include <future>
20 
21 #define DEBUG_TYPE "orc"
22 
23 namespace llvm {
24 namespace orc {
25 
28 char SymbolsNotFound::ID = 0;
32 char Task::ID = 0;
34 
37 
38 void MaterializationUnit::anchor() {}
39 
41  assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&
42  "JITDylib must be two byte aligned");
43  JD->Retain();
44  JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get()));
45 }
46 
48  getJITDylib().getExecutionSession().destroyResourceTracker(*this);
49  getJITDylib().Release();
50 }
51 
53  return getJITDylib().getExecutionSession().removeResourceTracker(*this);
54 }
55 
57  getJITDylib().getExecutionSession().transferResourceTracker(DstRT, *this);
58 }
59 
60 void ResourceTracker::makeDefunct() {
61  uintptr_t Val = JDAndFlag.load();
62  Val |= 0x1U;
63  JDAndFlag.store(Val);
64 }
65 
67 
69  : RT(std::move(RT)) {}
70 
73 }
74 
76  OS << "Resource tracker " << (void *)RT.get() << " became defunct";
77 }
78 
80  std::shared_ptr<SymbolDependenceMap> Symbols)
81  : Symbols(std::move(Symbols)) {
82  assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");
83 }
84 
85 std::error_code FailedToMaterialize::convertToErrorCode() const {
87 }
88 
90  OS << "Failed to materialize symbols: " << *Symbols;
91 }
92 
94  for (auto &Sym : Symbols)
95  this->Symbols.push_back(Sym);
96  assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
97 }
98 
100  : Symbols(std::move(Symbols)) {
101  assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
102 }
103 
104 std::error_code SymbolsNotFound::convertToErrorCode() const {
106 }
107 
109  OS << "Symbols not found: " << Symbols;
110 }
111 
113  : Symbols(std::move(Symbols)) {
114  assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");
115 }
116 
119 }
120 
122  OS << "Symbols could not be removed: " << Symbols;
123 }
124 
127 }
128 
130  OS << "Missing definitions in module " << ModuleName
131  << ": " << Symbols;
132 }
133 
136 }
137 
139  OS << "Unexpected definitions in module " << ModuleName
140  << ": " << Symbols;
141 }
142 
144  const SymbolLookupSet &Symbols, SymbolState RequiredState,
145  SymbolsResolvedCallback NotifyComplete)
146  : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {
147  assert(RequiredState >= SymbolState::Resolved &&
148  "Cannot query for a symbols that have not reached the resolve state "
149  "yet");
150 
151  OutstandingSymbolsCount = Symbols.size();
152 
153  for (auto &KV : Symbols)
154  ResolvedSymbols[KV.first] = nullptr;
155 }
156 
159  auto I = ResolvedSymbols.find(Name);
160  assert(I != ResolvedSymbols.end() &&
161  "Resolving symbol outside the requested set");
162  assert(I->second.getAddress() == 0 && "Redundantly resolving symbol Name");
163 
164  // If this is a materialization-side-effects-only symbol then drop it,
165  // otherwise update its map entry with its resolved address.
167  ResolvedSymbols.erase(I);
168  else
169  I->second = std::move(Sym);
170  --OutstandingSymbolsCount;
171 }
172 
173 void AsynchronousSymbolQuery::handleComplete(ExecutionSession &ES) {
174  assert(OutstandingSymbolsCount == 0 &&
175  "Symbols remain, handleComplete called prematurely");
176 
177  class RunQueryCompleteTask : public Task {
178  public:
179  RunQueryCompleteTask(SymbolMap ResolvedSymbols,
180  SymbolsResolvedCallback NotifyComplete)
181  : ResolvedSymbols(std::move(ResolvedSymbols)),
182  NotifyComplete(std::move(NotifyComplete)) {}
183  void printDescription(raw_ostream &OS) override {
184  OS << "Execute query complete callback for " << ResolvedSymbols;
185  }
186  void run() override { NotifyComplete(std::move(ResolvedSymbols)); }
187 
188  private:
189  SymbolMap ResolvedSymbols;
190  SymbolsResolvedCallback NotifyComplete;
191  };
192 
193  auto T = std::make_unique<RunQueryCompleteTask>(std::move(ResolvedSymbols),
194  std::move(NotifyComplete));
195  NotifyComplete = SymbolsResolvedCallback();
196  ES.dispatchTask(std::move(T));
197 }
198 
199 void AsynchronousSymbolQuery::handleFailed(Error Err) {
200  assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&
201  OutstandingSymbolsCount == 0 &&
202  "Query should already have been abandoned");
203  NotifyComplete(std::move(Err));
204  NotifyComplete = SymbolsResolvedCallback();
205 }
206 
207 void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,
208  SymbolStringPtr Name) {
209  bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;
210  (void)Added;
211  assert(Added && "Duplicate dependence notification?");
212 }
213 
214 void AsynchronousSymbolQuery::removeQueryDependence(
215  JITDylib &JD, const SymbolStringPtr &Name) {
216  auto QRI = QueryRegistrations.find(&JD);
217  assert(QRI != QueryRegistrations.end() &&
218  "No dependencies registered for JD");
219  assert(QRI->second.count(Name) && "No dependency on Name in JD");
220  QRI->second.erase(Name);
221  if (QRI->second.empty())
222  QueryRegistrations.erase(QRI);
223 }
224 
225 void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) {
226  auto I = ResolvedSymbols.find(Name);
227  assert(I != ResolvedSymbols.end() &&
228  "Redundant removal of weakly-referenced symbol");
229  ResolvedSymbols.erase(I);
230  --OutstandingSymbolsCount;
231 }
232 
233 void AsynchronousSymbolQuery::detach() {
234  ResolvedSymbols.clear();
235  OutstandingSymbolsCount = 0;
236  for (auto &KV : QueryRegistrations)
237  KV.first->detachQueryHelper(*this, KV.second);
238  QueryRegistrations.clear();
239 }
240 
242  SymbolMap Symbols)
243  : MaterializationUnit(extractFlags(Symbols), nullptr),
244  Symbols(std::move(Symbols)) {}
245 
247  return "<Absolute Symbols>";
248 }
249 
250 void AbsoluteSymbolsMaterializationUnit::materialize(
251  std::unique_ptr<MaterializationResponsibility> R) {
252  // No dependencies, so these calls can't fail.
253  cantFail(R->notifyResolved(Symbols));
254  cantFail(R->notifyEmitted());
255 }
256 
257 void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD,
258  const SymbolStringPtr &Name) {
259  assert(Symbols.count(Name) && "Symbol is not part of this MU");
260  Symbols.erase(Name);
261 }
262 
264 AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {
265  SymbolFlagsMap Flags;
266  for (const auto &KV : Symbols)
267  Flags[KV.first] = KV.second.getFlags();
268  return Flags;
269 }
270 
272  JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,
273  SymbolAliasMap Aliases)
274  : MaterializationUnit(extractFlags(Aliases), nullptr), SourceJD(SourceJD),
275  SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {}
276 
278  return "<Reexports>";
279 }
280 
281 void ReExportsMaterializationUnit::materialize(
282  std::unique_ptr<MaterializationResponsibility> R) {
283 
284  auto &ES = R->getTargetJITDylib().getExecutionSession();
285  JITDylib &TgtJD = R->getTargetJITDylib();
286  JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
287 
288  // Find the set of requested aliases and aliasees. Return any unrequested
289  // aliases back to the JITDylib so as to not prematurely materialize any
290  // aliasees.
291  auto RequestedSymbols = R->getRequestedSymbols();
292  SymbolAliasMap RequestedAliases;
293 
294  for (auto &Name : RequestedSymbols) {
295  auto I = Aliases.find(Name);
296  assert(I != Aliases.end() && "Symbol not found in aliases map?");
297  RequestedAliases[Name] = std::move(I->second);
298  Aliases.erase(I);
299  }
300 
301  LLVM_DEBUG({
302  ES.runSessionLocked([&]() {
303  dbgs() << "materializing reexports: target = " << TgtJD.getName()
304  << ", source = " << SrcJD.getName() << " " << RequestedAliases
305  << "\n";
306  });
307  });
308 
309  if (!Aliases.empty()) {
310  auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases),
311  SourceJDLookupFlags))
312  : R->replace(symbolAliases(std::move(Aliases)));
313 
314  if (Err) {
315  // FIXME: Should this be reported / treated as failure to materialize?
316  // Or should this be treated as a sanctioned bailing-out?
317  ES.reportError(std::move(Err));
318  R->failMaterialization();
319  return;
320  }
321  }
322 
323  // The OnResolveInfo struct will hold the aliases and responsibilty for each
324  // query in the list.
325  struct OnResolveInfo {
326  OnResolveInfo(std::unique_ptr<MaterializationResponsibility> R,
327  SymbolAliasMap Aliases)
328  : R(std::move(R)), Aliases(std::move(Aliases)) {}
329 
330  std::unique_ptr<MaterializationResponsibility> R;
331  SymbolAliasMap Aliases;
332  };
333 
334  // Build a list of queries to issue. In each round we build a query for the
335  // largest set of aliases that we can resolve without encountering a chain of
336  // aliases (e.g. Foo -> Bar, Bar -> Baz). Such a chain would deadlock as the
337  // query would be waiting on a symbol that it itself had to resolve. Creating
338  // a new query for each link in such a chain eliminates the possibility of
339  // deadlock. In practice chains are likely to be rare, and this algorithm will
340  // usually result in a single query to issue.
341 
342  std::vector<std::pair<SymbolLookupSet, std::shared_ptr<OnResolveInfo>>>
343  QueryInfos;
344  while (!RequestedAliases.empty()) {
345  SymbolNameSet ResponsibilitySymbols;
346  SymbolLookupSet QuerySymbols;
347  SymbolAliasMap QueryAliases;
348 
349  // Collect as many aliases as we can without including a chain.
350  for (auto &KV : RequestedAliases) {
351  // Chain detected. Skip this symbol for this round.
352  if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||
353  RequestedAliases.count(KV.second.Aliasee)))
354  continue;
355 
356  ResponsibilitySymbols.insert(KV.first);
357  QuerySymbols.add(KV.second.Aliasee,
358  KV.second.AliasFlags.hasMaterializationSideEffectsOnly()
361  QueryAliases[KV.first] = std::move(KV.second);
362  }
363 
364  // Remove the aliases collected this round from the RequestedAliases map.
365  for (auto &KV : QueryAliases)
366  RequestedAliases.erase(KV.first);
367 
368  assert(!QuerySymbols.empty() && "Alias cycle detected!");
369 
370  auto NewR = R->delegate(ResponsibilitySymbols);
371  if (!NewR) {
372  ES.reportError(NewR.takeError());
373  R->failMaterialization();
374  return;
375  }
376 
377  auto QueryInfo = std::make_shared<OnResolveInfo>(std::move(*NewR),
378  std::move(QueryAliases));
379  QueryInfos.push_back(
380  make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
381  }
382 
383  // Issue the queries.
384  while (!QueryInfos.empty()) {
385  auto QuerySymbols = std::move(QueryInfos.back().first);
386  auto QueryInfo = std::move(QueryInfos.back().second);
387 
388  QueryInfos.pop_back();
389 
390  auto RegisterDependencies = [QueryInfo,
391  &SrcJD](const SymbolDependenceMap &Deps) {
392  // If there were no materializing symbols, just bail out.
393  if (Deps.empty())
394  return;
395 
396  // Otherwise the only deps should be on SrcJD.
397  assert(Deps.size() == 1 && Deps.count(&SrcJD) &&
398  "Unexpected dependencies for reexports");
399 
400  auto &SrcJDDeps = Deps.find(&SrcJD)->second;
401  SymbolDependenceMap PerAliasDepsMap;
402  auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
403 
404  for (auto &KV : QueryInfo->Aliases)
405  if (SrcJDDeps.count(KV.second.Aliasee)) {
406  PerAliasDeps = {KV.second.Aliasee};
407  QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap);
408  }
409  };
410 
411  auto OnComplete = [QueryInfo](Expected<SymbolMap> Result) {
412  auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();
413  if (Result) {
414  SymbolMap ResolutionMap;
415  for (auto &KV : QueryInfo->Aliases) {
416  assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||
417  Result->count(KV.second.Aliasee)) &&
418  "Result map missing entry?");
419  // Don't try to resolve materialization-side-effects-only symbols.
420  if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly())
421  continue;
422 
423  ResolutionMap[KV.first] = JITEvaluatedSymbol(
424  (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
425  }
426  if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {
427  ES.reportError(std::move(Err));
428  QueryInfo->R->failMaterialization();
429  return;
430  }
431  if (auto Err = QueryInfo->R->notifyEmitted()) {
432  ES.reportError(std::move(Err));
433  QueryInfo->R->failMaterialization();
434  return;
435  }
436  } else {
437  ES.reportError(Result.takeError());
438  QueryInfo->R->failMaterialization();
439  }
440  };
441 
443  JITDylibSearchOrder({{&SrcJD, SourceJDLookupFlags}}),
444  QuerySymbols, SymbolState::Resolved, std::move(OnComplete),
445  std::move(RegisterDependencies));
446  }
447 }
448 
449 void ReExportsMaterializationUnit::discard(const JITDylib &JD,
450  const SymbolStringPtr &Name) {
451  assert(Aliases.count(Name) &&
452  "Symbol not covered by this MaterializationUnit");
453  Aliases.erase(Name);
454 }
455 
457 ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
459  for (auto &KV : Aliases)
460  SymbolFlags[KV.first] = KV.second.AliasFlags;
461 
462  return SymbolFlags;
463 }
464 
466  SymbolNameSet Symbols) {
467  SymbolLookupSet LookupSet(Symbols);
468  auto Flags = SourceJD.getExecutionSession().lookupFlags(
470  SymbolLookupSet(std::move(Symbols)));
471 
472  if (!Flags)
473  return Flags.takeError();
474 
475  SymbolAliasMap Result;
476  for (auto &Name : Symbols) {
477  assert(Flags->count(Name) && "Missing entry in flags map");
478  Result[Name] = SymbolAliasMapEntry(Name, (*Flags)[Name]);
479  }
480 
481  return Result;
482 }
483 
485 public:
491  }
493  virtual void complete(std::unique_ptr<InProgressLookupState> IPLS) = 0;
494  virtual void fail(Error Err) = 0;
495 
500 
501  std::unique_lock<std::mutex> GeneratorLock;
503  bool NewJITDylib = true;
506  std::vector<std::weak_ptr<DefinitionGenerator>> CurDefGeneratorStack;
507 };
508 
510 public:
513  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete)
516  OnComplete(std::move(OnComplete)) {}
517 
518  void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
519  GeneratorLock = {}; // Unlock and release.
520  auto &ES = SearchOrder.front().first->getExecutionSession();
521  ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete));
522  }
523 
524  void fail(Error Err) override {
525  GeneratorLock = {}; // Unlock and release.
526  OnComplete(std::move(Err));
527  }
528 
529 private:
530  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete;
531 };
532 
534 public:
538  std::shared_ptr<AsynchronousSymbolQuery> Q,
539  RegisterDependenciesFunction RegisterDependencies)
541  RequiredState),
542  Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) {
543  }
544 
545  void complete(std::unique_ptr<InProgressLookupState> IPLS) override {
546  GeneratorLock = {}; // Unlock and release.
547  auto &ES = SearchOrder.front().first->getExecutionSession();
548  ES.OL_completeLookup(std::move(IPLS), std::move(Q),
549  std::move(RegisterDependencies));
550  }
551 
552  void fail(Error Err) override {
553  GeneratorLock = {};
554  Q->detach();
555  Q->handleFailed(std::move(Err));
556  }
557 
558 private:
559  std::shared_ptr<AsynchronousSymbolQuery> Q;
560  RegisterDependenciesFunction RegisterDependencies;
561 };
562 
564  JITDylibLookupFlags SourceJDLookupFlags,
566  : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),
567  Allow(std::move(Allow)) {}
568 
570  JITDylib &JD,
571  JITDylibLookupFlags JDLookupFlags,
572  const SymbolLookupSet &LookupSet) {
573  assert(&JD != &SourceJD && "Cannot re-export from the same dylib");
574 
575  // Use lookupFlags to find the subset of symbols that match our lookup.
576  auto Flags = JD.getExecutionSession().lookupFlags(
577  K, {{&SourceJD, JDLookupFlags}}, LookupSet);
578  if (!Flags)
579  return Flags.takeError();
580 
581  // Create an alias map.
582  orc::SymbolAliasMap AliasMap;
583  for (auto &KV : *Flags)
584  if (!Allow || Allow(KV.first))
585  AliasMap[KV.first] = SymbolAliasMapEntry(KV.first, KV.second);
586 
587  if (AliasMap.empty())
588  return Error::success();
589 
590  // Define the re-exports.
591  return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));
592 }
593 
594 LookupState::LookupState(std::unique_ptr<InProgressLookupState> IPLS)
595  : IPLS(std::move(IPLS)) {}
596 
597 void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); }
598 
599 LookupState::LookupState() = default;
600 LookupState::LookupState(LookupState &&) = default;
601 LookupState &LookupState::operator=(LookupState &&) = default;
602 LookupState::~LookupState() = default;
603 
605  assert(IPLS && "Cannot call continueLookup on empty LookupState");
606  auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession();
607  ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));
608 }
609 
611 
613  std::vector<ResourceTrackerSP> TrackersToRemove;
614  ES.runSessionLocked([&]() {
615  for (auto &KV : TrackerSymbols)
616  TrackersToRemove.push_back(KV.first);
617  TrackersToRemove.push_back(getDefaultResourceTracker());
618  });
619 
620  Error Err = Error::success();
621  for (auto &RT : TrackersToRemove)
622  Err = joinErrors(std::move(Err), RT->remove());
623  return Err;
624 }
625 
627  return ES.runSessionLocked([this] {
628  if (!DefaultTracker)
629  DefaultTracker = new ResourceTracker(this);
630  return DefaultTracker;
631  });
632 }
633 
635  return ES.runSessionLocked([this] {
636  ResourceTrackerSP RT = new ResourceTracker(this);
637  return RT;
638  });
639 }
640 
642  std::lock_guard<std::mutex> Lock(GeneratorsMutex);
643  auto I = llvm::find_if(DefGenerators,
644  [&](const std::shared_ptr<DefinitionGenerator> &H) {
645  return H.get() == &G;
646  });
647  assert(I != DefGenerators.end() && "Generator not found");
648  DefGenerators.erase(I);
649 }
650 
652 JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) {
653 
654  return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
655  std::vector<SymbolTable::iterator> AddedSyms;
656  std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs;
657 
658  for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end();
659  SFItr != SFEnd; ++SFItr) {
660 
661  auto &Name = SFItr->first;
662  auto &Flags = SFItr->second;
663 
664  auto EntryItr = Symbols.find(Name);
665 
666  // If the entry already exists...
667  if (EntryItr != Symbols.end()) {
668 
669  // If this is a strong definition then error out.
670  if (!Flags.isWeak()) {
671  // Remove any symbols already added.
672  for (auto &SI : AddedSyms)
673  Symbols.erase(SI);
674 
675  // FIXME: Return all duplicates.
676  return make_error<DuplicateDefinition>(std::string(*Name));
677  }
678 
679  // Otherwise just make a note to discard this symbol after the loop.
680  RejectedWeakDefs.push_back(SFItr);
681  continue;
682  } else
683  EntryItr =
684  Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;
685 
686  AddedSyms.push_back(EntryItr);
687  EntryItr->second.setState(SymbolState::Materializing);
688  }
689 
690  // Remove any rejected weak definitions from the SymbolFlags map.
691  while (!RejectedWeakDefs.empty()) {
692  SymbolFlags.erase(RejectedWeakDefs.back());
693  RejectedWeakDefs.pop_back();
694  }
695 
696  return SymbolFlags;
697  });
698 }
699 
700 Error JITDylib::replace(MaterializationResponsibility &FromMR,
701  std::unique_ptr<MaterializationUnit> MU) {
702  assert(MU != nullptr && "Can not replace with a null MaterializationUnit");
703  std::unique_ptr<MaterializationUnit> MustRunMU;
704  std::unique_ptr<MaterializationResponsibility> MustRunMR;
705 
706  auto Err =
707  ES.runSessionLocked([&, this]() -> Error {
708  auto RT = getTracker(FromMR);
709 
710  if (RT->isDefunct())
711  return make_error<ResourceTrackerDefunct>(std::move(RT));
712 
713 #ifndef NDEBUG
714  for (auto &KV : MU->getSymbols()) {
715  auto SymI = Symbols.find(KV.first);
716  assert(SymI != Symbols.end() && "Replacing unknown symbol");
717  assert(SymI->second.getState() == SymbolState::Materializing &&
718  "Can not replace a symbol that ha is not materializing");
719  assert(!SymI->second.hasMaterializerAttached() &&
720  "Symbol should not have materializer attached already");
721  assert(UnmaterializedInfos.count(KV.first) == 0 &&
722  "Symbol being replaced should have no UnmaterializedInfo");
723  }
724 #endif // NDEBUG
725 
726  // If the tracker is defunct we need to bail out immediately.
727 
728  // If any symbol has pending queries against it then we need to
729  // materialize MU immediately.
730  for (auto &KV : MU->getSymbols()) {
731  auto MII = MaterializingInfos.find(KV.first);
732  if (MII != MaterializingInfos.end()) {
733  if (MII->second.hasQueriesPending()) {
734  MustRunMR = ES.createMaterializationResponsibility(
735  *RT, std::move(MU->SymbolFlags), std::move(MU->InitSymbol));
736  MustRunMU = std::move(MU);
737  return Error::success();
738  }
739  }
740  }
741 
742  // Otherwise, make MU responsible for all the symbols.
743  auto RTI = MRTrackers.find(&FromMR);
744  assert(RTI != MRTrackers.end() && "No tracker for FromMR");
745  auto UMI =
746  std::make_shared<UnmaterializedInfo>(std::move(MU), RTI->second);
747  for (auto &KV : UMI->MU->getSymbols()) {
748  auto SymI = Symbols.find(KV.first);
749  assert(SymI->second.getState() == SymbolState::Materializing &&
750  "Can not replace a symbol that is not materializing");
751  assert(!SymI->second.hasMaterializerAttached() &&
752  "Can not replace a symbol that has a materializer attached");
753  assert(UnmaterializedInfos.count(KV.first) == 0 &&
754  "Unexpected materializer entry in map");
755  SymI->second.setAddress(SymI->second.getAddress());
756  SymI->second.setMaterializerAttached(true);
757 
758  auto &UMIEntry = UnmaterializedInfos[KV.first];
759  assert((!UMIEntry || !UMIEntry->MU) &&
760  "Replacing symbol with materializer still attached");
761  UMIEntry = UMI;
762  }
763 
764  return Error::success();
765  });
766 
767  if (Err)
768  return Err;
769 
770  if (MustRunMU) {
771  assert(MustRunMR && "MustRunMU set implies MustRunMR set");
772  ES.dispatchTask(std::make_unique<MaterializationTask>(
773  std::move(MustRunMU), std::move(MustRunMR)));
774  } else {
775  assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset");
776  }
777 
778  return Error::success();
779 }
780 
781 Expected<std::unique_ptr<MaterializationResponsibility>>
782 JITDylib::delegate(MaterializationResponsibility &FromMR,
783  SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol) {
784 
785  return ES.runSessionLocked(
786  [&]() -> Expected<std::unique_ptr<MaterializationResponsibility>> {
787  auto RT = getTracker(FromMR);
788 
789  if (RT->isDefunct())
790  return make_error<ResourceTrackerDefunct>(std::move(RT));
791 
792  return ES.createMaterializationResponsibility(
793  *RT, std::move(SymbolFlags), std::move(InitSymbol));
794  });
795 }
796 
798 JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {
799  return ES.runSessionLocked([&]() {
800  SymbolNameSet RequestedSymbols;
801 
802  for (auto &KV : SymbolFlags) {
803  assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");
804  assert(Symbols.find(KV.first)->second.getState() !=
805  SymbolState::NeverSearched &&
806  Symbols.find(KV.first)->second.getState() != SymbolState::Ready &&
807  "getRequestedSymbols can only be called for symbols that have "
808  "started materializing");
809  auto I = MaterializingInfos.find(KV.first);
810  if (I == MaterializingInfos.end())
811  continue;
812 
813  if (I->second.hasQueriesPending())
814  RequestedSymbols.insert(KV.first);
815  }
816 
817  return RequestedSymbols;
818  });
819 }
820 
821 void JITDylib::addDependencies(const SymbolStringPtr &Name,
822  const SymbolDependenceMap &Dependencies) {
823  ES.runSessionLocked([&]() {
824  assert(Symbols.count(Name) && "Name not in symbol table");
825  assert(Symbols[Name].getState() < SymbolState::Emitted &&
826  "Can not add dependencies for a symbol that is not materializing");
827 
828  LLVM_DEBUG({
829  dbgs() << "In " << getName() << " adding dependencies for " << *Name
830  << ": " << Dependencies << "\n";
831  });
832 
833  // If Name is already in an error state then just bail out.
834  if (Symbols[Name].getFlags().hasError())
835  return;
836 
837  auto &MI = MaterializingInfos[Name];
838  assert(Symbols[Name].getState() != SymbolState::Emitted &&
839  "Can not add dependencies to an emitted symbol");
840 
841  bool DependsOnSymbolInErrorState = false;
842 
843  // Register dependencies, record whether any depenendency is in the error
844  // state.
845  for (auto &KV : Dependencies) {
846  assert(KV.first && "Null JITDylib in dependency?");
847  auto &OtherJITDylib = *KV.first;
848  auto &DepsOnOtherJITDylib = MI.UnemittedDependencies[&OtherJITDylib];
849 
850  for (auto &OtherSymbol : KV.second) {
851 
852  // Check the sym entry for the dependency.
853  auto OtherSymI = OtherJITDylib.Symbols.find(OtherSymbol);
854 
855  // Assert that this symbol exists and has not reached the ready state
856  // already.
857  assert(OtherSymI != OtherJITDylib.Symbols.end() &&
858  "Dependency on unknown symbol");
859 
860  auto &OtherSymEntry = OtherSymI->second;
861 
862  // If the other symbol is already in the Ready state then there's no
863  // dependency to add.
864  if (OtherSymEntry.getState() == SymbolState::Ready)
865  continue;
866 
867  // If the dependency is in an error state then note this and continue,
868  // we will move this symbol to the error state below.
869  if (OtherSymEntry.getFlags().hasError()) {
870  DependsOnSymbolInErrorState = true;
871  continue;
872  }
873 
874  // If the dependency was not in the error state then add it to
875  // our list of dependencies.
876  auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
877 
878  if (OtherSymEntry.getState() == SymbolState::Emitted)
879  transferEmittedNodeDependencies(MI, Name, OtherMI);
880  else if (&OtherJITDylib != this || OtherSymbol != Name) {
881  OtherMI.Dependants[this].insert(Name);
882  DepsOnOtherJITDylib.insert(OtherSymbol);
883  }
884  }
885 
886  if (DepsOnOtherJITDylib.empty())
887  MI.UnemittedDependencies.erase(&OtherJITDylib);
888  }
889 
890  // If this symbol dependended on any symbols in the error state then move
891  // this symbol to the error state too.
892  if (DependsOnSymbolInErrorState)
893  Symbols[Name].setFlags(Symbols[Name].getFlags() |
895  });
896 }
897 
898 Error JITDylib::resolve(MaterializationResponsibility &MR,
899  const SymbolMap &Resolved) {
900  AsynchronousSymbolQuerySet CompletedQueries;
901 
902  if (auto Err = ES.runSessionLocked([&, this]() -> Error {
903  auto RTI = MRTrackers.find(&MR);
904  assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
905  if (RTI->second->isDefunct())
906  return make_error<ResourceTrackerDefunct>(RTI->second);
907 
908  struct WorklistEntry {
909  SymbolTable::iterator SymI;
910  JITEvaluatedSymbol ResolvedSym;
911  };
912 
913  SymbolNameSet SymbolsInErrorState;
914  std::vector<WorklistEntry> Worklist;
915  Worklist.reserve(Resolved.size());
916 
917  // Build worklist and check for any symbols in the error state.
918  for (const auto &KV : Resolved) {
919 
920  assert(!KV.second.getFlags().hasError() &&
921  "Resolution result can not have error flag set");
922 
923  auto SymI = Symbols.find(KV.first);
924 
925  assert(SymI != Symbols.end() && "Symbol not found");
926  assert(!SymI->second.hasMaterializerAttached() &&
927  "Resolving symbol with materializer attached?");
928  assert(SymI->second.getState() == SymbolState::Materializing &&
929  "Symbol should be materializing");
930  assert(SymI->second.getAddress() == 0 &&
931  "Symbol has already been resolved");
932 
933  if (SymI->second.getFlags().hasError())
934  SymbolsInErrorState.insert(KV.first);
935  else {
936  auto Flags = KV.second.getFlags();
938  assert(Flags ==
939  (SymI->second.getFlags() &
941  "Resolved flags should match the declared flags");
942 
943  Worklist.push_back(
944  {SymI, JITEvaluatedSymbol(KV.second.getAddress(), Flags)});
945  }
946  }
947 
948  // If any symbols were in the error state then bail out.
949  if (!SymbolsInErrorState.empty()) {
950  auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
951  (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
952  return make_error<FailedToMaterialize>(
953  std::move(FailedSymbolsDepMap));
954  }
955 
956  while (!Worklist.empty()) {
957  auto SymI = Worklist.back().SymI;
958  auto ResolvedSym = Worklist.back().ResolvedSym;
959  Worklist.pop_back();
960 
961  auto &Name = SymI->first;
962 
963  // Resolved symbols can not be weak: discard the weak flag.
964  JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();
965  SymI->second.setAddress(ResolvedSym.getAddress());
966  SymI->second.setFlags(ResolvedFlags);
967  SymI->second.setState(SymbolState::Resolved);
968 
969  auto MII = MaterializingInfos.find(Name);
970  if (MII == MaterializingInfos.end())
971  continue;
972 
973  auto &MI = MII->second;
974  for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
975  Q->notifySymbolMetRequiredState(Name, ResolvedSym);
976  Q->removeQueryDependence(*this, Name);
977  if (Q->isComplete())
978  CompletedQueries.insert(std::move(Q));
979  }
980  }
981 
982  return Error::success();
983  }))
984  return Err;
985 
986  // Otherwise notify all the completed queries.
987  for (auto &Q : CompletedQueries) {
988  assert(Q->isComplete() && "Q not completed");
989  Q->handleComplete(ES);
990  }
991 
992  return Error::success();
993 }
994 
995 Error JITDylib::emit(MaterializationResponsibility &MR,
996  const SymbolFlagsMap &Emitted) {
997  AsynchronousSymbolQuerySet CompletedQueries;
998  DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;
999 
1000  if (auto Err = ES.runSessionLocked([&, this]() -> Error {
1001  auto RTI = MRTrackers.find(&MR);
1002  assert(RTI != MRTrackers.end() && "No resource tracker for MR?");
1003  if (RTI->second->isDefunct())
1004  return make_error<ResourceTrackerDefunct>(RTI->second);
1005 
1006  SymbolNameSet SymbolsInErrorState;
1007  std::vector<SymbolTable::iterator> Worklist;
1008 
1009  // Scan to build worklist, record any symbols in the erorr state.
1010  for (const auto &KV : Emitted) {
1011  auto &Name = KV.first;
1012 
1013  auto SymI = Symbols.find(Name);
1014  assert(SymI != Symbols.end() && "No symbol table entry for Name");
1015 
1016  if (SymI->second.getFlags().hasError())
1017  SymbolsInErrorState.insert(Name);
1018  else
1019  Worklist.push_back(SymI);
1020  }
1021 
1022  // If any symbols were in the error state then bail out.
1023  if (!SymbolsInErrorState.empty()) {
1024  auto FailedSymbolsDepMap = std::make_shared<SymbolDependenceMap>();
1025  (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);
1026  return make_error<FailedToMaterialize>(
1027  std::move(FailedSymbolsDepMap));
1028  }
1029 
1030  // Otherwise update dependencies and move to the emitted state.
1031  while (!Worklist.empty()) {
1032  auto SymI = Worklist.back();
1033  Worklist.pop_back();
1034 
1035  auto &Name = SymI->first;
1036  auto &SymEntry = SymI->second;
1037 
1038  // Move symbol to the emitted state.
1039  assert(((SymEntry.getFlags().hasMaterializationSideEffectsOnly() &&
1040  SymEntry.getState() == SymbolState::Materializing) ||
1041  SymEntry.getState() == SymbolState::Resolved) &&
1042  "Emitting from state other than Resolved");
1043  SymEntry.setState(SymbolState::Emitted);
1044 
1045  auto MII = MaterializingInfos.find(Name);
1046 
1047  // If this symbol has no MaterializingInfo then it's trivially ready.
1048  // Update its state and continue.
1049  if (MII == MaterializingInfos.end()) {
1050  SymEntry.setState(SymbolState::Ready);
1051  continue;
1052  }
1053 
1054  auto &MI = MII->second;
1055 
1056  // For each dependant, transfer this node's emitted dependencies to
1057  // it. If the dependant node is ready (i.e. has no unemitted
1058  // dependencies) then notify any pending queries.
1059  for (auto &KV : MI.Dependants) {
1060  auto &DependantJD = *KV.first;
1061  auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];
1062  for (auto &DependantName : KV.second) {
1063  auto DependantMII =
1064  DependantJD.MaterializingInfos.find(DependantName);
1065  assert(DependantMII != DependantJD.MaterializingInfos.end() &&
1066  "Dependant should have MaterializingInfo");
1067 
1068  auto &DependantMI = DependantMII->second;
1069 
1070  // Remove the dependant's dependency on this node.
1071  assert(DependantMI.UnemittedDependencies.count(this) &&
1072  "Dependant does not have an unemitted dependencies record "
1073  "for "
1074  "this JITDylib");
1075  assert(DependantMI.UnemittedDependencies[this].count(Name) &&
1076  "Dependant does not count this symbol as a dependency?");
1077 
1078  DependantMI.UnemittedDependencies[this].erase(Name);
1079  if (DependantMI.UnemittedDependencies[this].empty())
1080  DependantMI.UnemittedDependencies.erase(this);
1081 
1082  // Transfer unemitted dependencies from this node to the
1083  // dependant.
1084  DependantJD.transferEmittedNodeDependencies(DependantMI,
1085  DependantName, MI);
1086 
1087  auto DependantSymI = DependantJD.Symbols.find(DependantName);
1088  assert(DependantSymI != DependantJD.Symbols.end() &&
1089  "Dependant has no entry in the Symbols table");
1090  auto &DependantSymEntry = DependantSymI->second;
1091 
1092  // If the dependant is emitted and this node was the last of its
1093  // unemitted dependencies then the dependant node is now ready, so
1094  // notify any pending queries on the dependant node.
1095  if (DependantSymEntry.getState() == SymbolState::Emitted &&
1096  DependantMI.UnemittedDependencies.empty()) {
1097  assert(DependantMI.Dependants.empty() &&
1098  "Dependants should be empty by now");
1099 
1100  // Since this dependant is now ready, we erase its
1101  // MaterializingInfo and update its materializing state.
1102  DependantSymEntry.setState(SymbolState::Ready);
1103  DependantJDReadySymbols.push_back(DependantName);
1104 
1105  for (auto &Q :
1106  DependantMI.takeQueriesMeeting(SymbolState::Ready)) {
1107  Q->notifySymbolMetRequiredState(
1108  DependantName, DependantSymI->second.getSymbol());
1109  if (Q->isComplete())
1110  CompletedQueries.insert(Q);
1111  Q->removeQueryDependence(DependantJD, DependantName);
1112  }
1113  DependantJD.MaterializingInfos.erase(DependantMII);
1114  }
1115  }
1116  }
1117 
1118  auto &ThisJDReadySymbols = ReadySymbols[this];
1119  MI.Dependants.clear();
1120  if (MI.UnemittedDependencies.empty()) {
1121  SymI->second.setState(SymbolState::Ready);
1122  ThisJDReadySymbols.push_back(Name);
1123  for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {
1124  Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
1125  if (Q->isComplete())
1126  CompletedQueries.insert(Q);
1127  Q->removeQueryDependence(*this, Name);
1128  }
1129  MaterializingInfos.erase(MII);
1130  }
1131  }
1132 
1133  return Error::success();
1134  }))
1135  return Err;
1136 
1137  // Otherwise notify all the completed queries.
1138  for (auto &Q : CompletedQueries) {
1139  assert(Q->isComplete() && "Q is not complete");
1140  Q->handleComplete(ES);
1141  }
1142 
1143  return Error::success();
1144 }
1145 
1146 void JITDylib::unlinkMaterializationResponsibility(
1147  MaterializationResponsibility &MR) {
1148  ES.runSessionLocked([&]() {
1149  auto I = MRTrackers.find(&MR);
1150  assert(I != MRTrackers.end() && "MaterializationResponsibility not linked");
1151  MRTrackers.erase(I);
1152  });
1153 }
1154 
1155 std::pair<JITDylib::AsynchronousSymbolQuerySet,
1156  std::shared_ptr<SymbolDependenceMap>>
1157 JITDylib::failSymbols(FailedSymbolsWorklist Worklist) {
1158  AsynchronousSymbolQuerySet FailedQueries;
1159  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
1160 
1161  while (!Worklist.empty()) {
1162  assert(Worklist.back().first && "Failed JITDylib can not be null");
1163  auto &JD = *Worklist.back().first;
1164  auto Name = std::move(Worklist.back().second);
1165  Worklist.pop_back();
1166 
1167  (*FailedSymbolsMap)[&JD].insert(Name);
1168 
1169  assert(JD.Symbols.count(Name) && "No symbol table entry for Name");
1170  auto &Sym = JD.Symbols[Name];
1171 
1172  // Move the symbol into the error state.
1173  // Note that this may be redundant: The symbol might already have been
1174  // moved to this state in response to the failure of a dependence.
1175  Sym.setFlags(Sym.getFlags() | JITSymbolFlags::HasError);
1176 
1177  // FIXME: Come up with a sane mapping of state to
1178  // presence-of-MaterializingInfo so that we can assert presence / absence
1179  // here, rather than testing it.
1180  auto MII = JD.MaterializingInfos.find(Name);
1181 
1182  if (MII == JD.MaterializingInfos.end())
1183  continue;
1184 
1185  auto &MI = MII->second;
1186 
1187  // Move all dependants to the error state and disconnect from them.
1188  for (auto &KV : MI.Dependants) {
1189  auto &DependantJD = *KV.first;
1190  for (auto &DependantName : KV.second) {
1191  assert(DependantJD.Symbols.count(DependantName) &&
1192  "No symbol table entry for DependantName");
1193  auto &DependantSym = DependantJD.Symbols[DependantName];
1194  DependantSym.setFlags(DependantSym.getFlags() |
1195  JITSymbolFlags::HasError);
1196 
1197  assert(DependantJD.MaterializingInfos.count(DependantName) &&
1198  "No MaterializingInfo for dependant");
1199  auto &DependantMI = DependantJD.MaterializingInfos[DependantName];
1200 
1201  auto UnemittedDepI = DependantMI.UnemittedDependencies.find(&JD);
1202  assert(UnemittedDepI != DependantMI.UnemittedDependencies.end() &&
1203  "No UnemittedDependencies entry for this JITDylib");
1204  assert(UnemittedDepI->second.count(Name) &&
1205  "No UnemittedDependencies entry for this symbol");
1206  UnemittedDepI->second.erase(Name);
1207  if (UnemittedDepI->second.empty())
1208  DependantMI.UnemittedDependencies.erase(UnemittedDepI);
1209 
1210  // If this symbol is already in the emitted state then we need to
1211  // take responsibility for failing its queries, so add it to the
1212  // worklist.
1213  if (DependantSym.getState() == SymbolState::Emitted) {
1214  assert(DependantMI.Dependants.empty() &&
1215  "Emitted symbol should not have dependants");
1216  Worklist.push_back(std::make_pair(&DependantJD, DependantName));
1217  }
1218  }
1219  }
1220  MI.Dependants.clear();
1221 
1222  // Disconnect from all unemitted depenencies.
1223  for (auto &KV : MI.UnemittedDependencies) {
1224  auto &UnemittedDepJD = *KV.first;
1225  for (auto &UnemittedDepName : KV.second) {
1226  auto UnemittedDepMII =
1227  UnemittedDepJD.MaterializingInfos.find(UnemittedDepName);
1228  assert(UnemittedDepMII != UnemittedDepJD.MaterializingInfos.end() &&
1229  "Missing MII for unemitted dependency");
1230  assert(UnemittedDepMII->second.Dependants.count(&JD) &&
1231  "JD not listed as a dependant of unemitted dependency");
1232  assert(UnemittedDepMII->second.Dependants[&JD].count(Name) &&
1233  "Name is not listed as a dependant of unemitted dependency");
1234  UnemittedDepMII->second.Dependants[&JD].erase(Name);
1235  if (UnemittedDepMII->second.Dependants[&JD].empty())
1236  UnemittedDepMII->second.Dependants.erase(&JD);
1237  }
1238  }
1239  MI.UnemittedDependencies.clear();
1240 
1241  // Collect queries to be failed for this MII.
1242  AsynchronousSymbolQueryList ToDetach;
1243  for (auto &Q : MII->second.pendingQueries()) {
1244  // Add the query to the list to be failed and detach it.
1245  FailedQueries.insert(Q);
1246  ToDetach.push_back(Q);
1247  }
1248  for (auto &Q : ToDetach)
1249  Q->detach();
1250 
1251  assert(MI.Dependants.empty() &&
1252  "Can not delete MaterializingInfo with dependants still attached");
1253  assert(MI.UnemittedDependencies.empty() &&
1254  "Can not delete MaterializingInfo with unemitted dependencies "
1255  "still attached");
1256  assert(!MI.hasQueriesPending() &&
1257  "Can not delete MaterializingInfo with queries pending");
1258  JD.MaterializingInfos.erase(MII);
1259  }
1260 
1261  return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));
1262 }
1263 
1264 void JITDylib::setLinkOrder(JITDylibSearchOrder NewLinkOrder,
1265  bool LinkAgainstThisJITDylibFirst) {
1266  ES.runSessionLocked([&]() {
1267  if (LinkAgainstThisJITDylibFirst) {
1268  LinkOrder.clear();
1269  if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)
1270  LinkOrder.push_back(
1271  std::make_pair(this, JITDylibLookupFlags::MatchAllSymbols));
1272  llvm::append_range(LinkOrder, NewLinkOrder);
1273  } else
1274  LinkOrder = std::move(NewLinkOrder);
1275  });
1276 }
1277 
1278 void JITDylib::addToLinkOrder(JITDylib &JD, JITDylibLookupFlags JDLookupFlags) {
1279  ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });
1280 }
1281 
1282 void JITDylib::replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
1283  JITDylibLookupFlags JDLookupFlags) {
1284  ES.runSessionLocked([&]() {
1285  for (auto &KV : LinkOrder)
1286  if (KV.first == &OldJD) {
1287  KV = {&NewJD, JDLookupFlags};
1288  break;
1289  }
1290  });
1291 }
1292 
1293 void JITDylib::removeFromLinkOrder(JITDylib &JD) {
1294  ES.runSessionLocked([&]() {
1295  auto I = llvm::find_if(LinkOrder,
1296  [&](const JITDylibSearchOrder::value_type &KV) {
1297  return KV.first == &JD;
1298  });
1299  if (I != LinkOrder.end())
1300  LinkOrder.erase(I);
1301  });
1302 }
1303 
1305  return ES.runSessionLocked([&]() -> Error {
1306  using SymbolMaterializerItrPair =
1307  std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;
1308  std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1309  SymbolNameSet Missing;
1311 
1312  for (auto &Name : Names) {
1313  auto I = Symbols.find(Name);
1314 
1315  // Note symbol missing.
1316  if (I == Symbols.end()) {
1317  Missing.insert(Name);
1318  continue;
1319  }
1320 
1321  // Note symbol materializing.
1322  if (I->second.getState() != SymbolState::NeverSearched &&
1323  I->second.getState() != SymbolState::Ready) {
1324  Materializing.insert(Name);
1325  continue;
1326  }
1327 
1328  auto UMII = I->second.hasMaterializerAttached()
1329  ? UnmaterializedInfos.find(Name)
1330  : UnmaterializedInfos.end();
1331  SymbolsToRemove.push_back(std::make_pair(I, UMII));
1332  }
1333 
1334  // If any of the symbols are not defined, return an error.
1335  if (!Missing.empty())
1336  return make_error<SymbolsNotFound>(std::move(Missing));
1337 
1338  // If any of the symbols are currently materializing, return an error.
1339  if (!Materializing.empty())
1340  return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1341 
1342  // Remove the symbols.
1343  for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1344  auto UMII = SymbolMaterializerItrPair.second;
1345 
1346  // If there is a materializer attached, call discard.
1347  if (UMII != UnmaterializedInfos.end()) {
1348  UMII->second->MU->doDiscard(*this, UMII->first);
1349  UnmaterializedInfos.erase(UMII);
1350  }
1351 
1352  auto SymI = SymbolMaterializerItrPair.first;
1353  Symbols.erase(SymI);
1354  }
1355 
1356  return Error::success();
1357  });
1358 }
1359 
1361  ES.runSessionLocked([&, this]() {
1362  OS << "JITDylib \"" << JITDylibName << "\" (ES: "
1363  << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) << "):\n"
1364  << "Link order: " << LinkOrder << "\n"
1365  << "Symbol table:\n";
1366 
1367  for (auto &KV : Symbols) {
1368  OS << " \"" << *KV.first << "\": ";
1369  if (auto Addr = KV.second.getAddress())
1370  OS << format("0x%016" PRIx64, Addr) << ", " << KV.second.getFlags()
1371  << " ";
1372  else
1373  OS << "<not resolved> ";
1374 
1375  OS << KV.second.getFlags() << " " << KV.second.getState();
1376 
1377  if (KV.second.hasMaterializerAttached()) {
1378  OS << " (Materializer ";
1379  auto I = UnmaterializedInfos.find(KV.first);
1380  assert(I != UnmaterializedInfos.end() &&
1381  "Lazy symbol should have UnmaterializedInfo");
1382  OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";
1383  } else
1384  OS << "\n";
1385  }
1386 
1387  if (!MaterializingInfos.empty())
1388  OS << " MaterializingInfos entries:\n";
1389  for (auto &KV : MaterializingInfos) {
1390  OS << " \"" << *KV.first << "\":\n"
1391  << " " << KV.second.pendingQueries().size()
1392  << " pending queries: { ";
1393  for (const auto &Q : KV.second.pendingQueries())
1394  OS << Q.get() << " (" << Q->getRequiredState() << ") ";
1395  OS << "}\n Dependants:\n";
1396  for (auto &KV2 : KV.second.Dependants)
1397  OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1398  OS << " Unemitted Dependencies:\n";
1399  for (auto &KV2 : KV.second.UnemittedDependencies)
1400  OS << " " << KV2.first->getName() << ": " << KV2.second << "\n";
1401  assert((Symbols[KV.first].getState() != SymbolState::Ready ||
1402  !KV.second.pendingQueries().empty() ||
1403  !KV.second.Dependants.empty() ||
1404  !KV.second.UnemittedDependencies.empty()) &&
1405  "Stale materializing info entry");
1406  }
1407  });
1408 }
1409 
1410 void JITDylib::MaterializingInfo::addQuery(
1411  std::shared_ptr<AsynchronousSymbolQuery> Q) {
1412 
1413  auto I = std::lower_bound(
1414  PendingQueries.rbegin(), PendingQueries.rend(), Q->getRequiredState(),
1415  [](const std::shared_ptr<AsynchronousSymbolQuery> &V, SymbolState S) {
1416  return V->getRequiredState() <= S;
1417  });
1418  PendingQueries.insert(I.base(), std::move(Q));
1419 }
1420 
1421 void JITDylib::MaterializingInfo::removeQuery(
1422  const AsynchronousSymbolQuery &Q) {
1423  // FIXME: Implement 'find_as' for shared_ptr<T>/T*.
1424  auto I = llvm::find_if(
1425  PendingQueries, [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
1426  return V.get() == &Q;
1427  });
1428  assert(I != PendingQueries.end() &&
1429  "Query is not attached to this MaterializingInfo");
1430  PendingQueries.erase(I);
1431 }
1432 
1433 JITDylib::AsynchronousSymbolQueryList
1434 JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {
1435  AsynchronousSymbolQueryList Result;
1436  while (!PendingQueries.empty()) {
1437  if (PendingQueries.back()->getRequiredState() > RequiredState)
1438  break;
1439 
1440  Result.push_back(std::move(PendingQueries.back()));
1441  PendingQueries.pop_back();
1442  }
1443 
1444  return Result;
1445 }
1446 
1447 JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
1448  : ES(ES), JITDylibName(std::move(Name)) {
1449  LinkOrder.push_back({this, JITDylibLookupFlags::MatchAllSymbols});
1450 }
1451 
1452 ResourceTrackerSP JITDylib::getTracker(MaterializationResponsibility &MR) {
1453  auto I = MRTrackers.find(&MR);
1454  assert(I != MRTrackers.end() && "MR is not linked");
1455  assert(I->second && "Linked tracker is null");
1456  return I->second;
1457 }
1458 
1460  std::shared_ptr<SymbolDependenceMap>>
1461 JITDylib::removeTracker(ResourceTracker &RT) {
1462  // Note: Should be called under the session lock.
1463 
1464  SymbolNameVector SymbolsToRemove;
1465  std::vector<std::pair<JITDylib *, SymbolStringPtr>> SymbolsToFail;
1466 
1467  if (&RT == DefaultTracker.get()) {
1468  SymbolNameSet TrackedSymbols;
1469  for (auto &KV : TrackerSymbols)
1470  for (auto &Sym : KV.second)
1471  TrackedSymbols.insert(Sym);
1472 
1473  for (auto &KV : Symbols) {
1474  auto &Sym = KV.first;
1475  if (!TrackedSymbols.count(Sym))
1476  SymbolsToRemove.push_back(Sym);
1477  }
1478 
1479  DefaultTracker.reset();
1480  } else {
1481  /// Check for a non-default tracker.
1482  auto I = TrackerSymbols.find(&RT);
1483  if (I != TrackerSymbols.end()) {
1484  SymbolsToRemove = std::move(I->second);
1485  TrackerSymbols.erase(I);
1486  }
1487  // ... if not found this tracker was already defunct. Nothing to do.
1488  }
1489 
1490  for (auto &Sym : SymbolsToRemove) {
1491  assert(Symbols.count(Sym) && "Symbol not in symbol table");
1492 
1493  // If there is a MaterializingInfo then collect any queries to fail.
1494  auto MII = MaterializingInfos.find(Sym);
1495  if (MII != MaterializingInfos.end())
1496  SymbolsToFail.push_back({this, Sym});
1497  }
1498 
1499  AsynchronousSymbolQuerySet QueriesToFail;
1500  auto Result = failSymbols(std::move(SymbolsToFail));
1501 
1502  // Removed symbols should be taken out of the table altogether.
1503  for (auto &Sym : SymbolsToRemove) {
1504  auto I = Symbols.find(Sym);
1505  assert(I != Symbols.end() && "Symbol not present in table");
1506 
1507  // Remove Materializer if present.
1508  if (I->second.hasMaterializerAttached()) {
1509  // FIXME: Should this discard the symbols?
1510  UnmaterializedInfos.erase(Sym);
1511  } else {
1512  assert(!UnmaterializedInfos.count(Sym) &&
1513  "Symbol has materializer attached");
1514  }
1515 
1516  Symbols.erase(I);
1517  }
1518 
1519  return Result;
1520 }
1521 
1522 void JITDylib::transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT) {
1523  assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");
1524  assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");
1525  assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");
1526 
1527  // Update trackers for any not-yet materialized units.
1528  for (auto &KV : UnmaterializedInfos) {
1529  if (KV.second->RT == &SrcRT)
1530  KV.second->RT = &DstRT;
1531  }
1532 
1533  // Update trackers for any active materialization responsibilities.
1534  for (auto &KV : MRTrackers) {
1535  if (KV.second == &SrcRT)
1536  KV.second = &DstRT;
1537  }
1538 
1539  // If we're transfering to the default tracker we just need to delete the
1540  // tracked symbols for the source tracker.
1541  if (&DstRT == DefaultTracker.get()) {
1542  TrackerSymbols.erase(&SrcRT);
1543  return;
1544  }
1545 
1546  // If we're transferring from the default tracker we need to find all
1547  // currently untracked symbols.
1548  if (&SrcRT == DefaultTracker.get()) {
1549  assert(!TrackerSymbols.count(&SrcRT) &&
1550  "Default tracker should not appear in TrackerSymbols");
1551 
1552  SymbolNameVector SymbolsToTrack;
1553 
1554  SymbolNameSet CurrentlyTrackedSymbols;
1555  for (auto &KV : TrackerSymbols)
1556  for (auto &Sym : KV.second)
1557  CurrentlyTrackedSymbols.insert(Sym);
1558 
1559  for (auto &KV : Symbols) {
1560  auto &Sym = KV.first;
1561  if (!CurrentlyTrackedSymbols.count(Sym))
1562  SymbolsToTrack.push_back(Sym);
1563  }
1564 
1565  TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);
1566  return;
1567  }
1568 
1569  auto &DstTrackedSymbols = TrackerSymbols[&DstRT];
1570 
1571  // Finally if neither SrtRT or DstRT are the default tracker then
1572  // just append DstRT's tracked symbols to SrtRT's.
1573  auto SI = TrackerSymbols.find(&SrcRT);
1574  if (SI == TrackerSymbols.end())
1575  return;
1576 
1577  DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());
1578  for (auto &Sym : SI->second)
1579  DstTrackedSymbols.push_back(std::move(Sym));
1580  TrackerSymbols.erase(SI);
1581 }
1582 
1583 Error JITDylib::defineImpl(MaterializationUnit &MU) {
1584 
1585  LLVM_DEBUG({ dbgs() << " " << MU.getSymbols() << "\n"; });
1586 
1587  SymbolNameSet Duplicates;
1588  std::vector<SymbolStringPtr> ExistingDefsOverridden;
1589  std::vector<SymbolStringPtr> MUDefsOverridden;
1590 
1591  for (const auto &KV : MU.getSymbols()) {
1592  auto I = Symbols.find(KV.first);
1593 
1594  if (I != Symbols.end()) {
1595  if (KV.second.isStrong()) {
1596  if (I->second.getFlags().isStrong() ||
1597  I->second.getState() > SymbolState::NeverSearched)
1598  Duplicates.insert(KV.first);
1599  else {
1600  assert(I->second.getState() == SymbolState::NeverSearched &&
1601  "Overridden existing def should be in the never-searched "
1602  "state");
1603  ExistingDefsOverridden.push_back(KV.first);
1604  }
1605  } else
1606  MUDefsOverridden.push_back(KV.first);
1607  }
1608  }
1609 
1610  // If there were any duplicate definitions then bail out.
1611  if (!Duplicates.empty()) {
1612  LLVM_DEBUG(
1613  { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; });
1614  return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()));
1615  }
1616 
1617  // Discard any overridden defs in this MU.
1618  LLVM_DEBUG({
1619  if (!MUDefsOverridden.empty())
1620  dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n";
1621  });
1622  for (auto &S : MUDefsOverridden)
1623  MU.doDiscard(*this, S);
1624 
1625  // Discard existing overridden defs.
1626  LLVM_DEBUG({
1627  if (!ExistingDefsOverridden.empty())
1628  dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden
1629  << "\n";
1630  });
1631  for (auto &S : ExistingDefsOverridden) {
1632 
1633  auto UMII = UnmaterializedInfos.find(S);
1634  assert(UMII != UnmaterializedInfos.end() &&
1635  "Overridden existing def should have an UnmaterializedInfo");
1636  UMII->second->MU->doDiscard(*this, S);
1637  }
1638 
1639  // Finally, add the defs from this MU.
1640  for (auto &KV : MU.getSymbols()) {
1641  auto &SymEntry = Symbols[KV.first];
1642  SymEntry.setFlags(KV.second);
1643  SymEntry.setState(SymbolState::NeverSearched);
1644  SymEntry.setMaterializerAttached(true);
1645  }
1646 
1647  return Error::success();
1648 }
1649 
1650 void JITDylib::installMaterializationUnit(
1651  std::unique_ptr<MaterializationUnit> MU, ResourceTracker &RT) {
1652 
1653  /// defineImpl succeeded.
1654  if (&RT != DefaultTracker.get()) {
1655  auto &TS = TrackerSymbols[&RT];
1656  TS.reserve(TS.size() + MU->getSymbols().size());
1657  for (auto &KV : MU->getSymbols())
1658  TS.push_back(KV.first);
1659  }
1660 
1661  auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU), &RT);
1662  for (auto &KV : UMI->MU->getSymbols())
1663  UnmaterializedInfos[KV.first] = UMI;
1664 }
1665 
1666 void JITDylib::detachQueryHelper(AsynchronousSymbolQuery &Q,
1667  const SymbolNameSet &QuerySymbols) {
1668  for (auto &QuerySymbol : QuerySymbols) {
1669  assert(MaterializingInfos.count(QuerySymbol) &&
1670  "QuerySymbol does not have MaterializingInfo");
1671  auto &MI = MaterializingInfos[QuerySymbol];
1672  MI.removeQuery(Q);
1673  }
1674 }
1675 
1676 void JITDylib::transferEmittedNodeDependencies(
1677  MaterializingInfo &DependantMI, const SymbolStringPtr &DependantName,
1678  MaterializingInfo &EmittedMI) {
1679  for (auto &KV : EmittedMI.UnemittedDependencies) {
1680  auto &DependencyJD = *KV.first;
1681  SymbolNameSet *UnemittedDependenciesOnDependencyJD = nullptr;
1682 
1683  for (auto &DependencyName : KV.second) {
1684  auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1685 
1686  // Do not add self dependencies.
1687  if (&DependencyMI == &DependantMI)
1688  continue;
1689 
1690  // If we haven't looked up the dependencies for DependencyJD yet, do it
1691  // now and cache the result.
1692  if (!UnemittedDependenciesOnDependencyJD)
1693  UnemittedDependenciesOnDependencyJD =
1694  &DependantMI.UnemittedDependencies[&DependencyJD];
1695 
1696  DependencyMI.Dependants[this].insert(DependantName);
1697  UnemittedDependenciesOnDependencyJD->insert(DependencyName);
1698  }
1699  }
1700 }
1701 
1703 
1705  ExecutionSession &ES,
1706  const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1707 
1708  DenseMap<JITDylib *, SymbolMap> CompoundResult;
1709  Error CompoundErr = Error::success();
1710  std::mutex LookupMutex;
1711  std::condition_variable CV;
1712  uint64_t Count = InitSyms.size();
1713 
1714  LLVM_DEBUG({
1715  dbgs() << "Issuing init-symbol lookup:\n";
1716  for (auto &KV : InitSyms)
1717  dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1718  });
1719 
1720  for (auto &KV : InitSyms) {
1721  auto *JD = KV.first;
1722  auto Names = std::move(KV.second);
1723  ES.lookup(
1726  std::move(Names), SymbolState::Ready,
1727  [&, JD](Expected<SymbolMap> Result) {
1728  {
1729  std::lock_guard<std::mutex> Lock(LookupMutex);
1730  --Count;
1731  if (Result) {
1732  assert(!CompoundResult.count(JD) &&
1733  "Duplicate JITDylib in lookup?");
1734  CompoundResult[JD] = std::move(*Result);
1735  } else
1736  CompoundErr =
1737  joinErrors(std::move(CompoundErr), Result.takeError());
1738  }
1739  CV.notify_one();
1740  },
1742  }
1743 
1744  std::unique_lock<std::mutex> Lock(LookupMutex);
1745  CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });
1746 
1747  if (CompoundErr)
1748  return std::move(CompoundErr);
1749 
1750  return std::move(CompoundResult);
1751 }
1752 
1754  unique_function<void(Error)> OnComplete, ExecutionSession &ES,
1755  const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {
1756 
1757  class TriggerOnComplete {
1758  public:
1759  using OnCompleteFn = unique_function<void(Error)>;
1760  TriggerOnComplete(OnCompleteFn OnComplete)
1761  : OnComplete(std::move(OnComplete)) {}
1762  ~TriggerOnComplete() { OnComplete(std::move(LookupResult)); }
1763  void reportResult(Error Err) {
1764  std::lock_guard<std::mutex> Lock(ResultMutex);
1766  }
1767 
1768  private:
1769  std::mutex ResultMutex;
1771  OnCompleteFn OnComplete;
1772  };
1773 
1774  LLVM_DEBUG({
1775  dbgs() << "Issuing init-symbol lookup:\n";
1776  for (auto &KV : InitSyms)
1777  dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
1778  });
1779 
1780  auto TOC = std::make_shared<TriggerOnComplete>(std::move(OnComplete));
1781 
1782  for (auto &KV : InitSyms) {
1783  auto *JD = KV.first;
1784  auto Names = std::move(KV.second);
1785  ES.lookup(
1788  std::move(Names), SymbolState::Ready,
1789  [TOC](Expected<SymbolMap> Result) {
1790  TOC->reportResult(Result.takeError());
1791  },
1793  }
1794 }
1795 
1796 void Task::anchor() {}
1797 
1799  OS << "Materialization task: " << MU->getName() << " in "
1800  << MR->getTargetJITDylib().getName();
1801 }
1802 
1803 void MaterializationTask::run() { MU->materialize(std::move(MR)); }
1804 
1805 ExecutionSession::ExecutionSession(std::unique_ptr<ExecutorProcessControl> EPC)
1806  : EPC(std::move(EPC)) {
1807  // Associated EPC and this.
1808  this->EPC->ES = this;
1809 }
1810 
1812  LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
1813 
1814  std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] {
1815  SessionOpen = false;
1816  return std::move(JDs);
1817  });
1818 
1819  // TODO: notifiy platform? run static deinits?
1820 
1821  Error Err = Error::success();
1822  for (auto &JD : JITDylibsToClose)
1823  Err = joinErrors(std::move(Err), JD->clear());
1824 
1825  Err = joinErrors(std::move(Err), EPC->disconnect());
1826 
1827  return Err;
1828 }
1829 
1831  runSessionLocked([&] { ResourceManagers.push_back(&RM); });
1832 }
1833 
1835  runSessionLocked([&] {
1836  assert(!ResourceManagers.empty() && "No managers registered");
1837  if (ResourceManagers.back() == &RM)
1838  ResourceManagers.pop_back();
1839  else {
1840  auto I = llvm::find(ResourceManagers, &RM);
1841  assert(I != ResourceManagers.end() && "RM not registered");
1842  ResourceManagers.erase(I);
1843  }
1844  });
1845 }
1846 
1848  return runSessionLocked([&, this]() -> JITDylib * {
1849  for (auto &JD : JDs)
1850  if (JD->getName() == Name)
1851  return JD.get();
1852  return nullptr;
1853  });
1854 }
1855 
1857  assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");
1858  return runSessionLocked([&, this]() -> JITDylib & {
1859  JDs.push_back(new JITDylib(*this, std::move(Name)));
1860  return *JDs.back();
1861  });
1862 }
1863 
1865  auto &JD = createBareJITDylib(Name);
1866  if (P)
1867  if (auto Err = P->setupJITDylib(JD))
1868  return std::move(Err);
1869  return JD;
1870 }
1871 
1872 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder(ArrayRef<JITDylibSP> JDs) {
1873  if (JDs.empty())
1874  return {};
1875 
1876  auto &ES = JDs.front()->getExecutionSession();
1877  return ES.runSessionLocked([&]() {
1878  DenseSet<JITDylib *> Visited;
1879  std::vector<JITDylibSP> Result;
1880 
1881  for (auto &JD : JDs) {
1882 
1883  if (Visited.count(JD.get()))
1884  continue;
1885 
1886  SmallVector<JITDylibSP, 64> WorkStack;
1887  WorkStack.push_back(JD);
1888  Visited.insert(JD.get());
1889 
1890  while (!WorkStack.empty()) {
1891  Result.push_back(std::move(WorkStack.back()));
1892  WorkStack.pop_back();
1893 
1894  for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) {
1895  auto &JD = *KV.first;
1896  if (Visited.count(&JD))
1897  continue;
1898  Visited.insert(&JD);
1899  WorkStack.push_back(&JD);
1900  }
1901  }
1902  }
1903  return Result;
1904  });
1905 }
1906 
1907 std::vector<JITDylibSP>
1909  auto Tmp = getDFSLinkOrder(JDs);
1910  std::reverse(Tmp.begin(), Tmp.end());
1911  return Tmp;
1912 }
1913 
1914 std::vector<JITDylibSP> JITDylib::getDFSLinkOrder() {
1915  return getDFSLinkOrder({this});
1916 }
1917 
1918 std::vector<JITDylibSP> JITDylib::getReverseDFSLinkOrder() {
1919  return getReverseDFSLinkOrder({this});
1920 }
1921 
1923  LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet,
1924  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
1925 
1926  OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
1927  K, std::move(SearchOrder), std::move(LookupSet),
1928  std::move(OnComplete)),
1929  Error::success());
1930 }
1931 
1934  SymbolLookupSet LookupSet) {
1935 
1936  std::promise<MSVCPExpected<SymbolFlagsMap>> ResultP;
1937  OL_applyQueryPhase1(std::make_unique<InProgressLookupFlagsState>(
1938  K, std::move(SearchOrder), std::move(LookupSet),
1939  [&ResultP](Expected<SymbolFlagsMap> Result) {
1940  ResultP.set_value(std::move(Result));
1941  }),
1942  Error::success());
1943 
1944  auto ResultF = ResultP.get_future();
1945  return ResultF.get();
1946 }
1947 
1949  LookupKind K, const JITDylibSearchOrder &SearchOrder,
1950  SymbolLookupSet Symbols, SymbolState RequiredState,
1951  SymbolsResolvedCallback NotifyComplete,
1952  RegisterDependenciesFunction RegisterDependencies) {
1953 
1954  LLVM_DEBUG({
1955  runSessionLocked([&]() {
1956  dbgs() << "Looking up " << Symbols << " in " << SearchOrder
1957  << " (required state: " << RequiredState << ")\n";
1958  });
1959  });
1960 
1961  // lookup can be re-entered recursively if running on a single thread. Run any
1962  // outstanding MUs in case this query depends on them, otherwise this lookup
1963  // will starve waiting for a result from an MU that is stuck in the queue.
1964  dispatchOutstandingMUs();
1965 
1966  auto Unresolved = std::move(Symbols);
1967  auto Q = std::make_shared<AsynchronousSymbolQuery>(Unresolved, RequiredState,
1968  std::move(NotifyComplete));
1969 
1970  auto IPLS = std::make_unique<InProgressFullLookupState>(
1971  K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),
1972  std::move(RegisterDependencies));
1973 
1974  OL_applyQueryPhase1(std::move(IPLS), Error::success());
1975 }
1976 
1979  const SymbolLookupSet &Symbols, LookupKind K,
1980  SymbolState RequiredState,
1981  RegisterDependenciesFunction RegisterDependencies) {
1982 #if LLVM_ENABLE_THREADS
1983  // In the threaded case we use promises to return the results.
1984  std::promise<SymbolMap> PromisedResult;
1985  Error ResolutionError = Error::success();
1986 
1987  auto NotifyComplete = [&](Expected<SymbolMap> R) {
1988  if (R)
1989  PromisedResult.set_value(std::move(*R));
1990  else {
1991  ErrorAsOutParameter _(&ResolutionError);
1992  ResolutionError = R.takeError();
1993  PromisedResult.set_value(SymbolMap());
1994  }
1995  };
1996 
1997 #else
1998  SymbolMap Result;
1999  Error ResolutionError = Error::success();
2000 
2001  auto NotifyComplete = [&](Expected<SymbolMap> R) {
2002  ErrorAsOutParameter _(&ResolutionError);
2003  if (R)
2004  Result = std::move(*R);
2005  else
2006  ResolutionError = R.takeError();
2007  };
2008 #endif
2009 
2010  // Perform the asynchronous lookup.
2011  lookup(K, SearchOrder, Symbols, RequiredState, NotifyComplete,
2012  RegisterDependencies);
2013 
2014 #if LLVM_ENABLE_THREADS
2015  auto ResultFuture = PromisedResult.get_future();
2016  auto Result = ResultFuture.get();
2017 
2018  if (ResolutionError)
2019  return std::move(ResolutionError);
2020 
2021  return std::move(Result);
2022 
2023 #else
2024  if (ResolutionError)
2025  return std::move(ResolutionError);
2026 
2027  return Result;
2028 #endif
2029 }
2030 
2033  SymbolStringPtr Name, SymbolState RequiredState) {
2034  SymbolLookupSet Names({Name});
2035 
2036  if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,
2037  RequiredState, NoDependenciesToRegister)) {
2038  assert(ResultMap->size() == 1 && "Unexpected number of results");
2039  assert(ResultMap->count(Name) && "Missing result for symbol");
2040  return std::move(ResultMap->begin()->second);
2041  } else
2042  return ResultMap.takeError();
2043 }
2044 
2047  SymbolState RequiredState) {
2048  return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);
2049 }
2050 
2053  SymbolState RequiredState) {
2054  return lookup(SearchOrder, intern(Name), RequiredState);
2055 }
2056 
2059 
2060  auto TagAddrs = lookup({{&JD, JITDylibLookupFlags::MatchAllSymbols}},
2063  if (!TagAddrs)
2064  return TagAddrs.takeError();
2065 
2066  // Associate tag addresses with implementations.
2067  std::lock_guard<std::mutex> Lock(JITDispatchHandlersMutex);
2068  for (auto &KV : *TagAddrs) {
2069  auto TagAddr = KV.second.getAddress();
2070  if (JITDispatchHandlers.count(TagAddr))
2071  return make_error<StringError>("Tag " + formatv("{0:x16}", TagAddr) +
2072  " (for " + *KV.first +
2073  ") already registered",
2075  auto I = WFs.find(KV.first);
2076  assert(I != WFs.end() && I->second &&
2077  "JITDispatchHandler implementation missing");
2078  JITDispatchHandlers[KV.second.getAddress()] =
2079  std::make_shared<JITDispatchHandlerFunction>(std::move(I->second));
2080  LLVM_DEBUG({
2081  dbgs() << "Associated function tag \"" << *KV.first << "\" ("
2082  << formatv("{0:x}", KV.second.getAddress()) << ") with handler\n";
2083  });
2084  }
2085  return Error::success();
2086 }
2087 
2090  JITTargetAddress HandlerFnTagAddr, ArrayRef<char> ArgBuffer) {
2091 
2092  std::shared_ptr<JITDispatchHandlerFunction> F;
2093  {
2094  std::lock_guard<std::mutex> Lock(JITDispatchHandlersMutex);
2095  auto I = JITDispatchHandlers.find(HandlerFnTagAddr);
2096  if (I != JITDispatchHandlers.end())
2097  F = I->second;
2098  }
2099 
2100  if (F)
2101  (*F)(std::move(SendResult), ArgBuffer.data(), ArgBuffer.size());
2102  else
2104  ("No function registered for tag " +
2105  formatv("{0:x16}", HandlerFnTagAddr))
2106  .str()));
2107 }
2108 
2110  runSessionLocked([this, &OS]() {
2111  for (auto &JD : JDs)
2112  JD->dump(OS);
2113  });
2114 }
2115 
2116 void ExecutionSession::dispatchOutstandingMUs() {
2117  LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");
2118  while (1) {
2120  std::unique_ptr<MaterializationResponsibility>>>
2121  JMU;
2122 
2123  {
2124  std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2125  if (!OutstandingMUs.empty()) {
2126  JMU.emplace(std::move(OutstandingMUs.back()));
2127  OutstandingMUs.pop_back();
2128  }
2129  }
2130 
2131  if (!JMU)
2132  break;
2133 
2134  assert(JMU->first && "No MU?");
2135  LLVM_DEBUG(dbgs() << " Dispatching \"" << JMU->first->getName() << "\"\n");
2136  dispatchTask(std::make_unique<MaterializationTask>(std::move(JMU->first),
2137  std::move(JMU->second)));
2138  }
2139  LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");
2140 }
2141 
2142 Error ExecutionSession::removeResourceTracker(ResourceTracker &RT) {
2143  LLVM_DEBUG({
2144  dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "
2145  << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2146  });
2147  std::vector<ResourceManager *> CurrentResourceManagers;
2148 
2150  std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2151 
2152  runSessionLocked([&] {
2153  CurrentResourceManagers = ResourceManagers;
2154  RT.makeDefunct();
2155  std::tie(QueriesToFail, FailedSymbols) = RT.getJITDylib().removeTracker(RT);
2156  });
2157 
2158  Error Err = Error::success();
2159 
2160  for (auto *L : reverse(CurrentResourceManagers))
2161  Err =
2162  joinErrors(std::move(Err), L->handleRemoveResources(RT.getKeyUnsafe()));
2163 
2164  for (auto &Q : QueriesToFail)
2165  Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
2166 
2167  return Err;
2168 }
2169 
2170 void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,
2171  ResourceTracker &SrcRT) {
2172  LLVM_DEBUG({
2173  dbgs() << "In " << SrcRT.getJITDylib().getName()
2174  << " transfering resources from tracker "
2175  << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "
2176  << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";
2177  });
2178 
2179  // No-op transfers are allowed and do not invalidate the source.
2180  if (&DstRT == &SrcRT)
2181  return;
2182 
2183  assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&
2184  "Can't transfer resources between JITDylibs");
2185  runSessionLocked([&]() {
2186  SrcRT.makeDefunct();
2187  auto &JD = DstRT.getJITDylib();
2188  JD.transferTracker(DstRT, SrcRT);
2189  for (auto *L : reverse(ResourceManagers))
2190  L->handleTransferResources(DstRT.getKeyUnsafe(), SrcRT.getKeyUnsafe());
2191  });
2192 }
2193 
2194 void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {
2195  runSessionLocked([&]() {
2196  LLVM_DEBUG({
2197  dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "
2198  << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";
2199  });
2200  if (!RT.isDefunct())
2201  transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),
2202  RT);
2203  });
2204 }
2205 
2206 Error ExecutionSession::IL_updateCandidatesFor(
2207  JITDylib &JD, JITDylibLookupFlags JDLookupFlags,
2208  SymbolLookupSet &Candidates, SymbolLookupSet *NonCandidates) {
2209  return Candidates.forEachWithRemoval(
2210  [&](const SymbolStringPtr &Name,
2211  SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2212  /// Search for the symbol. If not found then continue without
2213  /// removal.
2214  auto SymI = JD.Symbols.find(Name);
2215  if (SymI == JD.Symbols.end())
2216  return false;
2217 
2218  // If this is a non-exported symbol and we're matching exported
2219  // symbols only then remove this symbol from the candidates list.
2220  //
2221  // If we're tracking non-candidates then add this to the non-candidate
2222  // list.
2223  if (!SymI->second.getFlags().isExported() &&
2225  if (NonCandidates)
2226  NonCandidates->add(Name, SymLookupFlags);
2227  return true;
2228  }
2229 
2230  // If we match against a materialization-side-effects only symbol
2231  // then make sure it is weakly-referenced. Otherwise bail out with
2232  // an error.
2233  // FIXME: Use a "materialization-side-effects-only symbols must be
2234  // weakly referenced" specific error here to reduce confusion.
2235  if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2237  return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
2238 
2239  // If we matched against this symbol but it is in the error state
2240  // then bail out and treat it as a failure to materialize.
2241  if (SymI->second.getFlags().hasError()) {
2242  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2243  (*FailedSymbolsMap)[&JD] = {Name};
2244  return make_error<FailedToMaterialize>(std::move(FailedSymbolsMap));
2245  }
2246 
2247  // Otherwise this is a match. Remove it from the candidate set.
2248  return true;
2249  });
2250 }
2251 
2252 void ExecutionSession::OL_applyQueryPhase1(
2253  std::unique_ptr<InProgressLookupState> IPLS, Error Err) {
2254 
2255  LLVM_DEBUG({
2256  dbgs() << "Entering OL_applyQueryPhase1:\n"
2257  << " Lookup kind: " << IPLS->K << "\n"
2258  << " Search order: " << IPLS->SearchOrder
2259  << ", Current index = " << IPLS->CurSearchOrderIndex
2260  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2261  << " Lookup set: " << IPLS->LookupSet << "\n"
2262  << " Definition generator candidates: "
2263  << IPLS->DefGeneratorCandidates << "\n"
2264  << " Definition generator non-candidates: "
2265  << IPLS->DefGeneratorNonCandidates << "\n";
2266  });
2267 
2268  // FIXME: We should attach the query as we go: This provides a result in a
2269  // single pass in the common case where all symbols have already reached the
2270  // required state. The query could be detached again in the 'fail' method on
2271  // IPLS. Phase 2 would be reduced to collecting and dispatching the MUs.
2272 
2273  while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {
2274 
2275  // If we've been handed an error or received one back from a generator then
2276  // fail the query. We don't need to unlink: At this stage the query hasn't
2277  // actually been lodged.
2278  if (Err)
2279  return IPLS->fail(std::move(Err));
2280 
2281  // Get the next JITDylib and lookup flags.
2282  auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];
2283  auto &JD = *KV.first;
2284  auto JDLookupFlags = KV.second;
2285 
2286  LLVM_DEBUG({
2287  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2288  << ") with lookup set " << IPLS->LookupSet << ":\n";
2289  });
2290 
2291  // If we've just reached a new JITDylib then perform some setup.
2292  if (IPLS->NewJITDylib) {
2293 
2294  // Acquire the generator lock for this JITDylib.
2295  IPLS->GeneratorLock = std::unique_lock<std::mutex>(JD.GeneratorsMutex);
2296 
2297  // Add any non-candidates from the last JITDylib (if any) back on to the
2298  // list of definition candidates for this JITDylib, reset definition
2299  // non-candiates to the empty set.
2300  SymbolLookupSet Tmp;
2301  std::swap(IPLS->DefGeneratorNonCandidates, Tmp);
2302  IPLS->DefGeneratorCandidates.append(std::move(Tmp));
2303 
2304  LLVM_DEBUG({
2305  dbgs() << " First time visiting " << JD.getName()
2306  << ", resetting candidate sets and building generator stack\n";
2307  });
2308 
2309  // Build the definition generator stack for this JITDylib.
2310  for (auto &DG : reverse(JD.DefGenerators))
2311  IPLS->CurDefGeneratorStack.push_back(DG);
2312 
2313  // Flag that we've done our initialization.
2314  IPLS->NewJITDylib = false;
2315  }
2316 
2317  // Remove any generation candidates that are already defined (and match) in
2318  // this JITDylib.
2319  runSessionLocked([&] {
2320  // Update the list of candidates (and non-candidates) for definition
2321  // generation.
2322  LLVM_DEBUG(dbgs() << " Updating candidate set...\n");
2323  Err = IL_updateCandidatesFor(
2324  JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2325  JD.DefGenerators.empty() ? nullptr
2326  : &IPLS->DefGeneratorNonCandidates);
2327  LLVM_DEBUG({
2328  dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates
2329  << "\n";
2330  });
2331  });
2332 
2333  // If we encountered an error while filtering generation candidates then
2334  // bail out.
2335  if (Err)
2336  return IPLS->fail(std::move(Err));
2337 
2338  /// Apply any definition generators on the stack.
2339  LLVM_DEBUG({
2340  if (IPLS->CurDefGeneratorStack.empty())
2341  LLVM_DEBUG(dbgs() << " No generators to run for this JITDylib.\n");
2342  else if (IPLS->DefGeneratorCandidates.empty())
2343  LLVM_DEBUG(dbgs() << " No candidates to generate.\n");
2344  else
2345  dbgs() << " Running " << IPLS->CurDefGeneratorStack.size()
2346  << " remaining generators for "
2347  << IPLS->DefGeneratorCandidates.size() << " candidates\n";
2348  });
2349  while (!IPLS->CurDefGeneratorStack.empty() &&
2350  !IPLS->DefGeneratorCandidates.empty()) {
2351  auto DG = IPLS->CurDefGeneratorStack.back().lock();
2352  IPLS->CurDefGeneratorStack.pop_back();
2353 
2354  if (!DG)
2355  return IPLS->fail(make_error<StringError>(
2356  "DefinitionGenerator removed while lookup in progress",
2358 
2359  auto K = IPLS->K;
2360  auto &LookupSet = IPLS->DefGeneratorCandidates;
2361 
2362  // Run the generator. If the generator takes ownership of QA then this
2363  // will break the loop.
2364  {
2365  LLVM_DEBUG(dbgs() << " Attempting to generate " << LookupSet << "\n");
2366  LookupState LS(std::move(IPLS));
2367  Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);
2368  IPLS = std::move(LS.IPLS);
2369  }
2370 
2371  // If there was an error then fail the query.
2372  if (Err) {
2373  LLVM_DEBUG({
2374  dbgs() << " Error attempting to generate " << LookupSet << "\n";
2375  });
2376  assert(IPLS && "LS cannot be retained if error is returned");
2377  return IPLS->fail(std::move(Err));
2378  }
2379 
2380  // Otherwise if QA was captured then break the loop.
2381  if (!IPLS) {
2382  LLVM_DEBUG(
2383  { dbgs() << " LookupState captured. Exiting phase1 for now.\n"; });
2384  return;
2385  }
2386 
2387  // Otherwise if we're continuing around the loop then update candidates
2388  // for the next round.
2389  runSessionLocked([&] {
2390  LLVM_DEBUG(dbgs() << " Updating candidate set post-generation\n");
2391  Err = IL_updateCandidatesFor(
2392  JD, JDLookupFlags, IPLS->DefGeneratorCandidates,
2393  JD.DefGenerators.empty() ? nullptr
2394  : &IPLS->DefGeneratorNonCandidates);
2395  });
2396 
2397  // If updating candidates failed then fail the query.
2398  if (Err) {
2399  LLVM_DEBUG(dbgs() << " Error encountered while updating candidates\n");
2400  return IPLS->fail(std::move(Err));
2401  }
2402  }
2403 
2404  // If we get here then we've moved on to the next JITDylib.
2405  LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");
2406  ++IPLS->CurSearchOrderIndex;
2407  IPLS->NewJITDylib = true;
2408  }
2409 
2410  // Remove any weakly referenced candidates that could not be found/generated.
2411  IPLS->DefGeneratorCandidates.remove_if(
2412  [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2413  return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2414  });
2415 
2416  // If we get here then we've finished searching all JITDylibs.
2417  // If we matched all symbols then move to phase 2, otherwise fail the query
2418  // with a SymbolsNotFound error.
2419  if (IPLS->DefGeneratorCandidates.empty()) {
2420  LLVM_DEBUG(dbgs() << "Phase 1 succeeded.\n");
2421  IPLS->complete(std::move(IPLS));
2422  } else {
2423  LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");
2424  IPLS->fail(make_error<SymbolsNotFound>(
2425  IPLS->DefGeneratorCandidates.getSymbolNames()));
2426  }
2427 }
2428 
2429 void ExecutionSession::OL_completeLookup(
2430  std::unique_ptr<InProgressLookupState> IPLS,
2431  std::shared_ptr<AsynchronousSymbolQuery> Q,
2432  RegisterDependenciesFunction RegisterDependencies) {
2433 
2434  LLVM_DEBUG({
2435  dbgs() << "Entering OL_completeLookup:\n"
2436  << " Lookup kind: " << IPLS->K << "\n"
2437  << " Search order: " << IPLS->SearchOrder
2438  << ", Current index = " << IPLS->CurSearchOrderIndex
2439  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2440  << " Lookup set: " << IPLS->LookupSet << "\n"
2441  << " Definition generator candidates: "
2442  << IPLS->DefGeneratorCandidates << "\n"
2443  << " Definition generator non-candidates: "
2444  << IPLS->DefGeneratorNonCandidates << "\n";
2445  });
2446 
2447  bool QueryComplete = false;
2448  DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;
2449 
2450  auto LodgingErr = runSessionLocked([&]() -> Error {
2451  for (auto &KV : IPLS->SearchOrder) {
2452  auto &JD = *KV.first;
2453  auto JDLookupFlags = KV.second;
2454  LLVM_DEBUG({
2455  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2456  << ") with lookup set " << IPLS->LookupSet << ":\n";
2457  });
2458 
2459  auto Err = IPLS->LookupSet.forEachWithRemoval(
2460  [&](const SymbolStringPtr &Name,
2461  SymbolLookupFlags SymLookupFlags) -> Expected<bool> {
2462  LLVM_DEBUG({
2463  dbgs() << " Attempting to match \"" << Name << "\" ("
2464  << SymLookupFlags << ")... ";
2465  });
2466 
2467  /// Search for the symbol. If not found then continue without
2468  /// removal.
2469  auto SymI = JD.Symbols.find(Name);
2470  if (SymI == JD.Symbols.end()) {
2471  LLVM_DEBUG(dbgs() << "skipping: not present\n");
2472  return false;
2473  }
2474 
2475  // If this is a non-exported symbol and we're matching exported
2476  // symbols only then skip this symbol without removal.
2477  if (!SymI->second.getFlags().isExported() &&
2478  JDLookupFlags ==
2480  LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2481  return false;
2482  }
2483 
2484  // If we match against a materialization-side-effects only symbol
2485  // then make sure it is weakly-referenced. Otherwise bail out with
2486  // an error.
2487  // FIXME: Use a "materialization-side-effects-only symbols must be
2488  // weakly referenced" specific error here to reduce confusion.
2489  if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&
2490  SymLookupFlags != SymbolLookupFlags::WeaklyReferencedSymbol) {
2491  LLVM_DEBUG({
2492  dbgs() << "error: "
2493  "required, but symbol is has-side-effects-only\n";
2494  });
2495  return make_error<SymbolsNotFound>(SymbolNameVector({Name}));
2496  }
2497 
2498  // If we matched against this symbol but it is in the error state
2499  // then bail out and treat it as a failure to materialize.
2500  if (SymI->second.getFlags().hasError()) {
2501  LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");
2502  auto FailedSymbolsMap = std::make_shared<SymbolDependenceMap>();
2503  (*FailedSymbolsMap)[&JD] = {Name};
2504  return make_error<FailedToMaterialize>(
2505  std::move(FailedSymbolsMap));
2506  }
2507 
2508  // Otherwise this is a match.
2509 
2510  // If this symbol is already in the requried state then notify the
2511  // query, remove the symbol and continue.
2512  if (SymI->second.getState() >= Q->getRequiredState()) {
2513  LLVM_DEBUG(dbgs()
2514  << "matched, symbol already in required state\n");
2515  Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
2516  return true;
2517  }
2518 
2519  // Otherwise this symbol does not yet meet the required state. Check
2520  // whether it has a materializer attached, and if so prepare to run
2521  // it.
2522  if (SymI->second.hasMaterializerAttached()) {
2523  assert(SymI->second.getAddress() == 0 &&
2524  "Symbol not resolved but already has address?");
2525  auto UMII = JD.UnmaterializedInfos.find(Name);
2526  assert(UMII != JD.UnmaterializedInfos.end() &&
2527  "Lazy symbol should have UnmaterializedInfo");
2528 
2529  auto UMI = UMII->second;
2530  assert(UMI->MU && "Materializer should not be null");
2531  assert(UMI->RT && "Tracker should not be null");
2532  LLVM_DEBUG({
2533  dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()
2534  << " (" << UMI->MU->getName() << ")\n";
2535  });
2536 
2537  // Move all symbols associated with this MaterializationUnit into
2538  // materializing state.
2539  for (auto &KV : UMI->MU->getSymbols()) {
2540  auto SymK = JD.Symbols.find(KV.first);
2541  assert(SymK != JD.Symbols.end() &&
2542  "No entry for symbol covered by MaterializationUnit");
2543  SymK->second.setMaterializerAttached(false);
2544  SymK->second.setState(SymbolState::Materializing);
2545  JD.UnmaterializedInfos.erase(KV.first);
2546  }
2547 
2548  // Add MU to the list of MaterializationUnits to be materialized.
2549  CollectedUMIs[&JD].push_back(std::move(UMI));
2550  } else
2551  LLVM_DEBUG(dbgs() << "matched, registering query");
2552 
2553  // Add the query to the PendingQueries list and continue, deleting
2554  // the element from the lookup set.
2555  assert(SymI->second.getState() != SymbolState::NeverSearched &&
2556  SymI->second.getState() != SymbolState::Ready &&
2557  "By this line the symbol should be materializing");
2558  auto &MI = JD.MaterializingInfos[Name];
2559  MI.addQuery(Q);
2560  Q->addQueryDependence(JD, Name);
2561 
2562  return true;
2563  });
2564 
2565  // Handle failure.
2566  if (Err) {
2567 
2568  LLVM_DEBUG({
2569  dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";
2570  });
2571 
2572  // Detach the query.
2573  Q->detach();
2574 
2575  // Replace the MUs.
2576  for (auto &KV : CollectedUMIs) {
2577  auto &JD = *KV.first;
2578  for (auto &UMI : KV.second)
2579  for (auto &KV2 : UMI->MU->getSymbols()) {
2580  assert(!JD.UnmaterializedInfos.count(KV2.first) &&
2581  "Unexpected materializer in map");
2582  auto SymI = JD.Symbols.find(KV2.first);
2583  assert(SymI != JD.Symbols.end() && "Missing symbol entry");
2584  assert(SymI->second.getState() == SymbolState::Materializing &&
2585  "Can not replace symbol that is not materializing");
2586  assert(!SymI->second.hasMaterializerAttached() &&
2587  "MaterializerAttached flag should not be set");
2588  SymI->second.setMaterializerAttached(true);
2589  JD.UnmaterializedInfos[KV2.first] = UMI;
2590  }
2591  }
2592 
2593  return Err;
2594  }
2595  }
2596 
2597  LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-referenced symbols\n");
2598  IPLS->LookupSet.forEachWithRemoval(
2599  [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2600  if (SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol) {
2601  Q->dropSymbol(Name);
2602  return true;
2603  } else
2604  return false;
2605  });
2606 
2607  if (!IPLS->LookupSet.empty()) {
2608  LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2609  return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
2610  }
2611 
2612  // Record whether the query completed.
2613  QueryComplete = Q->isComplete();
2614 
2615  LLVM_DEBUG({
2616  dbgs() << "Query successfully "
2617  << (QueryComplete ? "completed" : "lodged") << "\n";
2618  });
2619 
2620  // Move the collected MUs to the OutstandingMUs list.
2621  if (!CollectedUMIs.empty()) {
2622  std::lock_guard<std::recursive_mutex> Lock(OutstandingMUsMutex);
2623 
2624  LLVM_DEBUG(dbgs() << "Adding MUs to dispatch:\n");
2625  for (auto &KV : CollectedUMIs) {
2626  auto &JD = *KV.first;
2627  LLVM_DEBUG({
2628  dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size()
2629  << " MUs.\n";
2630  });
2631  for (auto &UMI : KV.second) {
2632  std::unique_ptr<MaterializationResponsibility> MR(
2634  &JD, std::move(UMI->MU->SymbolFlags),
2635  std::move(UMI->MU->InitSymbol)));
2636  JD.MRTrackers[MR.get()] = UMI->RT;
2637  OutstandingMUs.push_back(
2638  std::make_pair(std::move(UMI->MU), std::move(MR)));
2639  }
2640  }
2641  } else
2642  LLVM_DEBUG(dbgs() << "No MUs to dispatch.\n");
2643 
2644  if (RegisterDependencies && !Q->QueryRegistrations.empty()) {
2645  LLVM_DEBUG(dbgs() << "Registering dependencies\n");
2646  RegisterDependencies(Q->QueryRegistrations);
2647  } else
2648  LLVM_DEBUG(dbgs() << "No dependencies to register\n");
2649 
2650  return Error::success();
2651  });
2652 
2653  if (LodgingErr) {
2654  LLVM_DEBUG(dbgs() << "Failing query\n");
2655  Q->detach();
2656  Q->handleFailed(std::move(LodgingErr));
2657  return;
2658  }
2659 
2660  if (QueryComplete) {
2661  LLVM_DEBUG(dbgs() << "Completing query\n");
2662  Q->handleComplete(*this);
2663  }
2664 
2665  dispatchOutstandingMUs();
2666 }
2667 
2668 void ExecutionSession::OL_completeLookupFlags(
2669  std::unique_ptr<InProgressLookupState> IPLS,
2670  unique_function<void(Expected<SymbolFlagsMap>)> OnComplete) {
2671 
2672  auto Result = runSessionLocked([&]() -> Expected<SymbolFlagsMap> {
2673  LLVM_DEBUG({
2674  dbgs() << "Entering OL_completeLookupFlags:\n"
2675  << " Lookup kind: " << IPLS->K << "\n"
2676  << " Search order: " << IPLS->SearchOrder
2677  << ", Current index = " << IPLS->CurSearchOrderIndex
2678  << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"
2679  << " Lookup set: " << IPLS->LookupSet << "\n"
2680  << " Definition generator candidates: "
2681  << IPLS->DefGeneratorCandidates << "\n"
2682  << " Definition generator non-candidates: "
2683  << IPLS->DefGeneratorNonCandidates << "\n";
2684  });
2685 
2687 
2688  // Attempt to find flags for each symbol.
2689  for (auto &KV : IPLS->SearchOrder) {
2690  auto &JD = *KV.first;
2691  auto JDLookupFlags = KV.second;
2692  LLVM_DEBUG({
2693  dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags
2694  << ") with lookup set " << IPLS->LookupSet << ":\n";
2695  });
2696 
2697  IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,
2698  SymbolLookupFlags SymLookupFlags) {
2699  LLVM_DEBUG({
2700  dbgs() << " Attempting to match \"" << Name << "\" ("
2701  << SymLookupFlags << ")... ";
2702  });
2703 
2704  // Search for the symbol. If not found then continue without removing
2705  // from the lookup set.
2706  auto SymI = JD.Symbols.find(Name);
2707  if (SymI == JD.Symbols.end()) {
2708  LLVM_DEBUG(dbgs() << "skipping: not present\n");
2709  return false;
2710  }
2711 
2712  // If this is a non-exported symbol then it doesn't match. Skip it.
2713  if (!SymI->second.getFlags().isExported() &&
2715  LLVM_DEBUG(dbgs() << "skipping: not exported\n");
2716  return false;
2717  }
2718 
2719  LLVM_DEBUG({
2720  dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()
2721  << "\n";
2722  });
2723  Result[Name] = SymI->second.getFlags();
2724  return true;
2725  });
2726  }
2727 
2728  // Remove any weakly referenced symbols that haven't been resolved.
2729  IPLS->LookupSet.remove_if(
2730  [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {
2731  return SymLookupFlags == SymbolLookupFlags::WeaklyReferencedSymbol;
2732  });
2733 
2734  if (!IPLS->LookupSet.empty()) {
2735  LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");
2736  return make_error<SymbolsNotFound>(IPLS->LookupSet.getSymbolNames());
2737  }
2738 
2739  LLVM_DEBUG(dbgs() << "Succeded, result = " << Result << "\n");
2740  return Result;
2741  });
2742 
2743  // Run the callback on the result.
2744  LLVM_DEBUG(dbgs() << "Sending result to handler.\n");
2745  OnComplete(std::move(Result));
2746 }
2747 
2748 void ExecutionSession::OL_destroyMaterializationResponsibility(
2749  MaterializationResponsibility &MR) {
2750 
2751  assert(MR.SymbolFlags.empty() &&
2752  "All symbols should have been explicitly materialized or failed");
2753  MR.JD->unlinkMaterializationResponsibility(MR);
2754 }
2755 
2756 SymbolNameSet ExecutionSession::OL_getRequestedSymbols(
2757  const MaterializationResponsibility &MR) {
2758  return MR.JD->getRequestedSymbols(MR.SymbolFlags);
2759 }
2760 
2761 Error ExecutionSession::OL_notifyResolved(MaterializationResponsibility &MR,
2762  const SymbolMap &Symbols) {
2763  LLVM_DEBUG({
2764  dbgs() << "In " << MR.JD->getName() << " resolving " << Symbols << "\n";
2765  });
2766 #ifndef NDEBUG
2767  for (auto &KV : Symbols) {
2768  auto WeakFlags = JITSymbolFlags::Weak | JITSymbolFlags::Common;
2769  auto I = MR.SymbolFlags.find(KV.first);
2770  assert(I != MR.SymbolFlags.end() &&
2771  "Resolving symbol outside this responsibility set");
2772  assert(!I->second.hasMaterializationSideEffectsOnly() &&
2773  "Can't resolve materialization-side-effects-only symbol");
2774  assert((KV.second.getFlags() & ~WeakFlags) == (I->second & ~WeakFlags) &&
2775  "Resolving symbol with incorrect flags");
2776  }
2777 #endif
2778 
2779  return MR.JD->resolve(MR, Symbols);
2780 }
2781 
2782 Error ExecutionSession::OL_notifyEmitted(MaterializationResponsibility &MR) {
2783  LLVM_DEBUG({
2784  dbgs() << "In " << MR.JD->getName() << " emitting " << MR.SymbolFlags << "\n";
2785  });
2786 
2787  if (auto Err = MR.JD->emit(MR, MR.SymbolFlags))
2788  return Err;
2789 
2790  MR.SymbolFlags.clear();
2791  return Error::success();
2792 }
2793 
2794 Error ExecutionSession::OL_defineMaterializing(
2795  MaterializationResponsibility &MR, SymbolFlagsMap NewSymbolFlags) {
2796 
2797  LLVM_DEBUG({
2798  dbgs() << "In " << MR.JD->getName() << " defining materializing symbols "
2799  << NewSymbolFlags << "\n";
2800  });
2801  if (auto AcceptedDefs = MR.JD->defineMaterializing(std::move(NewSymbolFlags))) {
2802  // Add all newly accepted symbols to this responsibility object.
2803  for (auto &KV : *AcceptedDefs)
2804  MR.SymbolFlags.insert(KV);
2805  return Error::success();
2806  } else
2807  return AcceptedDefs.takeError();
2808 }
2809 
2810 void ExecutionSession::OL_notifyFailed(MaterializationResponsibility &MR) {
2811 
2812  LLVM_DEBUG({
2813  dbgs() << "In " << MR.JD->getName() << " failing materialization for "
2814  << MR.SymbolFlags << "\n";
2815  });
2816 
2817  JITDylib::FailedSymbolsWorklist Worklist;
2818 
2819  for (auto &KV : MR.SymbolFlags)
2820  Worklist.push_back(std::make_pair(MR.JD.get(), KV.first));
2821  MR.SymbolFlags.clear();
2822 
2823  if (Worklist.empty())
2824  return;
2825 
2827  std::shared_ptr<SymbolDependenceMap> FailedSymbols;
2828 
2829  runSessionLocked([&]() {
2830  auto RTI = MR.JD->MRTrackers.find(&MR);
2831  assert(RTI != MR.JD->MRTrackers.end() && "No tracker for this");
2832  if (RTI->second->isDefunct())
2833  return;
2834 
2835  std::tie(FailedQueries, FailedSymbols) =
2836  JITDylib::failSymbols(std::move(Worklist));
2837  });
2838 
2839  for (auto &Q : FailedQueries)
2840  Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
2841 }
2842 
2843 Error ExecutionSession::OL_replace(MaterializationResponsibility &MR,
2844  std::unique_ptr<MaterializationUnit> MU) {
2845  for (auto &KV : MU->getSymbols()) {
2846  assert(MR.SymbolFlags.count(KV.first) &&
2847  "Replacing definition outside this responsibility set");
2848  MR.SymbolFlags.erase(KV.first);
2849  }
2850 
2851  if (MU->getInitializerSymbol() == MR.InitSymbol)
2852  MR.InitSymbol = nullptr;
2853 
2854  LLVM_DEBUG(MR.JD->getExecutionSession().runSessionLocked([&]() {
2855  dbgs() << "In " << MR.JD->getName() << " replacing symbols with " << *MU
2856  << "\n";
2857  }););
2858 
2859  return MR.JD->replace(MR, std::move(MU));
2860 }
2861 
2862 Expected<std::unique_ptr<MaterializationResponsibility>>
2863 ExecutionSession::OL_delegate(MaterializationResponsibility &MR,
2864  const SymbolNameSet &Symbols) {
2865 
2866  SymbolStringPtr DelegatedInitSymbol;
2867  SymbolFlagsMap DelegatedFlags;
2868 
2869  for (auto &Name : Symbols) {
2870  auto I = MR.SymbolFlags.find(Name);
2871  assert(I != MR.SymbolFlags.end() &&
2872  "Symbol is not tracked by this MaterializationResponsibility "
2873  "instance");
2874 
2875  DelegatedFlags[Name] = std::move(I->second);
2876  if (Name == MR.InitSymbol)
2877  std::swap(MR.InitSymbol, DelegatedInitSymbol);
2878 
2879  MR.SymbolFlags.erase(I);
2880  }
2881 
2882  return MR.JD->delegate(MR, std::move(DelegatedFlags),
2883  std::move(DelegatedInitSymbol));
2884 }
2885 
2886 void ExecutionSession::OL_addDependencies(
2887  MaterializationResponsibility &MR, const SymbolStringPtr &Name,
2888  const SymbolDependenceMap &Dependencies) {
2889  LLVM_DEBUG({
2890  dbgs() << "Adding dependencies for " << Name << ": " << Dependencies
2891  << "\n";
2892  });
2893  assert(MR.SymbolFlags.count(Name) &&
2894  "Symbol not covered by this MaterializationResponsibility instance");
2895  MR.JD->addDependencies(Name, Dependencies);
2896 }
2897 
2898 void ExecutionSession::OL_addDependenciesForAll(
2899  MaterializationResponsibility &MR,
2900  const SymbolDependenceMap &Dependencies) {
2901  LLVM_DEBUG({
2902  dbgs() << "Adding dependencies for all symbols in " << MR.SymbolFlags << ": "
2903  << Dependencies << "\n";
2904  });
2905  for (auto &KV : MR.SymbolFlags)
2906  MR.JD->addDependencies(KV.first, Dependencies);
2907 }
2908 
2909 #ifndef NDEBUG
2910 void ExecutionSession::dumpDispatchInfo(Task &T) {
2911  runSessionLocked([&]() {
2912  dbgs() << "Dispatching: ";
2913  T.printDescription(dbgs());
2914  dbgs() << "\n";
2915  });
2916 }
2917 #endif // NDEBUG
2918 
2919 } // End namespace orc.
2920 } // End namespace llvm.
llvm::orc::SymbolLookupSet::fromMapKeys
static SymbolLookupSet fromMapKeys(const DenseMap< SymbolStringPtr, KeyT > &M, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Construct a SymbolLookupSet from DenseMap keys.
Definition: Core.h:223
llvm::JITSymbolFlags::HasError
@ HasError
Definition: JITSymbol.h:81
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::orc::Task::ID
static char ID
Definition: Core.h:1246
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::orc::SymbolsNotFound::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:108
llvm::orc::JITDylib
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:907
llvm::orc::ReexportsGenerator::tryToGenerate
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
Definition: Core.cpp:569
llvm::detail::DenseSetImpl::reserve
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again.
Definition: DenseSet.h:90
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::orc::AsynchronousSymbolQuery::notifySymbolMetRequiredState
void notifySymbolMetRequiredState(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym)
Notify the query that a requested symbol has reached the required state.
Definition: Core.cpp:157
llvm::orc::SymbolState::Materializing
@ Materializing
Added to the symbol table, never queried.
llvm::orc::DefinitionGenerator::~DefinitionGenerator
virtual ~DefinitionGenerator()
Definition: Core.cpp:610
llvm::orc::ExecutionSession::reportError
void reportError(Error Err)
Report a error for this execution session.
Definition: Core.h:1371
llvm::orc::InProgressLookupState
Definition: Core.cpp:484
llvm::unique_function< void(Expected< SymbolMap >)>
while
while(!ItemsToConvert.empty())
Definition: NVPTXLowerArgs.cpp:201
llvm::orc::SymbolsCouldNotBeRemoved::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:117
llvm::orc::ExecutionSession::getJITDylibByName
JITDylib * getJITDylibByName(StringRef Name)
Return a pointer to the "name" JITDylib.
Definition: Core.cpp:1847
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1661
llvm::orc::LookupState::operator=
LookupState & operator=(LookupState &&)
llvm::orc::ResourceTrackerDefunct::ID
static char ID
Definition: Core.h:406
llvm::orc::JITDylib::getDefaultResourceTracker
ResourceTrackerSP getDefaultResourceTracker()
Get the default resource tracker for this JITDylib.
Definition: Core.cpp:626
llvm::orc::ResourceTrackerDefunct::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:75
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:174
llvm::orc::Platform::~Platform
virtual ~Platform()
Definition: Core.cpp:1702
llvm::orc::LookupKind::Static
@ Static
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
llvm::orc::ReExportsMaterializationUnit::getName
StringRef getName() const override
Return the name of this materialization unit.
Definition: Core.cpp:277
llvm::orc::InProgressLookupFlagsState::InProgressLookupFlagsState
InProgressLookupFlagsState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)
Definition: Core.cpp:511
llvm::orc::OrcErrorCode::UnknownORCError
@ UnknownORCError
llvm::orc::ResourceManager::~ResourceManager
virtual ~ResourceManager()
Definition: Core.cpp:66
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::orc::InProgressFullLookupState::fail
void fail(Error Err) override
Definition: Core.cpp:552
llvm::orc::JITDylib::clear
Error clear()
Calls remove on all trackers currently associated with this JITDylib.
Definition: Core.cpp:612
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
llvm::orc::ResourceTracker::ResourceTracker
ResourceTracker(const ResourceTracker &)=delete
llvm::orc::FailedToMaterialize::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:85
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:333
llvm::orc::LookupState::~LookupState
~LookupState()
llvm::orc::ResourceTracker
API to remove / transfer ownership of JIT resources.
Definition: Core.h:52
MSVCErrorWorkarounds.h
llvm::orc::ExecutionSession::registerResourceManager
void registerResourceManager(ResourceManager &RM)
Register the given ResourceManager with this ExecutionSession.
Definition: Core.cpp:1830
llvm::orc::MaterializationTask::run
void run() override
Definition: Core.cpp:1803
llvm::Optional
Definition: APInt.h:33
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
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::LookupState::continueLookup
void continueLookup(Error Err)
Continue the lookup.
Definition: Core.cpp:604
STLExtras.h
llvm::orc::Platform::lookupInitSymbolsAsync
static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
Performs an async lookup for the the given symbols in each of the given JITDylibs,...
Definition: Core.cpp:1753
llvm::JITSymbolFlags::Common
@ Common
Definition: JITSymbol.h:83
llvm::orc::SymbolsNotFound::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:104
llvm::orc::orcError
std::error_code orcError(OrcErrorCode ErrCode)
Definition: OrcError.cpp:82
replace
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
Definition: ConstantMerge.cpp:116
llvm::orc::LookupKind
LookupKind
Describes the kind of lookup being performed.
Definition: Core.h:148
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::count
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
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:649
llvm::orc::InProgressLookupState::RequiredState
SymbolState RequiredState
Definition: Core.cpp:499
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::orc::ExecutionSession::dispatchTask
void dispatchTask(std::unique_ptr< Task > T)
Materialize the given unit.
Definition: Core.h:1450
llvm::orc::ExecutionSession::JITDylib
friend class JITDylib
Definition: Core.h:1278
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:162
llvm::JITEvaluatedSymbol
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:229
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:193
llvm::orc::InProgressLookupState::NewJITDylib
bool NewJITDylib
Definition: Core.cpp:503
llvm::orc::JITDylib::createResourceTracker
ResourceTrackerSP createResourceTracker()
Create a resource tracker for this JITDylib.
Definition: Core.cpp:634
DebugUtils.h
llvm::orc::buildSimpleReexportsAliasMap
Expected< SymbolAliasMap > buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols)
Build a SymbolAliasMap for the common case where you want to re-export symbols from another JITDylib ...
llvm::orc::FailedToMaterialize::ID
static char ID
Definition: Core.h:420
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::orc::RegisterDependenciesFunction
std::function< void(const SymbolDependenceMap &)> RegisterDependenciesFunction
Callback to register the dependencies for a given query.
Definition: Core.h:398
llvm::orc::InProgressLookupState::complete
virtual void complete(std::unique_ptr< InProgressLookupState > IPLS)=0
llvm::orc::ResourceTracker::getJITDylib
JITDylib & getJITDylib() const
Return the JITDylib targeted by this tracker.
Definition: Core.h:67
llvm::orc::ExecutionSession::dump
void dump(raw_ostream &OS)
Dump the state of all the JITDylibs in this session.
Definition: Core.cpp:2109
llvm::Expected
class LLVM_NODISCARD Expected
Definition: raw_ostream.h:38
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::orc::ExecutionSession::registerJITDispatchHandlers
Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)
For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...
Definition: Core.cpp:2057
llvm::orc::SymbolState
SymbolState
Represents the state that a symbol has reached during materialization.
Definition: Core.h:799
llvm::orc::InProgressLookupState::DefGeneratorNonCandidates
SymbolLookupSet DefGeneratorNonCandidates
Definition: Core.cpp:505
llvm::orc::tpctypes::LookupResult
std::vector< JITTargetAddress > LookupResult
Definition: TargetProcessControlTypes.h:144
llvm::orc::MissingSymbolDefinitions::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:129
llvm::orc::SymbolLookupFlags
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
Definition: Core.h:136
llvm::orc::UnexpectedSymbolDefinitions::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:138
llvm::orc::Platform::lookupInitSymbols
static Expected< DenseMap< JITDylib *, SymbolMap > > lookupInitSymbols(ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)
A utility function for looking up initializer symbols.
Definition: Core.cpp:1704
llvm::orc::UnexpectedSymbolDefinitions::ID
static char ID
Definition: Core.h:485
llvm::orc::NoDependenciesToRegister
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
Definition: Core.cpp:35
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::orc::OrcErrorCode::UnexpectedSymbolDefinitions
@ UnexpectedSymbolDefinitions
llvm::orc::SymbolMap
DenseMap< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
Definition: Core.h:112
llvm::JITEvaluatedSymbol::getFlags
JITSymbolFlags getFlags() const
Return the flags for this symbol.
Definition: JITSymbol.h:254
llvm::orc::InProgressLookupFlagsState::fail
void fail(Error Err) override
Definition: Core.cpp:524
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::InProgressLookupState::SearchOrder
JITDylibSearchOrder SearchOrder
Definition: Core.cpp:497
llvm::orc::SymbolAliasMap
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition: Core.h:391
llvm::orc::ExecutionSession::runSessionLocked
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1324
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1089
llvm::orc::AbsoluteSymbolsMaterializationUnit::getName
StringRef getName() const override
Return the name of this materialization unit.
Definition: Core.cpp:246
llvm::orc::FailedToMaterialize::FailedToMaterialize
FailedToMaterialize(std::shared_ptr< SymbolDependenceMap > Symbols)
Definition: Core.cpp:79
llvm::orc::SymbolsNotFound::ID
static char ID
Definition: Core.h:434
FormatVariadic.h
llvm::orc::InProgressLookupState::~InProgressLookupState
virtual ~InProgressLookupState()
Definition: Core.cpp:492
llvm::orc::InProgressLookupState::CurSearchOrderIndex
size_t CurSearchOrderIndex
Definition: Core.cpp:502
llvm::orc::SymbolLookupFlags::WeaklyReferencedSymbol
@ WeaklyReferencedSymbol
llvm::orc::ExecutionSession::createBareJITDylib
JITDylib & createBareJITDylib(std::string Name)
Add a new bare JITDylib to this ExecutionSession.
Definition: Core.cpp:1856
llvm::orc::ExecutionSession::endSession
Error endSession()
End the session.
Definition: Core.cpp:1811
llvm::orc::MaterializationTask::printDescription
void printDescription(raw_ostream &OS) override
Definition: Core.cpp:1798
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::DenseSet< SymbolStringPtr >
llvm::orc::InProgressLookupFlagsState
Definition: Core.cpp:509
llvm::JITSymbolFlags::hasMaterializationSideEffectsOnly
bool hasMaterializationSideEffectsOnly() const
Returns true if this symbol is a materialization-side-effects-only symbol.
Definition: JITSymbol.h:161
llvm::DenseMapBase::clear
void clear()
Definition: DenseMap.h:111
uint64_t
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1571
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::Optional::emplace
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:264
llvm::orc::ExecutionSession::lookupFlags
void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet Symbols, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)
Search the given JITDylibs to find the flags associated with each of the given symbols.
Definition: Core.cpp:1922
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, JITEvaluatedSymbol >
llvm::orc::InProgressLookupState::DefGeneratorCandidates
SymbolLookupSet DefGeneratorCandidates
Definition: Core.cpp:504
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::detail::DenseSetImpl::empty
bool empty() const
Definition: DenseSet.h:80
llvm::orc::JITDylib::AsynchronousSymbolQuerySet
std::set< std::shared_ptr< AsynchronousSymbolQuery > > AsynchronousSymbolQuerySet
Definition: Core.h:916
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:428
llvm::orc::SymbolState::NeverSearched
@ NeverSearched
No symbol should be in this state.
llvm::orc::ResourceTrackerSP
uint8_t IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
Definition: Core.h:46
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::orc::ReexportsGenerator::ReexportsGenerator
ReexportsGenerator(JITDylib &SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolPredicate Allow=SymbolPredicate())
Create a reexports generator.
Definition: Core.cpp:563
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::orc::AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit
AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols)
Definition: Core.cpp:241
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:1609
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::orc::ExecutionSession::ExecutionSession
ExecutionSession(std::unique_ptr< ExecutorProcessControl > EPC)
Construct an ExecutionSession with the given ExecutorProcessControl object.
Definition: Core.cpp:1805
llvm::orc::JITDylibSP
IntrusiveRefCntPtr< JITDylib > JITDylibSP
Definition: Core.h:47
llvm::orc::InProgressLookupFlagsState::complete
void complete(std::unique_ptr< InProgressLookupState > IPLS) override
Definition: Core.cpp:518
llvm::orc::InProgressLookupState::K
LookupKind K
Definition: Core.cpp:496
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:153
llvm::orc::JITDylib::getReverseDFSLinkOrder
std::vector< JITDylibSP > getReverseDFSLinkOrder()
Rteurn this JITDylib and its transitive dependencies in reverse DFS order based on linkage relationsh...
Definition: Core.cpp:1918
llvm::orc::DefinitionGenerator
Definition generators can be attached to JITDylibs to generate new definitions for otherwise unresolv...
Definition: Core.h:886
llvm::orc::InProgressLookupState::fail
virtual void fail(Error Err)=0
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::orc::reexports
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
Definition: Core.h:786
llvm::orc::ExecutionSession::deregisterResourceManager
void deregisterResourceManager(ResourceManager &RM)
Deregister the given ResourceManager with this ExecutionSession.
Definition: Core.cpp:1834
llvm::orc::InProgressLookupState::CurDefGeneratorStack
std::vector< std::weak_ptr< DefinitionGenerator > > CurDefGeneratorStack
Definition: Core.cpp:506
llvm::sys::fs::remove
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
llvm::AArch64::RM
@ RM
Definition: AArch64ISelLowering.h:472
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::orc::ExecutionSession::MaterializationResponsibility
friend class MaterializationResponsibility
Definition: Core.h:1280
llvm::JITSymbolFlags::Weak
@ Weak
Definition: JITSymbol.h:82
llvm::orc::ReexportsGenerator::SymbolPredicate
std::function< bool(SymbolStringPtr)> SymbolPredicate
Definition: Core.h:1777
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::orc::SymbolState::Ready
@ Ready
Emitted to memory, but waiting on transitive dependencies.
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1748
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::orc::LookupState
Wraps state for a lookup-in-progress.
Definition: Core.h:861
llvm::orc::JITDylib::getDFSLinkOrder
std::vector< JITDylibSP > getDFSLinkOrder()
Return this JITDylib and its transitive dependencies in DFS order based on linkage relationships.
Definition: Core.cpp:1914
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::orc::SymbolAliasMapEntry
Definition: Core.h:381
llvm::orc::InProgressFullLookupState
Definition: Core.cpp:533
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::ArrayRef::front
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:168
llvm::orc::ExecutionSession::createJITDylib
Expected< JITDylib & > createJITDylib(std::string Name)
Add a new JITDylib to this ExecutionSession.
Definition: Core.cpp:1864
llvm::orc::InProgressFullLookupState::InProgressFullLookupState
InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState, std::shared_ptr< AsynchronousSymbolQuery > Q, RegisterDependenciesFunction RegisterDependencies)
Definition: Core.cpp:535
llvm::orc::SymbolDependenceMap
DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap
A map from JITDylibs to sets of symbols.
Definition: Core.h:118
llvm::orc::ResourceTrackerDefunct::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:71
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1578
llvm::orc::SymbolFlagsMap
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
Definition: Core.h:115
llvm::DenseMapBase::empty
LLVM_NODISCARD bool empty() const
Definition: DenseMap.h:97
llvm::orc::AsynchronousSymbolQuery::AsynchronousSymbolQuery
AsynchronousSymbolQuery(const SymbolLookupSet &Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete)
Create a query for the given symbols.
Definition: Core.cpp:143
llvm::orc::ResourceManager
Listens for ResourceTracker operations.
Definition: Core.h:96
llvm::orc::ResourceTracker::transferTo
void transferTo(ResourceTracker &DstRT)
Transfer all resources associated with this key to the given tracker, which must target the same JITD...
Definition: Core.cpp:56
llvm::SymbolTableEntry
Symbol info for RuntimeDyld.
Definition: RuntimeDyldImpl.h:217
llvm::orc::InProgressLookupState::LookupSet
SymbolLookupSet LookupSet
Definition: Core.cpp:498
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
H
#define H(x, y, z)
Definition: MD5.cpp:58
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::orc::SymbolsNotFound::SymbolsNotFound
SymbolsNotFound(SymbolNameSet Symbols)
Definition: Core.cpp:93
getFlags
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:23
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::Task
Represents an abstract task for ORC to run.
Definition: Core.h:1244
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1275
llvm::orc::JITDylibLookupFlags::MatchExportedSymbolsOnly
@ MatchExportedSymbolsOnly
llvm::orc::InProgressLookupState::GeneratorLock
std::unique_lock< std::mutex > GeneratorLock
Definition: Core.cpp:501
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
llvm::orc::MissingSymbolDefinitions::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:125
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::size
unsigned size() const
Definition: DenseMap.h:100
llvm::orc::symbolAliases
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition: Core.h:777
llvm::orc::ExecutionSession::LookupState
friend class LookupState
Definition: Core.h:1279
llvm::orc::FailedToMaterialize::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:89
llvm::orc::shared::WrapperFunctionResult::createOutOfBandError
static WrapperFunctionResult createOutOfBandError(const char *Msg)
Create an out-of-band error by copying the given string.
Definition: WrapperFunctionUtils.h:146
Core.h
llvm::orc::ResourceTrackerDefunct::ResourceTrackerDefunct
ResourceTrackerDefunct(ResourceTrackerSP RT)
Definition: Core.cpp:68
llvm::orc::JITDylib::getName
const std::string & getName() const
Get the name for this JITDylib.
Definition: Core.h:924
llvm::orc::JITDylib::define
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition: Core.h:1692
llvm::orc::InProgressLookupState::InProgressLookupState
InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState)
Definition: Core.cpp:486
llvm::TPLoop::Allow
@ Allow
Definition: ARMTargetTransformInfo.h:53
llvm::orc::ExecutionSession::lookup
void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylibs for the given symbols.
Definition: Core.cpp:1948
llvm::orc::JITDylib::getExecutionSession
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:927
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::orc::MissingSymbolDefinitions::ID
static char ID
Definition: Core.h:466
llvm::orc::ExecutionSession::runJITDispatchHandler
void runJITDispatchHandler(ExecutorProcessControl::SendResultFunction SendResult, JITTargetAddress HandlerFnTagAddr, ArrayRef< char > ArgBuffer)
Run a registered jit-side wrapper function.
Definition: Core.cpp:2088
llvm::orc::SymbolNameSet
DenseSet< SymbolStringPtr > SymbolNameSet
A set of symbol names (represented by SymbolStringPtrs for.
Definition: Core.h:105
llvm::orc::JITDylibLookupFlags
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
Definition: Core.h:126
llvm::orc::SymbolState::Resolved
@ Resolved
Queried, materialization begun.
llvm::orc::MaterializationTask::ID
static char ID
Definition: Core.h:1261
llvm::orc::ReExportsMaterializationUnit::ReExportsMaterializationUnit
ReExportsMaterializationUnit(JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolAliasMap Aliases)
SourceJD is allowed to be nullptr, in which case the source JITDylib is taken to be whatever JITDylib...
Definition: Core.cpp:271
llvm::orc::MaterializationUnit::SymbolFlags
SymbolFlagsMap SymbolFlags
Definition: Core.h:690
llvm::ThreadSafeRefCountedBase::Release
void Release() const
Definition: IntrusiveRefCntPtr.h:124
llvm::orc::UnexpectedSymbolDefinitions::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Core.cpp:134
llvm::orc::LookupState::LookupState
LookupState()
llvm::orc::OrcErrorCode::MissingSymbolDefinitions
@ MissingSymbolDefinitions
llvm::orc::JITDylibLookupFlags::MatchAllSymbols
@ MatchAllSymbols
llvm::orc::SymbolLookupFlags::RequiredSymbol
@ RequiredSymbol
llvm::orc::SymbolsResolvedCallback
unique_function< void(Expected< SymbolMap >)> SymbolsResolvedCallback
Callback to notify client that symbols have been resolved.
Definition: Core.h:394
llvm::orc::SymbolsCouldNotBeRemoved::SymbolsCouldNotBeRemoved
SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
Definition: Core.cpp:112
OrcError.h
llvm::orc::InProgressFullLookupState::complete
void complete(std::unique_ptr< InProgressLookupState > IPLS) override
Definition: Core.cpp:545
llvm::orc::SymbolNameVector
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
Definition: Core.h:108
llvm::orc::makeJITDylibSearchOrder
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition: Core.h:157
llvm::orc::SymbolsCouldNotBeRemoved::ID
static char ID
Definition: Core.h:449
llvm::orc::ResourceTracker::remove
Error remove()
Remove all resources associated with this key.
Definition: Core.cpp:52
llvm::orc::SymbolsCouldNotBeRemoved::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Core.cpp:121
llvm::orc::ResourceTracker::~ResourceTracker
~ResourceTracker()
Definition: Core.cpp:47
llvm::orc::JITDylib::removeGenerator
void removeGenerator(DefinitionGenerator &G)
Remove a definition generator from this JITDylib.
Definition: Core.cpp:641