Skip to content

Commit 395064f

Browse files
authored
Merge pull request #62286 from nate-chandler/opaque-values/5/20221118
[SILInliner] Borrow guaranteed yields.
2 parents 67cbe90 + 182bd34 commit 395064f

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,20 @@ class BeginApplySite {
162162
auto calleeYields = yield->getYieldedValues();
163163
auto callerYields = BeginApply->getYieldedValues();
164164
assert(calleeYields.size() == callerYields.size());
165+
SmallVector<BeginBorrowInst *, 2> guaranteedYields;
165166
for (auto i : indices(calleeYields)) {
166167
auto remappedYield = getMappedValue(calleeYields[i]);
168+
// When owned values are yielded @guaranteed, the mapped value must be
169+
// borrowed and the result be substituted in place of the originally
170+
// yielded value. Otherwise, there could be uses of the original value
171+
// which require an @guaranteed operand into which we'd be attempting to
172+
// substitute an @owned operand.
173+
if (calleeYields[i]->getOwnershipKind() == OwnershipKind::Owned &&
174+
!yield->getOperandRef(i).isConsuming()) {
175+
auto *bbi = Builder->createBeginBorrow(Loc, remappedYield);
176+
guaranteedYields.push_back(bbi);
177+
remappedYield = bbi;
178+
}
167179
callerYields[i]->replaceAllUsesWith(remappedYield);
168180
}
169181
Builder->createBranch(Loc, returnToBB);
@@ -172,11 +184,17 @@ class BeginApplySite {
172184
if (EndApply) {
173185
SavedInsertionPointRAII savedIP(*Builder, EndApplyBB);
174186
auto resumeBB = remapBlock(yield->getResumeBB());
187+
for (auto *bbi : guaranteedYields) {
188+
Builder->createEndBorrow(EndApply->getLoc(), bbi);
189+
}
175190
Builder->createBranch(EndApply->getLoc(), resumeBB);
176191
}
177192
if (AbortApply) {
178193
SavedInsertionPointRAII savedIP(*Builder, AbortApplyBB);
179194
auto unwindBB = remapBlock(yield->getUnwindBB());
195+
for (auto *bbi : guaranteedYields) {
196+
Builder->createEndBorrow(EndApply->getLoc(), bbi);
197+
}
180198
Builder->createBranch(AbortApply->getLoc(), unwindBB);
181199
}
182200
return true;

test/SILOptimizer/inline_begin_apply.sil

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ unwind:
4444
unwind
4545
}
4646

47+
sil [ossa] @getSomeClass : $@convention(thin) () -> @owned SomeClass
48+
49+
sil [transparent] [ossa] @yield_owned_as_guaranteed : $@yield_once @convention(thin) () -> @yields @guaranteed SomeClass {
50+
%getSomeClass = function_ref @getSomeClass : $@convention(thin) () -> @owned SomeClass
51+
%SomeClass = apply %getSomeClass() : $@convention(thin) () -> @owned SomeClass
52+
yield %SomeClass : $SomeClass, resume bb1, unwind bb2
53+
54+
bb1:
55+
destroy_value %SomeClass : $SomeClass
56+
%retval = tuple ()
57+
return %retval : $()
58+
59+
bb2:
60+
destroy_value %SomeClass : $SomeClass
61+
unwind
62+
}
63+
4764
sil [transparent] [ossa] @test_unreachable : $@yield_once <C: SomeClass> () -> (@yields @in Indirect<C>) {
4865
entry:
4966
unreachable
@@ -555,3 +572,48 @@ bb2:
555572
return %ret : $()
556573
}
557574

575+
576+
// CHECK-LABEL: sil [ossa] @test_store_borrow_owned_as_guaranteed_yield : {{.*}} {
577+
// CHECK: {{bb[0-9]+}}:
578+
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $SomeClass
579+
// CHECK: [[INSTANCE:%[^,]+]] = apply
580+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]]
581+
// CHECK: [[BORROW:%[^,]+]] = store_borrow [[LIFETIME]] to [[ADDR]]
582+
// CHECK: yield [[BORROW]] {{.*}}, resume [[BB_RESUME:bb[0-9]+]], unwind [[BB_UNWIND:bb[0-9]+]]
583+
// CHECK: [[BB_RESUME]]:
584+
// CHECK: end_borrow [[BORROW]]
585+
// CHECK: dealloc_stack [[ADDR]]
586+
// CHECK: end_borrow [[LIFETIME]]
587+
// CHECK: destroy_value [[INSTANCE]]
588+
// CHECK: tuple ()
589+
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
590+
// CHECK: return [[RETVAL]]
591+
// CHECK: [[BB_UNWIND]]:
592+
// CHECK: end_borrow [[BORROW]]
593+
// CHECK: dealloc_stack [[ADDR]]
594+
// CHECK: end_borrow [[LIFETIME]]
595+
// CHECK: destroy_value [[INSTANCE]]
596+
// CHECK: unwind
597+
// CHECK-LABEL: } // end sil function 'test_store_borrow_owned_as_guaranteed_yield'
598+
sil [ossa] @test_store_borrow_owned_as_guaranteed_yield : $@yield_once @convention(thin) @substituted <T> () -> @yields @in_guaranteed T for <SomeClass> {
599+
entry:
600+
%addr = alloc_stack $SomeClass
601+
%callee = function_ref @yield_owned_as_guaranteed : $@yield_once @convention(thin) () -> @yields @guaranteed SomeClass
602+
(%instance, %token) = begin_apply %callee() : $@yield_once @convention(thin) () -> @yields @guaranteed SomeClass
603+
%borrow = store_borrow %instance to %addr : $*SomeClass
604+
yield %borrow : $*SomeClass, resume bb_resume, unwind bb_unwind
605+
606+
bb_resume:
607+
end_borrow %borrow : $*SomeClass
608+
dealloc_stack %addr : $*SomeClass
609+
end_apply %token
610+
%retval = tuple ()
611+
return %retval : $()
612+
613+
bb_unwind:
614+
end_borrow %borrow : $*SomeClass
615+
dealloc_stack %addr : $*SomeClass
616+
abort_apply %token
617+
unwind
618+
619+
}

0 commit comments

Comments
 (0)