Skip to content

Commit 4f71049

Browse files
committed
[ORC] Remove symbols from dependency lists when failing materialization.
When failing materialization of a symbol X, remove X from the dependants list of any of X's dependencies. This ensures that when X's dependencies are emitted (or fail themselves) they do not try to access the no-longer-existing MaterializationInfo for X. llvm-svn: 359252
1 parent 1be5369 commit 4f71049

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

llvm/lib/ExecutionEngine/Orc/Core.cpp

+29-2
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,8 @@ SymbolNameSet MaterializationResponsibility::getRequestedSymbols() const {
390390
}
391391

392392
void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
393-
LLVM_DEBUG(dbgs() << "In " << JD.getName() << " resolving " << Symbols
394-
<< "\n");
393+
LLVM_DEBUG(
394+
{ dbgs() << "In " << JD.getName() << " resolving " << Symbols << "\n"; });
395395
#ifndef NDEBUG
396396
for (auto &KV : Symbols) {
397397
auto I = SymbolFlags.find(KV.first);
@@ -412,6 +412,11 @@ void MaterializationResponsibility::resolve(const SymbolMap &Symbols) {
412412
}
413413

414414
void MaterializationResponsibility::emit() {
415+
416+
LLVM_DEBUG({
417+
dbgs() << "In " << JD.getName() << " emitting " << SymbolFlags << "\n";
418+
});
419+
415420
#ifndef NDEBUG
416421
for (auto &KV : SymbolFlags)
417422
assert(!KV.second.isMaterializing() &&
@@ -441,6 +446,11 @@ Error MaterializationResponsibility::defineMaterializing(
441446

442447
void MaterializationResponsibility::failMaterialization() {
443448

449+
LLVM_DEBUG({
450+
dbgs() << "In " << JD.getName() << " failing materialization for "
451+
<< SymbolFlags << "\n";
452+
});
453+
444454
SymbolNameSet FailedSymbols;
445455
for (auto &KV : SymbolFlags)
446456
FailedSymbols.insert(KV.first);
@@ -1025,6 +1035,23 @@ void JITDylib::notifyFailed(const SymbolNameSet &FailedSymbols) {
10251035
if (MII == MaterializingInfos.end())
10261036
continue;
10271037

1038+
// Remove this symbol from the dependants list of any dependencies.
1039+
for (auto &KV : MII->second.UnemittedDependencies) {
1040+
auto *DependencyJD = KV.first;
1041+
auto &Dependencies = KV.second;
1042+
for (auto &DependencyName : Dependencies) {
1043+
auto DependencyMII =
1044+
DependencyJD->MaterializingInfos.find(DependencyName);
1045+
assert(DependencyMII != DependencyJD->MaterializingInfos.end() &&
1046+
"Unemitted dependency must have a MaterializingInfo entry");
1047+
assert(DependencyMII->second.Dependants.count(this) &&
1048+
"Dependency's dependants list does not contain this JITDylib");
1049+
assert(DependencyMII->second.Dependants[this].count(Name) &&
1050+
"Dependency's dependants list does not contain dependant");
1051+
DependencyMII->second.Dependants[this].erase(Name);
1052+
}
1053+
}
1054+
10281055
// Copy all the queries to the FailedQueries list, then abandon them.
10291056
// This has to be a copy, and the copy has to come before the abandon
10301057
// operation: Each Q.detach() call will reach back into this

llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ add_llvm_unittest(OrcJITTests
3030
ThreadSafeModuleTest.cpp
3131
)
3232

33-
target_link_libraries(OrcJITTests PRIVATE ${ORC_JIT_TEST_LIBS})
33+
target_link_libraries(OrcJITTests PRIVATE
34+
LLVMTestingSupport
35+
${ORC_JIT_TEST_LIBS})

llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/Config/llvm-config.h"
1111
#include "llvm/ExecutionEngine/Orc/Core.h"
1212
#include "llvm/ExecutionEngine/Orc/OrcError.h"
13+
#include "llvm/Testing/Support/Error.h"
1314

1415
#include <set>
1516
#include <thread>
@@ -730,6 +731,41 @@ TEST_F(CoreAPIsStandardTest, FailResolution) {
730731
}
731732
}
732733

734+
TEST_F(CoreAPIsStandardTest, FailEmissionEarly) {
735+
736+
cantFail(JD.define(absoluteSymbols({{Baz, BazSym}})));
737+
738+
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
739+
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
740+
[&](MaterializationResponsibility R) {
741+
R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
742+
743+
ES.lookup(
744+
JITDylibSearchList({{&JD, false}}), SymbolNameSet({Baz}),
745+
[&R](Expected<SymbolMap> Result) {
746+
// Called when "baz" is resolved. We don't actually depend
747+
// on or care about baz, but use it to trigger failure of
748+
// this materialization before Baz has been finalized in
749+
// order to test that error propagation is correct in this
750+
// scenario.
751+
cantFail(std::move(Result));
752+
R.failMaterialization();
753+
},
754+
[](Error Err) { cantFail(std::move(Err)); },
755+
[&](const SymbolDependenceMap &Deps) {
756+
R.addDependenciesForAll(Deps);
757+
});
758+
});
759+
760+
cantFail(JD.define(MU));
761+
762+
SymbolNameSet Names({Foo, Bar});
763+
auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
764+
765+
EXPECT_THAT_EXPECTED(std::move(Result), Failed())
766+
<< "Unexpected success while trying to test error propagation";
767+
}
768+
733769
TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
734770
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
735771
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),

0 commit comments

Comments
 (0)