Skip to content

Commit f675cc7

Browse files
committed
[refactor]: simplify to just cache info in DeadEndBlocks
1 parent 505ac43 commit f675cc7

File tree

4 files changed

+19
-39
lines changed

4 files changed

+19
-39
lines changed

include/swift/SIL/BasicBlockUtils.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ class DeadEndBlocks {
6868
const SILFunction *f;
6969
bool didComputeValue = false;
7070

71+
/// When non-null, indicates whether dead-end blocks are present
72+
/// in the current function.
73+
std::optional<bool> hasAnyDeadEnds = std::nullopt;
74+
7175
void compute();
7276

7377
public:
@@ -86,11 +90,14 @@ class DeadEndBlocks {
8690
}
8791

8892
/// Returns true iff none of the function's blocks is a dead-end.
89-
/// Note: This value is not cached, and may visit all the function's blocks
90-
/// to produce its return value.
93+
/// Note: The underlying value is lazily computed & cached.
9194
bool isEmpty() {
92-
return llvm::none_of(
93-
*f, [this](const SILBasicBlock &BB) { return isDeadEnd(&BB); });
95+
if (!hasAnyDeadEnds.has_value()) {
96+
hasAnyDeadEnds = llvm::any_of(
97+
*f, [this](const SILBasicBlock &BB) { return isDeadEnd(&BB); });
98+
}
99+
100+
return !hasAnyDeadEnds.value();
94101
}
95102

96103
/// Return true if this dead end blocks has computed its internal cache yet.

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,6 @@ class CanonicalizeOSSALifetime final {
237237
/// copies.
238238
const MaximizeLifetime_t maximizeLifetime;
239239

240-
/// When non-null, indicates whether dead-end blocks are assumed to be present
241-
/// in the current function.
242-
/// Set in `::canonicalizeValueLifetime`, and reset in `::clear`.
243-
std::optional<bool> hasDeadEnd = std::nullopt;
244-
245240
SILFunction *function;
246241

247242
// If present, will be used to ensure that the lifetime is not shortened to
@@ -380,8 +375,6 @@ class CanonicalizeOSSALifetime final {
380375
}
381376

382377
void clear() {
383-
hasDeadEnd.reset();
384-
385378
// Clear the access blocks analysis pointer in case the client invalidates
386379
// the analysis. If the client did, the analysis will be recomputed in
387380
// extendLivenessThroughOverlappingAccess; if it didn't, the analysis
@@ -418,10 +411,8 @@ class CanonicalizeOSSALifetime final {
418411
/// This only deletes instructions within \p def's extended lifetime. Use
419412
/// InstructionDeleter::cleanUpDeadInstructions() to recursively delete dead
420413
/// operands.
421-
bool
422-
canonicalizeValueLifetime(SILValue def,
423-
ArrayRef<SILInstruction *> lexicalLifetimeEnds = {},
424-
bool assumeDeadEnds = true);
414+
bool canonicalizeValueLifetime(
415+
SILValue def, ArrayRef<SILInstruction *> lexicalLifetimeEnds = {});
425416

426417
/// Compute the liveness information for \p def. But do not do any rewriting
427418
/// or computation of boundaries.
@@ -485,9 +476,6 @@ class CanonicalizeOSSALifetime final {
485476
}
486477

487478
bool hasAnyDeadEnds() const {
488-
if (hasDeadEnd)
489-
return *hasDeadEnd;
490-
491479
return !deadEndBlocksAnalysis->get(function)->isEmpty();
492480
}
493481

lib/SILOptimizer/Transforms/CopyPropagation.cpp

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -489,18 +489,6 @@ void CopyPropagation::propagateCopies(
489489
pruneDebug, MaximizeLifetime_t(!getFunction()->shouldOptimize()),
490490
getFunction(), accessBlockAnalysis, deadEndBlocksAnalysis, domTree,
491491
calleeAnalysis, deleter);
492-
493-
// Utility to canonicalize a value lifetime that lazily checks if dead
494-
// end blocks are present
495-
std::optional<bool> hasDeadEndBlocks = std::nullopt;
496-
auto canonicalizeValueLifetime = [&](SILValue def) -> bool {
497-
if (!hasDeadEndBlocks.has_value())
498-
hasDeadEndBlocks = !deadEndBlocksAnalysis->get(getFunction())->isEmpty();
499-
500-
return canonicalizer.canonicalizeValueLifetime(
501-
def, /*lexicalLifetimeEnd*/ {}, hasDeadEndBlocks.value());
502-
};
503-
504492
// NOTE: We assume that the function is in reverse post order so visiting the
505493
// blocks and pushing begin_borrows as we see them and then popping them
506494
// off the end will result in shrinking inner borrow scopes first.
@@ -532,7 +520,7 @@ void CopyPropagation::propagateCopies(
532520

533521
if (!continueWithNextSubpassRun(borrowee))
534522
return;
535-
auto canonicalized = canonicalizeValueLifetime(borrowee);
523+
auto canonicalized = canonicalizer.canonicalizeValueLifetime(borrowee);
536524
if (!canonicalized && !firstRun)
537525
break;
538526

@@ -541,7 +529,7 @@ void CopyPropagation::propagateCopies(
541529
auto folded = foldDestroysOfCopiedLexicalBorrow(bbi, *domTree, deleter);
542530
if (!folded)
543531
break;
544-
auto hoisted = canonicalizeValueLifetime(folded);
532+
auto hoisted = canonicalizer.canonicalizeValueLifetime(folded);
545533
// Keep running even if the new move's destroys can't be hoisted.
546534
(void)hoisted;
547535
if (!continueWithNextSubpassRun(folded))
@@ -559,7 +547,7 @@ void CopyPropagation::propagateCopies(
559547
if (argument->getOwnershipKind() == OwnershipKind::Owned) {
560548
if (!continueWithNextSubpassRun(argument))
561549
return;
562-
canonicalizeValueLifetime(argument);
550+
canonicalizer.canonicalizeValueLifetime(argument);
563551
}
564552
}
565553
deleter.cleanupDeadInstructions();
@@ -598,7 +586,7 @@ void CopyPropagation::propagateCopies(
598586
for (auto result : ownedForward->getResults()) {
599587
if (!continueWithNextSubpassRun(result))
600588
return;
601-
canonicalizeValueLifetime(result);
589+
canonicalizer.canonicalizeValueLifetime(result);
602590
}
603591
if (!continueWithNextSubpassRun(ownedForward))
604592
return;
@@ -643,7 +631,7 @@ void CopyPropagation::propagateCopies(
643631
SILValue def = defWorklist.ownedValues.pop_back_val();
644632
if (!continueWithNextSubpassRun(def))
645633
return;
646-
auto canonicalized = canonicalizeValueLifetime(def);
634+
auto canonicalized = canonicalizer.canonicalizeValueLifetime(def);
647635
if (!canonicalized)
648636
continue;
649637
// Copies of borrowed values may be dead.

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ void CanonicalizeOSSALifetime::extendLexicalLivenessToDeadEnds() {
300300
SSAPrunedLiveness directLiveness(function, &directDiscoverdBlocks);
301301
directLiveness.initializeDef(getCurrentDef());
302302
directLiveness.computeSimple();
303-
304303
OSSALifetimeCompletion::visitAvailabilityBoundary(
305304
getCurrentDef(), directLiveness, [&](auto *unreachable, auto end) {
306305
if (end == OSSALifetimeCompletion::LifetimeEnd::Boundary) {
@@ -1453,10 +1452,8 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
14531452

14541453
/// Canonicalize a single extended owned lifetime.
14551454
bool CanonicalizeOSSALifetime::canonicalizeValueLifetime(
1456-
SILValue def, ArrayRef<SILInstruction *> lexicalLifetimeEnds,
1457-
bool assumeDeadEnds) {
1455+
SILValue def, ArrayRef<SILInstruction *> lexicalLifetimeEnds) {
14581456
LivenessState livenessState(*this, def, lexicalLifetimeEnds);
1459-
hasDeadEnd = assumeDeadEnds;
14601457

14611458
// Don't canonicalize the lifetimes of values of move-only type. According to
14621459
// language rules, they are fixed.

0 commit comments

Comments
 (0)