From 9200e81a1828f7d3aa59a48c52317e1beeeac0b1 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 6 Aug 2008 23:16:52 +0000 Subject: [PATCH] SDISel's constant branch folding can fold away self-loops, which doesn't result in any dead blocks, but rather an incorrect phi input. Add code to UnreachableMachineBlockElim to get rid of these entries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54432 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/UnreachableBlockElim.cpp | 55 ++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp index f1e3aabaebe..57811cab0f6 100644 --- a/lib/CodeGen/UnreachableBlockElim.cpp +++ b/lib/CodeGen/UnreachableBlockElim.cpp @@ -111,9 +111,11 @@ bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) { // Loop over all dead blocks, remembering them and deleting all instructions // in them. std::vector DeadBlocks; - for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) - if (!Reachable.count(I)) { - MachineBasicBlock *BB = I; + for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) { + MachineBasicBlock *BB = I; + + // Test for deadness. + if (!Reachable.count(BB)) { DeadBlocks.push_back(BB); while (BB->succ_begin() != BB->succ_end()) { @@ -129,28 +131,51 @@ bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) { start->RemoveOperand(i-1); } - if (start->getNumOperands() == 3) { - MachineInstr* phi = start; - unsigned Input = phi->getOperand(1).getReg(); - unsigned Output = phi->getOperand(0).getReg(); - - start++; - phi->eraseFromParent(); - - if (Input != Output) - F.getRegInfo().replaceRegWith(Output, Input); - } else - start++; + start++; } BB->removeSuccessor(BB->succ_begin()); } } + } // Actually remove the blocks now. for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i) DeadBlocks[i]->eraseFromParent(); + // Cleanup PHI nodes. + for (MachineFunction::iterator I = F.begin(), E = F.end(); I != E; ++I) { + MachineBasicBlock *BB = I; + // Prune unneeded PHI entries. + SmallPtrSet preds(BB->pred_begin(), + BB->pred_end()); + MachineBasicBlock::iterator phi = BB->begin(); + while (phi != BB->end() && + phi->getOpcode() == TargetInstrInfo::PHI) { + if (phi->getNumOperands() == 3) { + unsigned Input = phi->getOperand(1).getReg(); + unsigned Output = phi->getOperand(0).getReg(); + + MachineInstr* temp = phi; + ++phi; + temp->eraseFromParent(); + + if (Input != Output) + F.getRegInfo().replaceRegWith(Output, Input); + + continue; + } + + for (unsigned i = phi->getNumOperands() - 1; i >= 2; i-=2) + if (!preds.count(phi->getOperand(i).getMBB())) { + phi->RemoveOperand(i); + phi->RemoveOperand(i-1); + } + + ++phi; + } + } + F.RenumberBlocks(); return DeadBlocks.size();