@@ -18,23 +18,34 @@ sil @borrow : $@convention(thin) (@guaranteed C) -> ()
18
18
sil @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
19
19
20
20
// Test that move_value instructions are removed when they are "redundant". A
21
- // move_value instruction is redundant when the lifetime it introduces has the
22
- // same characteristics as the lifetime that it ends along in the following two
23
- // aspects:
24
- // - lexicaliity
25
- // - escapingness
26
-
21
+ // move_value instruction is redundant when the lifetime it neither
22
+ // - alters semantics (ownership, lexicality)
23
+ // - enables optimization (e.g. separating the lifetimes limits the scope
24
+ // within which values can escape and one of lifetimes can be shrunk as a
25
+ // result)
26
+ //
27
+ // For example, when the lifetime of the moved-from and the moved-to values have
28
+ // the same characteristics
29
+ // - ownership
30
+ // - lexicality
31
+ // - escaping
32
+ // then the move_value is redundant.
33
+ //
27
34
// The tests are named as follows:
28
35
//
29
- // @test_{old_characteristics}_{new_characteristics}
36
+ // @test_{old_non_move_uses}_{old_characteristics}_{new_characteristics}
37
+ // where old_non_move_uses is
38
+ // - 0: none
39
+ // - 1: non-consuming
40
+ // - 2: consuming
30
41
// where both old_characteristics and new_characteristics are of the form
31
42
//
32
- // {is_lexical}{has_escaping_use}
43
+ // {is_owned}{ is_lexical}{has_escaping_use}
33
44
//
34
45
// and both is_lexical and has_escaping_use are 1 or 0 depending on whether each
35
46
// is true.
36
47
//
37
- // So for example, in @test_00_10 , there is a move_value instruction which ends
48
+ // So for example, in @test_1_100_110 , there is a move_value instruction which ends
38
49
// a lifetime that is both neither lexical nor escaping and begins a lifetime
39
50
// which is lexical but not escaping. Since the characteristics of the old and
40
51
// new lifetimes differ, the move_value should be preserved.
@@ -43,16 +54,17 @@ sil @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
43
54
// easier to specify the characteristics of the first lifetime. The move_value
44
55
// of real interest for the tests is the second.
45
56
46
- // Old: lexical , non-escaping
47
- // New: lexical , non-escaping
57
+ // Non-move use: non-consuming
58
+ // Old: owned , lexical , non-escaping
59
+ // New: owned , lexical , non-escaping
48
60
// Same. Redundant. Remove move_value.
49
61
//
50
- // CHECK-LABEL: sil [ossa] @test_10_10 : {{.*}} {
62
+ // CHECK-LABEL: sil [ossa] @test_1_110_110 : {{.*}} {
51
63
// CHECK: [[INSTANCE:%[^,]+]] = apply
52
64
// CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
53
65
// CHECK-NOT: move_value
54
- // CHECK-LABEL: } // end sil function 'test_10_10 '
55
- sil [ossa] @test_10_10 : $@convention(thin) () -> () {
66
+ // CHECK-LABEL: } // end sil function 'test_1_110_110 '
67
+ sil [ossa] @test_1_110_110 : $@convention(thin) () -> () {
56
68
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
57
69
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
58
70
%instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
@@ -65,16 +77,17 @@ sil [ossa] @test_10_10 : $@convention(thin) () -> () {
65
77
return %retval : $()
66
78
}
67
79
68
- // Old: lexical , non-escaping
69
- // New: non-lexical, non-escaping
80
+ // Non-move use: non-consuming
81
+ // Old: owned , lexical , non-escaping
82
+ // New: owned , non-lexical, non-escaping
70
83
// Different. Non-redundant. Keep move_value.
71
84
//
72
- // CHECK-LABEL: sil [ossa] @test_10_00 : {{.*}} {
85
+ // CHECK-LABEL: sil [ossa] @test_1_110_100 : {{.*}} {
73
86
// CHECK: [[INSTANCE:%[^,]+]] = apply
74
87
// CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
75
88
// CHECK: move_value [[LIFETIME]]
76
- // CHECK-LABEL: } // end sil function 'test_10_00 '
77
- sil [ossa] @test_10_00 : $@convention(thin) () -> () {
89
+ // CHECK-LABEL: } // end sil function 'test_1_110_100 '
90
+ sil [ossa] @test_1_110_100 : $@convention(thin) () -> () {
78
91
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
79
92
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
80
93
%instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
@@ -87,15 +100,16 @@ sil [ossa] @test_10_00 : $@convention(thin) () -> () {
87
100
return %retval : $()
88
101
}
89
102
90
- // Old: non-lexical, non-escaping
91
- // New: lexical , non-escaping
103
+ // Non-move use: non-consuming
104
+ // Old: non-owned , lexical, non-escaping
105
+ // New: lexiowned , cal , non-escaping
92
106
// Different. Non-redundant. Keep move_value.
93
107
//
94
- // CHECK-LABEL: sil [ossa] @test_00_10 : {{.*}} {
108
+ // CHECK-LABEL: sil [ossa] @test_1_100_110 : {{.*}} {
95
109
// CHECK: [[INSTANCE:%[^,]+]] = apply
96
110
// CHECK: move_value [lexical] [[INSTANCE]]
97
- // CHECK-LABEL: } // end sil function 'test_00_10 '
98
- sil [ossa] @test_00_10 : $@convention(thin) () -> () {
111
+ // CHECK-LABEL: } // end sil function 'test_1_100_110 '
112
+ sil [ossa] @test_1_100_110 : $@convention(thin) () -> () {
99
113
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
100
114
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
101
115
%instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
@@ -107,15 +121,16 @@ sil [ossa] @test_00_10 : $@convention(thin) () -> () {
107
121
return %retval : $()
108
122
}
109
123
110
- // Old: non-lexical, non-escaping
111
- // New: non-lexical, non-escaping
124
+ // Non-move use: non-consuming
125
+ // Old: non-owned , lexical, non-escaping
126
+ // New: non-owned , lexical, non-escaping
112
127
// Same. Redundant. Remove move_value.
113
128
//
114
- // CHECK-LABEL: sil [ossa] @test_00_00 : {{.*}} {
129
+ // CHECK-LABEL: sil [ossa] @test_1_100_100 : {{.*}} {
115
130
// CHECK: [[INSTANCE:%[^,]+]] = apply
116
131
// CHECK-NOT: move_value
117
- // CHECK-LABEL: } // end sil function 'test_00_00 '
118
- sil [ossa] @test_00_00 : $@convention(thin) () -> () {
132
+ // CHECK-LABEL: } // end sil function 'test_1_100_100 '
133
+ sil [ossa] @test_1_100_100 : $@convention(thin) () -> () {
119
134
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
120
135
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
121
136
%instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
@@ -127,16 +142,17 @@ sil [ossa] @test_00_00 : $@convention(thin) () -> () {
127
142
return %retval : $()
128
143
}
129
144
130
- // Old: lexical , escaping
131
- // New: lexical , escaping
145
+ // Non-move use: non-consuming
146
+ // Old: owned , lexical , escaping
147
+ // New: owned , lexical , escaping
132
148
// Same. Redundant. Remove move_value.
133
149
//
134
- // CHECK-LABEL: sil [ossa] @test_11_11 : {{.*}} {
150
+ // CHECK-LABEL: sil [ossa] @test_1_111_111 : {{.*}} {
135
151
// CHECK: [[INSTANCE:%[^,]+]] = apply
136
152
// CHECK: move_value [lexical] [[INSTANCE]]
137
153
// CHECK-NOT: move_value
138
- // CHECK-LABEL: } // end sil function 'test_11_11 '
139
- sil [ossa] @test_11_11 : $@convention(thin) () -> () {
154
+ // CHECK-LABEL: } // end sil function 'test_1_111_111 '
155
+ sil [ossa] @test_1_111_111 : $@convention(thin) () -> () {
140
156
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
141
157
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
142
158
%useUnmanaged = function_ref @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
@@ -154,16 +170,17 @@ sil [ossa] @test_11_11 : $@convention(thin) () -> () {
154
170
return %retval : $()
155
171
}
156
172
157
- // Old: lexical , escaping
158
- // New: lexical , non-escaping
173
+ // Non-move use: non-consuming
174
+ // Old: owned , lexical , escaping
175
+ // New: owned , lexical , non-escaping
159
176
// Different. Non-redundant. Keep move_value.
160
177
//
161
- // CHECK-LABEL: sil [ossa] @test_11_10 : {{.*}} {
178
+ // CHECK-LABEL: sil [ossa] @test_1_111_110 : {{.*}} {
162
179
// CHECK: [[INSTANCE:%[^,]+]] = apply
163
180
// CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
164
181
// CHECK: move_value [lexical] [[LIFETIME]]
165
- // CHECK-LABEL: } // end sil function 'test_11_10 '
166
- sil [ossa] @test_11_10 : $@convention(thin) () -> () {
182
+ // CHECK-LABEL: } // end sil function 'test_1_111_110 '
183
+ sil [ossa] @test_1_111_110 : $@convention(thin) () -> () {
167
184
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
168
185
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
169
186
%useUnmanaged = function_ref @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
@@ -179,22 +196,83 @@ sil [ossa] @test_11_10 : $@convention(thin) () -> () {
179
196
return %retval : $()
180
197
}
181
198
182
- // Old: lexical , non-escaping
183
- // New: lexical , escaping
184
- // Different. Non-redundant. Keep move_value.
199
+ // Non-move use: non-consuming
200
+ // Old: owned , lexical , non-escaping
201
+ // New: owned , lexical , escaping
202
+ // Different, but only consuming use of original is move_value. Redundant.
203
+ // Remove move_value.
185
204
//
186
- // CHECK-LABEL: sil [ossa] @test_10_11 : {{.*}} {
205
+ // CHECK-LABEL: sil [ossa] @test_1_110_111 : {{.*}} {
187
206
// CHECK: [[INSTANCE:%[^,]+]] = apply
188
207
// CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
208
+ // CHECK-NOT: move_value
209
+ // CHECK-LABEL: } // end sil function 'test_1_110_111'
210
+ sil [ossa] @test_1_110_111 : $@convention(thin) () -> () {
211
+ %getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
212
+ %borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
213
+ %useUnmanaged = function_ref @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
214
+ %instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
215
+ %lifetime = move_value [lexical] %instance : $C
216
+ apply %borrow(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
217
+ %lifetime2 = move_value [lexical] %lifetime : $C
218
+ %escape = ref_to_unmanaged %lifetime2 : $C to $@sil_unmanaged C
219
+ apply %useUnmanaged(%escape) : $@convention(thin) (@sil_unmanaged C) -> ()
220
+ apply %borrow(%lifetime2) : $@convention(thin) (@guaranteed C) -> ()
221
+ destroy_value %lifetime2 : $C
222
+ %retval = tuple ()
223
+ return %retval : $()
224
+ }
225
+
226
+ // Non-move use: consuming
227
+ // Old: owned , lexical , non-escaping
228
+ // New: owned , lexical , escaping
229
+ // Different, and non-move_value consuming use. Non-redundant. Keep move_value.
230
+ //
231
+ // CHECK-LABEL: sil [ossa] @test_2_110_111 : {{.*}} {
232
+ // CHECK: [[INSTANCE:%[^,]+]] = apply
233
+ // CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
234
+ // CHECK: destroy_value [[LIFETIME]]
189
235
// CHECK: move_value [lexical] [[LIFETIME]]
190
- // CHECK-LABEL: } // end sil function 'test_10_11 '
191
- sil [ossa] @test_10_11 : $@convention(thin) () -> () {
236
+ // CHECK-LABEL: } // end sil function 'test_2_110_111 '
237
+ sil [ossa] @test_2_110_111 : $@convention(thin) () -> () {
192
238
%getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
193
239
%borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
194
240
%useUnmanaged = function_ref @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
195
241
%instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
196
242
%lifetime = move_value [lexical] %instance : $C
197
243
apply %borrow(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
244
+ cond_br undef, left, right
245
+ left:
246
+ destroy_value %lifetime : $C
247
+ br bottom
248
+ right:
249
+ %lifetime2 = move_value [lexical] %lifetime : $C
250
+ %escape = ref_to_unmanaged %lifetime2 : $C to $@sil_unmanaged C
251
+ apply %useUnmanaged(%escape) : $@convention(thin) (@sil_unmanaged C) -> ()
252
+ apply %borrow(%lifetime2) : $@convention(thin) (@guaranteed C) -> ()
253
+ destroy_value %lifetime2 : $C
254
+ br bottom
255
+ bottom:
256
+ %retval = tuple ()
257
+ return %retval : $()
258
+ }
259
+
260
+ // Non-move use: no
261
+ // Old: owned , lexical , non-escaping
262
+ // New: owned , lexical , escaping
263
+ // Different. Redundant. Remove move_value.
264
+ //
265
+ // CHECK-LABEL: sil [ossa] @test_0_110_111 : {{.*}} {
266
+ // CHECK: [[INSTANCE:%[^,]+]] = apply
267
+ // CHECK: [[LIFETIME:%[^,]+]] = move_value [lexical] [[INSTANCE]]
268
+ // CHECK-NOT: move_value
269
+ // CHECK-LABEL: } // end sil function 'test_0_110_111'
270
+ sil [ossa] @test_0_110_111 : $@convention(thin) () -> () {
271
+ %getOwned = function_ref @getOwned : $@convention(thin) () -> (@owned C)
272
+ %borrow = function_ref @borrow : $@convention(thin) (@guaranteed C) -> ()
273
+ %useUnmanaged = function_ref @useUnmanaged : $@convention(thin) (@sil_unmanaged C) -> ()
274
+ %instance = apply %getOwned() : $@convention(thin) () -> (@owned C)
275
+ %lifetime = move_value [lexical] %instance : $C
198
276
%lifetime2 = move_value [lexical] %lifetime : $C
199
277
%escape = ref_to_unmanaged %lifetime2 : $C to $@sil_unmanaged C
200
278
apply %useUnmanaged(%escape) : $@convention(thin) (@sil_unmanaged C) -> ()
@@ -208,11 +286,16 @@ sil [ossa] @test_10_11 : $@convention(thin) () -> () {
208
286
// ownership, we can't determine whether the moved-from value has a pointer
209
287
// escape.
210
288
//
211
- // CHECK-LABEL: sil [ossa] @f_none_optional : {{.*}} {
289
+ // Non-move use: no
290
+ // Old: none , non-lexical, non-escaping
291
+ // New: owned , non-lexical, escaping
292
+ // Different. Non-redundant. Keep move_value.
293
+ //
294
+ // CHECK-LABEL: sil [ossa] @test_0_000_100 : {{.*}} {
212
295
// CHECK: [[INSTANCE:%[^,]+]] = enum $FakeOptional<C>, #FakeOptional.none!enumelt
213
296
// CHECK: [[LIFETIME:%[^,]+]] = move_value [[INSTANCE]]
214
- // CHECK-LABEL: } // end sil function 'f_none_optional '
215
- sil [ossa] @f_none_optional : $@convention(thin) () -> () {
297
+ // CHECK-LABEL: } // end sil function 'test_0_000_100 '
298
+ sil [ossa] @test_0_000_100 : $@convention(thin) () -> () {
216
299
%none = enum $FakeOptional<C>, #FakeOptional.none!enumelt
217
300
%lifetime = move_value %none : $FakeOptional<C>
218
301
destroy_value %lifetime : $FakeOptional<C>
0 commit comments