Skip to content

Commit 061632e

Browse files
committed
[sil-combine] Update fix_lifetime opts for ownership
The one opt we perform here is that we promote fix_lifetime on loadable alloc_stack addresses to fix_lifetimes on objects by loading the underlying value and putting the fix lifetime upon it.
1 parent a4112eb commit 061632e

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,17 +1849,17 @@ SILInstruction *SILCombiner::visitTupleExtractInst(TupleExtractInst *TEI) {
18491849
return nullptr;
18501850
}
18511851

1852-
SILInstruction *SILCombiner::visitFixLifetimeInst(FixLifetimeInst *FLI) {
1853-
if (FLI->getFunction()->hasOwnership())
1854-
return nullptr;
1855-
1852+
SILInstruction *SILCombiner::visitFixLifetimeInst(FixLifetimeInst *fli) {
18561853
// fix_lifetime(alloc_stack) -> fix_lifetime(load(alloc_stack))
1857-
Builder.setCurrentDebugScope(FLI->getDebugScope());
1858-
if (auto *AI = dyn_cast<AllocStackInst>(FLI->getOperand())) {
1859-
if (FLI->getOperand()->getType().isLoadable(*FLI->getFunction())) {
1860-
auto Load = Builder.createLoad(FLI->getLoc(), AI,
1861-
LoadOwnershipQualifier::Unqualified);
1862-
return Builder.createFixLifetime(FLI->getLoc(), Load);
1854+
Builder.setCurrentDebugScope(fli->getDebugScope());
1855+
if (auto *ai = dyn_cast<AllocStackInst>(fli->getOperand())) {
1856+
if (fli->getOperand()->getType().isLoadable(*fli->getFunction())) {
1857+
// load when ossa is disabled
1858+
auto load = Builder.emitLoadBorrowOperation(fli->getLoc(), ai);
1859+
Builder.createFixLifetime(fli->getLoc(), load);
1860+
// no-op when ossa is disabled
1861+
Builder.emitEndBorrowOperation(fli->getLoc(), load);
1862+
return eraseInstFromFunction(*fli);
18631863
}
18641864
}
18651865
return nullptr;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-sil-opt -enable-objc-interop -enforce-exclusivity=none -enable-sil-verify-all %s -sil-combine -sil-combine-disable-alloc-stack-opts | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
import Builtin
6+
7+
class Klass {}
8+
9+
// We test both the ossa and non-ossa variants.
10+
//
11+
// CHECK-LABEL: sil [ossa] @fix_lifetime_promotion_ossa : $@convention(thin) (@owned Klass) -> () {
12+
// CHECK: bb0([[ARG:%.*]] :
13+
// CHECK: [[STACK:%.*]] = alloc_stack $Klass
14+
// CHECK: store [[ARG]] to [init] [[STACK]]
15+
// CHECK: [[BORROW:%.*]] = load_borrow [[STACK]]
16+
// CHECK: fix_lifetime [[BORROW]]
17+
// CHECK: end_borrow [[BORROW]]
18+
// CHECK: destroy_addr [[STACK]]
19+
// CHECK: dealloc_stack [[STACK]]
20+
// CHECK: } // end sil function 'fix_lifetime_promotion_ossa'
21+
sil [ossa] @fix_lifetime_promotion_ossa : $@convention(thin) (@owned Klass) -> () {
22+
bb0(%0 : @owned $Klass):
23+
%1 = alloc_stack $Klass
24+
store %0 to [init] %1 : $*Klass
25+
fix_lifetime %1 : $*Klass
26+
destroy_addr %1 : $*Klass
27+
dealloc_stack %1 : $*Klass
28+
%9999 = tuple()
29+
return %9999 : $()
30+
}
31+
32+
// CHECK-LABEL: sil @fix_lifetime_promotion : $@convention(thin) (@owned Klass) -> () {
33+
// CHECK: bb0([[ARG:%.*]] :
34+
// CHECK: [[STACK:%.*]] = alloc_stack $Klass
35+
// CHECK: store [[ARG]] to [[STACK]]
36+
// CHECK: [[BORROW:%.*]] = load [[STACK]]
37+
// CHECK: fix_lifetime [[BORROW]]
38+
// CHECK: destroy_addr [[STACK]]
39+
// CHECK: dealloc_stack [[STACK]]
40+
// CHECK: } // end sil function 'fix_lifetime_promotion'
41+
sil @fix_lifetime_promotion : $@convention(thin) (@owned Klass) -> () {
42+
bb0(%0 : $Klass):
43+
%1 = alloc_stack $Klass
44+
store %0 to %1 : $*Klass
45+
fix_lifetime %1 : $*Klass
46+
destroy_addr %1 : $*Klass
47+
dealloc_stack %1 : $*Klass
48+
%9999 = tuple()
49+
return %9999 : $()
50+
}

0 commit comments

Comments
 (0)