11 #include "llvm/Config/llvm-config.h" 18 #if LLVM_ENABLE_THREADS 22 #define DEBUG_TYPE "orc" 31 cl::desc(
"debug print hidden symbols defined by " 32 "materialization units"),
36 cl::desc(
"debug print callable symbols defined by " 37 "materialization units"),
41 cl::desc(
"debug print data symbols defined by " 42 "materialization units"),
48 template <
typename T>
struct PrintAll {
49 bool operator()(
const T &
E) {
return true; }
52 bool anyPrintSymbolOptionSet() {
54 return PrintHidden || PrintCallable || PrintData;
82 template <
typename Set,
typename Pred = Pr
intAll<
typename Set::value_type>>
85 SetPrinter(
const Set &S, Pred ShouldPrint = Pred())
86 : S(S), ShouldPrint(std::move(ShouldPrint)) {}
89 bool PrintComma =
false;
104 mutable Pred ShouldPrint;
107 template <
typename Set,
typename Pred>
108 SetPrinter<Set, Pred> printSet(
const Set &S, Pred
P = Pred()) {
109 return SetPrinter<Set, Pred>(S, std::move(
P));
113 template <
typename Set,
typename Pred>
115 const SetPrinter<Set, Pred> &
Printer) {
120 struct PrintSymbolFlagsMapElemsMatchingCLOpts {
122 return flagsMatchCLOpts(KV.second);
126 struct PrintSymbolMapElemsMatchingCLOpts {
128 return flagsMatchCLOpts(KV.second.getFlags());
137 SymbolStringPool::PoolMapEntry SymbolStringPtr::Tombstone(0);
146 void MaterializationUnit::anchor() {}
153 return OS << printSet(Symbols, PrintAll<SymbolStringPtr>());
178 return OS <<
"(\"" << KV.first <<
"\", " << KV.second <<
")";
182 return OS <<
"(\"" << KV.first <<
"\": " << KV.second <<
")";
186 return OS << printSet(SymbolFlags, PrintSymbolFlagsMapElemsMatchingCLOpts());
190 return OS << printSet(Symbols, PrintSymbolMapElemsMatchingCLOpts());
194 const SymbolDependenceMap::value_type &KV) {
195 return OS <<
"(" << KV.first <<
", " << KV.second <<
")";
199 return OS << printSet(Deps, PrintAll<SymbolDependenceMap::value_type>());
203 OS <<
"MU@" << &MU <<
" (\"" << MU.
getName() <<
"\"";
204 if (anyPrintSymbolOptionSet())
212 assert(JDs.front().first &&
"JITDylibList entries must not be null");
213 OS <<
" (\"" << JDs.front().first->getName() <<
"\", " 214 << (JDs.front().second ?
"true" :
"false") <<
")";
215 for (
auto &KV :
make_range(std::next(JDs.begin()), JDs.end())) {
216 assert(KV.first &&
"JITDylibList entries must not be null");
217 OS <<
", (\"" << KV.first->getName() <<
"\", " 218 << (KV.second ?
"true" :
"false") <<
")";
226 : Symbols(
std::move(Symbols)) {
227 assert(!this->Symbols.
empty() &&
"Can not fail to resolve an empty set");
235 OS <<
"Failed to materialize symbols: " << Symbols;
239 : Symbols(
std::move(Symbols)) {
240 assert(!this->Symbols.
empty() &&
"Can not fail to resolve an empty set");
248 OS <<
"Symbols not found: " << Symbols;
252 : Symbols(
std::move(Symbols)) {
253 assert(!this->Symbols.
empty() &&
"Can not fail to resolve an empty set");
261 OS <<
"Symbols could not be removed: " << Symbols;
267 : NotifySymbolsResolved(
std::move(NotifySymbolsResolved)),
268 NotifySymbolsReady(
std::move(NotifySymbolsReady)) {
269 NotYetResolvedCount = NotYetReadyCount = Symbols.
size();
271 for (
auto &S : Symbols)
272 ResolvedSymbols[S] =
nullptr;
277 auto I = ResolvedSymbols.
find(Name);
279 "Resolving symbol outside the requested set");
280 assert(
I->second.getAddress() == 0 &&
"Redundantly resolving symbol Name");
281 I->second = std::move(Sym);
282 --NotYetResolvedCount;
286 assert(NotYetResolvedCount == 0 &&
"Not fully resolved?");
288 if (!NotifySymbolsResolved) {
291 assert(!NotifySymbolsReady &&
292 "NotifySymbolsResolved already called or an error occurred");
296 auto TmpNotifySymbolsResolved = std::move(NotifySymbolsResolved);
298 TmpNotifySymbolsResolved(std::move(ResolvedSymbols));
302 assert(NotYetReadyCount != 0 &&
"All symbols already emitted");
307 assert(NotifySymbolsReady &&
308 "NotifySymbolsReady already called or an error occurred");
310 auto TmpNotifySymbolsReady = std::move(NotifySymbolsReady);
313 if (NotYetResolvedCount == 0 && NotifySymbolsResolved) {
323 "Query is still registered with some symbols");
324 assert(!NotifySymbolsResolved &&
"Resolution not applied yet");
328 bool AsynchronousSymbolQuery::canStillFail() {
329 return (NotifySymbolsResolved || NotifySymbolsReady);
332 void AsynchronousSymbolQuery::handleFailed(
Error Err) {
334 NotYetResolvedCount == 0 && NotYetReadyCount == 0 &&
335 "Query should already have been abandoned");
336 if (NotifySymbolsResolved) {
337 NotifySymbolsResolved(std::move(Err));
340 assert(NotifySymbolsReady &&
"Failed after both callbacks issued?");
341 NotifySymbolsReady(std::move(Err));
346 void AsynchronousSymbolQuery::addQueryDependence(
JITDylib &JD,
348 bool Added = QueryRegistrations[&JD].
insert(std::move(Name)).second;
350 assert(Added &&
"Duplicate dependence notification?");
353 void AsynchronousSymbolQuery::removeQueryDependence(
355 auto QRI = QueryRegistrations.
find(&JD);
356 assert(QRI != QueryRegistrations.
end() &&
357 "No dependencies registered for JD");
358 assert(QRI->second.count(Name) &&
"No dependency on Name in JD");
359 QRI->second.erase(Name);
360 if (QRI->second.empty())
361 QueryRegistrations.
erase(QRI);
364 void AsynchronousSymbolQuery::detach() {
365 ResolvedSymbols.
clear();
366 NotYetResolvedCount = 0;
367 NotYetReadyCount = 0;
368 for (
auto &KV : QueryRegistrations)
369 KV.first->detachQueryHelper(*
this, KV.second);
370 QueryRegistrations.clear();
375 : JD(JD), SymbolFlags(std::move(SymbolFlags)), K(std::move(K)) {
376 assert(!this->SymbolFlags.
empty() &&
"Materializing nothing?");
379 for (
auto &KV : this->SymbolFlags)
386 "All symbols should have been explicitly materialized or failed");
390 return JD.getRequestedSymbols(SymbolFlags);
397 for (
auto &KV : Symbols) {
398 auto I = SymbolFlags.
find(KV.first);
400 "Resolving symbol outside this responsibility set");
401 assert(
I->second.isMaterializing() &&
"Duplicate resolution");
403 if (
I->second.isWeak())
405 "Resolving symbol with incorrect flags");
407 assert(
I->second == KV.second.getFlags() &&
408 "Resolving symbol with incorrect flags");
417 for (
auto &KV : SymbolFlags)
418 assert(!KV.second.isMaterializing() &&
419 "Failed to resolve symbol before emission");
422 JD.emit(SymbolFlags);
432 for (
auto &KV : NewSymbolFlags) {
433 auto I = SymbolFlags.
insert(KV).first;
440 return JD.defineMaterializing(NewSymbolFlags);
446 for (
auto &KV : SymbolFlags)
447 FailedSymbols.
insert(KV.first);
449 JD.notifyFailed(FailedSymbols);
454 std::unique_ptr<MaterializationUnit> MU) {
455 for (
auto &KV : MU->getSymbols())
456 SymbolFlags.
erase(KV.first);
459 dbgs() <<
"In " << JD.
getName() <<
" replacing symbols with " << *MU
463 JD.replace(std::move(MU));
475 for (
auto &Name : Symbols) {
476 auto I = SymbolFlags.
find(Name);
478 "Symbol is not tracked by this MaterializationResponsibility " 481 DelegatedFlags[
Name] = std::move(
I->second);
492 "Symbol not covered by this MaterializationResponsibility instance");
493 JD.addDependencies(Name, Dependencies);
498 for (
auto &KV : SymbolFlags)
499 JD.addDependencies(KV.first, Dependencies);
505 Symbols(
std::move(Symbols)) {}
508 return "<Absolute Symbols>";
511 void AbsoluteSymbolsMaterializationUnit::materialize(
517 void AbsoluteSymbolsMaterializationUnit::discard(
const JITDylib &JD,
519 assert(Symbols.
count(Name) &&
"Symbol is not part of this MU");
524 AbsoluteSymbolsMaterializationUnit::extractFlags(
const SymbolMap &Symbols) {
526 for (
const auto &KV : Symbols)
527 Flags[KV.first] = KV.second.getFlags();
535 SourceJD(SourceJD), MatchNonExported(MatchNonExported),
536 Aliases(
std::move(Aliases)) {}
539 return "<Reexports>";
542 void ReExportsMaterializationUnit::materialize(
547 JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;
555 for (
auto &Name : RequestedSymbols) {
556 auto I = Aliases.
find(Name);
557 assert(
I != Aliases.
end() &&
"Symbol not found in aliases map?");
558 RequestedAliases[
Name] = std::move(
I->second);
562 if (!Aliases.
empty()) {
571 struct OnResolveInfo {
573 : R(std::move(R)), Aliases(std::move(Aliases)) {}
585 std::vector<std::pair<SymbolNameSet, std::shared_ptr<OnResolveInfo>>>
587 while (!RequestedAliases.
empty()) {
593 for (
auto &KV : RequestedAliases) {
595 if (&SrcJD == &TgtJD && (QueryAliases.
count(KV.second.Aliasee) ||
596 RequestedAliases.count(KV.second.Aliasee)))
599 ResponsibilitySymbols.
insert(KV.first);
600 QuerySymbols.
insert(KV.second.Aliasee);
601 QueryAliases[KV.first] = std::move(KV.second);
605 for (
auto &KV : QueryAliases)
606 RequestedAliases.erase(KV.first);
608 assert(!QuerySymbols.
empty() &&
"Alias cycle detected!");
610 auto QueryInfo = std::make_shared<OnResolveInfo>(
611 R.
delegate(ResponsibilitySymbols), std::move(QueryAliases));
612 QueryInfos.push_back(
613 make_pair(std::move(QuerySymbols), std::move(QueryInfo)));
617 while (!QueryInfos.empty()) {
618 auto QuerySymbols = std::move(QueryInfos.back().first);
619 auto QueryInfo = std::move(QueryInfos.back().second);
621 QueryInfos.pop_back();
623 auto RegisterDependencies = [QueryInfo,
631 "Unexpected dependencies for reexports");
633 auto &SrcJDDeps = Deps.
find(&SrcJD)->second;
635 auto &PerAliasDeps = PerAliasDepsMap[&SrcJD];
637 for (
auto &KV : QueryInfo->Aliases)
638 if (SrcJDDeps.count(KV.second.Aliasee)) {
639 PerAliasDeps = {KV.second.Aliasee};
640 QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap);
647 for (
auto &KV : QueryInfo->Aliases) {
648 assert(Result->count(KV.second.Aliasee) &&
649 "Result map missing entry?");
651 (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
653 QueryInfo->R.resolve(ResolutionMap);
656 auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession();
657 ES.reportError(Result.takeError());
658 QueryInfo->R.failMaterialization();
662 auto OnReady = [&ES](
Error Err) { ES.reportError(std::move(Err)); };
665 std::move(OnResolve), std::move(OnReady),
666 std::move(RegisterDependencies));
670 void ReExportsMaterializationUnit::discard(
const JITDylib &JD,
672 assert(Aliases.count(Name) &&
673 "Symbol not covered by this MaterializationUnit");
678 ReExportsMaterializationUnit::extractFlags(
const SymbolAliasMap &Aliases) {
680 for (
auto &KV : Aliases)
681 SymbolFlags[KV.first] = KV.second.AliasFlags;
690 if (Flags.size() != Symbols.
size()) {
692 for (
auto &KV : Flags)
693 Unresolved.
erase(KV.first);
694 return make_error<SymbolsNotFound>(std::move(Unresolved));
698 for (
auto &Name : Symbols) {
699 assert(Flags.count(Name) &&
"Missing entry in flags map");
707 bool MatchNonExported,
709 : SourceJD(SourceJD), MatchNonExported(MatchNonExported),
710 Allow(
std::move(Allow)) {}
719 for (
auto &KV : Flags) {
720 if (Allow && !Allow(KV.first))
733 return ES.runSessionLocked([&]() ->
Error {
734 std::vector<SymbolMap::iterator> AddedSyms;
736 for (
auto &KV : SymbolFlags) {
740 auto NewFlags = KV.second;
743 std::tie(EntryItr, Added) = Symbols.
insert(
747 AddedSyms.push_back(EntryItr);
750 for (
auto &
SI : AddedSyms)
754 return make_error<DuplicateDefinition>(*KV.first);
762 void JITDylib::replace(std::unique_ptr<MaterializationUnit> MU) {
763 assert(MU !=
nullptr &&
"Can not replace with a null MaterializationUnit");
766 ES.runSessionLocked([&,
this]() -> std::unique_ptr<MaterializationUnit> {
769 for (
auto &KV : MU->getSymbols()) {
770 auto SymI = Symbols.
find(KV.first);
771 assert(SymI != Symbols.
end() &&
"Replacing unknown symbol");
772 assert(!SymI->second.getFlags().isLazy() &&
773 SymI->second.getFlags().isMaterializing() &&
774 "Can not replace symbol that is not materializing");
775 assert(UnmaterializedInfos.count(KV.first) == 0 &&
776 "Symbol being replaced should have no UnmaterializedInfo");
782 for (
auto &KV : MU->getSymbols()) {
783 auto MII = MaterializingInfos.find(KV.first);
784 if (MII != MaterializingInfos.end()) {
785 if (!MII->second.PendingQueries.empty())
786 return std::move(MU);
791 auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
792 for (
auto &KV : UMI->MU->getSymbols()) {
793 assert(!KV.second.isLazy() &&
794 "Lazy flag should be managed internally.");
795 assert(!KV.second.isMaterializing() &&
796 "Materializing flags should be managed internally.");
798 auto SymI = Symbols.
find(KV.first);
802 std::move(ReplaceFlags));
803 UnmaterializedInfos[KV.first] = UMI;
810 ES.dispatchMaterialization(*
this, std::move(MustRunMU));
814 JITDylib::getRequestedSymbols(
const SymbolFlagsMap &SymbolFlags)
const {
815 return ES.runSessionLocked([&]() {
818 for (
auto &KV : SymbolFlags) {
819 assert(Symbols.
count(KV.first) &&
"JITDylib does not cover this symbol?");
820 assert(Symbols.
find(KV.first)->second.getFlags().isMaterializing() &&
821 "getRequestedSymbols can only be called for materializing " 823 auto I = MaterializingInfos.find(KV.first);
824 if (I == MaterializingInfos.end())
827 if (!I->second.PendingQueries.empty())
828 RequestedSymbols.
insert(KV.first);
831 return RequestedSymbols;
837 assert(Symbols.
count(Name) &&
"Name not in symbol table");
838 assert((Symbols[Name].getFlags().isLazy() ||
839 Symbols[Name].getFlags().isMaterializing()) &&
840 "Symbol is not lazy or materializing");
842 auto &
MI = MaterializingInfos[
Name];
843 assert(!
MI.IsEmitted &&
"Can not add dependencies to an emitted symbol");
845 for (
auto &KV : Dependencies) {
846 assert(KV.first &&
"Null JITDylib in dependency?");
847 auto &OtherJITDylib = *KV.first;
848 auto &DepsOnOtherJITDylib =
MI.UnemittedDependencies[&OtherJITDylib];
850 for (
auto &OtherSymbol : KV.second) {
853 auto SymI = OtherJITDylib.Symbols.find(OtherSymbol);
854 assert(SymI != OtherJITDylib.Symbols.end() &&
855 (SymI->second.getFlags().isLazy() ||
856 SymI->second.getFlags().isMaterializing()) &&
857 "Dependency on emitted symbol");
860 auto &OtherMI = OtherJITDylib.MaterializingInfos[OtherSymbol];
862 if (OtherMI.IsEmitted)
863 transferEmittedNodeDependencies(
MI, Name, OtherMI);
864 else if (&OtherJITDylib !=
this || OtherSymbol != Name) {
865 OtherMI.Dependants[
this].insert(Name);
866 DepsOnOtherJITDylib.insert(OtherSymbol);
870 if (DepsOnOtherJITDylib.empty())
871 MI.UnemittedDependencies.erase(&OtherJITDylib);
875 void JITDylib::resolve(
const SymbolMap &Resolved) {
876 auto FullyResolvedQueries = ES.runSessionLocked([&,
this]() {
877 AsynchronousSymbolQuerySet FullyResolvedQueries;
878 for (
const auto &KV : Resolved) {
879 auto &Name = KV.first;
880 auto Sym = KV.second;
882 assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() &&
883 "Materializing flags should be managed internally");
885 auto I = Symbols.
find(Name);
887 assert(I != Symbols.
end() &&
"Symbol not found");
888 assert(!I->second.getFlags().isLazy() &&
889 I->second.getFlags().isMaterializing() &&
890 "Symbol should be materializing");
891 assert(I->second.getAddress() == 0 &&
"Symbol has already been resolved");
896 "Resolved flags should match the declared flags");
904 auto &
MI = MaterializingInfos[
Name];
905 for (
auto &Q : MI.PendingQueries) {
906 Q->resolve(Name, Sym);
907 if (Q->isFullyResolved())
908 FullyResolvedQueries.insert(Q);
912 return FullyResolvedQueries;
915 for (
auto &Q : FullyResolvedQueries) {
916 assert(Q->isFullyResolved() &&
"Q not fully resolved");
917 Q->handleFullyResolved();
922 auto FullyReadyQueries = ES.runSessionLocked([&,
this]() {
923 AsynchronousSymbolQuerySet ReadyQueries;
925 for (
const auto &KV : Emitted) {
926 const auto &Name = KV.first;
928 auto MII = MaterializingInfos.find(Name);
929 assert(MII != MaterializingInfos.end() &&
930 "Missing MaterializingInfo entry");
932 auto &
MI = MII->second;
937 for (
auto &KV : MI.Dependants) {
938 auto &DependantJD = *KV.first;
939 for (
auto &DependantName : KV.second) {
941 DependantJD.MaterializingInfos.find(DependantName);
942 assert(DependantMII != DependantJD.MaterializingInfos.end() &&
943 "Dependant should have MaterializingInfo");
945 auto &DependantMI = DependantMII->second;
948 assert(DependantMI.UnemittedDependencies[
this].count(Name) &&
949 "Dependant does not count this symbol as a dependency?");
950 DependantMI.UnemittedDependencies[
this].erase(Name);
951 if (DependantMI.UnemittedDependencies[
this].empty())
952 DependantMI.UnemittedDependencies.erase(
this);
955 DependantJD.transferEmittedNodeDependencies(DependantMI,
961 if (DependantMI.IsEmitted &&
962 DependantMI.UnemittedDependencies.empty()) {
963 assert(DependantMI.Dependants.empty() &&
964 "Dependants should be empty by now");
965 for (
auto &Q : DependantMI.PendingQueries) {
966 Q->notifySymbolReady();
967 if (Q->isFullyReady())
968 ReadyQueries.insert(Q);
969 Q->removeQueryDependence(DependantJD, DependantName);
974 assert(DependantJD.Symbols.count(DependantName) &&
975 "Dependant has no entry in the Symbols table");
976 auto &DependantSym = DependantJD.Symbols[DependantName];
977 DependantSym.setFlags(DependantSym.getFlags() &
979 DependantJD.MaterializingInfos.erase(DependantMII);
983 MI.Dependants.clear();
986 if (MI.UnemittedDependencies.empty()) {
987 for (
auto &Q : MI.PendingQueries) {
988 Q->notifySymbolReady();
989 if (Q->isFullyReady())
990 ReadyQueries.insert(Q);
991 Q->removeQueryDependence(*
this, Name);
994 "Symbol has no entry in the Symbols table");
995 auto &Sym = Symbols[
Name];
997 MaterializingInfos.
erase(MII);
1001 return ReadyQueries;
1004 for (
auto &Q : FullyReadyQueries) {
1005 assert(Q->isFullyReady() &&
"Q is not fully ready");
1006 Q->handleFullyReady();
1010 void JITDylib::notifyFailed(
const SymbolNameSet &FailedSymbols) {
1014 auto FailedQueriesToNotify = ES.runSessionLocked([&,
this]() {
1015 AsynchronousSymbolQuerySet FailedQueries;
1017 for (
auto &Name : FailedSymbols) {
1018 auto I = Symbols.
find(Name);
1019 assert(
I != Symbols.
end() &&
"Symbol not present in this JITDylib");
1022 auto MII = MaterializingInfos.find(Name);
1026 if (MII == MaterializingInfos.end())
1033 for (
auto &Q : MII->second.PendingQueries)
1034 FailedQueries.insert(Q);
1036 for (
auto &Q : FailedQueries)
1039 assert(MII->second.PendingQueries.empty() &&
1040 "Queries remain after symbol was failed");
1042 MaterializingInfos.erase(MII);
1045 return FailedQueries;
1048 for (
auto &Q : FailedQueriesToNotify)
1049 Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
1053 bool SearchThisJITDylibFirst,
1054 bool MatchNonExportedInThisDylib) {
1055 if (SearchThisJITDylibFirst && NewSearchOrder.front().first !=
this)
1056 NewSearchOrder.insert(NewSearchOrder.begin(),
1057 {
this, MatchNonExportedInThisDylib});
1059 ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
1063 ES.runSessionLocked([&]() {
1064 SearchOrder.push_back({&JD, MatchNonExported});
1069 bool MatchNonExported) {
1070 ES.runSessionLocked([&]() {
1071 auto I =
std::find_if(SearchOrder.begin(), SearchOrder.end(),
1072 [&](
const JITDylibSearchList::value_type &KV) {
1073 return KV.first == &OldJD;
1076 if (
I != SearchOrder.end())
1077 *
I = {&NewJD, MatchNonExported};
1082 ES.runSessionLocked([&]() {
1083 auto I =
std::find_if(SearchOrder.begin(), SearchOrder.end(),
1084 [&](
const JITDylibSearchList::value_type &KV) {
1085 return KV.first == &JD;
1087 if (
I != SearchOrder.end())
1088 SearchOrder.erase(
I);
1093 return ES.runSessionLocked([&]() ->
Error {
1094 using SymbolMaterializerItrPair =
1095 std::pair<SymbolMap::iterator, UnmaterializedInfosMap::iterator>;
1096 std::vector<SymbolMaterializerItrPair> SymbolsToRemove;
1100 for (
auto &Name : Names) {
1101 auto I = Symbols.
find(Name);
1104 if (
I == Symbols.
end()) {
1110 if (
I->second.getFlags().isMaterializing()) {
1111 Materializing.
insert(Name);
1115 auto UMII =
I->second.getFlags().isLazy() ? UnmaterializedInfos.find(Name)
1116 : UnmaterializedInfos.end();
1117 SymbolsToRemove.push_back(std::make_pair(
I, UMII));
1121 if (!Missing.
empty())
1122 return make_error<SymbolsNotFound>(std::move(Missing));
1125 if (!Materializing.
empty())
1126 return make_error<SymbolsCouldNotBeRemoved>(std::move(Materializing));
1129 for (
auto &SymbolMaterializerItrPair : SymbolsToRemove) {
1130 auto UMII = SymbolMaterializerItrPair.second;
1133 if (UMII != UnmaterializedInfos.end()) {
1134 UMII->second->MU->doDiscard(*
this, UMII->first);
1135 UnmaterializedInfos.erase(UMII);
1138 auto SymI = SymbolMaterializerItrPair.first;
1139 Symbols.
erase(SymI);
1147 return ES.runSessionLocked([&,
this]() {
1149 auto Unresolved = lookupFlagsImpl(Result, Names);
1150 if (DefGenerator && !Unresolved.empty()) {
1151 auto NewDefs = DefGenerator(*
this, Unresolved);
1152 if (!NewDefs.empty()) {
1153 auto Unresolved2 = lookupFlagsImpl(Result, NewDefs);
1155 assert(Unresolved2.empty() &&
1156 "All fallback defs should have been found by lookupFlagsImpl");
1167 for (
auto &Name : Names) {
1168 auto I = Symbols.
find(Name);
1170 if (
I == Symbols.
end()) {
1175 assert(!Flags.
count(Name) &&
"Symbol already present in Flags map");
1182 void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
1185 assert(Q &&
"Query can not be null");
1187 lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs);
1188 if (DefGenerator && !Unresolved.
empty()) {
1189 auto NewDefs = DefGenerator(*
this, Unresolved);
1190 if (!NewDefs.empty()) {
1191 for (
auto &
D : NewDefs)
1193 lodgeQueryImpl(Q, NewDefs, MatchNonExported, MUs);
1194 assert(NewDefs.empty() &&
1195 "All fallback defs should have been found by lookupImpl");
1200 void JITDylib::lodgeQueryImpl(
1201 std::shared_ptr<AsynchronousSymbolQuery> &Q,
SymbolNameSet &Unresolved,
1202 bool MatchNonExported,
1203 std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
1205 std::vector<SymbolStringPtr> ToRemove;
1206 for (
auto Name : Unresolved) {
1208 auto SymI = Symbols.
find(Name);
1209 if (SymI == Symbols.
end())
1213 if (!SymI->second.getFlags().isExported() && !MatchNonExported)
1218 ToRemove.push_back(Name);
1221 if (SymI->second.getAddress() != 0)
1222 Q->resolve(Name, SymI->second);
1225 if (SymI->second.getFlags().isLazy()) {
1226 assert(SymI->second.getAddress() == 0 &&
1227 "Lazy symbol should not have a resolved address");
1228 assert(!SymI->second.getFlags().isMaterializing() &&
1229 "Materializing and lazy should not both be set");
1230 auto UMII = UnmaterializedInfos.find(Name);
1231 assert(UMII != UnmaterializedInfos.end() &&
1232 "Lazy symbol should have UnmaterializedInfo");
1233 auto MU = std::move(UMII->second->MU);
1234 assert(MU !=
nullptr &&
"Materializer should not be null");
1238 for (
auto &KV : MU->getSymbols()) {
1239 auto SymK = Symbols.
find(KV.first);
1240 auto Flags = SymK->second.getFlags();
1243 SymK->second.setFlags(Flags);
1244 UnmaterializedInfos.erase(KV.first);
1248 MUs.push_back(std::move(MU));
1249 }
else if (!SymI->second.getFlags().isMaterializing()) {
1252 Q->notifySymbolReady();
1257 assert(SymI->second.getFlags().isMaterializing() &&
1258 "By this line the symbol should be materializing");
1259 auto &
MI = MaterializingInfos[
Name];
1260 MI.PendingQueries.push_back(Q);
1261 Q->addQueryDependence(*
this, Name);
1265 for (
auto &Name : ToRemove)
1266 Unresolved.erase(Name);
1271 assert(Q &&
"Query can not be null");
1273 ES.runOutstandingMUs();
1275 LookupImplActionFlags ActionFlags =
None;
1276 std::vector<std::unique_ptr<MaterializationUnit>> MUs;
1279 ES.runSessionLocked([&,
this]() {
1280 ActionFlags = lookupImpl(Q, MUs, Unresolved);
1281 if (DefGenerator && !Unresolved.
empty()) {
1283 "ActionFlags set but unresolved symbols remain?");
1284 auto NewDefs = DefGenerator(*
this, Unresolved);
1285 if (!NewDefs.empty()) {
1286 for (
auto &
D : NewDefs)
1288 ActionFlags = lookupImpl(Q, MUs, NewDefs);
1289 assert(NewDefs.empty() &&
1290 "All fallback defs should have been found by lookupImpl");
1295 assert((MUs.empty() || ActionFlags ==
None) &&
1296 "If action flags are set, there should be no work to do (so no MUs)");
1298 if (ActionFlags & NotifyFullyResolved)
1299 Q->handleFullyResolved();
1301 if (ActionFlags & NotifyFullyReady)
1302 Q->handleFullyReady();
1308 std::lock_guard<std::recursive_mutex>
Lock(ES.OutstandingMUsMutex);
1309 for (
auto &MU : MUs)
1310 ES.OutstandingMUs.push_back(make_pair(
this, std::move(MU)));
1312 ES.runOutstandingMUs();
1321 JITDylib::LookupImplActionFlags
1322 JITDylib::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
1323 std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
1325 LookupImplActionFlags ActionFlags =
None;
1326 std::vector<SymbolStringPtr> ToRemove;
1328 for (
auto Name : Unresolved) {
1331 auto SymI = Symbols.
find(Name);
1332 if (SymI == Symbols.
end())
1336 ToRemove.push_back(Name);
1339 if (SymI->second.getAddress() != 0) {
1340 Q->resolve(Name, SymI->second);
1341 if (Q->isFullyResolved())
1342 ActionFlags |= NotifyFullyResolved;
1346 if (SymI->second.getFlags().isLazy()) {
1347 assert(SymI->second.getAddress() == 0 &&
1348 "Lazy symbol should not have a resolved address");
1349 assert(!SymI->second.getFlags().isMaterializing() &&
1350 "Materializing and lazy should not both be set");
1351 auto UMII = UnmaterializedInfos.find(Name);
1352 assert(UMII != UnmaterializedInfos.end() &&
1353 "Lazy symbol should have UnmaterializedInfo");
1354 auto MU = std::move(UMII->second->MU);
1355 assert(MU !=
nullptr &&
"Materializer should not be null");
1359 for (
auto &KV : MU->getSymbols()) {
1360 auto SymK = Symbols.
find(KV.first);
1361 auto Flags = SymK->second.getFlags();
1364 SymK->second.setFlags(Flags);
1365 UnmaterializedInfos.erase(KV.first);
1369 MUs.push_back(std::move(MU));
1370 }
else if (!SymI->second.getFlags().isMaterializing()) {
1373 Q->notifySymbolReady();
1374 if (Q->isFullyReady())
1375 ActionFlags |= NotifyFullyReady;
1380 assert(SymI->second.getFlags().isMaterializing() &&
1381 "By this line the symbol should be materializing");
1382 auto &
MI = MaterializingInfos[
Name];
1383 MI.PendingQueries.push_back(Q);
1384 Q->addQueryDependence(*
this, Name);
1388 for (
auto &Name : ToRemove)
1389 Unresolved.erase(Name);
1395 ES.runSessionLocked([&,
this]() {
1396 OS <<
"JITDylib \"" << JITDylibName <<
"\" (ES: " 1397 <<
format(
"0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES)) <<
"):\n" 1398 <<
"Search order: [";
1399 for (
auto &KV : SearchOrder)
1400 OS <<
" (\"" << KV.first->getName() <<
"\", " 1401 << (KV.second ?
"all" :
"exported only") <<
")";
1403 <<
"Symbol table:\n";
1405 for (
auto &KV : Symbols) {
1406 OS <<
" \"" << *KV.first <<
"\": ";
1407 if (
auto Addr = KV.second.getAddress())
1408 OS <<
format(
"0x%016" PRIx64, Addr) <<
", " << KV.second.getFlags();
1410 OS <<
"<not resolved>";
1411 if (KV.second.getFlags().isLazy() ||
1412 KV.second.getFlags().isMaterializing()) {
1414 if (KV.second.getFlags().isLazy()) {
1415 auto I = UnmaterializedInfos.find(KV.first);
1416 assert(
I != UnmaterializedInfos.end() &&
1417 "Lazy symbol should have UnmaterializedInfo");
1418 OS <<
" Lazy (MU=" <<
I->second->MU.get() <<
")";
1420 if (KV.second.getFlags().isMaterializing())
1421 OS <<
" Materializing";
1422 OS <<
", " << KV.second.getFlags() <<
" )\n";
1427 if (!MaterializingInfos.empty())
1428 OS <<
" MaterializingInfos entries:\n";
1429 for (
auto &KV : MaterializingInfos) {
1430 OS <<
" \"" << *KV.first <<
"\":\n" 1431 <<
" IsEmitted = " << (KV.second.IsEmitted ?
"true" :
"false")
1433 <<
" " << KV.second.PendingQueries.size()
1434 <<
" pending queries: { ";
1435 for (
auto &Q : KV.second.PendingQueries)
1436 OS << Q.get() <<
" ";
1437 OS <<
"}\n Dependants:\n";
1438 for (
auto &KV2 : KV.second.Dependants)
1439 OS <<
" " << KV2.first->getName() <<
": " << KV2.second <<
"\n";
1440 OS <<
" Unemitted Dependencies:\n";
1441 for (
auto &KV2 : KV.second.UnemittedDependencies)
1442 OS <<
" " << KV2.first->getName() <<
": " << KV2.second <<
"\n";
1448 : ES(ES), JITDylibName(std::move(Name)) {
1449 SearchOrder.push_back({
this,
true});
1456 struct ExistingDefOverriddenEntry {
1460 std::vector<ExistingDefOverriddenEntry> ExistingDefsOverridden;
1463 assert(!KV.second.isLazy() &&
"Lazy flag should be managed internally.");
1464 assert(!KV.second.isMaterializing() &&
1465 "Materializing flags should be managed internally.");
1470 auto NewFlags = KV.second;
1473 std::tie(EntryItr, Added) = Symbols.
insert(
1477 if (KV.second.isStrong()) {
1478 if (EntryItr->second.getFlags().isStrong() ||
1480 Duplicates.
insert(KV.first);
1482 ExistingDefsOverridden.push_back({EntryItr, NewFlags});
1484 MUDefsOverridden.
insert(KV.first);
1488 if (!Duplicates.
empty()) {
1491 if (Duplicates.
count(KV.first))
1495 for (
const auto &EDO : ExistingDefsOverridden)
1496 if (EDO.ExistingDefItr->first == KV.first)
1500 Symbols.
erase(KV.first);
1504 return make_error<DuplicateDefinition>(**Duplicates.
begin());
1508 for (
auto &EDO : ExistingDefsOverridden) {
1509 assert(EDO.ExistingDefItr->second.getFlags().isLazy() &&
1510 !EDO.ExistingDefItr->second.getFlags().isMaterializing() &&
1511 "Overridden existing def should be in the Lazy state");
1513 EDO.ExistingDefItr->second.setFlags(EDO.NewFlags);
1515 auto UMII = UnmaterializedInfos.find(EDO.ExistingDefItr->first);
1516 assert(UMII != UnmaterializedInfos.end() &&
1517 "Overridden existing def should have an UnmaterializedInfo");
1519 UMII->second->MU->doDiscard(*
this, EDO.ExistingDefItr->first);
1523 for (
auto &Sym : MUDefsOverridden)
1531 for (
auto &QuerySymbol : QuerySymbols) {
1532 assert(MaterializingInfos.count(QuerySymbol) &&
1533 "QuerySymbol does not have MaterializingInfo");
1534 auto &
MI = MaterializingInfos[QuerySymbol];
1536 auto IdenticalQuery =
1537 [&](
const std::shared_ptr<AsynchronousSymbolQuery> &R) {
1538 return R.get() == &Q;
1541 auto I =
std::find_if(MI.PendingQueries.begin(), MI.PendingQueries.end(),
1543 assert(
I != MI.PendingQueries.end() &&
1544 "Query Q should be in the PendingQueries list for QuerySymbol");
1545 MI.PendingQueries.erase(
I);
1549 void JITDylib::transferEmittedNodeDependencies(
1551 MaterializingInfo &EmittedMI) {
1552 for (
auto &KV : EmittedMI.UnemittedDependencies) {
1553 auto &DependencyJD = *KV.first;
1554 SymbolNameSet *UnemittedDependenciesOnDependencyJD =
nullptr;
1556 for (
auto &DependencyName : KV.second) {
1557 auto &DependencyMI = DependencyJD.MaterializingInfos[DependencyName];
1560 if (&DependencyMI == &DependantMI)
1565 if (!UnemittedDependenciesOnDependencyJD)
1566 UnemittedDependenciesOnDependencyJD =
1567 &DependantMI.UnemittedDependencies[&DependencyJD];
1569 DependencyMI.Dependants[
this].
insert(DependantName);
1570 UnemittedDependenciesOnDependencyJD->
insert(DependencyName);
1578 JDs.push_back(std::unique_ptr<JITDylib>(
new JITDylib(*
this,
"<main>")));
1586 bool AddToMainDylibSearchOrder) {
1589 std::unique_ptr<JITDylib>(
new JITDylib(*
this, std::move(Name))));
1590 if (AddToMainDylibSearchOrder)
1591 JDs.front()->addToSearchOrder(*JDs.back());
1597 assert(!!Err &&
"Error should be in failure state");
1599 bool SendErrorToQuery;
1602 SendErrorToQuery = Q.canStillFail();
1605 if (SendErrorToQuery)
1606 Q.handleFailed(std::move(Err));
1614 #if LLVM_ENABLE_THREADS 1616 std::promise<SymbolMap> PromisedResult;
1617 std::mutex ErrMutex;
1619 std::promise<void> PromisedReady;
1623 PromisedResult.set_value(std::move(*R));
1627 std::lock_guard<std::mutex>
Lock(ErrMutex);
1628 ResolutionError = R.takeError();
1634 std::function<void(Error)> OnReady;
1635 if (WaitUntilReady) {
1636 OnReady = [&](
Error Err) {
1639 std::lock_guard<std::mutex>
Lock(ErrMutex);
1640 ReadyError = std::move(Err);
1642 PromisedReady.set_value();
1645 OnReady = [&](
Error Err) {
1659 Result = std::move(*R);
1661 ResolutionError = R.takeError();
1664 std::function<void(Error)> OnReady;
1665 if (WaitUntilReady) {
1666 OnReady = [&](
Error Err) {
1669 ReadyError = std::move(Err);
1672 OnReady = [&](
Error Err) {
1679 auto Query = std::make_shared<AsynchronousSymbolQuery>(
1680 Names, std::move(OnResolve), std::move(OnReady));
1687 if (UnresolvedSymbols.empty())
1688 RegisterDependencies(
Query->QueryRegistrations);
1692 return Query->canStillFail();
1694 auto Err = make_error<SymbolsNotFound>(std::move(UnresolvedSymbols));
1696 Query->handleFailed(std::move(Err));
1701 #if LLVM_ENABLE_THREADS 1702 auto ResultFuture = PromisedResult.get_future();
1703 auto Result = ResultFuture.get();
1706 std::lock_guard<std::mutex>
Lock(ErrMutex);
1707 if (ResolutionError) {
1710 return std::move(ResolutionError);
1714 if (WaitUntilReady) {
1715 auto ReadyFuture = PromisedReady.get_future();
1719 std::lock_guard<std::mutex>
Lock(ErrMutex);
1721 return std::move(ReadyError);
1726 return std::move(Result);
1729 if (ResolutionError) {
1732 return std::move(ResolutionError);
1736 return std::move(ReadyError);
1750 runOutstandingMUs();
1752 auto Unresolved = std::move(Symbols);
1753 std::map<JITDylib *, MaterializationUnitList> CollectedMUsMap;
1754 auto Q = std::make_shared<AsynchronousSymbolQuery>(
1755 Unresolved, std::move(OnResolve), std::move(OnReady));
1756 bool QueryIsFullyResolved =
false;
1757 bool QueryIsFullyReady =
false;
1758 bool QueryFailed =
false;
1761 for (
auto &KV : SearchOrder) {
1762 assert(KV.first &&
"JITDylibList entries must not be null");
1763 assert(!CollectedMUsMap.count(KV.first) &&
1764 "JITDylibList should not contain duplicate entries");
1766 auto &JD = *KV.first;
1767 auto MatchNonExported = KV.second;
1768 JD.lodgeQuery(Q, Unresolved, MatchNonExported, CollectedMUsMap[&JD]);
1771 if (Unresolved.empty()) {
1781 if (RegisterDependencies && !Q->QueryRegistrations.
empty())
1782 RegisterDependencies(Q->QueryRegistrations);
1791 for (
auto &KV : CollectedMUsMap)
1792 for (
auto &MU : KV.second)
1793 KV.first->replace(std::move(MU));
1798 Q->handleFailed(make_error<SymbolsNotFound>(std::move(Unresolved)));
1801 if (QueryIsFullyResolved)
1803 if (QueryIsFullyReady)
1809 std::lock_guard<std::recursive_mutex>
Lock(OutstandingMUsMutex);
1811 for (
auto &KV : CollectedMUsMap)
1812 for (
auto &MU : KV.second)
1813 OutstandingMUs.push_back(std::make_pair(KV.first, std::move(MU)));
1816 runOutstandingMUs();
1822 #if LLVM_ENABLE_THREADS 1824 std::promise<SymbolMap> PromisedResult;
1825 std::mutex ErrMutex;
1827 std::promise<void> PromisedReady;
1831 PromisedResult.set_value(std::move(*R));
1835 std::lock_guard<std::mutex>
Lock(ErrMutex);
1836 ResolutionError = R.takeError();
1842 std::function<void(Error)> OnReady;
1843 if (WaitUntilReady) {
1844 OnReady = [&](
Error Err) {
1847 std::lock_guard<std::mutex>
Lock(ErrMutex);
1848 ReadyError = std::move(Err);
1850 PromisedReady.set_value();
1853 OnReady = [&](
Error Err) {
1867 Result = std::move(*R);
1869 ResolutionError = R.takeError();
1872 std::function<void(Error)> OnReady;
1873 if (WaitUntilReady) {
1874 OnReady = [&](
Error Err) {
1877 ReadyError = std::move(Err);
1880 OnReady = [&](
Error Err) {
1888 lookup(SearchOrder, Symbols, OnResolve, OnReady, RegisterDependencies);
1890 #if LLVM_ENABLE_THREADS 1891 auto ResultFuture = PromisedResult.get_future();
1892 auto Result = ResultFuture.get();
1895 std::lock_guard<std::mutex>
Lock(ErrMutex);
1896 if (ResolutionError) {
1899 return std::move(ResolutionError);
1903 if (WaitUntilReady) {
1904 auto ReadyFuture = PromisedReady.get_future();
1908 std::lock_guard<std::mutex>
Lock(ErrMutex);
1910 return std::move(ReadyError);
1915 return std::move(Result);
1918 if (ResolutionError) {
1921 return std::move(ResolutionError);
1925 return std::move(ReadyError);
1936 if (
auto ResultMap =
lookup(SearchOrder, std::move(Names),
1937 NoDependenciesToRegister,
true)) {
1938 assert(ResultMap->size() == 1 &&
"Unexpected number of results");
1939 assert(ResultMap->count(Name) &&
"Missing result for symbol");
1940 return std::move(ResultMap->begin()->second);
1942 return ResultMap.takeError();
1952 for (
auto *JD : SearchOrder)
1953 FullSearchOrder.push_back({JD,
false});
1955 return lookup(FullSearchOrder, Name);
1965 for (
auto &JD : JDs)
1970 void ExecutionSession::runOutstandingMUs() {
1972 std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>> JITDylibAndMU;
1975 std::lock_guard<std::recursive_mutex>
Lock(OutstandingMUsMutex);
1976 if (!OutstandingMUs.empty()) {
1977 JITDylibAndMU = std::move(OutstandingMUs.back());
1978 OutstandingMUs.pop_back();
1982 if (JITDylibAndMU.first) {
1983 assert(JITDylibAndMU.second &&
"JITDylib, but no MU?");
1985 std::move(JITDylibAndMU.second));
1995 std::string MangledName;
2000 return ES.
intern(MangledName);
void log(raw_ostream &OS) const override
Print an error message to an output stream.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
A parsed version of the target data layout string in and methods for querying it. ...
void emit()
Notifies the target JITDylib (and any pending queries on that JITDylib) that all symbols covered by t...
bool isCommon() const
Returns true if the Common flag is set.
This class represents lattice values for constants.
String pool for symbol names used by the JIT.
void dispatchMaterialization(JITDylib &JD, std::unique_ptr< MaterializationUnit > MU)
Materialize the given unit.
Error defineMaterializing(const SymbolFlagsMap &SymbolFlags)
Adds new symbols to the JITDylib and this responsibility instance.
void replace(std::unique_ptr< MaterializationUnit > MU)
Transfers responsibility to the given MaterializationUnit for all symbols defined by that Materializa...
~MaterializationResponsibility()
Destruct a MaterializationResponsibility instance.
std::function< void(const SymbolDependenceMap &)> RegisterDependenciesFunction
Callback to register the dependencies for a given query.
void doDiscard(const JITDylib &JD, const SymbolStringPtr &Name)
Called by JITDylibs to notify MaterializationUnits that the given symbol has been overridden...
Error remove(const SymbolNameSet &Names)
Tries to remove the given symbols.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym)
Set the resolved symbol information for the given symbol name.
JITSymbolFlags getFlags() const
Return the flags for this symbol.
bool erase(const ValueT &V)
void addDependencies(const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies)
print alias Alias Set Printer
uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
JITDylib(const JITDylib &)=delete
SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names)
std::function< bool(SymbolStringPtr)> SymbolPredicate
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
bool isWeak() const
Returns true if the Weak flag is set.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
MaterializationResponsibility(MaterializationResponsibility &&)=default
amdgpu Simplify well known AMD library false Value Value const Twine & Name
SymbolsCouldNotBeRemoved(SymbolNameSet Symbols)
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
std::error_code orcError(OrcErrorCode ErrCode)
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
SymbolFlagsMap SymbolFlags
Error define(std::unique_ptr< MaterializationUnitType > &&MU)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Tagged union holding either a T or a Error.
std::function< SymbolNameSet(std::shared_ptr< AsynchronousSymbolQuery > Q, SymbolNameSet Names)> LegacyAsyncLookupFunction
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
SymbolFlagsMap lookupFlags(const SymbolNameSet &Names)
Search the given JITDylib for the symbols in Symbols.
void notifySymbolReady()
Notify the query that a requested symbol is ready for execution.
void dump(raw_ostream &OS)
Dump the state of all the JITDylibs in this session.
llvm::detail::DenseMapPair< SymbolStringPtr, JITSymbolFlags > value_type
SymbolStringPtr operator()(StringRef Name)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err)
JITDylib & getTargetJITDylib() const
Returns the target JITDylib that these symbols are being materialized into.
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
void removeFromSearchOrder(JITDylib &JD)
Remove the given JITDylib from the search order for this JITDylib if it is present.
bool isCallable() const
Returns true if the given symbol is known to be callable.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, bool MatchNonExported=false, VModuleKey K=VModuleKey())
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
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 ...
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases, VModuleKey K=VModuleKey())
Create a ReExportsMaterializationUnit with the given aliases.
void setSearchOrder(JITDylibSearchList NewSearchOrder, bool SearchThisJITDylibFirst=true, bool MatchNonExportedInThisDylib=true)
Set the search order to be used when fixing up definitions in JITDylib.
Pointer to a pooled string representing a symbol name.
iterator find(const_arg_type_t< KeyT > Val)
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
void log(raw_ostream &OS) const override
Print an error message to an output stream.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD, bool MatchNonExported=false)
Replace OldJD with NewJD in the search order if OldJD is present.
std::pair< iterator, bool > insert(const ValueT &V)
std::function< void(Expected< SymbolMap >)> SymbolsResolvedCallback
Callback to notify client that symbols have been resolved.
Flags for symbols in the JIT.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
DenseMap< SymbolStringPtr, JITEvaluatedSymbol > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)
static ErrorSuccess success()
Create a success value.
MaterializationResponsibility delegate(const SymbolNameSet &Symbols, VModuleKey NewKey=VModuleKey())
Delegates responsibility for the given symbols to the returned materialization responsibility.
void resolve(const SymbolMap &Symbols)
Notifies the target JITDylib that the given symbols have been resolved.
JITDylib & createJITDylib(std::string Name, bool AddToMainDylibSearchOrder=true)
Add a new JITDylib to this ExecutionSession.
void addDependenciesForAll(const SymbolDependenceMap &Dependencies)
Add dependencies that apply to all symbols covered by this instance.
SymbolsNotFound(SymbolNameSet Symbols)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
SymbolNameSet getRequestedSymbols() const
Returns the names of any symbols covered by this MaterializationResponsibility object that have queri...
SymbolNameSet legacyLookup(std::shared_ptr< AsynchronousSymbolQuery > Q, SymbolNameSet Names)
FIXME: Remove this when we remove the old ORC layers.
An ExecutionSession represents a running JIT program.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
AsynchronousSymbolQuery(const SymbolNameSet &Symbols, SymbolsResolvedCallback NotifySymbolsResolved, SymbolsReadyCallback NotifySymbolsReady)
Create a query for the given symbols, notify-resolved and notify-ready callbacks. ...
Represents a symbol that has been evaluated to an address already.
Helper for Errors used as out-parameters.
A symbol query that returns results via a callback when results are ready.
std::vector< std::unique_ptr< MaterializationUnit > > MaterializationUnitList
const SymbolFlagsMap & getSymbols() const
Return the set of symbols that this source provides.
AbsoluteSymbolsMaterializationUnit(SymbolMap Symbols, VModuleKey K)
void reportError(Error Err)
Report a error for this execution session.
ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported=false, SymbolPredicate Allow=SymbolPredicate())
Create a reexports generator.
auto runSessionLocked(Func &&F) -> decltype(F())
Run the given lambda with the session mutex locked.
bool isExported() const
Returns true if the Exported flag is set.
Expected< SymbolMap > legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names, bool WaiUntilReady, RegisterDependenciesFunction RegisterDependencies)
A legacy lookup function for JITSymbolResolverAdapter.
const std::string & getName() const
Get the name for this JITDylib.
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again...
StringRef getName() const override
Return the name of this materialization unit.
static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
bool isFullyReady() const
Returns true if all symbols covered by this query are ready.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void addToSearchOrder(JITDylib &JD, bool MatcNonExported=false)
Add the given JITDylib to the search order for definitions in this JITDylib.
LLVM_NODISCARD bool empty() const
std::function< void(Error)> SymbolsReadyCallback
Callback to notify client that symbols are ready for execution.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
JITDylib & getMainJITDylib()
Get the "main" JITDylib, which is created automatically on construction of the ExecutionSession.
void failMaterialization()
Notify all not-yet-emitted covered by this MaterializationResponsibility instance that an error has o...
A raw_ostream that writes to an std::string.
void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols, SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady, RegisterDependenciesFunction RegisterDependencies)
Search the given JITDylib list for the given symbols.
Lightweight error class with error context and mandatory checking.
static JITSymbolFlags stripTransientFlags(JITSymbolFlags Orig)
This class implements an extremely fast bulk output stream that can only output to a stream...
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
StringRef - Represent a constant reference to a string, i.e.
JITTargetAddress getAddress() const
Return the address of this symbol.
bool isFullyResolved() const
Returns true if all symbols covered by this query have been resolved.
RegisterDependenciesFunction NoDependenciesToRegister
This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...
static cl::opt< bool > PrintAll("print-all-alias-modref-info", cl::ReallyHidden)
ReExportsMaterializationUnit(JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases, VModuleKey K)
SourceJD is allowed to be nullptr, in which case the source JITDylib is taken to be whatever JITDylib...
void handleFullyResolved()
Call the NotifySymbolsResolved callback.
StringRef getName() const override
Return the name of this materialization unit.
ExecutionSession(std::shared_ptr< SymbolStringPool > SSP=nullptr)
Construct an ExecutionSession.
void handleFullyReady()
Calls the NotifySymbolsReady callback.
A symbol table that supports asynchoronous symbol queries.
void dump(raw_ostream &OS)
Dump current JITDylib state to OS.
virtual StringRef getName() const =0
Return the name of this materialization unit.