Skip to content

Commit e705a6d

Browse files
committed
Temporarily introduce AnyInteriorPointer operand ownership.
This is necessary to fix a recent OSSA bug that breaks common occurrences on mark_dependence [nonescaping]. Rather than reverting that change above, we make forward progress toward implicit borrows scopes, as was the original intention. In the near future, all InteriorPointer instructions will create an implicit borrow scope. This means we have the option of not emitting extraneous begin/end_borrow instructions around intructions like ref_element_addr, open_existential, and project_box. After that, we can also migrate GuaranteedForwarding instructions like tuple_extract and struct_extract.
1 parent d3d8fe9 commit e705a6d

17 files changed

+65
-18
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,11 @@ extension OwnershipUseVisitor {
415415
case .borrow:
416416
return visitBorrowingUse(of: operand)
417417

418-
// TODO: Eventually, visit owned InteriorPointers as implicit borrows.
419-
case .interiorPointer, .trivialUse, .endBorrow, .reborrow,
420-
.guaranteedForwarding:
418+
case .anyInteriorPointer:
419+
return visitInteriorPointerUse(of: operand)
420+
421+
// TODO: .interiorPointer should instead be handled like .anyInteriorPointer.
422+
case .interiorPointer, .trivialUse, .endBorrow, .reborrow, .guaranteedForwarding:
421423
fatalError("ownership incompatible with an owned value");
422424
}
423425
}
@@ -449,7 +451,7 @@ extension OwnershipUseVisitor {
449451
case .borrow:
450452
return visitBorrowingUse(of: operand)
451453

452-
case .interiorPointer:
454+
case .interiorPointer, .anyInteriorPointer:
453455
return visitInteriorPointerUse(of: operand)
454456

455457
case .trivialUse, .forwardingConsume, .destroyingConsume:

SwiftCompilerSources/Sources/SIL/Operand.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,11 @@ public enum OperandOwnership {
268268
/// Interior Pointer. Propagates a trivial value (e.g. address, pointer, or no-escape closure) that depends on the guaranteed value within the base's borrow scope. The verifier checks that all uses of the trivial
269269
/// value are in scope. (ref_element_addr, open_existential_box)
270270
case interiorPointer
271-
271+
272+
/// Any Interior Pointer. An interior pointer that allows any operand ownership. This will be removed as soon as SIL
273+
/// migrates away from extraneous borrow scopes.
274+
case anyInteriorPointer
275+
272276
/// Forwarded Borrow. Propagates the guaranteed value within the base's borrow scope. (tuple_extract, struct_extract, cast, switch)
273277
case guaranteedForwarding
274278

@@ -282,7 +286,7 @@ public enum OperandOwnership {
282286
switch self {
283287
case .nonUse, .trivialUse, .instantaneousUse, .unownedInstantaneousUse,
284288
.forwardingUnowned, .pointerEscape, .bitwiseEscape, .borrow,
285-
.interiorPointer, .guaranteedForwarding:
289+
.interiorPointer, .anyInteriorPointer, .guaranteedForwarding:
286290
return false
287291
case .destroyingConsume, .forwardingConsume, .endBorrow, .reborrow:
288292
return true
@@ -313,6 +317,8 @@ public enum OperandOwnership {
313317
return BridgedOperand.OperandOwnership.ForwardingConsume
314318
case .interiorPointer:
315319
return BridgedOperand.OperandOwnership.InteriorPointer
320+
case .anyInteriorPointer:
321+
return BridgedOperand.OperandOwnership.AnyInteriorPointer
316322
case .guaranteedForwarding:
317323
return BridgedOperand.OperandOwnership.GuaranteedForwarding
318324
case .endBorrow:
@@ -337,6 +343,7 @@ extension Operand {
337343
case .DestroyingConsume: return .destroyingConsume
338344
case .ForwardingConsume: return .forwardingConsume
339345
case .InteriorPointer: return .interiorPointer
346+
case .AnyInteriorPointer: return .anyInteriorPointer
340347
case .GuaranteedForwarding: return .guaranteedForwarding
341348
case .EndBorrow: return .endBorrow
342349
case .Reborrow: return .reborrow

include/swift/SIL/OwnershipUseVisitor.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ bool OwnershipUseVisitor<Impl>::visitOwnedUse(Operand *use) {
397397
}
398398
return handleUsePoint(use, UseLifetimeConstraint::LifetimeEnding);
399399

400+
case OperandOwnership::AnyInteriorPointer:
401+
return visitInteriorPointerUses(use);
402+
400403
case OperandOwnership::PointerEscape:
401404
// TODO: Change ProjectBox ownership to InteriorPointer and allow them to
402405
// take owned values.
@@ -416,7 +419,7 @@ bool OwnershipUseVisitor<Impl>::visitOwnedUse(Operand *use) {
416419
case OperandOwnership::Borrow:
417420
return visitInnerBorrow(use);
418421

419-
// TODO: Eventually, handle owned InteriorPointers as implicit borrows.
422+
// TODO: InteriorPointer should be handled like AnyInteriorPointer.
420423
case OperandOwnership::InteriorPointer:
421424
case OperandOwnership::TrivialUse:
422425
case OperandOwnership::EndBorrow:
@@ -479,6 +482,7 @@ bool OwnershipUseVisitor<Impl>::visitGuaranteedUse(Operand *use) {
479482
return visitInnerBorrow(use);
480483

481484
case OperandOwnership::InteriorPointer:
485+
case OperandOwnership::AnyInteriorPointer:
482486
return visitInteriorPointerUses(use);
483487

484488
case OperandOwnership::TrivialUse:
@@ -490,8 +494,9 @@ bool OwnershipUseVisitor<Impl>::visitGuaranteedUse(Operand *use) {
490494

491495
template <typename Impl>
492496
bool OwnershipUseVisitor<Impl>::visitInteriorPointerUses(Operand *use) {
493-
assert(use->getOperandOwnership() == OperandOwnership::InteriorPointer ||
494-
isa<ProjectBoxInst>(use->getUser()));
497+
assert(use->getOperandOwnership() == OperandOwnership::InteriorPointer
498+
|| use->getOperandOwnership() == OperandOwnership::AnyInteriorPointer
499+
|| isa<ProjectBoxInst>(use->getUser()));
495500

496501
if (auto scopedAddress = ScopedAddressValue::forUse(use)) {
497502
// e.g. client may need to insert end_borrow if scopedAddress is a store_borrow.

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ struct BridgedOperand {
373373
DestroyingConsume,
374374
ForwardingConsume,
375375
InteriorPointer,
376+
AnyInteriorPointer,
376377
GuaranteedForwarding,
377378
EndBorrow,
378379
Reborrow

include/swift/SIL/SILBridgingImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ BridgedOperand::OperandOwnership BridgedOperand::getOperandOwnership() const {
645645
return OperandOwnership::ForwardingConsume;
646646
case swift::OperandOwnership::InteriorPointer:
647647
return OperandOwnership::InteriorPointer;
648+
case swift::OperandOwnership::AnyInteriorPointer:
649+
return OperandOwnership::AnyInteriorPointer;
648650
case swift::OperandOwnership::GuaranteedForwarding:
649651
return OperandOwnership::GuaranteedForwarding;
650652
case swift::OperandOwnership::EndBorrow:

include/swift/SIL/SILValue.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,13 @@ struct OperandOwnership {
848848
/// value are in scope.
849849
/// (ref_element_addr, open_existential_box)
850850
InteriorPointer,
851+
852+
// TODO: Remove AnyInteriorPointer after fixing
853+
// OperandOwnership::getOwnershipConstraint() to allow InteriorPointer
854+
// operands to take any operand ownership. This will prevent useless borrow
855+
// scopes from being generated, so it will require some SIL migration. But
856+
// all OSSA utilities need to correctly handle interior uses anyway.
857+
AnyInteriorPointer,
851858
/// Forwarded Borrow. Propagates the guaranteed value within the base's
852859
/// borrow scope.
853860
/// (tuple_extract, struct_extract, cast, switch)
@@ -942,6 +949,9 @@ inline OwnershipConstraint OperandOwnership::getOwnershipConstraint() {
942949
case OperandOwnership::DestroyingConsume:
943950
case OperandOwnership::ForwardingConsume:
944951
return {OwnershipKind::Owned, UseLifetimeConstraint::LifetimeEnding};
952+
case OperandOwnership::AnyInteriorPointer:
953+
return {OwnershipKind::Any, UseLifetimeConstraint::NonLifetimeEnding};
954+
// TODO: InteriorPointer should be handled like AnyInteriorPointer.
945955
case OperandOwnership::InteriorPointer:
946956
case OperandOwnership::GuaranteedForwarding:
947957
return {OwnershipKind::Guaranteed,
@@ -971,6 +981,7 @@ inline bool canAcceptUnownedValue(OperandOwnership operandOwnership) {
971981
case OperandOwnership::DestroyingConsume:
972982
case OperandOwnership::ForwardingConsume:
973983
case OperandOwnership::InteriorPointer:
984+
case OperandOwnership::AnyInteriorPointer:
974985
case OperandOwnership::GuaranteedForwarding:
975986
case OperandOwnership::EndBorrow:
976987
case OperandOwnership::Reborrow:

lib/SIL/IR/SILValue.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,8 @@ StringRef OperandOwnership::asString() const {
564564
return "forwarding-consume";
565565
case OperandOwnership::InteriorPointer:
566566
return "interior-pointer";
567+
case OperandOwnership::AnyInteriorPointer:
568+
return "any-interior-pointer";
567569
case OperandOwnership::GuaranteedForwarding:
568570
return "guaranteed-forwarding";
569571
case OperandOwnership::EndBorrow:

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ bool swift::findPointerEscape(SILValue original) {
8181
});
8282
break;
8383
}
84-
case OperandOwnership::InteriorPointer: {
84+
case OperandOwnership::InteriorPointer:
85+
case OperandOwnership::AnyInteriorPointer: {
8586
if (InteriorPointerOperand(use).findTransitiveUses() !=
8687
AddressUseKind::NonEscaping) {
8788
return true;
@@ -247,6 +248,7 @@ bool swift::findInnerTransitiveGuaranteedUses(
247248
break;
248249

249250
case OperandOwnership::InteriorPointer:
251+
case OperandOwnership::AnyInteriorPointer:
250252
#if 0 // FIXME!!! Enable in a following commit that fixes RAUW
251253
// If our base guaranteed value does not have any consuming uses
252254
// (consider function arguments), we need to be sure to include interior
@@ -387,6 +389,7 @@ bool swift::findExtendedUsesOfSimpleBorrowedValue(
387389
break;
388390

389391
case OperandOwnership::InteriorPointer:
392+
case OperandOwnership::AnyInteriorPointer:
390393
if (InteriorPointerOperandKind::get(use) ==
391394
InteriorPointerOperandKind::Invalid)
392395
return false;

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ PrunedLiveRange<LivenessWithDefs>::updateForBorrowingOperand(Operand *operand) {
299299
template <typename LivenessWithDefs>
300300
AddressUseKind PrunedLiveRange<LivenessWithDefs>::checkAndUpdateInteriorPointer(
301301
Operand *operand) {
302-
assert(operand->getOperandOwnership() == OperandOwnership::InteriorPointer);
302+
assert(operand->getOperandOwnership() == OperandOwnership::InteriorPointer
303+
|| operand->getOperandOwnership() == OperandOwnership::AnyInteriorPointer);
303304

304305
if (auto scopedAddress = ScopedAddressValue::forUse(operand)) {
305306
scopedAddress.visitScopeEndingUses([this](Operand *end) {
@@ -364,6 +365,7 @@ LiveRangeSummary PrunedLiveRange<LivenessWithDefs>::recursivelyUpdateForDef(
364365
summary.meet(AddressUseKind::PointerEscape);
365366
break;
366367
case OperandOwnership::InteriorPointer:
368+
case OperandOwnership::AnyInteriorPointer:
367369
summary.meet(checkAndUpdateInteriorPointer(use));
368370
break;
369371
case OperandOwnership::GuaranteedForwarding: {

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,12 +1458,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
14581458
"kind since guaranteed and owned values can always be passed "
14591459
"in unowned positions");
14601460

1461-
require(operand.getOperandOwnership() !=
1462-
OperandOwnership::InteriorPointer ||
1463-
InteriorPointerOperandKind::get(&operand) !=
1464-
InteriorPointerOperandKind::Invalid,
1465-
"All operands with InteriorPointer operand ownership should be "
1466-
"added to the InteriorPointerOperand utility");
1461+
switch (operand.getOperandOwnership()) {
1462+
default:
1463+
break;
1464+
case OperandOwnership::InteriorPointer:
1465+
case OperandOwnership::AnyInteriorPointer:
1466+
require(InteriorPointerOperandKind::get(&operand) !=
1467+
InteriorPointerOperandKind::Invalid,
1468+
"All operands with InteriorPointer operand ownership should be "
1469+
"added to the InteriorPointerOperand utility");
1470+
}
14671471
}
14681472
}
14691473

lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ bool CheckerLivenessInfo::compute() {
175175
return true;
176176
});
177177
break;
178-
case OperandOwnership::InteriorPointer: {
178+
case OperandOwnership::InteriorPointer:
179+
case OperandOwnership::AnyInteriorPointer: {
179180
// An interior pointer user extends liveness until the end of the
180181
// interior pointer section.
181182
//

lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ visitUses(SILValue def, bool updateLivenessAndWeakStores, int callDepth) {
261261
continue;
262262

263263
case OperandOwnership::InteriorPointer:
264+
case OperandOwnership::AnyInteriorPointer:
264265
// Treat most interior pointers as escapes until they can be audited.
265266
// But if the interior pointer cannot be used to copy the parent
266267
// reference, then it does not need to be considered an escape.

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,7 @@ struct CopiedLoadBorrowEliminationVisitor
16871687
case OperandOwnership::InstantaneousUse:
16881688
case OperandOwnership::UnownedInstantaneousUse:
16891689
case OperandOwnership::InteriorPointer:
1690+
case OperandOwnership::AnyInteriorPointer:
16901691
case OperandOwnership::BitwiseEscape: {
16911692
// Look through copy_value of a move only value. We treat copy_value of
16921693
// copyable values as normal uses.

lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ bool Implementation::gatherUses(SILValue value) {
296296
case OperandOwnership::InstantaneousUse:
297297
case OperandOwnership::UnownedInstantaneousUse:
298298
case OperandOwnership::InteriorPointer:
299+
case OperandOwnership::AnyInteriorPointer:
299300
case OperandOwnership::BitwiseEscape: {
300301
// Look through copy_value of a move only value. We treat copy_value of
301302
// copyable values as normal uses.
@@ -1587,6 +1588,7 @@ static bool gatherBorrows(SILValue rootValue,
15871588
}
15881589
continue;
15891590
case OperandOwnership::InteriorPointer:
1591+
case OperandOwnership::AnyInteriorPointer:
15901592
// We don't care about these.
15911593
continue;
15921594
case OperandOwnership::GuaranteedForwarding:

lib/SILOptimizer/Mandatory/MoveOnlyObjectCheckerUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ bool MoveOnlyObjectCheckerPImpl::checkForSameInstMultipleUseErrors(
243243
instToOperandsMap.insert(nextUse->getUser(), nextUse);
244244
continue;
245245
case OperandOwnership::InteriorPointer:
246+
case OperandOwnership::AnyInteriorPointer:
246247
// We do not care about interior pointer uses since there aren't any
247248
// interior pointer using instructions that are also consuming uses.
248249
continue;

lib/SILOptimizer/Utils/CanonicalizeBorrowScope.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ bool CanonicalizeBorrowScope::visitBorrowScopeUses(SILValue innerValue,
264264
llvm_unreachable("this operand cannot handle ownership");
265265

266266
case OperandOwnership::InteriorPointer:
267+
case OperandOwnership::AnyInteriorPointer:
267268
case OperandOwnership::EndBorrow:
268269
case OperandOwnership::Reborrow:
269270
// Ignore uses that must be within the borrow scope.

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ bool CanonicalizeOSSALifetime::computeCanonicalLiveness() {
238238
}
239239
break;
240240
case OperandOwnership::InteriorPointer:
241+
case OperandOwnership::AnyInteriorPointer:
241242
case OperandOwnership::GuaranteedForwarding:
242243
case OperandOwnership::EndBorrow:
243244
// Guaranteed values are exposed by inner adjacent reborrows. If user is

0 commit comments

Comments
 (0)