Skip to content

Commit aace459

Browse files
authored
Merge pull request #65074 from meg-gupta/completelifetimefixes
Fixes to utilities used by OSSALifetimeCompletion
2 parents 35fcc37 + 264d86d commit aace459

File tree

5 files changed

+90
-3
lines changed

5 files changed

+90
-3
lines changed

include/swift/SIL/OwnershipUseVisitor.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,18 @@ bool OwnershipUseVisitor<Impl>::visitInnerBorrowScopeEnd(Operand *borrowEnd) {
283283
case OperandOwnership::EndBorrow:
284284
return handleUsePoint(borrowEnd, UseLifetimeConstraint::NonLifetimeEnding);
285285

286-
case OperandOwnership::Reborrow:
286+
case OperandOwnership::Reborrow: {
287287
if (!asImpl().handleInnerReborrow(borrowEnd))
288288
return false;
289289

290290
return handleUsePoint(borrowEnd, UseLifetimeConstraint::NonLifetimeEnding);
291+
}
292+
case OperandOwnership::DestroyingConsume: {
293+
// partial_apply [on_stack] can introduce borrowing operand and can have destroy_value consumes.
294+
auto *pai = dyn_cast<PartialApplyInst>(borrowEnd->get());
295+
assert(pai && pai->isOnStack());
296+
return handleUsePoint(borrowEnd, UseLifetimeConstraint::NonLifetimeEnding);
297+
}
291298

292299
default:
293300
llvm_unreachable("expected borrow scope end");

include/swift/SIL/OwnershipUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,9 @@ struct BorrowingOperand {
475475
/// valid BorrowedValue instance.
476476
BorrowedValue getBorrowIntroducingUserResult();
477477

478+
/// Return the borrowing operand's value.
479+
SILValue getScopeIntroducingUserResult();
480+
478481
/// Compute the implicit uses that this borrowing operand "injects" into the
479482
/// set of its operands uses.
480483
///

lib/SIL/Utils/OwnershipLiveness.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,10 @@ struct InteriorLivenessVisitor :
140140
/// Handles begin_borrow, load_borrow, store_borrow, begin_apply.
141141
bool handleInnerBorrow(BorrowingOperand borrowingOperand) {
142142
if (handleInnerScopeCallback) {
143-
handleInnerScopeCallback(
144-
borrowingOperand.getBorrowIntroducingUserResult().value);
143+
auto value = borrowingOperand.getScopeIntroducingUserResult();
144+
if (value) {
145+
handleInnerScopeCallback(value);
146+
}
145147
}
146148
return true;
147149
}

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,30 @@ BorrowedValue BorrowingOperand::getBorrowIntroducingUserResult() {
751751
llvm_unreachable("covered switch");
752752
}
753753

754+
SILValue BorrowingOperand::getScopeIntroducingUserResult() {
755+
switch (kind) {
756+
case BorrowingOperandKind::Invalid:
757+
case BorrowingOperandKind::Yield:
758+
case BorrowingOperandKind::Apply:
759+
case BorrowingOperandKind::TryApply:
760+
return SILValue();
761+
762+
case BorrowingOperandKind::BeginAsyncLet:
763+
case BorrowingOperandKind::PartialApplyStack:
764+
case BorrowingOperandKind::BeginBorrow:
765+
return cast<SingleValueInstruction>(op->getUser());
766+
767+
case BorrowingOperandKind::BeginApply:
768+
return cast<BeginApplyInst>(op->getUser())->getTokenResult();
769+
770+
case BorrowingOperandKind::Branch: {
771+
PhiOperand phiOp(op);
772+
return phiOp.getValue();
773+
}
774+
}
775+
llvm_unreachable("covered switch");
776+
}
777+
754778
void BorrowingOperand::getImplicitUses(
755779
SmallVectorImpl<Operand *> &foundUses) const {
756780
// FIXME: this visitScopeEndingUses should never return false once dead

test/SILOptimizer/ossa_lifetime_completion.sil

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,31 @@ bb3:
102102
return %r : $()
103103
}
104104

105+
sil @use_guaranteed : $@convention(thin) (@guaranteed C) -> ()
106+
107+
sil [ossa] @argTest : $@convention(method) (@owned C) -> () {
108+
bb0(%0 : @owned $C):
109+
test_specification "ossa-lifetime-completion @argument"
110+
debug_value %0 : $C
111+
cond_br undef, bb1, bb2
112+
113+
bb1:
114+
br bb4
115+
116+
bb2:
117+
br bb3
118+
119+
bb3:
120+
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed C) -> ()
121+
%4 = apply %3(%0) : $@convention(thin) (@guaranteed C) -> ()
122+
destroy_value %0 : $C
123+
%r = tuple ()
124+
return %r : $()
125+
126+
bb4:
127+
unreachable
128+
}
129+
105130
// Ensure no assert fires while inserting dead end blocks to the worklist
106131
sil [ossa] @testLexicalLifetimeCompletion : $@convention(thin) (@owned C) -> () {
107132
bb0(%0 : @owned $C):
@@ -143,3 +168,29 @@ bb10:
143168
br bb8
144169
}
145170

171+
sil @foo : $@convention(thin) (@guaranteed C) -> ()
172+
173+
// Ensure no assert fires while handling lifetime end of partial_apply
174+
sil [ossa] @testPartialApplyStack : $@convention(thin) (@guaranteed C) -> () {
175+
bb0(%0 : @guaranteed $C):
176+
test_specification "ossa-lifetime-completion @instruction[0]"
177+
%8 = copy_value %0 : $C
178+
%9 = begin_borrow %8 : $C
179+
%80 = function_ref @foo : $@convention(thin) (@guaranteed C) -> ()
180+
%81 = partial_apply [callee_guaranteed] [on_stack] %80(%9) : $@convention(thin) (@guaranteed C) -> ()
181+
cond_br undef, bb1, bb2
182+
183+
bb1:
184+
destroy_value %81 : $@noescape @callee_guaranteed () -> ()
185+
br bb3
186+
187+
bb2:
188+
unreachable
189+
190+
bb3:
191+
end_borrow %9 : $C
192+
destroy_value %8 : $C
193+
%180 = tuple ()
194+
return %180 : $()
195+
}
196+

0 commit comments

Comments
 (0)