Skip to content

Commit e0262eb

Browse files
committed
[SSADestroyHoisting] Fixed barrier check.
Previously, FindBarrierAccessScopes::checkReachablePhiBarrier was not looking at the terminator of predecessors but rather looking at the terminator of block itself. Previously, in cases where the current block's terminator was in fact a barrier, that resulted in failing to hoist any live-in access scopes. Now that we aren't running the data flow twice, the result was worse: in cases where the current block's terminator was a barrier but there was no access scope in play, no barrier would be added at all.
1 parent 26853f4 commit e0262eb

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ class DeinitBarriers {
367367
bool checkReachablePhiBarrier(SILBasicBlock *block) {
368368
bool isBarrier =
369369
llvm::any_of(block->getPredecessorBlocks(), [&](auto *predecessor) {
370-
return result.isBarrier(block->getTerminator());
370+
return result.isBarrier(predecessor->getTerminator());
371371
});
372372
if (isBarrier) {
373373
// If there's a barrier preventing us from hoisting out of this block,

test/SILOptimizer/hoist_destroy_addr.sil

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,22 @@ struct TrivialStruct {
4343
var e: E
4444
}
4545

46+
enum Change {
47+
case insert(offset: Int, element: X)
48+
case remove(offset: Int, element: X)
49+
}
50+
51+
struct Int {
52+
@_hasStorage var _value : Builtin.Int64
53+
}
54+
4655
sil @unknown : $@convention(thin) () -> ()
4756
sil @use_S : $@convention(thin) (@in_guaranteed S) -> ()
4857

4958
sil @f_out : $@convention(thin) <T> () -> @out T
5059
sil @f_bool : $@convention(thin) () -> Builtin.Int1
5160
sil [ossa] @take_trivial_struct : $@convention(thin) (TrivialStruct) -> ()
61+
sil [ossa] @get_change_out : $@convention(thin) () -> @out Change
5262

5363
// CHECK-LABEL: sil [ossa] @test_simple
5464
// CHECK: bb0(%0 : $*S):
@@ -270,6 +280,53 @@ entry(%addr : $*X):
270280
return %tuple : $()
271281
}
272282

283+
// Hoist a destroy_addr over a phi.
284+
//
285+
// CHECK-LABEL: sil [ossa] @hoist_over_undef_phi : {{.*}} {
286+
// CHECK: [[STACK1:%[^,]+]] = alloc_stack
287+
// CHECK-NEXT: apply undef
288+
// CHECK-NEXT: destroy_addr [[STACK1]]
289+
// CHECK-LABEL: } // end sil function 'hoist_over_undef_phi'
290+
sil [ossa] @hoist_over_undef_phi : $@convention(thin) () -> () {
291+
entry:
292+
br latch
293+
294+
latch:
295+
cond_br undef, top, exit
296+
297+
top:
298+
%stack1 = alloc_stack $Change
299+
apply undef(%stack1) : $@convention(thin) () -> @out Change
300+
%access = begin_access [static] [modify] %stack1 : $*Change
301+
br top2(undef : $())
302+
303+
top2(%66 : $()):
304+
end_access %access : $*Change
305+
destroy_addr %stack1 : $*Change
306+
dealloc_stack %stack1 : $*Change
307+
%stack2 = alloc_stack $Change
308+
apply undef(%stack2) : $@convention(thin) () -> @out Change
309+
switch_enum_addr %stack2 : $*Change, case #Change.insert!enumelt: left, case #Change.remove!enumelt: right
310+
311+
left:
312+
br bottom
313+
314+
right:
315+
br bottom
316+
317+
bottom:
318+
destroy_addr %stack2 : $*Change
319+
dealloc_stack %stack2 : $*Change
320+
br backedge
321+
322+
backedge:
323+
br latch
324+
325+
exit:
326+
%321 = tuple ()
327+
return %321 : $()
328+
}
329+
273330
// Fold destroy_addr and a load [copy] into a load [take] even when that
274331
// load [take] is guarded by an access scope.
275332
//

0 commit comments

Comments
 (0)