Skip to content

Commit 6ef4990

Browse files
committed
Re-apply "[ORC] Track all dependencies on symbols that aren't..." with fixes.
This reapplies 427fb5c, which was reverted in 08c1a6b due to bot failures. The fix was to remove an incorrect assertion: In IL_emit, during the initial worklist loop, an EDU can have all of its dependencies removed without becoming ready (because it may still have implicit dependencies that will be added back during the subsequent propagateExtraEmitDeps operation). The EDU will be marked Ready at the end of IL_emit if its Dependencies set is empty at that point. Prior to that we can only assert that it's either Emitted or Ready (which is already covered by other assertions).
1 parent 295d6b1 commit 6ef4990

File tree

2 files changed

+73
-7
lines changed

2 files changed

+73
-7
lines changed

llvm/lib/ExecutionEngine/Orc/Core.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,6 @@ Error JITDylib::resolve(MaterializationResponsibility &MR,
938938
auto &MI = MII->second;
939939
for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {
940940
Q->notifySymbolMetRequiredState(Name, ResolvedSym);
941-
Q->removeQueryDependence(*this, Name);
942941
if (Q->isComplete())
943942
CompletedQueries.insert(std::move(Q));
944943
}
@@ -1207,9 +1206,8 @@ void JITDylib::MaterializingInfo::removeQuery(
12071206
PendingQueries, [&Q](const std::shared_ptr<AsynchronousSymbolQuery> &V) {
12081207
return V.get() == &Q;
12091208
});
1210-
assert(I != PendingQueries.end() &&
1211-
"Query is not attached to this MaterializingInfo");
1212-
PendingQueries.erase(I);
1209+
if (I != PendingQueries.end())
1210+
PendingQueries.erase(I);
12131211
}
12141212

12151213
JITDylib::AsynchronousSymbolQueryList
@@ -2615,6 +2613,12 @@ void ExecutionSession::OL_completeLookup(
26152613
LLVM_DEBUG(dbgs()
26162614
<< "matched, symbol already in required state\n");
26172615
Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());
2616+
2617+
// If this symbol is in anything other than the Ready state then
2618+
// we need to track the dependence.
2619+
if (SymI->second.getState() != SymbolState::Ready)
2620+
Q->addQueryDependence(JD, Name);
2621+
26182622
return true;
26192623
}
26202624

@@ -3165,7 +3169,6 @@ void ExecutionSession::IL_makeEDUEmitted(
31653169
Q->notifySymbolMetRequiredState(SymbolStringPtr(Sym), Entry.getSymbol());
31663170
if (Q->isComplete())
31673171
Queries.insert(Q);
3168-
Q->removeQueryDependence(JD, SymbolStringPtr(Sym));
31693172
}
31703173
}
31713174

@@ -3317,8 +3320,6 @@ ExecutionSession::IL_emit(MaterializationResponsibility &MR,
33173320
auto &DepMI = DepJD->MaterializingInfos[SymbolStringPtr(Dep)];
33183321
assert(DepMI.DefiningEDU &&
33193322
"Emitted symbol does not have a defining EDU");
3320-
assert(!DepMI.DefiningEDU->Dependencies.empty() &&
3321-
"Emitted symbol has empty dependencies (should be ready)");
33223323
assert(DepMI.DependantEDUs.empty() &&
33233324
"Already-emitted symbol has dependant EDUs?");
33243325
auto &DepEDUInfo = EDUInfos[DepMI.DefiningEDU.get()];

llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,71 @@ TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) {
518518
<< "Self-dependency prevented symbol from being marked ready";
519519
}
520520

521+
TEST_F(CoreAPIsStandardTest, TestBasicQueryDependenciesReporting) {
522+
// Test that dependencies are reported as expected.
523+
524+
bool DependenciesCallbackRan = false;
525+
526+
std::unique_ptr<MaterializationResponsibility> FooR;
527+
std::unique_ptr<MaterializationResponsibility> BarR;
528+
529+
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
530+
SymbolFlagsMap({{Foo, FooSym.getFlags()}}),
531+
[&](std::unique_ptr<MaterializationResponsibility> R) {
532+
FooR = std::move(R);
533+
})));
534+
535+
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
536+
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
537+
[&](std::unique_ptr<MaterializationResponsibility> R) {
538+
BarR = std::move(R);
539+
})));
540+
541+
cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
542+
SymbolFlagsMap({{Baz, BazSym.getFlags()}}),
543+
[&](std::unique_ptr<MaterializationResponsibility> R) {
544+
cantFail(R->notifyResolved({{Baz, BazSym}}));
545+
cantFail(R->notifyEmitted({}));
546+
})));
547+
548+
// First issue a lookup for Foo and Bar so that we can put them
549+
// into the required states for the test lookup below.
550+
ES.lookup(
551+
LookupKind::Static, makeJITDylibSearchOrder(&JD),
552+
SymbolLookupSet({Foo, Bar}), SymbolState::Resolved,
553+
[](Expected<SymbolMap> Result) {
554+
EXPECT_THAT_EXPECTED(std::move(Result), Succeeded());
555+
},
556+
NoDependenciesToRegister);
557+
558+
cantFail(FooR->notifyResolved({{Foo, FooSym}}));
559+
cantFail(FooR->notifyEmitted({}));
560+
561+
cantFail(BarR->notifyResolved({{Bar, BarSym}}));
562+
563+
ES.lookup(
564+
LookupKind::Static, makeJITDylibSearchOrder(&JD),
565+
SymbolLookupSet({Foo, Bar, Baz}), SymbolState::Resolved,
566+
[](Expected<SymbolMap> Result) {
567+
EXPECT_THAT_EXPECTED(std::move(Result), Succeeded());
568+
},
569+
[&](const SymbolDependenceMap &Dependencies) {
570+
EXPECT_EQ(Dependencies.size(), 1U)
571+
<< "Expect dependencies on only one JITDylib";
572+
EXPECT_TRUE(Dependencies.count(&JD))
573+
<< "Expect dependencies on JD only";
574+
auto &Deps = Dependencies.begin()->second;
575+
EXPECT_EQ(Deps.size(), 2U);
576+
EXPECT_TRUE(Deps.count(Bar));
577+
EXPECT_TRUE(Deps.count(Baz));
578+
DependenciesCallbackRan = true;
579+
});
580+
581+
cantFail(BarR->notifyEmitted({}));
582+
583+
EXPECT_TRUE(DependenciesCallbackRan);
584+
}
585+
521586
TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) {
522587
// Test that a circular symbol dependency between three symbols in a JITDylib
523588
// does not prevent any symbol from becoming 'ready' once all symbols are

0 commit comments

Comments
 (0)