diff options
author | Michael Zolotukhin <mzolotukhin@apple.com> | 2016-04-06 21:47:12 +0000 |
---|---|---|
committer | Michael Zolotukhin <mzolotukhin@apple.com> | 2016-04-06 21:47:12 +0000 |
commit | 97567e141e85aa26ac4df7ceda15a31ed034409e (patch) | |
tree | d07efb40d5b6cfdcedf0ebe2e598f5e86aeae772 /llvm/lib | |
parent | c916204a81ea85b51c1469c4858b13a452fde4c0 (diff) | |
download | bcm5719-llvm-97567e141e85aa26ac4df7ceda15a31ed034409e.tar.gz bcm5719-llvm-97567e141e85aa26ac4df7ceda15a31ed034409e.zip |
[LoopUnroll] Fix the way we update DT after complete unrolling.
Updating dominators for exit-blocks of the unrolled loops is not enough,
as shown in PR27157. The proper way is to update dominators for all
dominance-children of original loop blocks.
llvm-svn: 265605
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnroll.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp index 20822df819d..e9840424354 100644 --- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp @@ -262,6 +262,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool CompletelyUnroll = Count == TripCount; SmallVector<BasicBlock *, 4> ExitBlocks; L->getExitBlocks(ExitBlocks); + std::vector<BasicBlock*> OriginalLoopBlocks = L->getBlocks(); // Go through all exits of L and see if there are any phi-nodes there. We just // conservatively assume that they're inserted to preserve LCSSA form, which @@ -551,20 +552,24 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, Term->eraseFromParent(); } } - // Update dominators of loop exit blocks. - // Immediate dominator of an exit block might change, because we add more + // Update dominators of blocks we might reach through exits. + // Immediate dominator of such block might change, because we add more // routes which can lead to the exit: we can now reach it from the copied - // iterations too. Thus, the new idom of the exit block will be the nearest + // iterations too. Thus, the new idom of the block will be the nearest // common dominator of the previous idom and common dominator of all copies of - // the exiting block. This is equivalent to the nearest common dominator of + // the previous idom. This is equivalent to the nearest common dominator of // the previous idom and the first latch, which dominates all copies of the - // exiting block. + // previous idom. if (DT && Count > 1) { - for (auto Exit : ExitBlocks) { - BasicBlock *PrevIDom = DT->getNode(Exit)->getIDom()->getBlock(); - BasicBlock *NewIDom = - DT->findNearestCommonDominator(PrevIDom, Latches[0]); - DT->changeImmediateDominator(Exit, NewIDom); + for (auto *BB : OriginalLoopBlocks) { + auto *BBDomNode = DT->getNode(BB); + for (auto *ChildDomNode : BBDomNode->getChildren()) { + auto *ChildBB = ChildDomNode->getBlock(); + if (L->contains(ChildBB)) + continue; + BasicBlock *NewIDom = DT->findNearestCommonDominator(BB, Latches[0]); + DT->changeImmediateDominator(ChildBB, NewIDom); + } } } |