diff options
-rw-r--r-- | lib/Transforms/Scalar/LoopRotation.cpp | 17 | ||||
-rw-r--r-- | lib/Transforms/Utils/BreakCriticalEdges.cpp | 75 | ||||
-rw-r--r-- | test/Transforms/LoopUnswitch/preserve-analyses.ll | 34 |
3 files changed, 86 insertions, 40 deletions
diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index 4b10d1006e..ca394bdc46 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -542,22 +542,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { // Preserve canonical loop form, which means Exit block should // have only one predecessor. - BasicBlock *NExit = SplitEdge(L->getLoopLatch(), Exit, this); - - // Preserve LCSSA. - for (BasicBlock::iterator I = Exit->begin(); - (PN = dyn_cast<PHINode>(I)); ++I) { - unsigned N = PN->getNumIncomingValues(); - for (unsigned index = 0; index != N; ++index) - if (PN->getIncomingBlock(index) == NExit) { - PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName(), - NExit->begin()); - NewPN->addIncoming(PN->getIncomingValue(index), L->getLoopLatch()); - PN->setIncomingValue(index, NewPN); - PN->setIncomingBlock(index, NExit); - break; - } - } + SplitEdge(L->getLoopLatch(), Exit, this); assert(NewHeader && L->getHeader() == NewHeader && "Invalid loop header after loop rotation"); diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp index 5c0afbeece..849b2b5d5c 100644 --- a/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -117,6 +117,38 @@ bool llvm::isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, return false; } +/// 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 +/// is the new loop exit block, and DestBB is the old loop exit, now the +/// successor of SplitBB. +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!"); + + // 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(), "split", + 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); + } +} + /// SplitCriticalEdge - If this edge is a critical edge, insert a new node to /// split the critical edge. This will update DominatorTree and /// DominatorFrontier information if it is available, thus calling this pass @@ -285,6 +317,16 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, // the loop, to maintain a LoopSimplify guarantee. if (!TIL->contains(DestBB) && P->mustPreserveAnalysisID(LoopSimplifyID)) { + assert(!TIL->contains(NewBB) && + "Split point for loop exit is contained in loop!"); + + // Update LCSSA form in the newly created exit block. + if (P->mustPreserveAnalysisID(LCSSAID)) { + SmallVector<BasicBlock *, 1> OrigPred; + OrigPred.push_back(TIBB); + CreatePHIsForSplitLoopExit(OrigPred, NewBB, DestBB); + } + // For each unique exit block... SmallVector<BasicBlock *, 4> ExitBlocks; TIL->getExitBlocks(ExitBlocks); @@ -292,41 +334,26 @@ BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, // Collect all the preds that are inside the loop, and note // whether there are any preds outside the loop. SmallVector<BasicBlock *, 4> Preds; - bool AllPredsInLoop = false; + bool HasPredOutsideOfLoop = false; BasicBlock *Exit = ExitBlocks[i]; for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) if (TIL->contains(*I)) Preds.push_back(*I); else - AllPredsInLoop = true; + HasPredOutsideOfLoop = true; // If there are any preds not in the loop, we'll need to split // the edges. The Preds.empty() check is needed because a block // may appear multiple times in the list. We can't use // getUniqueExitBlocks above because that depends on LoopSimplify // form, which we're in the process of restoring! - if (Preds.empty() || !AllPredsInLoop) continue; - BasicBlock *NewBB = SplitBlockPredecessors(Exit, - Preds.data(), Preds.size(), - "split", P); - // Update LCSSA form by creating new PHIs in the new exit blocks - // as needed. - if (P->mustPreserveAnalysisID(LCSSAID)) - for (BasicBlock::iterator I = Exit->begin(); - PHINode *PN = dyn_cast<PHINode>(I); ++I) { - unsigned Idx = PN->getBasicBlockIndex(NewBB); - Value *V = PN->getIncomingValue(Idx); - // If the PHI is already suitable, don't create a new one. - if (PHINode *VP = dyn_cast<PHINode>(V)) - if (VP->getParent() == NewBB) - continue; - // A new PHI is needed. Create one and populate it. - PHINode *NewPN = - PHINode::Create(PN->getType(), "split", NewBB->getTerminator()); - for (unsigned i = 0, e = Preds.size(); i != e; ++i) - NewPN->addIncoming(V, Preds[i]); - PN->setIncomingValue(Idx, NewPN); - } + if (!Preds.empty() && HasPredOutsideOfLoop) { + BasicBlock *NewExitBB = + SplitBlockPredecessors(Exit, Preds.data(), Preds.size(), + "split", P); + if (P->mustPreserveAnalysisID(LCSSAID)) + CreatePHIsForSplitLoopExit(Preds, NewExitBB, Exit); + } } } // LCSSA form was updated above for the case where LoopSimplify is diff --git a/test/Transforms/LoopUnswitch/preserve-analyses.ll b/test/Transforms/LoopUnswitch/preserve-analyses.ll index 1a0e9e6c87..8d3f1382f3 100644 --- a/test/Transforms/LoopUnswitch/preserve-analyses.ll +++ b/test/Transforms/LoopUnswitch/preserve-analyses.ll @@ -93,3 +93,37 @@ bb6: ; preds = %bb2 return: ; preds = %bb8, %bb ret void } + +; This function requires special handling to preserve LCSSA form. +; PR4934 + +define void @pnp_check_irq() nounwind noredzone { +entry: + %conv56 = trunc i64 undef to i32 ; <i32> [#uses=1] + br label %while.cond.i + +while.cond.i: ; preds = %while.cond.i.backedge, %entry + %call.i25 = call i8* @pci_get_device() nounwind noredzone ; <i8*> [#uses=2] + br i1 undef, label %if.then65, label %while.body.i + +while.body.i: ; preds = %while.cond.i + br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge + +while.cond.i.backedge: ; preds = %if.then31.i.i, %while.body.i + br label %while.cond.i + +if.then31.i.i: ; preds = %while.body.i + switch i32 %conv56, label %while.cond.i.backedge [ + i32 14, label %if.then42.i.i + i32 15, label %if.then42.i.i + ] + +if.then42.i.i: ; preds = %if.then31.i.i, %if.then31.i.i + %call.i25.lcssa48 = phi i8* [ %call.i25, %if.then31.i.i ], [ %call.i25, %if.then31.i.i ] ; <i8*> [#uses=0] + unreachable + +if.then65: ; preds = %while.cond.i + unreachable +} + +declare i8* @pci_get_device() noredzone |