File: partial_apply_simplification.sil

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (212 lines) | stat: -rw-r--r-- 10,974 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// RUN: %target-sil-opt -enable-sil-verify-all %s -partial-apply-simplification | %FileCheck %s

import Swift

// CHECK-LABEL: sil private @closure_common_uses
// CHECK-SAME:    : $@convention(method) (Int, @guaranteed { let Int }) -> Int {
// CHECK:      bb0([[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT:   [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:   [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT:   return [[Y]]
sil private @closure_common_uses : $@convention(thin) (Int, Int) -> Int {
entry(%x : $Int, %y : $Int):
  return %y : $Int
}

// CHECK-LABEL: sil @closure_common_uses_user_a
// CHECK:       bb0([[Y:%.*]] : $Int):
// CHECK:         [[F:%.*]] = function_ref @closure_common_uses
// CHECK-NEXT:    [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT:    [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:    store [[Y]] to [[BOX_0]]
// CHECK-NEXT:    [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_common_uses_user_a : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int):
  %f = function_ref @closure_common_uses : $@convention(thin) (Int, Int) -> Int
  %c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> Int
  return %c : $@callee_guaranteed (Int) -> Int
}

// CHECK-LABEL: sil @closure_common_uses_user_b
// CHECK:       bb0([[Y:%.*]] : $Int):
// CHECK:         [[F:%.*]] = function_ref @closure_common_uses
// CHECK-NEXT:    [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT:    [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:    store [[Y]] to [[BOX_0]]
// CHECK-NEXT:    [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_common_uses_user_b : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int):
  %f = function_ref @closure_common_uses : $@convention(thin) (Int, Int) -> Int
  %c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> Int
  return %c : $@callee_guaranteed (Int) -> Int
}

// CHECK-LABEL: sil private @closure_common_uses_owned
// CHECK-SAME:    : $@convention(method) (Int, @owned { let Int }) -> Int {
// CHECK:      bb0([[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT:   [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:   [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT:   strong_release [[BOX]]
// CHECK-NEXT:   return [[Y]]
sil private @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int {
entry(%x : $Int, %y : $Int):
  return %y : $Int
}

sil @closure_common_uses_owned_user_a : $@convention(thin) (Int) -> @owned @callee_owned (Int) -> Int {
entry(%y : $Int):
  %f = function_ref @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int
  %c = partial_apply %f(%y) : $@convention(thin) (Int, Int) -> Int
  return %c : $@callee_owned (Int) -> Int
}

sil @closure_common_uses_owned_user_b : $@convention(thin) (Int) -> @owned @callee_owned (Int) -> Int {
entry(%y : $Int):
  %f = function_ref @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int
  %c = partial_apply %f(%y) : $@convention(thin) (Int, Int) -> Int
  return %c : $@callee_owned (Int) -> Int
}

// CHECK-LABEL: sil private @closure_out_param
// CHECK-SAME:    : $@convention(method) (Int, @guaranteed { let Int }) -> @out Int {
// CHECK:      bb0([[R:%.*]] : $*Int, [[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT:   [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:   [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT:   store [[Y]] to [[R]]
// CHECK-NEXT:   return
sil private @closure_out_param : $@convention(thin) (Int, Int) -> @out Int {
entry(%r : $*Int, %x : $Int, %y : $Int):
  store %y to %r : $*Int
  return undef : $()
}

// CHECK-LABEL: sil @closure_out_param_user
// CHECK:       bb0([[Y:%.*]] : $Int):
// CHECK:         [[F:%.*]] = function_ref @closure_out_param
// CHECK-NEXT:    [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT:    [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT:    store [[Y]] to [[BOX_0]]
// CHECK-NEXT:    [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_out_param_user : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> @out Int {
entry(%y : $Int):
  %f = function_ref @closure_out_param : $@convention(thin) (Int, Int) -> @out Int
  %c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> @out Int
  return %c : $@callee_guaranteed (Int) -> @out Int
}

sil @add : $@convention(thin) (Int, Int) -> Int

// CHECK-LABEL: sil private @closure_multi_capture
// CHECK-SAME:    : $@convention(method) (Int, @guaranteed { let (Int, Int) }) -> Int
// CHECK:       bb0([[X:%.*]] : $Int, [[YZ:%.*]] : ${ let (Int, Int) }):
// CHECK-NEXT:   [[BOX_PROJ:%.*]] = project_box [[YZ]] :
// CHECK-NEXT:   [[BOX_0:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 0
// CHECK-NEXT:   [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT:   [[BOX_PROJ:%.*]] = project_box [[YZ]] :
// CHECK-NEXT:   [[BOX_1:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 1
// CHECK-NEXT:   [[Z:%.*]] = load [[BOX_1]] : $*Int
// CHECK:        [[ADD:%.*]] = function_ref @add
// CHECK-NEXT:   apply [[ADD]]([[Y]], [[Z]])
sil private @closure_multi_capture : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
  %f = function_ref @add : $@convention(thin) (Int, Int) -> Int
  %r = apply %f(%y, %z) : $@convention(thin) (Int, Int) -> Int
  return %r : $Int
}

// CHECK-LABEL: sil @closure_multi_capture_user
// CHECK:       bb0([[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK:         [[BOX:%.*]] = alloc_box [reflection] ${ let (Int, Int) }
// CHECK:         [[BOX_PROJ:%.*]] = project_box [[BOX]]
// CHECK:         [[BOX_0:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 0
// CHECK:         store [[Y]] to [[BOX_0]]
// CHECK:         [[BOX_1:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 1
// CHECK:         store [[Z]] to [[BOX_1]]
// CHECK:         [[RESULT:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX]])
// CHECK:         return [[RESULT]]
sil @closure_multi_capture_user : $@convention(thin) (Int, Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int, %z : $Int):
  %f = function_ref @closure_multi_capture : $@convention(thin) (Int, Int, Int) -> Int
  %c = partial_apply [callee_guaranteed] %f(%y, %z) : $@convention(thin) (Int, Int, Int) -> Int
  return %c : $@callee_guaranteed (Int) -> Int
}

// CHECK-LABEL: sil private @closure_nonescaping
// CHECK-SAME:    : $@convention(method) (Int, @in_guaranteed (Int, Int)) -> Int
// CHECK:       bb0([[X:%.*]] : $Int, [[YZ:%.*]] : $*(Int, Int)):
// CHECK:         [[BOX_0:%.*]] = tuple_element_addr [[YZ]] : {{.*}}, 0
// CHECK-NEXT:    [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT:    [[BOX_1:%.*]] = tuple_element_addr [[YZ]] : {{.*}}, 1
// CHECK-NEXT:    [[Z:%.*]] = load [[BOX_1]] : $*Int
// CHECK:         [[ADD:%.*]] = function_ref @add
// CHECK-NEXT:    apply [[ADD]]([[Y]], [[Z]])
sil private @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
  %f = function_ref @add : $@convention(thin) (Int, Int) -> Int
  %r = apply %f(%y, %z) : $@convention(thin) (Int, Int) -> Int
  return %r : $Int
}

sil @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int {
entry(%f : $@noescape @callee_guaranteed (Int) -> Int, %x : $Int):
  %y = apply %f(%x) : $@noescape @callee_guaranteed (Int) -> Int
  return %y : $Int
}

// CHECK-LABEL: sil @closure_nonescaping_user
// CHECK:       bb0([[X:%.*]] : $Int, [[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK:         [[F:%.*]] = function_ref @closure_nonescaping
// CHECK:         [[CONTEXT:%.*]] = alloc_stack $(Int, Int)
// CHECK:         [[CONTEXT_Y:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 0
// CHECK:         store [[Y]] to [[CONTEXT_Y]]
// CHECK:         [[CONTEXT_Z:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 1
// CHECK:         store [[Z]] to [[CONTEXT_Z]]
// CHECK:         [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[F]]([[CONTEXT]])
// CHECK:         [[CONSUMER:%.*]] = function_ref @closure_nonescaping_consumer
// CHECK:         apply [[CONSUMER]]([[CLOSURE]], [[X]])
sil @closure_nonescaping_user : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
  %f = function_ref @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int
  %c = partial_apply [callee_guaranteed] [on_stack] %f(%y, %z) : $@convention(thin) (Int, Int, Int) -> Int
  %g = function_ref @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
  %r = apply %g(%c, %x) : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
  dealloc_stack %c : $@noescape @callee_guaranteed (Int) -> Int
  return %r : $Int
}

// CHECK-LABEL: sil @closure_nonescaping_full_apply
// CHECK:       bb0([[X:%.*]] : $Int, [[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK:         [[F:%.*]] = function_ref @closure_nonescaping
// CHECK:         [[CONTEXT:%.*]] = alloc_stack $(Int, Int)
// CHECK:         [[CONTEXT_Y:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 0
// CHECK:         store [[Y]] to [[CONTEXT_Y]]
// CHECK:         [[CONTEXT_Z:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 1
// CHECK:         store [[Z]] to [[CONTEXT_Z]]
// CHECK:         [[CLOSURE:%.*]] = apply [[F]]([[X]], [[CONTEXT]])
sil @closure_nonescaping_full_apply : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
  %f = function_ref @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int
  %r = apply %f(%x, %y, %z) : $@convention(thin) (Int, Int, Int) -> Int
  return %r : $Int
}

// CHECK-LABEL: sil private @closure_nonescaping_convention_change
// CHECK-SAME:    : $@convention(method) (Int, @in_guaranteed Int) -> Int {
sil private @closure_nonescaping_convention_change : $@convention(thin) (Int, @in_guaranteed Int) -> Int {
entry(%x : $Int, %y : $*Int):
  %f = function_ref @add : $@convention(thin) (Int, Int) -> Int
  %z = load %y : $*Int
  %r = apply %f(%x, %z) : $@convention(thin) (Int, Int) -> Int
  return %r : $Int
}

sil @closure_nonescaping_convention_change_user : $@convention(thin) (Int, @in_guaranteed Int) -> Int {
entry(%x : $Int, %y : $*Int):
  %f = function_ref @closure_nonescaping_convention_change : $@convention(thin) (Int, @in_guaranteed Int) -> Int
  %c = partial_apply [callee_guaranteed] [on_stack] %f(%y) : $@convention(thin) (Int, @in_guaranteed Int) -> Int
  %g = function_ref @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
  %r = apply %g(%c, %x) : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
  dealloc_stack %c : $@noescape @callee_guaranteed (Int) -> Int
  return %r : $Int
}