diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 29 | 
1 files changed, 24 insertions, 5 deletions
| diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 02eb4d6f60a..d889422992b 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<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>()) { | 

