diff options
author | Max Kazantsev <max.kazantsev@azul.com> | 2019-02-08 08:12:41 +0000 |
---|---|---|
committer | Max Kazantsev <max.kazantsev@azul.com> | 2019-02-08 08:12:41 +0000 |
commit | 6b63d3a27709e8b9165b77819cb21696791339e6 (patch) | |
tree | 2f56ad74e044ec3b6b1a28c8b4c3499aed2f35bd /llvm/lib/Transforms/Scalar | |
parent | 5b09834bc364313e48cc54dccd8f251232d84b65 (diff) | |
download | bcm5719-llvm-6b63d3a27709e8b9165b77819cb21696791339e6.tar.gz bcm5719-llvm-6b63d3a27709e8b9165b77819cb21696791339e6.zip |
[LoopSimplifyCFG] Use DTU.applyUpdates instead of insert/deleteEdge
`insert/deleteEdge` methods in DTU can make updates incorrectly in some cases
(see https://bugs.llvm.org/show_bug.cgi?id=40528), and it is recommended to
use `applyUpdates` methods instead when it is needed to make a mass update in CFG.
Differential Revision: https://reviews.llvm.org/D57316
Reviewed By: kuhar
llvm-svn: 353502
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp index dbe68d00c50..01d770ca515 100644 --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -89,6 +89,8 @@ private: DominatorTree &DT; ScalarEvolution &SE; MemorySSAUpdater *MSSAU; + DomTreeUpdater DTU; + SmallVector<DominatorTree::UpdateType, 16> DTUpdates; // Whether or not the current loop has irreducible CFG. bool HasIrreducibleCFG = false; @@ -319,14 +321,13 @@ private: // Construct split preheader and the dummy switch to thread edges from it to // dead exits. - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); BasicBlock *Preheader = L.getLoopPreheader(); BasicBlock *NewPreheader = Preheader->splitBasicBlock( Preheader->getTerminator(), Twine(Preheader->getName()).concat("-split")); - DTU.deleteEdge(Preheader, L.getHeader()); - DTU.insertEdge(NewPreheader, L.getHeader()); - DTU.insertEdge(Preheader, NewPreheader); + DTUpdates.push_back({DominatorTree::Delete, Preheader, L.getHeader()}); + DTUpdates.push_back({DominatorTree::Insert, NewPreheader, L.getHeader()}); + DTUpdates.push_back({DominatorTree::Insert, Preheader, NewPreheader}); IRBuilder<> Builder(Preheader->getTerminator()); SwitchInst *DummySwitch = Builder.CreateSwitch(Builder.getInt32(0), NewPreheader); @@ -345,7 +346,7 @@ private: } assert(DummyIdx != 0 && "Too many dead exits!"); DummySwitch->addCase(Builder.getInt32(DummyIdx++), BB); - DTU.insertEdge(Preheader, BB); + DTUpdates.push_back({DominatorTree::Insert, Preheader, BB}); ++NumLoopExitsDeleted; } @@ -389,6 +390,9 @@ private: while (FixLCSSALoop->getParentLoop() != StillReachable) FixLCSSALoop = FixLCSSALoop->getParentLoop(); assert(FixLCSSALoop && "Should be a loop!"); + // We need all DT updates to be done before forming LCSSA. + DTU.applyUpdates(DTUpdates); + DTUpdates.clear(); formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE); } } @@ -397,7 +401,6 @@ private: /// Delete loop blocks that have become unreachable after folding. Make all /// relevant updates to DT and LI. void deleteDeadLoopBlocks() { - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); if (MSSAU) { SmallPtrSet<BasicBlock *, 8> DeadLoopBlocksSet(DeadLoopBlocks.begin(), DeadLoopBlocks.end()); @@ -415,15 +418,18 @@ private: LI.removeBlock(BB); } - DeleteDeadBlocks(DeadLoopBlocks, &DTU); + DetatchDeadBlocks(DeadLoopBlocks, &DTUpdates); + DTU.applyUpdates(DTUpdates); + DTUpdates.clear(); + for (auto *BB : DeadLoopBlocks) + BB->eraseFromParent(); + NumLoopBlocksDeleted += DeadLoopBlocks.size(); } /// Constant-fold terminators of blocks acculumated in FoldCandidates into the /// unconditional branches. void foldTerminators() { - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); - for (BasicBlock *BB : FoldCandidates) { assert(LI.getLoopFor(BB) == &L && "Should be a loop block!"); BasicBlock *TheOnlySucc = getOnlyLiveSuccessor(BB); @@ -465,7 +471,7 @@ private: Term->eraseFromParent(); for (auto *DeadSucc : DeadSuccessors) - DTU.deleteEdge(BB, DeadSucc); + DTUpdates.push_back({DominatorTree::Delete, BB, DeadSucc}); ++NumTerminatorsFolded; } @@ -475,7 +481,8 @@ public: ConstantTerminatorFoldingImpl(Loop &L, LoopInfo &LI, DominatorTree &DT, ScalarEvolution &SE, MemorySSAUpdater *MSSAU) - : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU) {} + : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU), + DTU(DT, DomTreeUpdater::UpdateStrategy::Eager) {} bool run() { assert(L.getLoopLatch() && "Should be single latch!"); @@ -539,6 +546,10 @@ public: << " dead blocks in loop " << L.getHeader()->getName() << "\n"); deleteDeadLoopBlocks(); + } else { + // If we didn't do updates inside deleteDeadLoopBlocks, do them here. + DTU.applyUpdates(DTUpdates); + DTUpdates.clear(); } #ifndef NDEBUG |