forked from OSchip/llvm-project
Update domtree incrementally in loop peeling.
With this change dominator tree remains in sync after each step of loop peeling. Differential Revision: https://reviews.llvm.org/D29029 llvm-svn: 292895
This commit is contained in:
parent
fc8798fa1b
commit
098ee2fe02
|
@ -165,7 +165,8 @@ static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop,
|
||||||
BasicBlock *InsertBot, BasicBlock *Exit,
|
BasicBlock *InsertBot, BasicBlock *Exit,
|
||||||
SmallVectorImpl<BasicBlock *> &NewBlocks,
|
SmallVectorImpl<BasicBlock *> &NewBlocks,
|
||||||
LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
|
LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
|
||||||
ValueToValueMapTy &LVMap, LoopInfo *LI) {
|
ValueToValueMapTy &LVMap, DominatorTree *DT,
|
||||||
|
LoopInfo *LI) {
|
||||||
|
|
||||||
BasicBlock *Header = L->getHeader();
|
BasicBlock *Header = L->getHeader();
|
||||||
BasicBlock *Latch = L->getLoopLatch();
|
BasicBlock *Latch = L->getLoopLatch();
|
||||||
|
@ -186,6 +187,17 @@ static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop,
|
||||||
ParentLoop->addBasicBlockToLoop(NewBB, *LI);
|
ParentLoop->addBasicBlockToLoop(NewBB, *LI);
|
||||||
|
|
||||||
VMap[*BB] = NewBB;
|
VMap[*BB] = NewBB;
|
||||||
|
|
||||||
|
// If dominator tree is available, insert nodes to represent cloned blocks.
|
||||||
|
if (DT) {
|
||||||
|
if (Header == *BB)
|
||||||
|
DT->addNewBlock(NewBB, InsertTop);
|
||||||
|
else {
|
||||||
|
DomTreeNode *IDom = DT->getNode(*BB)->getIDom();
|
||||||
|
// VMap must contain entry for IDom, as the iteration order is RPO.
|
||||||
|
DT->addNewBlock(NewBB, cast<BasicBlock>(VMap[IDom->getBlock()]));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook-up the control flow for the newly inserted blocks.
|
// Hook-up the control flow for the newly inserted blocks.
|
||||||
|
@ -199,11 +211,13 @@ static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop,
|
||||||
// The backedge now goes to the "bottom", which is either the loop's real
|
// The backedge now goes to the "bottom", which is either the loop's real
|
||||||
// header (for the last peeled iteration) or the copied header of the next
|
// header (for the last peeled iteration) or the copied header of the next
|
||||||
// iteration (for every other iteration)
|
// iteration (for every other iteration)
|
||||||
BranchInst *LatchBR =
|
BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
|
||||||
cast<BranchInst>(cast<BasicBlock>(VMap[Latch])->getTerminator());
|
BranchInst *LatchBR = cast<BranchInst>(NewLatch->getTerminator());
|
||||||
unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
|
unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
|
||||||
LatchBR->setSuccessor(HeaderIdx, InsertBot);
|
LatchBR->setSuccessor(HeaderIdx, InsertBot);
|
||||||
LatchBR->setSuccessor(1 - HeaderIdx, Exit);
|
LatchBR->setSuccessor(1 - HeaderIdx, Exit);
|
||||||
|
if (DT)
|
||||||
|
DT->changeImmediateDominator(InsertBot, NewLatch);
|
||||||
|
|
||||||
// The new copy of the loop body starts with a bunch of PHI nodes
|
// The new copy of the loop body starts with a bunch of PHI nodes
|
||||||
// that pick an incoming value from either the preheader, or the previous
|
// that pick an incoming value from either the preheader, or the previous
|
||||||
|
@ -359,7 +373,19 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
|
||||||
CurHeaderWeight = 1;
|
CurHeaderWeight = 1;
|
||||||
|
|
||||||
cloneLoopBlocks(L, Iter, InsertTop, InsertBot, Exit,
|
cloneLoopBlocks(L, Iter, InsertTop, InsertBot, Exit,
|
||||||
NewBlocks, LoopBlocks, VMap, LVMap, LI);
|
NewBlocks, LoopBlocks, VMap, LVMap, DT, LI);
|
||||||
|
if (DT) {
|
||||||
|
// Latches of the cloned loops dominate over the loop exit, so idom of the
|
||||||
|
// latter is the first cloned loop body, as original PreHeader dominates
|
||||||
|
// the original loop body.
|
||||||
|
if (Iter == 0)
|
||||||
|
DT->changeImmediateDominator(Exit, cast<BasicBlock>(LVMap[Latch]));
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (VerifyDomInfo)
|
||||||
|
DT->verifyDomTree();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
updateBranchWeights(InsertBot, cast<BranchInst>(VMap[LatchBR]), Iter,
|
updateBranchWeights(InsertBot, cast<BranchInst>(VMap[LatchBR]), Iter,
|
||||||
PeelCount, ExitWeight);
|
PeelCount, ExitWeight);
|
||||||
|
|
||||||
|
@ -405,9 +431,6 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
|
||||||
LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
|
LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Incrementally update domtree.
|
|
||||||
DT->recalculate(*L->getHeader()->getParent());
|
|
||||||
|
|
||||||
// If the loop is nested, we changed the parent loop, update SE.
|
// If the loop is nested, we changed the parent loop, update SE.
|
||||||
if (Loop *ParentLoop = L->getParentLoop()) {
|
if (Loop *ParentLoop = L->getParentLoop()) {
|
||||||
SE->forgetLoop(ParentLoop);
|
SE->forgetLoop(ParentLoop);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=3 -simplifycfg -instcombine | FileCheck %s
|
; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=3 -verify-dom-info -simplifycfg -instcombine | FileCheck %s
|
||||||
|
|
||||||
; Basic loop peeling - check that we can peel-off the first 3 loop iterations
|
; Basic loop peeling - check that we can peel-off the first 3 loop iterations
|
||||||
; when explicitly requested.
|
; when explicitly requested.
|
||||||
|
|
Loading…
Reference in New Issue