Skip to content

Commit 78732c6

Browse files
Merge pull request #65590 from nate-chandler/pruned-liveness/remove-invalidate
[Pruned Liveness] Removed invalidate API.
2 parents 41c180d + 689fe3a commit 78732c6

File tree

8 files changed

+43
-68
lines changed

8 files changed

+43
-68
lines changed

include/swift/SIL/PrunedLiveness.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,6 @@ class PrunedLiveBlocks {
202202

203203
bool isInitialized() const { return initializedFlag; }
204204

205-
void invalidate() {
206-
initializedFlag = false;
207-
}
208-
209205
void initializeDiscoveredBlocks(
210206
SmallVectorImpl<SILBasicBlock *> *discoveredBlocks) {
211207
assert(!isInitialized() && "cannot reinitialize after blocks are live");
@@ -371,11 +367,6 @@ class PrunedLiveness {
371367

372368
bool empty() const { return users.empty(); }
373369

374-
void invalidate() {
375-
liveBlocks.invalidate();
376-
users.clear();
377-
}
378-
379370
void initializeDiscoveredBlocks(
380371
SmallVectorImpl<SILBasicBlock *> *discoveredBlocks) {
381372
liveBlocks.initializeDiscoveredBlocks(discoveredBlocks);
@@ -639,12 +630,6 @@ class SSAPrunedLiveness : public PrunedLiveRange<SSAPrunedLiveness> {
639630

640631
SILValue getDef() const { return def; }
641632

642-
void invalidate() {
643-
def = SILValue();
644-
defInst = nullptr;
645-
PrunedLiveRange::invalidate();
646-
}
647-
648633
void initializeDef(SILValue def) {
649634
assert(!this->def && "reinitialization");
650635

@@ -710,10 +695,6 @@ class MultiDefPrunedLiveness : public PrunedLiveRange<MultiDefPrunedLiveness> {
710695
: PrunedLiveRange(function, discoveredBlocks), defs(function),
711696
defBlocks(function) {}
712697

713-
void invalidate() {
714-
PrunedLiveRange::invalidate();
715-
}
716-
717698
void initializeDef(SILInstruction *defInst) {
718699
initializeDefNode(cast<SILNode>(defInst));
719700
}
@@ -800,12 +781,6 @@ class DiagnosticPrunedLiveness : public SSAPrunedLiveness {
800781
: SSAPrunedLiveness(function, discoveredBlocks),
801782
nonLifetimeEndingUsesInLiveOut(nonLifetimeEndingUsesInLiveOut) {}
802783

803-
void invalidate() {
804-
SSAPrunedLiveness::invalidate();
805-
if (nonLifetimeEndingUsesInLiveOut)
806-
nonLifetimeEndingUsesInLiveOut->clear();
807-
}
808-
809784
void updateForUse(SILInstruction *user, bool lifetimeEnding);
810785

811786
using NonLifetimeEndingUsesInLiveOutRange =

include/swift/SIL/SILBitfield.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,16 @@ template <typename BitfieldContainer> struct BitfieldRef {
181181
return ref;
182182
}
183183

184+
explicit operator bool() { return ref; }
185+
184186
// Stack-allocated state must be nested relative to other node bitfields.
185187
struct StackState {
186188
BitfieldRef &ref;
187189
BitfieldContainer container;
188190

189-
StackState(BitfieldRef &ref, SILFunction *function)
190-
: ref(ref), container(function) {
191+
template <typename... ArgTypes>
192+
StackState(BitfieldRef &ref, ArgTypes &&...Args)
193+
: ref(ref), container(std::forward<ArgTypes>(Args)...) {
191194
ref.ref = &container;
192195
}
193196

include/swift/SILOptimizer/Utils/CanonicalizeBorrowScope.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ class CanonicalizeBorrowScope {
6060
// The borrow that begins this scope.
6161
BorrowedValue borrowedValue;
6262

63+
/// The function containing this scope.
64+
SILFunction *function;
65+
6366
/// Pruned liveness for the extended live range including copies. For this
6467
/// purpose, only consuming instructions are considered "lifetime
6568
/// ending". end_borrows do not end a liverange that may include owned copies.
66-
SSAPrunedLiveness liveness;
69+
BitfieldRef<SSAPrunedLiveness> liveness;
6770

6871
InstructionDeleter &deleter;
6972

@@ -86,11 +89,11 @@ class CanonicalizeBorrowScope {
8689

8790
public:
8891
CanonicalizeBorrowScope(SILFunction *function, InstructionDeleter &deleter)
89-
: liveness(function), deleter(deleter) {}
92+
: function(function), deleter(deleter) {}
9093

9194
BorrowedValue getBorrowedValue() const { return borrowedValue; }
9295

93-
const SSAPrunedLiveness &getLiveness() const { return liveness; }
96+
const SSAPrunedLiveness &getLiveness() const { return *liveness; }
9497

9598
InstructionDeleter &getDeleter() { return deleter; }
9699

@@ -136,11 +139,13 @@ class CanonicalizeBorrowScope {
136139

137140
protected:
138141
void initBorrow(BorrowedValue borrow) {
139-
assert(borrow && liveness.empty() && persistentCopies.empty());
142+
assert(borrow && persistentCopies.empty() &&
143+
(!liveness || liveness->empty()));
140144

141145
updatedCopies.clear();
142146
borrowedValue = borrow;
143-
liveness.initializeDef(borrowedValue.value);
147+
if (liveness)
148+
liveness->initializeDef(borrowedValue.value);
144149
}
145150

146151
bool computeBorrowLiveness();

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,9 @@ class CanonicalizeOSSALifetime final {
325325
liveness->initializeDef(getCurrentDef());
326326
}
327327

328-
void invalidateLiveness() {
328+
void clear() {
329329
consumingBlocks.clear();
330330
debugValues.clear();
331-
liveness->invalidate();
332331
discoveredBlocks.clear();
333332
}
334333

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,6 @@ class GuaranteedOwnershipExtension {
115115
: deleter(deleter), deBlocks(deBlocks),
116116
guaranteedLiveness(function), ownedLifetime(function) {}
117117

118-
void invalidate() {
119-
guaranteedLiveness.invalidate();
120-
ownedLifetime.invalidate();
121-
ownedConsumeBlocks.clear();
122-
beginBorrow = nullptr;
123-
}
124-
125118
/// Invalid indicates that the current guaranteed scope is insufficient, and
126119
/// it does not meet the precondition for scope extension.
127120
///

lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,12 @@ struct CheckerLivenessInfo {
5858
SmallSetVector<Operand *, 8> consumingUse;
5959
SmallSetVector<SILInstruction *, 8> nonLifetimeEndingUsesInLiveOut;
6060
SmallVector<Operand *, 8> interiorPointerTransitiveUses;
61-
DiagnosticPrunedLiveness liveness;
61+
BitfieldRef<DiagnosticPrunedLiveness> liveness;
6262

63-
CheckerLivenessInfo(SILFunction *fn)
64-
: nonLifetimeEndingUsesInLiveOut(),
65-
liveness(fn, nullptr, &nonLifetimeEndingUsesInLiveOut) {}
63+
CheckerLivenessInfo() : nonLifetimeEndingUsesInLiveOut() {}
6664

6765
void initDef(SILValue def) {
68-
liveness.initializeDef(def);
66+
liveness->initializeDef(def);
6967
defUseWorklist.insert(def);
7068
}
7169

@@ -78,7 +76,6 @@ struct CheckerLivenessInfo {
7876

7977
void clear() {
8078
defUseWorklist.clear();
81-
liveness.invalidate();
8279
consumingUse.clear();
8380
interiorPointerTransitiveUses.clear();
8481
nonLifetimeEndingUsesInLiveOut.clear();
@@ -121,16 +118,16 @@ bool CheckerLivenessInfo::compute() {
121118
case OperandOwnership::InstantaneousUse:
122119
case OperandOwnership::UnownedInstantaneousUse:
123120
case OperandOwnership::BitwiseEscape:
124-
liveness.updateForUse(user, /*lifetimeEnding*/ false);
121+
liveness->updateForUse(user, /*lifetimeEnding*/ false);
125122
break;
126123
case OperandOwnership::ForwardingConsume:
127124
consumingUse.insert(use);
128-
liveness.updateForUse(user, /*lifetimeEnding*/ true);
125+
liveness->updateForUse(user, /*lifetimeEnding*/ true);
129126
break;
130127
case OperandOwnership::DestroyingConsume:
131128
// destroy_value does not force pruned liveness (but store etc. does).
132129
if (!isa<DestroyValueInst>(user)) {
133-
liveness.updateForUse(user, /*lifetimeEnding*/ true);
130+
liveness->updateForUse(user, /*lifetimeEnding*/ true);
134131
}
135132
consumingUse.insert(use);
136133
break;
@@ -147,12 +144,12 @@ bool CheckerLivenessInfo::compute() {
147144
// of the new variable as a use. Thus we only include the begin_borrow
148145
// itself as the use.
149146
if (bbi->isLexical()) {
150-
liveness.updateForUse(bbi, false /*lifetime ending*/);
147+
liveness->updateForUse(bbi, false /*lifetime ending*/);
151148
} else {
152149
// Otherwise, try to update liveness for a borrowing operand
153150
// use. This will make it so that we add the end_borrows of the
154151
// liveness use. If we have a reborrow here, we will bail.
155-
if (liveness.updateForBorrowingOperand(use) !=
152+
if (liveness->updateForBorrowingOperand(use) !=
156153
InnerBorrowKind::Contained) {
157154
return false;
158155
}
@@ -163,7 +160,7 @@ bool CheckerLivenessInfo::compute() {
163160
case OperandOwnership::GuaranteedForwarding:
164161
// A forwarding borrow is validated as part of its parent borrow. So
165162
// just mark it as extending liveness and look through it.
166-
liveness.updateForUse(user, /*lifetimeEnding*/ false);
163+
liveness->updateForUse(user, /*lifetimeEnding*/ false);
167164
ForwardingOperand(use).visitForwardedValues([&](SILValue result) {
168165
if (SILArgument::isTerminatorResult(result)) {
169166
return true;
@@ -187,7 +184,8 @@ bool CheckerLivenessInfo::compute() {
187184
(void)addrUseKind;
188185
while (!interiorPointerTransitiveUses.empty()) {
189186
auto *addrUse = interiorPointerTransitiveUses.pop_back_val();
190-
liveness.updateForUse(addrUse->getUser(), /*lifetimeEnding*/ false);
187+
liveness->updateForUse(addrUse->getUser(),
188+
/*lifetimeEnding*/ false);
191189
}
192190
}
193191
break;
@@ -220,8 +218,7 @@ struct ConsumeOperatorCopyableValuesChecker {
220218
SILLoopInfo *loopInfoToUpdate;
221219

222220
ConsumeOperatorCopyableValuesChecker(SILFunction *fn)
223-
: fn(fn), livenessInfo(fn), dominanceToUpdate(nullptr),
224-
loopInfoToUpdate(nullptr) {}
221+
: fn(fn), dominanceToUpdate(nullptr), loopInfoToUpdate(nullptr) {}
225222

226223
void setDominanceToUpdate(DominanceInfo *newDFI) {
227224
dominanceToUpdate = newDFI;
@@ -262,7 +259,7 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
262259
// going to be emitting a diagnostic and thus later parts of the compiler are
263260
// not going to run. First we look for uses in the same block as our move.
264261
auto *mviBlock = mvi->getParent();
265-
auto mviBlockLiveness = livenessInfo.liveness.getBlockLiveness(mviBlock);
262+
auto mviBlockLiveness = livenessInfo.liveness->getBlockLiveness(mviBlock);
266263
switch (mviBlockLiveness) {
267264
case PrunedLiveBlocks::Dead:
268265
llvm_unreachable("We should never see this");
@@ -278,7 +275,7 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
278275
// implementation choice.
279276
for (SILInstruction &inst :
280277
make_range(std::next(mvi->getIterator()), mviBlock->end())) {
281-
switch (livenessInfo.liveness.isInterestingUser(&inst)) {
278+
switch (livenessInfo.liveness->isInterestingUser(&inst)) {
282279
case PrunedLiveness::NonUser:
283280
break;
284281
case PrunedLiveness::NonLifetimeEndingUse:
@@ -334,9 +331,9 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
334331
// adding successors since we do not need to look further than the pruned
335332
// liveness boundary for uses.
336333
if (PrunedLiveBlocks::LiveOut !=
337-
livenessInfo.liveness.getBlockLiveness(block)) {
334+
livenessInfo.liveness->getBlockLiveness(block)) {
338335
for (SILInstruction &inst : *block) {
339-
switch (livenessInfo.liveness.isInterestingUser(&inst)) {
336+
switch (livenessInfo.liveness->isInterestingUser(&inst)) {
340337
case PrunedLiveness::NonUser:
341338
break;
342339
case PrunedLiveness::NonLifetimeEndingUse:
@@ -442,6 +439,10 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
442439
// TODO: We should add llvm.dbg.addr support for fastisel and also teach
443440
// CodeGen how to handle llvm.dbg.addr better.
444441
while (!valuesToProcess.empty()) {
442+
BitfieldRef<DiagnosticPrunedLiveness>::StackState livenessBitfieldContainer(
443+
livenessInfo.liveness, fn, nullptr,
444+
&livenessInfo.nonLifetimeEndingUsesInLiveOut);
445+
445446
auto lexicalValue = valuesToProcess.front();
446447
valuesToProcess = valuesToProcess.drop_front(1);
447448
LLVM_DEBUG(llvm::dbgs() << "Visiting: " << *lexicalValue);
@@ -473,7 +474,7 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
473474
mvi->setAllowsDiagnostics(false);
474475

475476
LLVM_DEBUG(llvm::dbgs() << "Move Value: " << *mvi);
476-
if (livenessInfo.liveness.isWithinBoundary(mvi)) {
477+
if (livenessInfo.liveness->isWithinBoundary(mvi)) {
477478
LLVM_DEBUG(llvm::dbgs() << " WithinBoundary: Yes!\n");
478479
emitDiagnosticForMove(lexicalValue, varName, mvi);
479480
} else {

lib/SILOptimizer/Utils/CanonicalizeBorrowScope.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ bool CanonicalizeBorrowScope::computeBorrowLiveness() {
180180
// the reborrowed value will not be rewritten when canonicalizing the current
181181
// borrow scope because they are "hidden" behind the reborrow.
182182
borrowedValue.visitLocalScopeEndingUses([this](Operand *use) {
183-
liveness.updateForUse(use->getUser(), /*lifetimeEnding*/ true);
183+
liveness->updateForUse(use->getUser(), /*lifetimeEnding*/ true);
184184
return true;
185185
});
186186
return true;
@@ -824,8 +824,6 @@ bool CanonicalizeBorrowScope::canonicalizeFunctionArgument(
824824

825825
LLVM_DEBUG(llvm::dbgs() << "*** Canonicalize Borrow: " << borrowedValue);
826826

827-
SWIFT_DEFER { liveness.invalidate(); };
828-
829827
RewriteInnerBorrowUses innerRewriter(*this);
830828
beginVisitBorrowScopeUses(); // reset the def/use worklist
831829

@@ -839,12 +837,13 @@ bool CanonicalizeBorrowScope::canonicalizeFunctionArgument(
839837
/// forwarding operations.
840838
bool CanonicalizeBorrowScope::
841839
canonicalizeBorrowScope(BorrowedValue borrowedValue) {
840+
BitfieldRef<SSAPrunedLiveness>::StackState livenessBitfieldContainer(
841+
liveness, function);
842+
842843
LLVM_DEBUG(llvm::dbgs() << "*** Canonicalize Borrow: " << borrowedValue);
843844

844845
initBorrow(borrowedValue);
845846

846-
SWIFT_DEFER { liveness.invalidate(); };
847-
848847
if (!computeBorrowLiveness())
849848
return false;
850849

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ bool CanonicalizeOSSALifetime::computeLiveness() {
11081108
// Step 1: compute liveness
11091109
if (!computeCanonicalLiveness()) {
11101110
LLVM_DEBUG(llvm::errs() << "Failed to compute canonical liveness?!\n");
1111-
invalidateLiveness();
1111+
clear();
11121112
return false;
11131113
}
11141114
if (currentDef->isLexical()) {
@@ -1145,7 +1145,7 @@ void CanonicalizeOSSALifetime::rewriteLifetimes() {
11451145
// Step 6: rewrite copies and delete extra destroys
11461146
rewriteCopies();
11471147

1148-
invalidateLiveness();
1148+
clear();
11491149
consumes.clear();
11501150
}
11511151

0 commit comments

Comments
 (0)