diff options
-rw-r--r-- | include/llvm/Transforms/Utils/BasicBlockUtils.h | 2 | ||||
-rw-r--r-- | lib/Transforms/Utils/BasicBlockUtils.cpp | 29 |
2 files changed, 25 insertions, 6 deletions
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index f1a7a26..5b36701 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/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/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>()) { |