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 | c6d527067b9d23dda51bb5fd2fefd2fc19889b26 (patch) | |
tree | f186d820fff3c77ca413738be05c15828e9ebe46 /llvm/lib | |
parent | ec8f5eb5aee7bd955ea91ff8a5081edc44fd9d97 (diff) | |
download | bcm5719-llvm-c6d527067b9d23dda51bb5fd2fefd2fc19889b26.tar.gz bcm5719-llvm-c6d527067b9d23dda51bb5fd2fefd2fc19889b26.zip |
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.
llvm-svn: 54432
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/UnreachableBlockElim.cpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/UnreachableBlockElim.cpp b/llvm/lib/CodeGen/UnreachableBlockElim.cpp index f1e3aabaebe..57811cab0f6 100644 --- a/llvm/lib/CodeGen/UnreachableBlockElim.cpp +++ b/llvm/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(); |