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

0 commit comments

Comments
 (0)