Skip to content

Commit a54a23a

Browse files
authored
Merge pull request #79177 from atrick/fix-markdep-ownership
Fix mark_dependence [nonescaping] ownership
2 parents 57234f8 + 01c3343 commit a54a23a

20 files changed

+85
-21
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/OperandOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ OperandOwnershipClassifier::visitMarkDependenceInst(MarkDependenceInst *mdi) {
678678
// which we treat like a borrow.
679679
return OperandOwnership::Borrow;
680680
}
681-
return OperandOwnership::InteriorPointer;
681+
return OperandOwnership::AnyInteriorPointer;
682682
}
683683
if (mdi->hasUnresolvedEscape()) {
684684
// This creates a dependent value that may extend beyond the parent's

lib/SIL/IR/SILInstruction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,7 @@ bool MarkDependenceInst::visitNonEscapingLifetimeEnds(
20092009
llvm::function_ref<bool (Operand *)> visitUnknownUse) const {
20102010
assert(getFunction()->hasOwnership() && isNonEscaping()
20112011
&& "only meaningful for nonescaping dependencies");
2012+
assert(getType().isObject() && "lifetime ends only exist for values");
20122013
bool noUsers = true;
20132014
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, visitScopeEnd,
20142015
visitUnknownUse)) {

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: 5 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;
@@ -712,6 +715,7 @@ bool BorrowingOperand::visitScopeEndingUses(
712715
case BorrowingOperandKind::MarkDependenceNonEscaping: {
713716
auto *user = cast<MarkDependenceInst>(op->getUser());
714717
assert(user->isNonEscaping() && "escaping dependencies don't borrow");
718+
assert(user->getType().isObject() && "borrows only exist for values");
715719
return user->visitNonEscapingLifetimeEnds(visitScopeEnd, visitUnknownUse);
716720
}
717721
case BorrowingOperandKind::BeginAsyncLet: {

0 commit comments

Comments
 (0)