forked from OSchip/llvm-project
[LoopRotate][Dominators] Use the incremental API to update DomTree
Summary: This patch teaches LoopRotate to use the new incremental API to update the DominatorTree. Reviewers: dberlin, davide, grosser, sanjoy Reviewed By: dberlin, davide Subscribers: hiraditya, llvm-commits, mzolotukhin Differential Revision: https://reviews.llvm.org/D35581 llvm-svn: 311125
This commit is contained in:
parent
6e07bfd0d9
commit
e608ef7635
|
@ -395,6 +395,17 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||||
L->moveToHeader(NewHeader);
|
L->moveToHeader(NewHeader);
|
||||||
assert(L->getHeader() == NewHeader && "Latch block is our new header");
|
assert(L->getHeader() == NewHeader && "Latch block is our new header");
|
||||||
|
|
||||||
|
// Inform DT about changes to the CFG.
|
||||||
|
if (DT) {
|
||||||
|
// The OrigPreheader branches to the NewHeader and Exit now. Then, inform
|
||||||
|
// the DT about the removed edge to the OrigHeader (that got removed).
|
||||||
|
SmallVector<DominatorTree::UpdateType, 3> Updates;
|
||||||
|
Updates.push_back({DominatorTree::Insert, OrigPreheader, Exit});
|
||||||
|
Updates.push_back({DominatorTree::Insert, OrigPreheader, NewHeader});
|
||||||
|
Updates.push_back({DominatorTree::Delete, OrigPreheader, OrigHeader});
|
||||||
|
DT->applyUpdates(Updates);
|
||||||
|
}
|
||||||
|
|
||||||
// At this point, we've finished our major CFG changes. As part of cloning
|
// At this point, we've finished our major CFG changes. As part of cloning
|
||||||
// the loop into the preheader we've simplified instructions and the
|
// the loop into the preheader we've simplified instructions and the
|
||||||
// duplicated conditional branch may now be branching on a constant. If it is
|
// duplicated conditional branch may now be branching on a constant. If it is
|
||||||
|
@ -408,26 +419,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||||
PHBI->getSuccessor(cast<ConstantInt>(PHBI->getCondition())->isZero()) !=
|
PHBI->getSuccessor(cast<ConstantInt>(PHBI->getCondition())->isZero()) !=
|
||||||
NewHeader) {
|
NewHeader) {
|
||||||
// The conditional branch can't be folded, handle the general case.
|
// The conditional branch can't be folded, handle the general case.
|
||||||
// Update DominatorTree to reflect the CFG change we just made. Then split
|
// Split edges as necessary to preserve LoopSimplify form.
|
||||||
// edges as necessary to preserve LoopSimplify form.
|
|
||||||
if (DT) {
|
|
||||||
// Everything that was dominated by the old loop header is now dominated
|
|
||||||
// by the original loop preheader. Conceptually the header was merged
|
|
||||||
// into the preheader, even though we reuse the actual block as a new
|
|
||||||
// loop latch.
|
|
||||||
DomTreeNode *OrigHeaderNode = DT->getNode(OrigHeader);
|
|
||||||
SmallVector<DomTreeNode *, 8> HeaderChildren(OrigHeaderNode->begin(),
|
|
||||||
OrigHeaderNode->end());
|
|
||||||
DomTreeNode *OrigPreheaderNode = DT->getNode(OrigPreheader);
|
|
||||||
for (unsigned I = 0, E = HeaderChildren.size(); I != E; ++I)
|
|
||||||
DT->changeImmediateDominator(HeaderChildren[I], OrigPreheaderNode);
|
|
||||||
|
|
||||||
assert(DT->getNode(Exit)->getIDom() == OrigPreheaderNode);
|
|
||||||
assert(DT->getNode(NewHeader)->getIDom() == OrigPreheaderNode);
|
|
||||||
|
|
||||||
// Update OrigHeader to be dominated by the new header block.
|
|
||||||
DT->changeImmediateDominator(OrigHeader, OrigLatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
|
// Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
|
||||||
// thus is not a preheader anymore.
|
// thus is not a preheader anymore.
|
||||||
|
@ -467,52 +459,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||||
PHBI->eraseFromParent();
|
PHBI->eraseFromParent();
|
||||||
|
|
||||||
// With our CFG finalized, update DomTree if it is available.
|
// With our CFG finalized, update DomTree if it is available.
|
||||||
if (DT) {
|
if (DT) DT->deleteEdge(OrigPreheader, Exit);
|
||||||
// Update OrigHeader to be dominated by the new header block.
|
|
||||||
DT->changeImmediateDominator(NewHeader, OrigPreheader);
|
|
||||||
DT->changeImmediateDominator(OrigHeader, OrigLatch);
|
|
||||||
|
|
||||||
// Brute force incremental dominator tree update. Call
|
|
||||||
// findNearestCommonDominator on all CFG predecessors of each child of the
|
|
||||||
// original header.
|
|
||||||
DomTreeNode *OrigHeaderNode = DT->getNode(OrigHeader);
|
|
||||||
SmallVector<DomTreeNode *, 8> HeaderChildren(OrigHeaderNode->begin(),
|
|
||||||
OrigHeaderNode->end());
|
|
||||||
bool Changed;
|
|
||||||
do {
|
|
||||||
Changed = false;
|
|
||||||
for (unsigned I = 0, E = HeaderChildren.size(); I != E; ++I) {
|
|
||||||
DomTreeNode *Node = HeaderChildren[I];
|
|
||||||
BasicBlock *BB = Node->getBlock();
|
|
||||||
|
|
||||||
BasicBlock *NearestDom = nullptr;
|
|
||||||
for (BasicBlock *Pred : predecessors(BB)) {
|
|
||||||
// Consider only reachable basic blocks.
|
|
||||||
if (!DT->getNode(Pred))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!NearestDom) {
|
|
||||||
NearestDom = Pred;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NearestDom = DT->findNearestCommonDominator(NearestDom, Pred);
|
|
||||||
assert(NearestDom && "No NearestCommonDominator found");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(NearestDom && "Nearest dominator not found");
|
|
||||||
|
|
||||||
// Remember if this changes the DomTree.
|
|
||||||
if (Node->getIDom()->getBlock() != NearestDom) {
|
|
||||||
DT->changeImmediateDominator(BB, NearestDom);
|
|
||||||
Changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the dominator changed, this may have an effect on other
|
|
||||||
// predecessors, continue until we reach a fixpoint.
|
|
||||||
} while (Changed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
|
assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
|
||||||
|
|
Loading…
Reference in New Issue