Skip to content

Commit b6f9129

Browse files
committed
We can only eliminate dealloc_stack in an unreachable block if we can eliminate all dealloc_stack instructions in the block
1 parent 614006e commit b6f9129

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,26 @@ bool SimplifyCFG::simplifySwitchValueBlock(SwitchValueInst *SVI) {
18431843
return simplifyTermWithIdenticalDestBlocks(ThisBB);
18441844
}
18451845

1846+
bool onlyContainsRefcountAndDeallocStackInst(
1847+
SILBasicBlock::reverse_iterator I, SILBasicBlock::reverse_iterator End) {
1848+
while (I != End) {
1849+
auto MaybeDead = I++;
1850+
switch (MaybeDead->getKind()) {
1851+
// These technically have side effects, but not ones that matter
1852+
// in a block that we shouldn't really reach...
1853+
case SILInstructionKind::StrongRetainInst:
1854+
case SILInstructionKind::StrongReleaseInst:
1855+
case SILInstructionKind::RetainValueInst:
1856+
case SILInstructionKind::ReleaseValueInst:
1857+
case SILInstructionKind::DeallocStackInst:
1858+
break;
1859+
1860+
default:
1861+
return false;
1862+
}
1863+
}
1864+
return true;
1865+
}
18461866
/// simplifyUnreachableBlock - Simplify blocks ending with unreachable by
18471867
/// removing instructions that are safe to delete backwards until we
18481868
/// hit an instruction we cannot delete.
@@ -1853,6 +1873,8 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
18531873
auto End = BB->rend();
18541874
SmallVector<SILInstruction *, 8> DeadInstrs;
18551875

1876+
bool canIgnoreRestOfBlock = false;
1877+
18561878
// Walk backwards deleting instructions that should be safe to delete
18571879
// in a block that ends with unreachable.
18581880
while (I != End) {
@@ -1865,12 +1887,20 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
18651887
case SILInstructionKind::StrongReleaseInst:
18661888
case SILInstructionKind::RetainValueInst:
18671889
case SILInstructionKind::ReleaseValueInst:
1868-
case SILInstructionKind::DeallocStackInst:
18691890
break;
1870-
1891+
// We can only ignore a dealloc_stack instruction if we can ignore all
1892+
// instructions in the block.
1893+
case SILInstructionKind::DeallocStackInst: {
1894+
if (canIgnoreRestOfBlock ||
1895+
onlyContainsRefcountAndDeallocStackInst(MaybeDead, End)) {
1896+
canIgnoreRestOfBlock = true;
1897+
break;
1898+
}
1899+
LLVM_FALLTHROUGH;
1900+
}
18711901
default:
18721902
if (MaybeDead->mayHaveSideEffects()) {
1873-
if (Changed)
1903+
if (Changed)
18741904
for (auto Dead : DeadInstrs)
18751905
Dead->eraseFromParent();
18761906
return Changed;

0 commit comments

Comments
 (0)