Skip to content

Commit e45acc2

Browse files
Merge pull request swiftlang#36856 from nate-chandler/rdar76479222
[IRGen] Emit PAF for generic methods.
2 parents f4fc022 + ba4aa08 commit e45acc2

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,6 +3218,13 @@ static bool isSimplePartialApply(IRGenFunction &IGF, PartialApplyInst *i) {
32183218

32193219
if (calleeTy->getRepresentation() != SILFunctionTypeRepresentation::Method)
32203220
return false;
3221+
3222+
// Partially applying a polymorphic function entails capturing its generic
3223+
// arguments (it is not legal to leave any polymorphic arguments unbound)
3224+
// which means that both self and those generic arguments would need to be
3225+
// captured.
3226+
if (calleeTy->isPolymorphic())
3227+
return false;
32213228

32223229
// There should be one applied argument.
32233230
// (This is a bit stricter than necessary, because empty arguments could be
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift-dylib(%t/%target-library-name(PrintShims)) %S/../Inputs/print-shims.swift -module-name PrintShims -emit-module -emit-module-path %t/PrintShims.swiftmodule
3+
// RUN: %target-codesign %t/%target-library-name(PrintShims)
4+
// RUN: %target-build-swift -g -parse-sil %s -emit-ir -I %t -L %t -lPrintShim | %FileCheck %s --check-prefix=CHECK-LL
5+
// RUN: %target-build-swift -g -parse-sil %s -module-name main -o %t/main -I %t -L %t -lPrintShims %target-rpath(%t)
6+
// RUN: %target-codesign %t/main
7+
// RUN: %target-run %t/main %t/%target-library-name(PrintShims) | %FileCheck %s
8+
9+
// REQUIRES: executable_test
10+
// REQUIRES: swift_test_mode_optimize_none
11+
12+
sil_stage raw
13+
14+
import Builtin
15+
import Swift
16+
import SwiftShims
17+
18+
// CHECK-LL-LABEL: define hidden swiftcc void @call_generic_function
19+
// CHECK-LL: call swiftcc void @"$sTA"
20+
sil hidden [ossa] @call_generic_function : $@convention(thin) <On, T where On : C> (@guaranteed On, @in_guaranteed T) -> @out T {
21+
bb0(%out : $*T, %on_guaranteed : @guaranteed $On, %in : $*T):
22+
%on = copy_value %on_guaranteed : $On
23+
%c = upcast %on : $On to $C
24+
%method = class_method %c : $C, #C.generic_function : <T> (C) -> (T) -> T, $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed C) -> @out τ_0_0
25+
%closure = partial_apply [callee_guaranteed] %method<T>(%c) : $@convention(method) <τ_1_0> (@in_guaranteed τ_1_0, @guaranteed C) -> @out τ_1_0
26+
%result = apply %closure(%out, %in) : $@callee_guaranteed (@in_guaranteed T) -> @out T
27+
destroy_value %closure : $@callee_guaranteed (@in_guaranteed T) -> @out T
28+
return %result : $()
29+
}
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
class C {
44+
@_silgen_name("generic_function")
45+
func generic_function<T>(_ t: T) -> T
46+
deinit
47+
init()
48+
}
49+
50+
@_silgen_name("call_generic_function")
51+
func call_generic_function<On, T>(on: On, with t: T) -> T where On : C
52+
53+
@main struct Main {
54+
static func main()
55+
init()
56+
}
57+
58+
59+
sil hidden [ossa] @generic_function : $@convention(method) <T> (@in_guaranteed T, @guaranteed C) -> @out T {
60+
61+
62+
63+
bb0(%0 : $*T, %1 : $*T, %2 : @guaranteed $C):
64+
debug_value_addr %1 : $*T, let, name "t", argno 1
65+
debug_value %2 : $C, let, name "self", argno 2
66+
copy_addr %1 to [initialization] %0 : $*T
67+
%6 = tuple ()
68+
return %6 : $()
69+
}
70+
71+
72+
sil hidden [ossa] @$s4main1CCfd : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject {
73+
74+
bb0(%0 : @guaranteed $C):
75+
debug_value %0 : $C, let, name "self", argno 1
76+
%2 = unchecked_ref_cast %0 : $C to $Builtin.NativeObject
77+
%3 = unchecked_ownership_conversion %2 : $Builtin.NativeObject, @guaranteed to @owned
78+
return %3 : $Builtin.NativeObject
79+
}
80+
81+
82+
sil hidden [ossa] @$s4main1CCfD : $@convention(method) (@owned C) -> () {
83+
84+
bb0(%0 : @owned $C):
85+
debug_value %0 : $C, let, name "self", argno 1
86+
87+
%2 = function_ref @$s4main1CCfd : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
88+
%3 = begin_borrow %0 : $C
89+
%4 = apply %2(%3) : $@convention(method) (@guaranteed C) -> @owned Builtin.NativeObject
90+
end_borrow %3 : $C
91+
end_lifetime %0 : $C
92+
%7 = unchecked_ref_cast %4 : $Builtin.NativeObject to $C
93+
dealloc_ref %7 : $C
94+
%9 = tuple ()
95+
return %9 : $()
96+
}
97+
98+
99+
sil hidden [exact_self_class] [ossa] @$s4main1CCACycfC : $@convention(method) (@thick C.Type) -> @owned C {
100+
101+
bb0(%0 : $@thick C.Type):
102+
%1 = alloc_ref $C
103+
104+
%2 = function_ref @$s4main1CCACycfc : $@convention(method) (@owned C) -> @owned C
105+
%3 = apply %2(%1) : $@convention(method) (@owned C) -> @owned C
106+
return %3 : $C
107+
}
108+
109+
110+
sil hidden [ossa] @$s4main1CCACycfc : $@convention(method) (@owned C) -> @owned C {
111+
112+
bb0(%0 : @owned $C):
113+
debug_value %0 : $C, let, name "self", argno 1
114+
%2 = mark_uninitialized [rootself] %0 : $C
115+
%3 = copy_value %2 : $C
116+
destroy_value %2 : $C
117+
return %3 : $C
118+
}
119+
120+
121+
sil hidden [ossa] @$s4main4MainVAAyyFZ : $@convention(method) (@thin Main.Type) -> () {
122+
123+
bb0(%0 : $@thin Main.Type):
124+
debug_value %0 : $@thin Main.Type, let, name "self", argno 1
125+
%2 = metatype $@thick C.Type
126+
127+
%3 = function_ref @$s4main1CCACycfC : $@convention(method) (@thick C.Type) -> @owned C
128+
%4 = apply %3(%2) : $@convention(method) (@thick C.Type) -> @owned C
129+
debug_value %4 : $C, let, name "s"
130+
%6 = integer_literal $Builtin.IntLiteral, 42
131+
%7 = metatype $@thin Int.Type
132+
133+
%8 = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
134+
%9 = apply %8(%6, %7) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
135+
debug_value %9 : $Int, let, name "t"
136+
%11 = alloc_stack $Int
137+
%12 = begin_borrow %4 : $C
138+
%13 = alloc_stack $Int
139+
store %9 to [trivial] %13 : $*Int
140+
141+
%15 = function_ref @call_generic_function : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : C> (@guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out τ_0_1
142+
%16 = apply %15<C, Int>(%11, %12, %13) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : C> (@guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out τ_0_1
143+
dealloc_stack %13 : $*Int
144+
end_borrow %12 : $C
145+
%19 = load [trivial] %11 : $*Int
146+
debug_value %19 : $Int, let, name "out"
147+
dealloc_stack %11 : $*Int
148+
%22 = alloc_stack $Int
149+
store %19 to [trivial] %22 : $*Int
150+
151+
%24 = function_ref @printGeneric : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
152+
// CHECK: 42
153+
%25 = apply %24<Int>(%22) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
154+
dealloc_stack %22 : $*Int
155+
destroy_value %4 : $C
156+
%28 = tuple ()
157+
return %28 : $()
158+
}
159+
160+
161+
sil [transparent] [serialized] @$sSi22_builtinIntegerLiteralSiBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
162+
163+
164+
sil public_external @printGeneric : $@convention(thin) <T> (@in_guaranteed T) -> ()
165+
166+
167+
sil hidden [ossa] @$s4main4MainVACycfC : $@convention(method) (@thin Main.Type) -> Main {
168+
169+
bb0(%0 : $@thin Main.Type):
170+
%1 = alloc_box ${ var Main }, var, name "self"
171+
%2 = mark_uninitialized [rootself] %1 : ${ var Main }
172+
%3 = project_box %2 : ${ var Main }, 0
173+
%4 = load [trivial] %3 : $*Main
174+
destroy_value %2 : ${ var Main }
175+
return %4 : $Main
176+
}
177+
178+
179+
sil hidden [ossa] @$s4main4MainV5$mainyyFZ : $@convention(method) (@thin Main.Type) -> () {
180+
181+
bb0(%0 : $@thin Main.Type):
182+
debug_value %0 : $@thin Main.Type, let, name "self", argno 1
183+
%2 = metatype $@thin Main.Type
184+
185+
%3 = function_ref @$s4main4MainVAAyyFZ : $@convention(method) (@thin Main.Type) -> ()
186+
%4 = apply %3(%2) : $@convention(method) (@thin Main.Type) -> ()
187+
%5 = tuple ()
188+
return %5 : $()
189+
}
190+
191+
192+
193+
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
194+
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
195+
%2 = metatype $@thin Main.Type
196+
197+
%3 = function_ref @$s4main4MainV5$mainyyFZ : $@convention(method) (@thin Main.Type) -> ()
198+
%4 = apply %3(%2) : $@convention(method) (@thin Main.Type) -> ()
199+
%5 = integer_literal $Builtin.Int32, 0
200+
br bb1(%5 : $Builtin.Int32)
201+
202+
203+
bb1(%7 : $Builtin.Int32):
204+
%8 = struct $Int32 (%7 : $Builtin.Int32)
205+
return %8 : $Int32
206+
}
207+
208+
sil_vtable C {
209+
#C.generic_function: <T> (C) -> (T) -> T : @generic_function
210+
#C.init!allocator: (C.Type) -> () -> C : @$s4main1CCACycfC
211+
#C.deinit!deallocator: @$s4main1CCfD
212+
}

0 commit comments

Comments
 (0)