Skip to content

Commit 413501b

Browse files
committed
[SIL] Separate thunks from signature optimization from other thunks.
Signature optimization is slightly different to (most) other thunks, in that it's taking an existing function and turning that into a thunk, rather than creating a thunk that calls an existing function. These symbols can be public, etc. and so need to be handled a bit different to other types of thunks.
1 parent d82137b commit 413501b

File tree

9 files changed

+59
-51
lines changed

9 files changed

+59
-51
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ class SILProfiler;
4040
enum IsBare_t { IsNotBare, IsBare };
4141
enum IsTransparent_t { IsNotTransparent, IsTransparent };
4242
enum Inline_t { InlineDefault, NoInline, AlwaysInline };
43-
enum IsThunk_t { IsNotThunk, IsThunk, IsReabstractionThunk };
43+
enum IsThunk_t {
44+
IsNotThunk,
45+
IsThunk,
46+
IsReabstractionThunk,
47+
IsSignatureOptimizedThunk
48+
};
4449

4550
class SILSpecializeAttr final {
4651
friend SILFunction;

lib/SIL/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,9 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
23262326
switch (isThunk()) {
23272327
case IsNotThunk: break;
23282328
case IsThunk: OS << "[thunk] "; break;
2329+
case IsSignatureOptimizedThunk:
2330+
OS << "[signature_optimized_thunk] ";
2331+
break;
23292332
case IsReabstractionThunk: OS << "[reabstraction_thunk] "; break;
23302333
}
23312334

lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
529529
}
530530

531531
// Create the thunk body !
532-
F->setThunk(IsThunk);
532+
F->setThunk(IsSignatureOptimizedThunk);
533533
// The thunk now carries the information on how the signature is
534534
// optimized. If we inline the thunk, we will get the benefit of calling
535535
// the signature optimized function without additional setup on the

lib/Serialization/SILFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ namespace sil_block {
286286
BCRecordLayout<SIL_FUNCTION, SILLinkageField,
287287
BCFixed<1>, // transparent
288288
BCFixed<2>, // serialized
289-
BCFixed<2>, // thunk/reabstraction_thunk
289+
BCFixed<2>, // thunks: signature optimized/reabstraction
290290
BCFixed<1>, // global_init
291291
BCFixed<2>, // inlineStrategy
292292
BCFixed<2>, // optimizationMode

test/SILOptimizer/dead_partial_apply_arg.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extension Int32 {
88

99
// This function has an unused metatype argument.
1010

11-
// CHECK-LABEL: sil [thunk] [always_inline] @$Ss5Int32V4testE8lessthan3lhs3rhsSbAB_ABtFZ : $@convention(method) (Int32, Int32, @thin Int32.Type) -> Bool
11+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @$Ss5Int32V4testE8lessthan3lhs3rhsSbAB_ABtFZ : $@convention(method) (Int32, Int32, @thin Int32.Type) -> Bool
1212
public static func lessthan (lhs: Int32, rhs: Int32) -> Bool {
1313
return lhs < rhs
1414
}

test/SILOptimizer/deadargsignatureopt.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Swift
55

66
// Specialize to a function with removed dead argument.
77

8-
// CHECK-LABEL: sil [thunk] [always_inline] @one_arg_dead
8+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @one_arg_dead
99
// CHECK: [[F:%[0-9]+]] = function_ref @$S12one_arg_deadTf4nnd_n
1010
// CHECK: [[A:%[0-9]+]] = apply [[F]](%0, %1)
1111
// CHECK: return [[A]]
@@ -18,7 +18,7 @@ bb0(%0 : $Int32, %1 : $Int32, %2 : $@thin Int32.Type):
1818
return %8 : $Bool
1919
}
2020

21-
// CHECK-LABEL: sil [thunk] [always_inline] @always_inline_one_arg_dead
21+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @always_inline_one_arg_dead
2222
// CHECK: [[F:%[0-9]+]] = function_ref @$S26always_inline_one_arg_deadTf4nnd_n
2323
// CHECK: [[A:%[0-9]+]] = apply [[F]](%0, %1)
2424
// CHECK: return [[A]]
@@ -33,7 +33,7 @@ bb0(%0 : $Int32, %1 : $Int32, %2 : $@thin Int32.Type):
3333

3434
// Still delete only one dead arg as only one arg is partially applied.
3535

36-
// CHECK-LABEL: sil [thunk] [always_inline] @two_args_dead
36+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @two_args_dead
3737
// CHECK: [[F:%[0-9]+]] = function_ref @$S13two_args_deadTf4nnd_n
3838
// CHECK: [[A:%[0-9]+]] = apply [[F]](%0, %1)
3939
// CHECK: return [[A]]

test/SILOptimizer/funcsig_opaque.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ sil @testAggregateArgHelper : $@convention(thin) (@owned R<S>) -> ()
1414

1515
// Test owned-to-guaranteed transformation of opaque arguments.
1616
//
17-
// CHECK-LABEL: sil [thunk] [always_inline] @testAggregateArg : $@convention(thin) (@in R<S>) -> @out () {
17+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @testAggregateArg : $@convention(thin) (@in R<S>) -> @out () {
1818
// CHECK: bb0(%0 : $R<S>):
1919
// CHECK: [[F:%.*]] = function_ref @$S16testAggregateArgTf4g_n : $@convention(thin) (@in_guaranteed R<S>) -> @out ()
2020
// CHECK: [[CALL:%.*]] = apply [[F]](%0) : $@convention(thin) (@in_guaranteed R<S>) -> @out ()

test/SILOptimizer/functionsigopts.sil

Lines changed: 31 additions & 31 deletions
Large diffs are not rendered by default.

test/SILOptimizer/functionsigopts_sroa.sil

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ struct SingleFieldLvl3 {
136136

137137
/// This checks the case where we have a single level hierarchy and the root is
138138
/// dead.
139-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @single_level_dead_root_callee : $@convention(thin) (S1) -> Builtin.Int32 {
139+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @single_level_dead_root_callee : $@convention(thin) (S1) -> Builtin.Int32 {
140140
// CHECK: bb0([[INPUT:%[0-9]+]] : $S1):
141141
// CHECK: [[FN:%[0-9]+]] = function_ref @$S29single_level_dead_root_calleeTfq4x_n : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
142142
// CHECK: [[ARG:%.*]] = struct_extract [[INPUT]] : $S1, #S1.f2
@@ -182,7 +182,7 @@ bb0(%0 : $S1):
182182
return %9999 : $()
183183
}
184184

185-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @single_level_live_root_callee : $@convention(thin) (S1) -> Builtin.Int32 {
185+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @single_level_live_root_callee : $@convention(thin) (S1) -> Builtin.Int32 {
186186
// CHECK: bb0([[INPUT:%[0-9]+]] : $S1):
187187
// CHECK: [[FN:%[0-9]+]] = function_ref @$S29single_level_live_root_calleeTfq4x_n : $@convention(thin) (Builtin.Int16, Builtin.Int32) -> Builtin.Int32
188188
// CHECK: [[ARG2:%.*]] = struct_extract [[INPUT]] : $S1, #S1.f2
@@ -234,7 +234,7 @@ bb0(%0 : $S1):
234234
// This test checks where we have a multiple level hierarchy, the root is dead,
235235
// but the root has all fields used. This means that we should extract
236236
// everything, but we should not "reform" the aggregate.
237-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @multiple_level_all_root_fields_used_callee : $@convention(thin) (S2) -> (Builtin.Int16, Builtin.Int64) {
237+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @multiple_level_all_root_fields_used_callee : $@convention(thin) (S2) -> (Builtin.Int16, Builtin.Int64) {
238238
// CHECK: bb0([[INPUT:%.*]] : $S2):
239239
// CHECK: [[FN:%.*]] = function_ref @$S42multiple_level_all_root_fields_used_calleeTfq4x_n : $@convention(thin) (Builtin.Int16, Builtin.Int64) -> (Builtin.Int16, Builtin.Int64)
240240
// CHECK: [[EXT1:%.*]] = struct_extract [[INPUT]] : $S2, #S2.f2
@@ -292,7 +292,7 @@ bb0(%0 : $S2):
292292
}
293293

294294
/// This test checks a multiple level hierarchy where the root has no fields used.
295-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @multiple_level_no_root_fields_have_direct_uses_callee : $@convention(thin) (S3) -> (Builtin.Int16, Builtin.Int64) {
295+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @multiple_level_no_root_fields_have_direct_uses_callee : $@convention(thin) (S3) -> (Builtin.Int16, Builtin.Int64) {
296296
// CHECK: bb0([[IN:%.*]] : $S3):
297297
// CHECK: [[FN:%.*]] = function_ref @$S53multiple_level_no_root_fields_have_direct_uses_calleeTfq4x_n : $@convention(thin) (Builtin.Int16, Builtin.Int64) -> (Builtin.Int16, Builtin.Int64)
298298
// CHECK: [[EXT1:%.*]] = struct_extract [[IN]] : $S3, #S3.f2
@@ -355,7 +355,7 @@ bb0(%0 : $S3):
355355

356356
// This test checks a multiple level hierarchy where the root has its own use
357357
// and needs to be reformed via a struct.
358-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @multiple_level_root_must_be_reformed_callee : $@convention(thin) (S2) -> (Builtin.Int16, Builtin.Int64) {
358+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @multiple_level_root_must_be_reformed_callee : $@convention(thin) (S2) -> (Builtin.Int16, Builtin.Int64) {
359359
// CHECK: bb0([[IN:%.*]] : $S2):
360360
// CHECK: [[FN:%.*]] = function_ref @$S43multiple_level_root_must_be_reformed_calleeTfq4x_n : $@convention(thin) (Builtin.Int16, Builtin.Int32, Builtin.Int64) -> (Builtin.Int16, Builtin.Int64)
361361
// CHECK: [[EXT1:%.*]] = struct_extract [[IN]] : $S2, #S2.f2
@@ -439,7 +439,7 @@ bb0(%0 : $S2):
439439
}
440440

441441
// This test checks if we can handle @owned structs correctly
442-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @owned_struct_1_callee : $@convention(thin) (@owned S5, @owned S5) -> (Builtin.Int16, Builtin.Int32, Builtin.Int16, Builtin.Int32) {
442+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_struct_1_callee : $@convention(thin) (@owned S5, @owned S5) -> (Builtin.Int16, Builtin.Int32, Builtin.Int16, Builtin.Int32) {
443443
// CHECK: bb0([[IN1:%.*]] : $S5, [[IN2:%.*]] : $S5):
444444
// CHECK: [[FN:%.*]] = function_ref @$S21owned_struct_1_calleeTfq4dgX_n : $@convention(thin) (@guaranteed S4, Builtin.Int16, Builtin.Int32) -> (Builtin.Int16, Builtin.Int32, Builtin.Int16, Builtin.Int32)
445445
// CHECK: [[EXT1:%.*]] = struct_extract [[IN2]] : $S5, #S5.f2
@@ -505,7 +505,7 @@ bb0(%0 : $S5):
505505
}
506506

507507
// This test checks if we can properly insert arguments in between dead arguments.
508-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @owned_struct_2_callee : $@convention(thin) (Builtin.Int256, Builtin.Int256, @owned S5, Builtin.Int128, Builtin.Int128) -> (Builtin.Int256, Builtin.Int16, Builtin.Int32, Builtin.Int128) {
508+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_struct_2_callee : $@convention(thin) (Builtin.Int256, Builtin.Int256, @owned S5, Builtin.Int128, Builtin.Int128) -> (Builtin.Int256, Builtin.Int16, Builtin.Int32, Builtin.Int128) {
509509
// CHECK: bb0([[IN1:%.*]] : $Builtin.Int256, [[IN2:%.*]] : $Builtin.Int256, [[IN3:%.*]] : $S5, [[IN4:%.*]] : $Builtin.Int128, [[IN5:%.*]] : $Builtin.Int128):
510510
// CHECK: [[FN:%.*]] = function_ref @$S21owned_struct_2_calleeTfq4ndgXdn_n : $@convention(thin) (Builtin.Int256, @guaranteed S4, Builtin.Int16, Builtin.Int32, Builtin.Int128) -> (Builtin.Int256, Builtin.Int16, Builtin.Int32, Builtin.Int128)
511511
// CHECK: [[EXT1:%.*]] = struct_extract [[IN3]] : $S5, #S5.f2
@@ -567,7 +567,7 @@ bb0(%0 : $Builtin.Int256, %1 : $S5, %2 : $Builtin.Int128):
567567
}
568568

569569
/// This test makes sure that we ignore pointer arguments for now.
570-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @ignore_ptrs_callee : $@convention(thin) (@in S1, S1, S1) -> (Builtin.Int16, Builtin.Int16) {
570+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @ignore_ptrs_callee : $@convention(thin) (@in S1, S1, S1) -> (Builtin.Int16, Builtin.Int16) {
571571
// CHECK: bb0([[IN1:%.*]] : $*S1, [[IN2:%.*]] : $S1, [[IN3:%.*]] : $S1):
572572
// CHECK: [[FN:%.*]] = function_ref @$S18ignore_ptrs_calleeTfq4nxx_n : $@convention(thin) (@in S1, Builtin.Int16, Builtin.Int16) -> (Builtin.Int16, Builtin.Int16)
573573
// CHECK: [[EXT1:%.*]] = struct_extract [[IN2]] : $S1, #S1.f1
@@ -677,7 +677,7 @@ bb0(%0 : $FakeStaticString, %1 : $FakeString, %2 : $FakeStaticString):
677677
// This test makes sure that we handle cases where the callee has field uses
678678
// that are processed in a different order than the fields are layed out in the
679679
// structure.
680-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @check_out_of_order_uses_callee : $@convention(thin) (S1) -> () {
680+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @check_out_of_order_uses_callee : $@convention(thin) (S1) -> () {
681681
// CHECK: bb0([[IN:%.*]] : $S1):
682682
// CHECK: [[FN:%.*]] = function_ref @$S30check_out_of_order_uses_calleeTfq4x_n : $@convention(thin) (Builtin.Int16, Builtin.Int32) -> ()
683683
// CHECK: [[EXT1:%.*]] = struct_extract [[IN]] : $S1, #S1.f2
@@ -735,7 +735,7 @@ bb0(%0 : $S1):
735735
}
736736

737737
// Make sure that we do not SROA classes.
738-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @class_callee_1 : $@convention(thin) (@owned C1, Builtin.Int32) -> Builtin.Int32 {
738+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @class_callee_1 : $@convention(thin) (@owned C1, Builtin.Int32) -> Builtin.Int32 {
739739
// CHECK: bb0([[IN1:%.*]] : $C1, [[IN2:%.*]] : $Builtin.Int32):
740740
// CHECK: [[FN:%.*]] = function_ref @$S14class_callee_1Tfq4gn_n : $@convention(thin) (@guaranteed C1, Builtin.Int32) -> Builtin.Int32
741741
// CHECK: apply [[FN]]([[IN1]], [[IN2]]) : $@convention(thin) (@guaranteed C1, Builtin.Int32) -> Builtin.Int32
@@ -774,7 +774,7 @@ bb0(%0 : $C1, %1 : $Builtin.Int32):
774774
return %1 : $Builtin.Int32
775775
}
776776

777-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @class_caller_1 : $@convention(thin) (@owned C1, Builtin.Int32) -> Builtin.Int32 {
777+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @class_caller_1 : $@convention(thin) (@owned C1, Builtin.Int32) -> Builtin.Int32 {
778778
// CHECK: bb0([[IN1:%.*]] : $C1, [[IN2:%.*]] : $Builtin.Int32):
779779
// CHECK: [[FN:%.*]] = function_ref @$S14class_callee_1Tfq4gn_n : $@convention(thin) (@guaranteed C1, Builtin.Int32) -> Builtin.Int32
780780
// CHECK: apply [[FN]]([[IN1]], [[IN2]]) : $@convention(thin) (@guaranteed C1, Builtin.Int32) -> Builtin.Int32
@@ -856,7 +856,7 @@ bb0(%0 : $ThirtySixFieldStruct):
856856
return %9999 : $()
857857
}
858858

859-
// CHECK-LABEL: sil [serialized] [thunk] [always_inline] @more_than_32_type_sized_callee : $@convention(thin) (ThirtySixFieldStruct) -> Builtin.Int32 {
859+
// CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @more_than_32_type_sized_callee : $@convention(thin) (ThirtySixFieldStruct) -> Builtin.Int32 {
860860
sil [serialized] @more_than_32_type_sized_callee : $@convention(thin) (ThirtySixFieldStruct) -> Builtin.Int32 {
861861
bb0(%0 : $ThirtySixFieldStruct):
862862
// make it a non-trivial function

0 commit comments

Comments
 (0)