Skip to content

Commit e090bc4

Browse files
committed
PassManager: cleanup the analysis-invalidation mechanism for swift passes
This fixes a bug with module passes.
1 parent 000df95 commit e090bc4

File tree

2 files changed

+35
-33
lines changed

2 files changed

+35
-33
lines changed

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class SwiftPassInvocation {
6161
/// Non-null if this is an instruction pass, invoked from SILCombine.
6262
SILCombiner *silCombiner = nullptr;
6363

64+
/// Change notifications, collected during a pass run.
65+
SILAnalysis::InvalidationKind changeNotifications =
66+
SILAnalysis::InvalidationKind::Nothing;
67+
6468
/// All slabs, allocated by the pass.
6569
SILModule::SlabList allocatedSlabs;
6670

@@ -126,17 +130,9 @@ class SwiftPassInvocation {
126130
/// Called by the SILCombiner when the instruction pass has finished.
127131
void finishedInstructionPassRun();
128132

129-
void beginTransformFunction(SILFunction *function) {
130-
assert(!this->function && transform && "not running a module pass");
131-
this->function = function;
132-
}
133+
void beginTransformFunction(SILFunction *function);
133134

134-
void endTransformFunction() {
135-
assert(function && "beginTransformFunction not called");
136-
function = nullptr;
137-
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
138-
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
139-
}
135+
void endTransformFunction();
140136
};
141137

142138
/// The SIL pass manager.
@@ -184,10 +180,6 @@ class SILPassManager {
184180
/// For invoking Swift passes.
185181
SwiftPassInvocation swiftPassInvocation;
186182

187-
/// Change notifications, collected during a bridged pass run.
188-
SILAnalysis::InvalidationKind changeNotifications =
189-
SILAnalysis::InvalidationKind::Nothing;
190-
191183
/// A mask which has one bit for each pass. A one for a pass-bit means that
192184
/// the pass doesn't need to run, because nothing has changed since the
193185
/// previous run of that pass.
@@ -341,11 +333,6 @@ class SILPassManager {
341333
CompletedPassesMap[F].reset();
342334
}
343335

344-
void notifyPassChanges(SILAnalysis::InvalidationKind invalidationKind) {
345-
changeNotifications = (SILAnalysis::InvalidationKind)
346-
(changeNotifications | invalidationKind);
347-
}
348-
349336
/// Reset the state of the pass manager and remove all transformation
350337
/// owned by the pass manager. Analysis passes will be kept.
351338
void resetAndRemoveTransformations();
@@ -440,7 +427,8 @@ class SILPassManager {
440427

441428
inline void SwiftPassInvocation::
442429
notifyChanges(SILAnalysis::InvalidationKind invalidationKind) {
443-
passManager->notifyPassChanges(invalidationKind);
430+
changeNotifications = (SILAnalysis::InvalidationKind)
431+
(changeNotifications | invalidationKind);
444432
}
445433

446434
} // end namespace swift

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,6 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
530530
forcePrecomputeAnalyses(F);
531531
}
532532

533-
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
534-
&& "change notifications not cleared");
535-
536533
llvm::sys::TimePoint<> startTime = std::chrono::system_clock::now();
537534
std::chrono::nanoseconds duration(0);
538535

@@ -553,24 +550,21 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
553550
// Run it!
554551
SFT->run();
555552

556-
if (CurrentPassHasInvalidated ||
557-
changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
553+
swiftPassInvocation.finishedFunctionPassRun();
554+
555+
if (CurrentPassHasInvalidated) {
558556
// Pause time measurement while invalidating analysis and restoring the snapshot.
559557
duration += (std::chrono::system_clock::now() - startTime);
560558

561559
if (runIdx < numRepeats - 1) {
562560
invalidateAnalysis(F, SILAnalysis::InvalidationKind::Everything);
563561
F->restoreFromSnapshot(SnapshotID);
564-
} else if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
565-
invalidateAnalysis(F, changeNotifications);
566562
}
567-
changeNotifications = SILAnalysis::InvalidationKind::Nothing;
568563

569564
// Continue time measurement (including flushing deleted instructions).
570565
startTime = std::chrono::system_clock::now();
571566
}
572567
Mod->flushDeletedInsts();
573-
swiftPassInvocation.finishedFunctionPassRun();
574568
}
575569

576570
duration += (std::chrono::system_clock::now() - startTime);
@@ -1289,9 +1283,9 @@ void SwiftPassInvocation::startModulePassRun(SILModuleTransform *transform) {
12891283
}
12901284

12911285
void SwiftPassInvocation::startFunctionPassRun(SILFunctionTransform *transform) {
1292-
assert(!this->function && !this->transform && "a pass is already running");
1293-
this->function = transform->getFunction();
1286+
assert(!this->transform && "a pass is already running");
12941287
this->transform = transform;
1288+
beginTransformFunction(transform->getFunction());
12951289
}
12961290

12971291
void SwiftPassInvocation::startInstructionPassRun(SILInstruction *inst) {
@@ -1302,13 +1296,15 @@ void SwiftPassInvocation::startInstructionPassRun(SILInstruction *inst) {
13021296
void SwiftPassInvocation::finishedModulePassRun() {
13031297
endPassRunChecks();
13041298
assert(!function && transform && "not running a pass");
1299+
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
1300+
&& "unhandled change notifications at end of module pass");
13051301
transform = nullptr;
13061302
}
13071303

13081304
void SwiftPassInvocation::finishedFunctionPassRun() {
13091305
endPassRunChecks();
1310-
assert(function && transform && "not running a pass");
1311-
function = nullptr;
1306+
endTransformFunction();
1307+
assert(allocatedSlabs.empty() && "StackList is leaking slabs");
13121308
transform = nullptr;
13131309
}
13141310

@@ -1322,6 +1318,24 @@ void SwiftPassInvocation::endPassRunChecks() {
13221318
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
13231319
}
13241320

1321+
void SwiftPassInvocation::beginTransformFunction(SILFunction *function) {
1322+
assert(!this->function && transform && "not running a pass");
1323+
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
1324+
&& "change notifications not cleared");
1325+
this->function = function;
1326+
}
1327+
1328+
void SwiftPassInvocation::endTransformFunction() {
1329+
assert(function && transform && "not running a pass");
1330+
if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
1331+
passManager->invalidateAnalysis(function, changeNotifications);
1332+
changeNotifications = SILAnalysis::InvalidationKind::Nothing;
1333+
}
1334+
function = nullptr;
1335+
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
1336+
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
1337+
}
1338+
13251339
//===----------------------------------------------------------------------===//
13261340
// Swift Bridging
13271341
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)