diff options
author | Owen Anderson <resistor@mac.com> | 2008-08-06 23:16:52 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2008-08-06 23:16:52 +0000 |
commit | 9200e81a1828f7d3aa59a48c52317e1beeeac0b1 (patch) | |
tree | f6ed06ea65730d5f57e3b613bb8cabcb3df0e3b6 /lib/CodeGen | |
parent | 883771f86a111c43ce7c30085a1f4820b66f5712 (diff) | |
download | external_llvm-9200e81a1828f7d3aa59a48c52317e1beeeac0b1.zip external_llvm-9200e81a1828f7d3aa59a48c52317e1beeeac0b1.tar.gz external_llvm-9200e81a1828f7d3aa59a48c52317e1beeeac0b1.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/UnreachableBlockElim.cpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp index f1e3aab..57811ca 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<MachineBasicBlock*> 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<MachineBasicBlock*, 8> 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(); |