Make MergeBlockIntoPredecessor more aggressive when the same successor appears

more than once.

llvm-svn: 53731
This commit is contained in:
Owen Anderson 2008-07-17 19:42:29 +00:00
parent addbe3eed1
commit 27405efdc0
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,
/// 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)
// 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,
/// if possible. The return value indicates success or failure.
bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
// Can't merge the entry block.
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.
if (PredBB->getTerminator()->getNumSuccessors() != 1) return false;
// Can't merge if there are multiple predecessors.
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.
while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
@ -52,6 +67,10 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
// source...
BB->replaceAllUsesWith(PredBB);
// Inherit predecessors name if it exists.
if (!PredBB->hasName())
PredBB->takeName(BB);
// Finally, erase the old block and update dominator info.
if (P) {
if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {