Make MergeBlockIntoPredecessor more aggressive when the same successor appears

more than once.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53731 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2008-07-17 19:42:29 +00:00
parent c2b856e5b4
commit 11f2ec8eb5
2 changed files with 25 additions and 6 deletions

View File

@ -27,7 +27,7 @@ class Pass;
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure. /// if possible. The return value indicates success or failure.
bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P); bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0);
// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI) // ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
// with a value, then remove and delete the original instruction. // with a value, then remove and delete the original instruction.

View File

@ -26,15 +26,30 @@ using namespace llvm;
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure. /// if possible. The return value indicates success or failure.
bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) { bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
// Can't merge the entry block. // Can't merge the entry block.
if (pred_begin(BB) == pred_end(BB)) return false; if (pred_begin(BB) == pred_end(BB)) return false;
// Can't merge if there are multiple preds.
if (++pred_begin(BB) != pred_end(BB)) return false;
BasicBlock* PredBB = *pred_begin(BB); BasicBlock *PredBB = *PI++;
for (; PI != PE; ++PI) // Search all predecessors, see if they are all same
if (*PI != PredBB) {
PredBB = 0; // There are multiple different predecessors...
break;
}
// Can't merge if the edge is critical. // Can't merge if there are multiple predecessors.
if (PredBB->getTerminator()->getNumSuccessors() != 1) return false; if (!PredBB) return false;
succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
BasicBlock* OnlySucc = BB;
for (; SI != SE; ++SI)
if (*SI != OnlySucc) {
OnlySucc = 0; // There are multiple distinct successors!
break;
}
// Can't merge if there are multiple successors.
if (!OnlySucc) return false;
// Begin by getting rid of unneeded PHIs. // Begin by getting rid of unneeded PHIs.
while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) { while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
@ -52,6 +67,10 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
// source... // source...
BB->replaceAllUsesWith(PredBB); BB->replaceAllUsesWith(PredBB);
// Inherit predecessors name if it exists.
if (!PredBB->hasName())
PredBB->takeName(BB);
// Finally, erase the old block and update dominator info. // Finally, erase the old block and update dominator info.
if (P) { if (P) {
if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) { if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {