@@ -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 {
0 commit comments