Skip to content

Commit 849af19

Browse files
authored
Merge pull request #40500 from atrick/fix-semanticarc
SemanticARCOpts fix - remove deadEndBlocks checks
2 parents 69be7b1 + febde3d commit 849af19

File tree

6 files changed

+29
-18
lines changed

6 files changed

+29
-18
lines changed

include/swift/SIL/OwnershipUtils.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,11 @@ struct BorrowedValue {
566566
/// This ignores reborrows. The assumption is that, since \p uses are
567567
/// dominated by this local scope, checking the extended borrow scope should
568568
/// not be necessary to determine they are within the scope.
569+
///
570+
/// \p deadEndBlocks is optional during transition. It will be completely
571+
/// removed in an upcoming commit.
569572
bool areUsesWithinLocalScope(ArrayRef<Operand *> uses,
570-
DeadEndBlocks &deadEndBlocks) const;
573+
DeadEndBlocks *deadEndBlocks) const;
571574

572575
/// Given a local borrow scope introducer, visit all non-forwarding consuming
573576
/// users. This means that this looks through guaranteed block arguments. \p

include/swift/SIL/PrunedLiveness.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,9 @@ class PrunedLiveness {
334334
/// client already knows that inst occurs after the start of liveness.
335335
bool isWithinBoundary(SILInstruction *inst) const;
336336

337+
/// \p deadEndBlocks is optional.
337338
bool areUsesWithinBoundary(ArrayRef<Operand *> uses,
338-
DeadEndBlocks &deadEndBlocks) const;
339+
DeadEndBlocks *deadEndBlocks) const;
339340

340341
/// Compute liveness for a single SSA definition.
341342
void computeSSALiveness(SILValue def);

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ void BorrowedValue::computeLiveness(PrunedLiveness &liveness) const {
627627
}
628628

629629
bool BorrowedValue::areUsesWithinLocalScope(
630-
ArrayRef<Operand *> uses, DeadEndBlocks &deadEndBlocks) const {
630+
ArrayRef<Operand *> uses, DeadEndBlocks *deadEndBlocks) const {
631631
// First make sure that we actually have a local scope. If we have a non-local
632632
// scope, then we have something (like a SILFunctionArgument) where a larger
633633
// semantic construct (in the case of SILFunctionArgument, the function
@@ -906,14 +906,14 @@ bool AddressOwnership::areUsesWithinLifetime(
906906
SILValue root = base.getOwnershipReferenceRoot();
907907
BorrowedValue borrow(root);
908908
if (borrow)
909-
return borrow.areUsesWithinLocalScope(uses, deadEndBlocks);
909+
return borrow.areUsesWithinLocalScope(uses, &deadEndBlocks);
910910

911911
// --- A reference no borrow scope. Currently happens for project_box.
912912

913913
// Compute the reference value's liveness.
914914
PrunedLiveness liveness;
915915
liveness.computeSSALiveness(root);
916-
return liveness.areUsesWithinBoundary(uses, deadEndBlocks);
916+
return liveness.areUsesWithinBoundary(uses, &deadEndBlocks);
917917
}
918918

919919
//===----------------------------------------------------------------------===//

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,14 @@ bool PrunedLiveness::isWithinBoundary(SILInstruction *inst) const {
154154
}
155155

156156
bool PrunedLiveness::areUsesWithinBoundary(ArrayRef<Operand *> uses,
157-
DeadEndBlocks &deadEndBlocks) const {
157+
DeadEndBlocks *deadEndBlocks) const {
158+
auto checkDeadEnd = [deadEndBlocks](SILInstruction *inst) {
159+
return deadEndBlocks && deadEndBlocks->isDeadEnd(inst->getParent());
160+
};
161+
158162
for (auto *use : uses) {
159163
auto *user = use->getUser();
160-
if (!isWithinBoundary(user) && !deadEndBlocks.isDeadEnd(user->getParent()))
164+
if (!isWithinBoundary(user) && !checkDeadEnd(user))
161165
return false;
162166
}
163167
return true;

lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
153153
// dead end blocks that use the value in a non-consuming way.
154154
//
155155
// TODO: There may be some way of sinking this into the loop below.
156+
//
157+
// FIXME: The haveAnyLocalScopes and destroy.empty() checks are relics of
158+
// attempts to handle dead end blocks during areUsesWithinLocalScope. If we
159+
// don't use dead end blocks at all, they should not be relevant.
156160
bool haveAnyLocalScopes =
157161
llvm::any_of(borrowScopeIntroducers, [](BorrowedValue borrowScope) {
158162
return borrowScope.isLocalScope();
@@ -177,17 +181,16 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
177181
// anyways, we want to be conservative here and optimize only if we do not
178182
// need to insert an end_borrow since all of our borrow introducers are
179183
// non-local scopes.
184+
//
185+
// The call to areUsesWithinLocalScope cannot consider dead-end blocks. A
186+
// local borrow scope requires all its inner uses to be inside the borrow
187+
// scope, regardless of whether the end of the scope is inside a dead-end
188+
// block.
180189
{
181-
bool foundNonDeadEnd = false;
182-
for (auto *d : destroys) {
183-
foundNonDeadEnd |= !getDeadEndBlocks().isDeadEnd(d->getParentBlock());
184-
}
185-
if (!foundNonDeadEnd && haveAnyLocalScopes)
186-
return false;
187190
SmallVector<Operand *, 8> scratchSpace;
188191
if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
189-
return !borrowScope.areUsesWithinLocalScope(lr.getAllConsumingUses(),
190-
getDeadEndBlocks());
192+
return !borrowScope.areUsesWithinLocalScope(lr.getAllConsumingUses(),
193+
nullptr);
191194
})) {
192195
return false;
193196
}
@@ -216,7 +219,7 @@ bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
216219

217220
if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
218221
return !borrowScope.areUsesWithinLocalScope(
219-
phiArgLR.getAllConsumingUses(), getDeadEndBlocks());
222+
phiArgLR.getAllConsumingUses(), nullptr);
220223
})) {
221224
return false;
222225
}

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ GuaranteedOwnershipExtension::checkBorrowExtension(
176176
assert(guaranteedLiveness.empty());
177177
borrow.computeLiveness(guaranteedLiveness);
178178

179-
if (guaranteedLiveness.areUsesWithinBoundary(newUses, deBlocks))
179+
if (guaranteedLiveness.areUsesWithinBoundary(newUses, &deBlocks))
180180
return Valid; // reuse the borrow scope as-is
181181

182182
beginBorrow = dyn_cast<BeginBorrowInst>(borrow.value);
@@ -224,7 +224,7 @@ GuaranteedOwnershipExtension::checkLifetimeExtension(
224224
ownedConsumeBlocks.push_back(user->getParent());
225225
}
226226
}
227-
if (ownedLifetime.areUsesWithinBoundary(newUses, deBlocks))
227+
if (ownedLifetime.areUsesWithinBoundary(newUses, &deBlocks))
228228
return Valid;
229229

230230
return ExtendLifetime; // Can't cover newUses without destroy sinking.

0 commit comments

Comments
 (0)