mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
We can only eliminate dealloc_stack in an unreachable block if we can eliminate all dealloc_stack instructions in the block
This commit is contained in:
@@ -1843,6 +1843,26 @@ bool SimplifyCFG::simplifySwitchValueBlock(SwitchValueInst *SVI) {
|
||||
return simplifyTermWithIdenticalDestBlocks(ThisBB);
|
||||
}
|
||||
|
||||
bool onlyContainsRefcountAndDeallocStackInst(
|
||||
SILBasicBlock::reverse_iterator I, SILBasicBlock::reverse_iterator End) {
|
||||
while (I != End) {
|
||||
auto MaybeDead = I++;
|
||||
switch (MaybeDead->getKind()) {
|
||||
// These technically have side effects, but not ones that matter
|
||||
// in a block that we shouldn't really reach...
|
||||
case SILInstructionKind::StrongRetainInst:
|
||||
case SILInstructionKind::StrongReleaseInst:
|
||||
case SILInstructionKind::RetainValueInst:
|
||||
case SILInstructionKind::ReleaseValueInst:
|
||||
case SILInstructionKind::DeallocStackInst:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/// simplifyUnreachableBlock - Simplify blocks ending with unreachable by
|
||||
/// removing instructions that are safe to delete backwards until we
|
||||
/// hit an instruction we cannot delete.
|
||||
@@ -1853,6 +1873,8 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
|
||||
auto End = BB->rend();
|
||||
SmallVector<SILInstruction *, 8> DeadInstrs;
|
||||
|
||||
bool canIgnoreRestOfBlock = false;
|
||||
|
||||
// Walk backwards deleting instructions that should be safe to delete
|
||||
// in a block that ends with unreachable.
|
||||
while (I != End) {
|
||||
@@ -1865,12 +1887,20 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
|
||||
case SILInstructionKind::StrongReleaseInst:
|
||||
case SILInstructionKind::RetainValueInst:
|
||||
case SILInstructionKind::ReleaseValueInst:
|
||||
case SILInstructionKind::DeallocStackInst:
|
||||
break;
|
||||
|
||||
// We can only ignore a dealloc_stack instruction if we can ignore all
|
||||
// instructions in the block.
|
||||
case SILInstructionKind::DeallocStackInst: {
|
||||
if (canIgnoreRestOfBlock ||
|
||||
onlyContainsRefcountAndDeallocStackInst(MaybeDead, End)) {
|
||||
canIgnoreRestOfBlock = true;
|
||||
break;
|
||||
}
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
default:
|
||||
if (MaybeDead->mayHaveSideEffects()) {
|
||||
if (Changed)
|
||||
if (Changed)
|
||||
for (auto Dead : DeadInstrs)
|
||||
Dead->eraseFromParent();
|
||||
return Changed;
|
||||
|
||||
Reference in New Issue
Block a user