[ORC] Change how non-exported symbols are matched during lookup.
In the new scheme the client passes a list of (JITDylib&, bool) pairs, rather
than a list of JITDylibs. For each JITDylib the boolean indicates whether or not
to match against non-exported symbols (true means that they should be found,
false means that they should not). The MatchNonExportedInJD and MatchNonExported
parameters on lookup are removed.
The new scheme is more flexible, and easier to understand.
This patch also updates JITDylib search orders to be lists of (JITDylib&, bool)
pairs to match the new lookup scheme. Error handling is also plumbed through
the LLJIT class to allow regression tests to fail predictably when a lookup from
a lazy call-through fails.
llvm-svn: 345077
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index de1fa07..241eb36 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -157,7 +157,7 @@
return;
}
- R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables)));
+ R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true));
R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
std::move(Callables)));
}
@@ -166,10 +166,17 @@
CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {
auto I = DylibResources.find(&TargetD);
if (I == DylibResources.end()) {
- auto &ImplD =
- getExecutionSession().createJITDylib(TargetD.getName() + ".impl");
- TargetD.withSearchOrderDo([&](const JITDylibList &TargetSearchOrder) {
- ImplD.setSearchOrder(TargetSearchOrder, false);
+ auto &ImplD = getExecutionSession().createJITDylib(
+ TargetD.getName() + ".impl", false);
+ TargetD.withSearchOrderDo([&](const JITDylibSearchList &TargetSearchOrder) {
+ auto NewSearchOrder = TargetSearchOrder;
+ assert(!NewSearchOrder.empty() &&
+ NewSearchOrder.front().first == &TargetD &&
+ NewSearchOrder.front().second == true &&
+ "TargetD must be at the front of its own search order and match "
+ "non-exported symbol");
+ NewSearchOrder.insert(std::next(NewSearchOrder.begin()), {&ImplD, true});
+ ImplD.setSearchOrder(std::move(NewSearchOrder), false);
});
PerDylibResources PDR(ImplD, BuildIndirectStubsManager());
I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index df4d002..8a9740e 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -205,14 +205,16 @@
return OS << ")";
}
-raw_ostream &operator<<(raw_ostream &OS, const JITDylibList &JDs) {
+raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs) {
OS << "[";
if (!JDs.empty()) {
- assert(JDs.front() && "JITDylibList entries must not be null");
- OS << " " << JDs.front()->getName();
- for (auto *JD : make_range(std::next(JDs.begin()), JDs.end())) {
- assert(JD && "JITDylibList entries must not be null");
- OS << ", " << JD->getName();
+ assert(JDs.front().first && "JITDylibList entries must not be null");
+ OS << " (\"" << JDs.front().first->getName() << "\", "
+ << (JDs.front().second ? "true" : "false") << ")";
+ for (auto &KV : make_range(std::next(JDs.begin()), JDs.end())) {
+ assert(KV.first && "JITDylibList entries must not be null");
+ OS << ", (\"" << KV.first->getName() << "\", "
+ << (KV.second ? "true" : "false") << ")";
}
}
OS << " ]";
@@ -526,9 +528,11 @@
}
ReExportsMaterializationUnit::ReExportsMaterializationUnit(
- JITDylib *SourceJD, SymbolAliasMap Aliases, VModuleKey K)
+ JITDylib *SourceJD, bool MatchNonExported, SymbolAliasMap Aliases,
+ VModuleKey K)
: MaterializationUnit(extractFlags(Aliases), std::move(K)),
- SourceJD(SourceJD), Aliases(std::move(Aliases)) {}
+ SourceJD(SourceJD), MatchNonExported(MatchNonExported),
+ Aliases(std::move(Aliases)) {}
StringRef ReExportsMaterializationUnit::getName() const {
return "<Reexports>";
@@ -556,7 +560,7 @@
if (!Aliases.empty()) {
if (SourceJD)
- R.replace(reexports(*SourceJD, std::move(Aliases)));
+ R.replace(reexports(*SourceJD, std::move(Aliases), MatchNonExported));
else
R.replace(symbolAliases(std::move(Aliases)));
}
@@ -656,8 +660,8 @@
auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
- ES.lookup({&SrcJD}, QuerySymbols, std::move(OnResolve), std::move(OnReady),
- std::move(RegisterDependencies), nullptr, true);
+ ES.lookup({{&SrcJD, MatchNonExported}}, QuerySymbols, std::move(OnResolve),
+ std::move(OnReady), std::move(RegisterDependencies));
}
}
@@ -698,8 +702,10 @@
}
ReexportsGenerator::ReexportsGenerator(JITDylib &SourceJD,
+ bool MatchNonExported,
SymbolPredicate Allow)
- : SourceJD(SourceJD), Allow(std::move(Allow)) {}
+ : SourceJD(SourceJD), MatchNonExported(MatchNonExported),
+ Allow(std::move(Allow)) {}
SymbolNameSet ReexportsGenerator::operator()(JITDylib &JD,
const SymbolNameSet &Names) {
@@ -716,7 +722,7 @@
}
if (!Added.empty())
- cantFail(JD.define(reexports(SourceJD, AliasMap)));
+ cantFail(JD.define(reexports(SourceJD, AliasMap, MatchNonExported)));
return Added;
}
@@ -1041,30 +1047,41 @@
Q->handleFailed(make_error<FailedToMaterialize>(FailedSymbols));
}
-void JITDylib::setSearchOrder(JITDylibList NewSearchOrder,
- bool SearchThisJITDylibFirst) {
- if (SearchThisJITDylibFirst && NewSearchOrder.front() != this)
- NewSearchOrder.insert(NewSearchOrder.begin(), this);
+void JITDylib::setSearchOrder(JITDylibSearchList NewSearchOrder,
+ bool SearchThisJITDylibFirst,
+ bool MatchNonExportedInThisDylib) {
+ if (SearchThisJITDylibFirst && NewSearchOrder.front().first != this)
+ NewSearchOrder.insert(NewSearchOrder.begin(),
+ {this, MatchNonExportedInThisDylib});
ES.runSessionLocked([&]() { SearchOrder = std::move(NewSearchOrder); });
}
-void JITDylib::addToSearchOrder(JITDylib &JD) {
- ES.runSessionLocked([&]() { SearchOrder.push_back(&JD); });
+void JITDylib::addToSearchOrder(JITDylib &JD, bool MatchNonExported) {
+ ES.runSessionLocked([&]() {
+ SearchOrder.push_back({&JD, MatchNonExported});
+ });
}
-void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD) {
+void JITDylib::replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
+ bool MatchNonExported) {
ES.runSessionLocked([&]() {
- auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &OldJD);
+ auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
+ [&](const JITDylibSearchList::value_type &KV) {
+ return KV.first == &OldJD;
+ });
if (I != SearchOrder.end())
- *I = &NewJD;
+ *I = {&NewJD, MatchNonExported};
});
}
void JITDylib::removeFromSearchOrder(JITDylib &JD) {
ES.runSessionLocked([&]() {
- auto I = std::find(SearchOrder.begin(), SearchOrder.end(), &JD);
+ auto I = std::find_if(SearchOrder.begin(), SearchOrder.end(),
+ [&](const JITDylibSearchList::value_type &KV) {
+ return KV.first == &JD;
+ });
if (I != SearchOrder.end())
SearchOrder.erase(I);
});
@@ -1161,18 +1178,17 @@
}
void JITDylib::lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
- SymbolNameSet &Unresolved,
- JITDylib *MatchNonExportedInJD, bool MatchNonExported,
+ SymbolNameSet &Unresolved, bool MatchNonExported,
MaterializationUnitList &MUs) {
assert(Q && "Query can not be null");
- lodgeQueryImpl(Q, Unresolved, MatchNonExportedInJD, MatchNonExported, MUs);
+ lodgeQueryImpl(Q, Unresolved, MatchNonExported, MUs);
if (DefGenerator && !Unresolved.empty()) {
auto NewDefs = DefGenerator(*this, Unresolved);
if (!NewDefs.empty()) {
for (auto &D : NewDefs)
Unresolved.erase(D);
- lodgeQueryImpl(Q, NewDefs, MatchNonExportedInJD, MatchNonExported, MUs);
+ lodgeQueryImpl(Q, NewDefs, MatchNonExported, MUs);
assert(NewDefs.empty() &&
"All fallback defs should have been found by lookupImpl");
}
@@ -1181,7 +1197,7 @@
void JITDylib::lodgeQueryImpl(
std::shared_ptr<AsynchronousSymbolQuery> &Q, SymbolNameSet &Unresolved,
- JITDylib *MatchNonExportedInJD, bool MatchNonExported,
+ bool MatchNonExported,
std::vector<std::unique_ptr<MaterializationUnit>> &MUs) {
std::vector<SymbolStringPtr> ToRemove;
@@ -1191,12 +1207,9 @@
if (SymI == Symbols.end())
continue;
- // If this is a non-exported symbol, then check the values of
- // MatchNonExportedInJD and MatchNonExported. Skip if we should not match
- // against this symbol.
- if (!SymI->second.getFlags().isExported())
- if (!MatchNonExported && MatchNonExportedInJD != this)
- continue;
+ // If this is a non exported symbol and we're skipping those then skip it.
+ if (!SymI->second.getFlags().isExported() && !MatchNonExported)
+ continue;
// If we matched against Name in JD, mark it to be removed from the Unresolved
// set.
@@ -1382,8 +1395,9 @@
<< "\" (ES: " << format("0x%016x", reinterpret_cast<uintptr_t>(&ES))
<< "):\n"
<< "Search order: [";
- for (auto *JD : SearchOrder)
- OS << " \"" << JD->getName() << "\"";
+ for (auto &KV : SearchOrder)
+ OS << " (\"" << KV.first->getName() << "\", "
+ << (KV.second ? "all" : "exported only") << ")";
OS << " ]\n"
<< "Symbol table:\n";
@@ -1431,7 +1445,7 @@
JITDylib::JITDylib(ExecutionSession &ES, std::string Name)
: ES(ES), JITDylibName(std::move(Name)) {
- SearchOrder.push_back(this);
+ SearchOrder.push_back({this, true});
}
Error JITDylib::defineImpl(MaterializationUnit &MU) {
@@ -1724,12 +1738,10 @@
#endif
}
-void ExecutionSession::lookup(const JITDylibList &JDs, SymbolNameSet Symbols,
- SymbolsResolvedCallback OnResolve,
- SymbolsReadyCallback OnReady,
- RegisterDependenciesFunction RegisterDependencies,
- JITDylib *MatchNonExportedInJD,
- bool MatchNonExported) {
+void ExecutionSession::lookup(
+ const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
+ SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
+ RegisterDependenciesFunction RegisterDependencies) {
// lookup can be re-entered recursively if running on a single thread. Run any
// outstanding MUs in case this query depends on them, otherwise this lookup
@@ -1745,12 +1757,14 @@
bool QueryFailed = false;
runSessionLocked([&]() {
- for (auto *JD : JDs) {
- assert(JD && "JITDylibList entries must not be null");
- assert(!CollectedMUsMap.count(JD) &&
+ for (auto &KV : SearchOrder) {
+ assert(KV.first && "JITDylibList entries must not be null");
+ assert(!CollectedMUsMap.count(KV.first) &&
"JITDylibList should not contain duplicate entries");
- JD->lodgeQuery(Q, Unresolved, MatchNonExportedInJD, MatchNonExported,
- CollectedMUsMap[JD]);
+
+ auto &JD = *KV.first;
+ auto MatchNonExported = KV.second;
+ JD.lodgeQuery(Q, Unresolved, MatchNonExported, CollectedMUsMap[&JD]);
}
if (Unresolved.empty()) {
@@ -1801,11 +1815,9 @@
runOutstandingMUs();
}
-Expected<SymbolMap>
-ExecutionSession::lookup(const JITDylibList &JDs, const SymbolNameSet &Symbols,
- RegisterDependenciesFunction RegisterDependencies,
- bool WaitUntilReady, JITDylib *MatchNonExportedInJD,
- bool MatchNonExported) {
+Expected<SymbolMap> ExecutionSession::lookup(
+ const JITDylibSearchList &SearchOrder, const SymbolNameSet &Symbols,
+ RegisterDependenciesFunction RegisterDependencies, bool WaitUntilReady) {
#if LLVM_ENABLE_THREADS
// In the threaded case we use promises to return the results.
std::promise<SymbolMap> PromisedResult;
@@ -1872,8 +1884,7 @@
#endif
// Perform the asynchronous lookup.
- lookup(JDs, Symbols, OnResolve, OnReady, RegisterDependencies,
- MatchNonExportedInJD, MatchNonExported);
+ lookup(SearchOrder, Symbols, OnResolve, OnReady, RegisterDependencies);
#if LLVM_ENABLE_THREADS
auto ResultFuture = PromisedResult.get_future();
@@ -1916,14 +1927,13 @@
#endif
}
-/// Look up a symbol by searching a list of JDs.
-Expected<JITEvaluatedSymbol> ExecutionSession::lookup(const JITDylibList &JDs,
- SymbolStringPtr Name,
- bool MatchNonExported) {
+Expected<JITEvaluatedSymbol>
+ExecutionSession::lookup(const JITDylibSearchList &SearchOrder,
+ SymbolStringPtr Name) {
SymbolNameSet Names({Name});
- if (auto ResultMap = lookup(JDs, std::move(Names), NoDependenciesToRegister,
- true, nullptr, MatchNonExported)) {
+ if (auto ResultMap = lookup(SearchOrder, std::move(Names),
+ NoDependenciesToRegister, true)) {
assert(ResultMap->size() == 1 && "Unexpected number of results");
assert(ResultMap->count(Name) && "Missing result for symbol");
return std::move(ResultMap->begin()->second);
@@ -1931,10 +1941,21 @@
return ResultMap.takeError();
}
-Expected<JITEvaluatedSymbol> ExecutionSession::lookup(const JITDylibList &JDs,
- StringRef Name,
- bool MatchNonExported) {
- return lookup(JDs, intern(Name), MatchNonExported);
+Expected<JITEvaluatedSymbol>
+ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder,
+ SymbolStringPtr Name) {
+ SymbolNameSet Names({Name});
+
+ JITDylibSearchList FullSearchOrder(SearchOrder.size());
+ for (auto *JD : SearchOrder)
+ FullSearchOrder.push_back({JD, false});
+
+ return lookup(FullSearchOrder, Name);
+}
+
+Expected<JITEvaluatedSymbol>
+ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name) {
+ return lookup(SearchOrder, intern(Name));
}
void ExecutionSession::dump(raw_ostream &OS) {
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 21a604f..3a1984e 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -129,9 +129,8 @@
}
auto &ES = JD.getExecutionSession();
- if (auto CtorDtorMap =
- ES.lookup({&JD}, std::move(Names), NoDependenciesToRegister, true,
- nullptr, true)) {
+ if (auto CtorDtorMap = ES.lookup({{&JD, true}}, std::move(Names),
+ NoDependenciesToRegister, true)) {
for (auto &KV : CtorDtorsByPriority) {
for (auto &Name : KV.second) {
assert(CtorDtorMap->count(Name) && "No entry for Name");
diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index c10d15a..205821b 100644
--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -101,7 +101,7 @@
Name = I->second;
}
- if (auto Sym = ES.lookup({&CallbacksJD}, Name, true))
+ if (auto Sym = ES.lookup({{&CallbacksJD, true}}, Name))
return Sym->getAddress();
else {
llvm::dbgs() << "Didn't find callback.\n";
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index ac71a5e..8486fe4 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -76,7 +76,7 @@
Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
StringRef Name) {
- return ES->lookup({&JD}, ES->intern(Name));
+ return ES->lookup({{&JD, true}}, ES->intern(Name));
}
LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
@@ -144,13 +144,13 @@
}
Expected<std::unique_ptr<LLLazyJIT>>
- LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
- unsigned NumCompileThreads) {
+LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
+ JITTargetAddress ErrorAddr, unsigned NumCompileThreads) {
auto ES = llvm::make_unique<ExecutionSession>();
const Triple &TT = JTMB.getTargetTriple();
- auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
+ auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr);
if (!LCTMgr)
return LCTMgr.takeError();
diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
index af4c508..ba8e2a9 100644
--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp
@@ -52,8 +52,8 @@
SymbolName = I->second.second;
}
- auto LookupResult = ES.lookup({SourceJD}, {SymbolName},
- NoDependenciesToRegister, true, nullptr, true);
+ auto LookupResult = ES.lookup({{SourceJD, true}}, {SymbolName},
+ NoDependenciesToRegister, true);
if (!LookupResult) {
ES.reportError(LookupResult.takeError());
diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
index 616251c..299d761 100644
--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp
@@ -50,10 +50,11 @@
MR.addDependenciesForAll(Deps);
};
- MR.getTargetJITDylib().withSearchOrderDo([&](const JITDylibList &JDs) {
- ES.lookup(JDs, InternedSymbols, OnResolvedWithUnwrap, OnReady,
- RegisterDependencies, &MR.getTargetJITDylib());
- });
+ JITDylibSearchList SearchOrder;
+ MR.getTargetJITDylib().withSearchOrderDo(
+ [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
+ ES.lookup(SearchOrder, InternedSymbols, OnResolvedWithUnwrap, OnReady,
+ RegisterDependencies);
}
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) {