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);
|
||||
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
|
||||
// the loop into the preheader we've simplified instructions and the
|
||||
// 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()) !=
|
||||
NewHeader) {
|
||||
// The conditional branch can't be folded, handle the general case.
|
||||
// Update DominatorTree to reflect the CFG change we just made. Then split
|
||||
// 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);
|
||||
}
|
||||
// Split edges as necessary to preserve LoopSimplify form.
|
||||
|
||||
// Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
|
||||
// thus is not a preheader anymore.
|
||||
|
@ -467,52 +459,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
|||
PHBI->eraseFromParent();
|
||||
|
||||
// With our CFG finalized, update DomTree if it is available.
|
||||
if (DT) {
|
||||
// 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);
|
||||
}
|
||||
if (DT) DT->deleteEdge(OrigPreheader, Exit);
|
||||
}
|
||||
|
||||
assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
|
||||
|
|
Loading…
Reference in New Issue