Skip to content

Commit 30e3062

Browse files
committed
[sil-opaque-values] Allow ClosureSpecializer to handle @in captures.
1 parent 8cccadd commit 30e3062

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

lib/SILOptimizer/IPO/ClosureSpecializer.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@
4949
/// that the release occurs in the epilog after any retains associated with
5050
/// @owned return values.
5151
///
52-
/// 3. We do not support specialization of closures with arguments passed using
53-
/// any indirect calling conventions besides @inout and @inout_aliasable.
54-
/// This is a temporary limitation.
52+
/// 3. In !useLoweredAddresses mode, we do not support specialization of closures
53+
/// with arguments passed using any indirect calling conventions besides
54+
/// @inout and @inout_aliasable. This is a temporary limitation that goes
55+
/// away with sil-opaque-values.
5556
//===----------------------------------------------------------------------===//
5657

5758
#define DEBUG_TYPE "closure-specialization"
@@ -581,8 +582,9 @@ ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc,
581582
ParameterConvention ParamConv;
582583
if (PInfo.isFormalIndirect()) {
583584
ParamConv = PInfo.getConvention();
584-
assert(ParamConv == ParameterConvention::Indirect_Inout ||
585-
ParamConv == ParameterConvention::Indirect_InoutAliasable);
585+
assert(!SILModuleConventions(M).useLoweredAddresses()
586+
|| ParamConv == ParameterConvention::Indirect_Inout
587+
|| ParamConv == ParameterConvention::Indirect_InoutAliasable);
586588
} else {
587589
ParamConv = ClosedOverFunConv.getSILType(PInfo).isTrivial(M)
588590
? ParameterConvention::Direct_Unowned
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %target-sil-opt -enable-sil-opaque-values -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -closure-specialize %s | %FileCheck %s
2+
3+
struct TestView {}
4+
struct TestRange {}
5+
struct TestSlice {}
6+
7+
// helper
8+
sil @closure : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> () {
9+
bb0(%0 : $*TestView, %1 : $TestRange, %2 : $TestSlice):
10+
%1284 = tuple ()
11+
return %1284 : $()
12+
}
13+
14+
// helper
15+
sil @thunk : $@convention(thin) (@inout TestView, @owned @callee_owned (@inout TestView) -> ()) -> @out () {
16+
bb0(%0 : $*TestView, %1 : $@callee_owned (@inout TestView) ->()):
17+
%call = apply %1(%0) : $@callee_owned (@inout TestView) -> ()
18+
%1284 = tuple ()
19+
return %1284 : $()
20+
}
21+
22+
// Test that ClosureSpecializer can handle captured @in args, in addition to direct args.
23+
//
24+
// CHECK-LABEL: sil @testSpecializeThunk : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> () {
25+
// CHECK: bb0(%0 : $*TestView, %1 : $TestRange, %2 : $TestSlice):
26+
// CHECK: [[CLOSURE:%.*]] = function_ref @closure : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> ()
27+
// CHECK: [[SPECIALIZED:%.*]] = function_ref @_T05thunk7closure4main9TestRangeVAC0D5SliceVTf1nc_n : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> @out () // user: %6
28+
// CHECK: [[THUNK:%.*]] = function_ref @thunk : $@convention(thin) (@inout TestView, @owned @callee_owned (@inout TestView) -> ()) -> @out ()
29+
// CHECK: [[CALL:%.*]] = apply [[SPECIALIZED]](%0, %1, %2) : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> @out ()
30+
// CHECK: %{{.*}} = tuple ()
31+
// CHECK: return %{{.*}} : $()
32+
// CHECK-LABEL: } // end sil function 'testSpecializeThunk'
33+
sil @testSpecializeThunk : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> () {
34+
bb0(%0 : $*TestView, %1 : $TestRange, %2 : $TestSlice):
35+
%closurefn = function_ref @closure : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> ()
36+
%pa = partial_apply %closurefn(%1, %2) : $@convention(thin) (@inout TestView, TestRange, @in TestSlice) -> ()
37+
%thunk = function_ref @thunk : $@convention(thin) (@inout TestView, @owned @callee_owned (@inout TestView) -> ()) -> @out ()
38+
strong_retain %pa : $@callee_owned (@inout TestView) -> ()
39+
%call = apply %thunk(%0, %pa) : $@convention(thin) (@inout TestView, @owned @callee_owned (@inout TestView) -> ()) -> @out ()
40+
%1284 = tuple ()
41+
return %1284 : $()
42+
}

0 commit comments

Comments
 (0)