aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Utils
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2008-07-17 19:42:29 +0000
committerOwen Anderson <resistor@mac.com>2008-07-17 19:42:29 +0000
commite03e0059495aa6014549b462028ff9f383d830c8 (patch)
treee413a443d9b2d530977790ca231a68dcf2c48c4d /lib/Transforms/Utils
parent3a0536198e7f0005c1d199ba635f9f9984a7c0f2 (diff)
downloadexternal_llvm-e03e0059495aa6014549b462028ff9f383d830c8.zip
external_llvm-e03e0059495aa6014549b462028ff9f383d830c8.tar.gz
external_llvm-e03e0059495aa6014549b462028ff9f383d830c8.tar.bz2
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
Diffstat (limited to 'lib/Transforms/Utils')
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index 02eb4d6..d889422 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/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<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>()) {