Skip to content

Commit 209e3df

Browse files
committed
[Mem2Reg] Complete new enum phi lifetimes.
When multi-block `alloc_stack`s of enum type with users are promoted, lifetimes of stored values are completed to compensate for the legality of not `destroy_addr`ing the `alloc_stack` in blocks where no non-trivial value is known to be stored (the none case block of a `switch_enum` of a load_borrow of the `alloc_stack`, e.g.). Here, phis created during promotion are lifetime completed as well.
1 parent f5e8077 commit 209e3df

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,12 @@ void StackAllocationPromoter::run() {
18161816
// Use the lifetime completion utility to complete such lifetimes.
18171817
// First, collect the stored values to complete.
18181818
if (asi->getType().isOrHasEnum()) {
1819+
for (auto *block : livePhiBlocks) {
1820+
SILPhiArgument *argument = cast<SILPhiArgument>(
1821+
block->getArgument(block->getNumArguments() - 1));
1822+
assert(argument->isPhi());
1823+
valuesToComplete.push_back(argument);
1824+
}
18191825
for (auto it : initializationPoints) {
18201826
auto *si = it.second;
18211827
auto stored = si->getOperand(CopyLikeInstruction::Src);

test/SILOptimizer/mem2reg_ossa.sil

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,50 @@ bb7:
610610
return %r : $()
611611
}
612612

613+
// CHECK-LABEL: sil [ossa] @switch_enum_out_of_new_phi_block : {{.*}} {
614+
// CHECK-NOT: alloc_stack
615+
// CHECK: } // end sil function 'switch_enum_out_of_new_phi_block'
616+
sil [ossa] @switch_enum_out_of_new_phi_block : $() -> () {
617+
entry:
618+
%addr = alloc_stack $FakeOptional<Klass>
619+
cond_br undef, store_none, agg_either
620+
621+
store_none:
622+
%none1 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
623+
store %none1 to [init] %addr : $*FakeOptional<Klass>
624+
br switcheroo
625+
626+
agg_either:
627+
cond_br undef, agg_some, agg_none
628+
629+
agg_some:
630+
%Klass = apply undef() : $@convention(thin) () -> (@owned Klass)
631+
%some = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %Klass : $Klass
632+
br store_maybe(%some : $FakeOptional<Klass>)
633+
634+
agg_none:
635+
%none2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
636+
br store_maybe(%none2 : $FakeOptional<Klass>)
637+
638+
store_maybe(%maybe : @owned $FakeOptional<Klass>):
639+
store %maybe to [init] %addr : $*FakeOptional<Klass>
640+
br switcheroo
641+
642+
switcheroo:
643+
%borrow = load_borrow %addr : $*FakeOptional<Klass>
644+
switch_enum %borrow : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb14, case #FakeOptional.none!enumelt: bb15
645+
646+
bb14(%some_borrowed : @guaranteed $Klass):
647+
end_borrow %borrow : $FakeOptional<Klass>
648+
destroy_addr %addr : $*FakeOptional<Klass>
649+
br bb16
650+
651+
bb15:
652+
end_borrow %borrow : $FakeOptional<Klass>
653+
br bb16
654+
655+
bb16:
656+
dealloc_stack %addr : $*FakeOptional<Klass>
657+
%retval = tuple ()
658+
return %retval : $()
659+
}

0 commit comments

Comments
 (0)