[llvm] r311125 - [LoopRotate][Dominators] Use the incremental API to update DomTree
Jakub Kuderski via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 17 14:48:19 PDT 2017
Author: kuhar
Date: Thu Aug 17 14:48:19 2017
New Revision: 311125
URL: http://llvm.org/viewvc/llvm-project?rev=311125&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=311125&r1=311124&r2=311125&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Thu Aug 17 14:48:19 2017
@@ -395,6 +395,17 @@ bool LoopRotate::rotateLoop(Loop *L, boo
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, boo
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, boo
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");
More information about the llvm-commits
mailing list