Skip to content

Commit d3acfee

Browse files
committed
When DCE removes a dead terminator, insert appropriate lifetime ends
1 parent a78acfe commit d3acfee

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,16 @@ bool DCE::removeDead() {
611611

612612
// We want to replace dead terminators with unconditional branches to
613613
// the nearest post-dominator that has useful instructions.
614-
if (isa<TermInst>(Inst)) {
614+
if (auto *termInst = dyn_cast<TermInst>(Inst)) {
615615
SILBasicBlock *postDom = nearestUsefulPostDominator(Inst->getParent());
616616
if (!postDom)
617617
continue;
618618

619+
for (auto &op : termInst->getAllOperands()) {
620+
if (op.isLifetimeEnding()) {
621+
endLifetimeOfLiveValue(op.get(), termInst);
622+
}
623+
}
619624
LLVM_DEBUG(llvm::dbgs() << "Replacing branch: ");
620625
LLVM_DEBUG(Inst->dump());
621626
LLVM_DEBUG(llvm::dbgs() << "with jump to: BB" << postDom->getDebugID());

test/SILOptimizer/dead_code_elimination_nontrivial_ossa.sil

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ struct NonTrivialStruct {
1313
var val:Klass
1414
}
1515

16+
enum FakeOptional<T> {
17+
case none
18+
case some(T)
19+
}
20+
1621
sil [ossa] @$testtryapplyklassgen : $@convention(thin) () -> (@owned Klass, @error Error)
1722
sil [ossa] @$use_klass1 : $@convention(thin) (@owned Klass) -> ()
1823
sil [ossa] @$use_klass2 : $@convention(thin) (@guaranteed Klass) -> ()
@@ -558,3 +563,51 @@ bb3(%newborrow : @guaranteed $NonTrivialStruct, %newowned1 : @owned $NonTrivialS
558563
return %res : $NonTrivialStruct
559564
}
560565

566+
// CHECK-LABEL: sil [ossa] @dce_deadterm1 :
567+
// CHECK-NOT: switch_enum
568+
// CHECK-LABEL: } // end sil function 'dce_deadterm1'
569+
sil [ossa] @dce_deadterm1 : $@convention(thin) (@owned FakeOptional<Builtin.NativeObject>) -> () {
570+
bb0(%0 : @owned $FakeOptional<Builtin.NativeObject>):
571+
%0a = alloc_stack $FakeOptional<Builtin.NativeObject>
572+
store %0 to [init] %0a : $*FakeOptional<Builtin.NativeObject>
573+
%1 = load [take] %0a : $*FakeOptional<Builtin.NativeObject>
574+
switch_enum %1 : $FakeOptional<Builtin.NativeObject>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
575+
576+
bb1(%2 : @owned $Builtin.NativeObject):
577+
destroy_value %2 : $Builtin.NativeObject
578+
br bb3
579+
580+
bb2:
581+
br bb3
582+
583+
bb3:
584+
dealloc_stack %0a : $*FakeOptional<Builtin.NativeObject>
585+
%9999 = tuple()
586+
return %9999 : $()
587+
}
588+
589+
// CHECK-LABEL: sil [ossa] @dce_deadterm2 :
590+
// CHECK-NOT: load [copy]
591+
// CHECK-NOT: switch_enum
592+
// CHECK-LABEL: } // end sil function 'dce_deadterm2'
593+
sil [ossa] @dce_deadterm2 : $@convention(thin) (@owned FakeOptional<Builtin.NativeObject>) -> () {
594+
bb0(%0 : @owned $FakeOptional<Builtin.NativeObject>):
595+
%0a = alloc_stack $FakeOptional<Builtin.NativeObject>
596+
store %0 to [init] %0a : $*FakeOptional<Builtin.NativeObject>
597+
%1 = load [copy] %0a : $*FakeOptional<Builtin.NativeObject>
598+
switch_enum %1 : $FakeOptional<Builtin.NativeObject>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
599+
600+
bb1(%2 : @owned $Builtin.NativeObject):
601+
destroy_value %2 : $Builtin.NativeObject
602+
br bb3
603+
604+
bb2:
605+
br bb3
606+
607+
bb3:
608+
destroy_addr %0a : $*FakeOptional<Builtin.NativeObject>
609+
dealloc_stack %0a : $*FakeOptional<Builtin.NativeObject>
610+
%9999 = tuple()
611+
return %9999 : $()
612+
}
613+

0 commit comments

Comments
 (0)