From 27405efdc0bb030931b31ebf13b8e8b68985d32e Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 17 Jul 2008 19:42:29 +0000 Subject: [PATCH] Make MergeBlockIntoPredecessor more aggressive when the same successor appears more than once. llvm-svn: 53731 --- .../llvm/Transforms/Utils/BasicBlockUtils.h | 2 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h index f1a7a2641766..5b367015afa4 100644 --- a/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -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. diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 02eb4d6f60a6..d889422992b3 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -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(&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()) {