Skip to content

Commit 4d92cce

Browse files
committed
[DCE] Tweaked code to end borrows before destroys.
If a phi argument is dead and it reborrowing it was dependent on some other value, that other value on which it was dependent may have already itself been deleted. In that case, the destroy_value would have been added just before the terminator of the predecessors of the block which contained the dead phi. So, when deciding where to insert the end_borrow, iterate backwards from the end of the block, skipping the terminator updating the insertion point every time a destroy_value instruction is encountered until we hit an instruction with a different opcode. This ensures that no matter how many destroy_values may have been added just before the terminator, the end_borrow will preceed them. This commit just tweaks the preexisting logic that checked for this condition. Specifically, the previous code didn't handle the case where the block contains only a terminator and a destroy_value.
1 parent 6f34844 commit 4d92cce

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,19 @@ bool DCE::removeDead() {
601601
// may also have been dead and a destroy_value of its baseValue may
602602
// have been inserted before the pred's terminator. Make sure to
603603
// adjust the insertPt before any destroy_value.
604+
//
605+
// FIXME: This code currently can reorder destroys, e.g., when the
606+
// block already contains a destroy_value just before the
607+
// terminator. Fix this by making note of the added
608+
// destroy_value insts and only moving the insertion point
609+
// before those that are newly added.
604610
for (SILInstruction &predInst : llvm::reverse(*pred)) {
605611
if (&predInst == predTerm)
606612
continue;
607613
if (!isa<DestroyValueInst>(&predInst)) {
608-
insertPt = &*std::next(predInst.getIterator());
609614
break;
610615
}
616+
insertPt = &predInst;
611617
}
612618
}
613619

test/SILOptimizer/dead_code_elimination_nontrivial_ossa.sil

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,3 +679,44 @@ exit:
679679
%retval = tuple ()
680680
return %retval : $()
681681
}
682+
683+
// CHECK-LABEL: sil hidden [ossa] @add_end_borrow_after_destroy_value : {{.*}} {
684+
// CHECK: bb0({{%[^,]+}} : $Builtin.Int1, [[INSTANCE_1:%[^,]+]] : @owned $Klass, {{%[^,]+}} : @owned $Klass):
685+
// CHECK: [[LIFETIME_1:%[^,]+]] = begin_borrow [[INSTANCE_1]]
686+
// CHECK: copy_value [[LIFETIME_1]]
687+
// CHECK: cond_br {{%[^,]+}}, [[BASIC_BLOCK1:bb[0-9]+]], [[BASIC_BLOCK2:bb[0-9]+]]
688+
// CHECK: [[BASIC_BLOCK1]]:
689+
// CHECK: end_borrow [[LIFETIME_1]]
690+
// CHECK: destroy_value [[INSTANCE_1]]
691+
// CHECK: [[BASIC_BLOCK2]]:
692+
// CHECK: end_borrow [[LIFETIME_1]]
693+
// CHECK: destroy_value [[INSTANCE_1]]
694+
// CHECK-LABEL: } // end sil function 'add_end_borrow_after_destroy_value'
695+
sil hidden [ossa] @add_end_borrow_after_destroy_value : $@convention(thin) (Builtin.Int1, @owned Klass, @owned Klass) -> () {
696+
bb0(%condition : $Builtin.Int1, %instance_1 : @owned $Klass, %instance_2 : @owned $Klass):
697+
%lifetime_1 = begin_borrow %instance_1 : $Klass
698+
699+
%copy_1 = copy_value %lifetime_1 : $Klass
700+
%stack_addr = alloc_stack $Klass
701+
store %copy_1 to [init] %stack_addr : $*Klass
702+
destroy_addr %stack_addr : $*Klass
703+
dealloc_stack %stack_addr : $*Klass
704+
705+
cond_br %condition, bb1, bb2
706+
707+
bb1:
708+
end_borrow %lifetime_1 : $Klass
709+
destroy_value %instance_1 : $Klass
710+
%lifetime_2 = begin_borrow %instance_2 : $Klass
711+
br bb3(%instance_2 : $Klass, %lifetime_2 : $Klass)
712+
713+
bb2:
714+
destroy_value %instance_2 : $Klass
715+
br bb3(%instance_1 : $Klass, %lifetime_1 : $Klass)
716+
717+
bb3(%original : @owned $Klass, %lifetime : @guaranteed $Klass):
718+
end_borrow %lifetime : $Klass
719+
destroy_value %original : $Klass
720+
%result = tuple ()
721+
return %result : $()
722+
}

0 commit comments

Comments
 (0)