@@ -58,14 +58,12 @@ struct CheckerLivenessInfo {
58
58
SmallSetVector<Operand *, 8 > consumingUse;
59
59
SmallSetVector<SILInstruction *, 8 > nonLifetimeEndingUsesInLiveOut;
60
60
SmallVector<Operand *, 8 > interiorPointerTransitiveUses;
61
- DiagnosticPrunedLiveness liveness;
61
+ BitfieldRef< DiagnosticPrunedLiveness> liveness;
62
62
63
- CheckerLivenessInfo (SILFunction *fn)
64
- : nonLifetimeEndingUsesInLiveOut(),
65
- liveness (fn, nullptr , &nonLifetimeEndingUsesInLiveOut) {}
63
+ CheckerLivenessInfo () : nonLifetimeEndingUsesInLiveOut() {}
66
64
67
65
void initDef (SILValue def) {
68
- liveness. initializeDef (def);
66
+ liveness-> initializeDef (def);
69
67
defUseWorklist.insert (def);
70
68
}
71
69
@@ -78,7 +76,6 @@ struct CheckerLivenessInfo {
78
76
79
77
void clear () {
80
78
defUseWorklist.clear ();
81
- liveness.invalidate ();
82
79
consumingUse.clear ();
83
80
interiorPointerTransitiveUses.clear ();
84
81
nonLifetimeEndingUsesInLiveOut.clear ();
@@ -121,16 +118,16 @@ bool CheckerLivenessInfo::compute() {
121
118
case OperandOwnership::InstantaneousUse:
122
119
case OperandOwnership::UnownedInstantaneousUse:
123
120
case OperandOwnership::BitwiseEscape:
124
- liveness. updateForUse (user, /* lifetimeEnding*/ false );
121
+ liveness-> updateForUse (user, /* lifetimeEnding*/ false );
125
122
break ;
126
123
case OperandOwnership::ForwardingConsume:
127
124
consumingUse.insert (use);
128
- liveness. updateForUse (user, /* lifetimeEnding*/ true );
125
+ liveness-> updateForUse (user, /* lifetimeEnding*/ true );
129
126
break ;
130
127
case OperandOwnership::DestroyingConsume:
131
128
// destroy_value does not force pruned liveness (but store etc. does).
132
129
if (!isa<DestroyValueInst>(user)) {
133
- liveness. updateForUse (user, /* lifetimeEnding*/ true );
130
+ liveness-> updateForUse (user, /* lifetimeEnding*/ true );
134
131
}
135
132
consumingUse.insert (use);
136
133
break ;
@@ -147,12 +144,12 @@ bool CheckerLivenessInfo::compute() {
147
144
// of the new variable as a use. Thus we only include the begin_borrow
148
145
// itself as the use.
149
146
if (bbi->isLexical ()) {
150
- liveness. updateForUse (bbi, false /* lifetime ending*/ );
147
+ liveness-> updateForUse (bbi, false /* lifetime ending*/ );
151
148
} else {
152
149
// Otherwise, try to update liveness for a borrowing operand
153
150
// use. This will make it so that we add the end_borrows of the
154
151
// liveness use. If we have a reborrow here, we will bail.
155
- if (liveness. updateForBorrowingOperand (use) !=
152
+ if (liveness-> updateForBorrowingOperand (use) !=
156
153
InnerBorrowKind::Contained) {
157
154
return false ;
158
155
}
@@ -163,7 +160,7 @@ bool CheckerLivenessInfo::compute() {
163
160
case OperandOwnership::GuaranteedForwarding:
164
161
// A forwarding borrow is validated as part of its parent borrow. So
165
162
// just mark it as extending liveness and look through it.
166
- liveness. updateForUse (user, /* lifetimeEnding*/ false );
163
+ liveness-> updateForUse (user, /* lifetimeEnding*/ false );
167
164
ForwardingOperand (use).visitForwardedValues ([&](SILValue result) {
168
165
if (SILArgument::isTerminatorResult (result)) {
169
166
return true ;
@@ -187,7 +184,8 @@ bool CheckerLivenessInfo::compute() {
187
184
(void )addrUseKind;
188
185
while (!interiorPointerTransitiveUses.empty ()) {
189
186
auto *addrUse = interiorPointerTransitiveUses.pop_back_val ();
190
- liveness.updateForUse (addrUse->getUser (), /* lifetimeEnding*/ false );
187
+ liveness->updateForUse (addrUse->getUser (),
188
+ /* lifetimeEnding*/ false );
191
189
}
192
190
}
193
191
break ;
@@ -220,8 +218,7 @@ struct ConsumeOperatorCopyableValuesChecker {
220
218
SILLoopInfo *loopInfoToUpdate;
221
219
222
220
ConsumeOperatorCopyableValuesChecker (SILFunction *fn)
223
- : fn(fn), livenessInfo(fn), dominanceToUpdate(nullptr ),
224
- loopInfoToUpdate (nullptr ) {}
221
+ : fn(fn), dominanceToUpdate(nullptr ), loopInfoToUpdate(nullptr ) {}
225
222
226
223
void setDominanceToUpdate (DominanceInfo *newDFI) {
227
224
dominanceToUpdate = newDFI;
@@ -262,7 +259,7 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
262
259
// going to be emitting a diagnostic and thus later parts of the compiler are
263
260
// not going to run. First we look for uses in the same block as our move.
264
261
auto *mviBlock = mvi->getParent ();
265
- auto mviBlockLiveness = livenessInfo.liveness . getBlockLiveness (mviBlock);
262
+ auto mviBlockLiveness = livenessInfo.liveness -> getBlockLiveness (mviBlock);
266
263
switch (mviBlockLiveness) {
267
264
case PrunedLiveBlocks::Dead:
268
265
llvm_unreachable (" We should never see this" );
@@ -278,7 +275,7 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
278
275
// implementation choice.
279
276
for (SILInstruction &inst :
280
277
make_range (std::next (mvi->getIterator ()), mviBlock->end ())) {
281
- switch (livenessInfo.liveness . isInterestingUser (&inst)) {
278
+ switch (livenessInfo.liveness -> isInterestingUser (&inst)) {
282
279
case PrunedLiveness::NonUser:
283
280
break ;
284
281
case PrunedLiveness::NonLifetimeEndingUse:
@@ -334,9 +331,9 @@ void ConsumeOperatorCopyableValuesChecker::emitDiagnosticForMove(
334
331
// adding successors since we do not need to look further than the pruned
335
332
// liveness boundary for uses.
336
333
if (PrunedLiveBlocks::LiveOut !=
337
- livenessInfo.liveness . getBlockLiveness (block)) {
334
+ livenessInfo.liveness -> getBlockLiveness (block)) {
338
335
for (SILInstruction &inst : *block) {
339
- switch (livenessInfo.liveness . isInterestingUser (&inst)) {
336
+ switch (livenessInfo.liveness -> isInterestingUser (&inst)) {
340
337
case PrunedLiveness::NonUser:
341
338
break ;
342
339
case PrunedLiveness::NonLifetimeEndingUse:
@@ -442,6 +439,10 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
442
439
// TODO: We should add llvm.dbg.addr support for fastisel and also teach
443
440
// CodeGen how to handle llvm.dbg.addr better.
444
441
while (!valuesToProcess.empty ()) {
442
+ BitfieldRef<DiagnosticPrunedLiveness>::StackState livenessBitfieldContainer (
443
+ livenessInfo.liveness , fn, nullptr ,
444
+ &livenessInfo.nonLifetimeEndingUsesInLiveOut );
445
+
445
446
auto lexicalValue = valuesToProcess.front ();
446
447
valuesToProcess = valuesToProcess.drop_front (1 );
447
448
LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *lexicalValue);
@@ -473,7 +474,7 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
473
474
mvi->setAllowsDiagnostics (false );
474
475
475
476
LLVM_DEBUG (llvm::dbgs () << " Move Value: " << *mvi);
476
- if (livenessInfo.liveness . isWithinBoundary (mvi)) {
477
+ if (livenessInfo.liveness -> isWithinBoundary (mvi)) {
477
478
LLVM_DEBUG (llvm::dbgs () << " WithinBoundary: Yes!\n " );
478
479
emitDiagnosticForMove (lexicalValue, varName, mvi);
479
480
} else {
0 commit comments