@@ -1843,6 +1843,26 @@ bool SimplifyCFG::simplifySwitchValueBlock(SwitchValueInst *SVI) {
1843
1843
return simplifyTermWithIdenticalDestBlocks (ThisBB);
1844
1844
}
1845
1845
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
+ }
1846
1866
// / simplifyUnreachableBlock - Simplify blocks ending with unreachable by
1847
1867
// / removing instructions that are safe to delete backwards until we
1848
1868
// / hit an instruction we cannot delete.
@@ -1853,6 +1873,8 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
1853
1873
auto End = BB->rend ();
1854
1874
SmallVector<SILInstruction *, 8 > DeadInstrs;
1855
1875
1876
+ bool canIgnoreRestOfBlock = false ;
1877
+
1856
1878
// Walk backwards deleting instructions that should be safe to delete
1857
1879
// in a block that ends with unreachable.
1858
1880
while (I != End) {
@@ -1865,12 +1887,20 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
1865
1887
case SILInstructionKind::StrongReleaseInst:
1866
1888
case SILInstructionKind::RetainValueInst:
1867
1889
case SILInstructionKind::ReleaseValueInst:
1868
- case SILInstructionKind::DeallocStackInst:
1869
1890
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
+ }
1871
1901
default :
1872
1902
if (MaybeDead->mayHaveSideEffects ()) {
1873
- if (Changed)
1903
+ if (Changed)
1874
1904
for (auto Dead : DeadInstrs)
1875
1905
Dead->eraseFromParent ();
1876
1906
return Changed;
0 commit comments