Skip to content

Commit 8721d98

Browse files
authored
Merge pull request #22018 from gottesmm/pr-87f11264e3a0d398e96083f801b5ca5c4d3299e5
2 parents cf2c478 + 9cff942 commit 8721d98

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,9 @@ bool AllocOptimize::tryToRemoveDeadAllocation() {
12871287

12881288
switch (u.Kind) {
12891289
case PMOUseKind::Assign:
1290+
// Until we can promote the value being destroyed by the assign, we can
1291+
// not remove deallocations with such assigns.
1292+
return false;
12901293
case PMOUseKind::InitOrAssign:
12911294
break; // These don't prevent removal.
12921295
case PMOUseKind::Initialization:

test/SILOptimizer/predictable_deadalloc_elim.sil

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,175 @@ bb0(%0 : $Builtin.NativeObject):
9393
%9999 = tuple()
9494
return %9999 : $()
9595
}
96+
97+
//////////////////
98+
// Assign Tests //
99+
//////////////////
100+
101+
// Make sure that we do eliminate this allocation
102+
// CHECK-LABEL: sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
103+
// CHECK-NOT: alloc_stack
104+
// CHECK: } // end sil function 'simple_assign_take_trivial'
105+
sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
106+
bb0(%0 : $Builtin.Int32, %1 : $*Builtin.Int32):
107+
%2 = alloc_stack $Builtin.Int32
108+
store %0 to %2 : $*Builtin.Int32
109+
copy_addr [take] %1 to %2 : $*Builtin.Int32
110+
dealloc_stack %2 : $*Builtin.Int32
111+
%9999 = tuple()
112+
return %9999 : $()
113+
}
114+
115+
// In this case, we perform an init, copy. Since we do not want to lose the +1
116+
// on the argument, we do not eliminate this (even though with time perhaps we
117+
// could).
118+
// CHECK-LABEL: sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
119+
// CHECK: alloc_stack
120+
// CHECK: copy_addr
121+
// CHECK: } // end sil function 'simple_init_copy'
122+
sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
123+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
124+
%2 = alloc_stack $Builtin.NativeObject
125+
store %0 to %2 : $*Builtin.NativeObject
126+
destroy_addr %2 : $*Builtin.NativeObject
127+
copy_addr %1 to [initialization] %2 : $*Builtin.NativeObject
128+
destroy_addr %2 : $*Builtin.NativeObject
129+
dealloc_stack %2 : $*Builtin.NativeObject
130+
%9999 = tuple()
131+
return %9999 : $()
132+
}
133+
134+
// This we can promote successfully.
135+
// CHECK-LABEL: sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
136+
// CHECK: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $*Builtin.NativeObject):
137+
// CHECK-NOT: alloc_stack
138+
// CHECK: strong_release [[ARG0]]
139+
// CHECK: [[ARG1_LOADED:%.*]] = load [[ARG1]]
140+
// CHECK: strong_release [[ARG1_LOADED]]
141+
// CHECK: } // end sil function 'simple_init_take'
142+
sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
143+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
144+
%2 = alloc_stack $Builtin.NativeObject
145+
store %0 to %2 : $*Builtin.NativeObject
146+
destroy_addr %2 : $*Builtin.NativeObject
147+
copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
148+
destroy_addr %2 : $*Builtin.NativeObject
149+
dealloc_stack %2 : $*Builtin.NativeObject
150+
%9999 = tuple()
151+
return %9999 : $()
152+
}
153+
154+
// Since we are copying the input argument, we can not get rid of the copy_addr,
155+
// meaning we shouldn't eliminate the allocation here.
156+
// CHECK-LABEL: sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
157+
// CHECK: alloc_stack
158+
// CHECK: copy_addr
159+
// CHECK: } // end sil function 'simple_assign_no_take'
160+
sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
161+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
162+
%2 = alloc_stack $Builtin.NativeObject
163+
store %0 to %2 : $*Builtin.NativeObject
164+
copy_addr %1 to %2 : $*Builtin.NativeObject
165+
destroy_addr %2 : $*Builtin.NativeObject
166+
dealloc_stack %2 : $*Builtin.NativeObject
167+
%9999 = tuple()
168+
return %9999 : $()
169+
}
170+
171+
// If PMO understood how to promote assigns, we should be able to handle this
172+
// case.
173+
// CHECK-LABEL: sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
174+
// CHECK: alloc_stack
175+
// CHECK: copy_addr
176+
// CHECK: } // end sil function 'simple_assign_take'
177+
sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
178+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
179+
%2 = alloc_stack $Builtin.NativeObject
180+
store %0 to %2 : $*Builtin.NativeObject
181+
copy_addr [take] %1 to %2 : $*Builtin.NativeObject
182+
destroy_addr %2 : $*Builtin.NativeObject
183+
dealloc_stack %2 : $*Builtin.NativeObject
184+
%9999 = tuple()
185+
return %9999 : $()
186+
}
187+
188+
// CHECK-LABEL: sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
189+
// CHECK: bb0([[ARG:%.*]] :
190+
// CHECK-NOT: alloc_stack
191+
// CHECK-NOT: store
192+
// CHECK: bb3:
193+
// CHECK-NEXT: strong_release [[ARG]]
194+
// CHECK: } // end sil function 'simple_diamond_without_assign'
195+
sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
196+
bb0(%0 : $Builtin.NativeObject):
197+
%1 = alloc_stack $Builtin.NativeObject
198+
store %0 to %1 : $*Builtin.NativeObject
199+
cond_br undef, bb1, bb2
200+
201+
bb1:
202+
br bb3
203+
204+
bb2:
205+
br bb3
206+
207+
bb3:
208+
destroy_addr %1 : $*Builtin.NativeObject
209+
dealloc_stack %1 : $*Builtin.NativeObject
210+
%9999 = tuple()
211+
return %9999 : $()
212+
}
213+
214+
// We should not promote this due to this being an assign to %2.
215+
// CHECK-LABEL: sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
216+
// CHECK: alloc_stack
217+
// CHECK: copy_addr
218+
// CHECK: } // end sil function 'simple_diamond_with_assign'
219+
sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
220+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
221+
%2 = alloc_stack $Builtin.NativeObject
222+
store %0 to %2 : $*Builtin.NativeObject
223+
cond_br undef, bb1, bb2
224+
225+
bb1:
226+
copy_addr [take] %1 to %2 : $*Builtin.NativeObject
227+
br bb3
228+
229+
bb2:
230+
br bb3
231+
232+
bb3:
233+
destroy_addr %2 : $*Builtin.NativeObject
234+
dealloc_stack %2 : $*Builtin.NativeObject
235+
%9999 = tuple()
236+
return %9999 : $()
237+
}
238+
239+
// Today PMO can not handle different available values coming from different
240+
// BBs. With time it can be taught to do that if necessary. That being said,
241+
// this test shows that we /tried/ and failed with the available value test
242+
// instead of failing earlier due to the copy_addr being an assign since we
243+
// explode the copy_addr.
244+
// CHECK-LABEL: sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
245+
// CHECK: alloc_stack
246+
// CHECK-NOT: copy_addr
247+
// CHECK: } // end sil function 'simple_diamond_with_assign_remove'
248+
sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
249+
bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
250+
%2 = alloc_stack $Builtin.NativeObject
251+
store %0 to %2 : $*Builtin.NativeObject
252+
cond_br undef, bb1, bb2
253+
254+
bb1:
255+
destroy_addr %2 : $*Builtin.NativeObject
256+
copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
257+
br bb3
258+
259+
bb2:
260+
br bb3
261+
262+
bb3:
263+
destroy_addr %2 : $*Builtin.NativeObject
264+
dealloc_stack %2 : $*Builtin.NativeObject
265+
%9999 = tuple()
266+
return %9999 : $()
267+
}

0 commit comments

Comments
 (0)