diff options
Diffstat (limited to 'lib/Transforms/Utils')
| -rw-r--r-- | lib/Transforms/Utils/BreakCriticalEdges.cpp | 43 | 
1 files changed, 29 insertions, 14 deletions
| diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp index f752d7981c5fa..2a8e9b834e310 100644 --- a/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -117,33 +117,38 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,    return false;  } -/// CreatePHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form +/// createPHIsForSplitLoopExit - When a loop exit edge is split, LCSSA form  /// may require new PHIs in the new exit block. This function inserts the -/// new PHIs, as needed.  Preds is a list of preds inside the loop, SplitBB +/// new PHIs, as needed. Preds is a list of preds inside the loop, SplitBB  /// is the new loop exit block, and DestBB is the old loop exit, now the  /// successor of SplitBB. -static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds, +static void createPHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds,                                         BasicBlock *SplitBB,                                         BasicBlock *DestBB) {    // SplitBB shouldn't have anything non-trivial in it yet. -  assert(SplitBB->getFirstNonPHI() == SplitBB->getTerminator() && -         "SplitBB has non-PHI nodes!"); +  assert((SplitBB->getFirstNonPHI() == SplitBB->getTerminator() || +          SplitBB->isLandingPad()) && "SplitBB has non-PHI nodes!"); -  // For each PHI in the destination block... +  // For each PHI in the destination block.    for (BasicBlock::iterator I = DestBB->begin();         PHINode *PN = dyn_cast<PHINode>(I); ++I) {      unsigned Idx = PN->getBasicBlockIndex(SplitBB);      Value *V = PN->getIncomingValue(Idx); +      // If the input is a PHI which already satisfies LCSSA, don't create      // a new one.      if (const PHINode *VP = dyn_cast<PHINode>(V))        if (VP->getParent() == SplitBB)          continue; +      // Otherwise a new PHI is needed. Create one and populate it. -    PHINode *NewPN = PHINode::Create(PN->getType(), Preds.size(), "split", -                                     SplitBB->getTerminator()); +    PHINode *NewPN = +      PHINode::Create(PN->getType(), Preds.size(), "split", +                      SplitBB->isLandingPad() ? +                      SplitBB->begin() : SplitBB->getTerminator());      for (unsigned i = 0, e = Preds.size(); i != e; ++i)        NewPN->addIncoming(V, Preds[i]); +      // Update the original PHI.      PN->setIncomingValue(Idx, NewPN);    } @@ -168,7 +173,8 @@ static void CreatePHIsForSplitLoopExit(SmallVectorImpl<BasicBlock *> &Preds,  ///  BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,                                      Pass *P, bool MergeIdenticalEdges, -                                    bool DontDeleteUselessPhis) { +                                    bool DontDeleteUselessPhis, +                                    bool SplitLandingPads) {    if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0;    assert(!isa<IndirectBrInst>(TI) && @@ -338,7 +344,7 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,          if (P->mustPreserveAnalysisID(LCSSAID)) {            SmallVector<BasicBlock *, 1> OrigPred;            OrigPred.push_back(TIBB); -          CreatePHIsForSplitLoopExit(OrigPred, NewBB, DestBB); +          createPHIsForSplitLoopExit(OrigPred, NewBB, DestBB);          }          // For each unique exit block... @@ -371,10 +377,19 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,            // getUniqueExitBlocks above because that depends on LoopSimplify            // form, which we're in the process of restoring!            if (!Preds.empty() && HasPredOutsideOfLoop) { -            BasicBlock *NewExitBB = -              SplitBlockPredecessors(Exit, Preds, "split", P); -            if (P->mustPreserveAnalysisID(LCSSAID)) -              CreatePHIsForSplitLoopExit(Preds, NewExitBB, Exit); +            if (!Exit->isLandingPad()) { +              BasicBlock *NewExitBB = +                SplitBlockPredecessors(Exit, Preds, "split", P); +              if (P->mustPreserveAnalysisID(LCSSAID)) +                createPHIsForSplitLoopExit(Preds, NewExitBB, Exit); +            } else if (SplitLandingPads) { +              SmallVector<BasicBlock*, 8> NewBBs; +              SplitLandingPadPredecessors(Exit, Preds, +                                          ".split1", ".split2", +                                          P, NewBBs); +              if (P->mustPreserveAnalysisID(LCSSAID)) +                createPHIsForSplitLoopExit(Preds, NewBBs[0], Exit); +            }            }          }        } | 
