diff options
author | Alina Sbirlea <asbirlea@google.com> | 2020-01-21 16:56:39 -0800 |
---|---|---|
committer | Alina Sbirlea <asbirlea@google.com> | 2020-01-22 11:38:38 -0800 |
commit | efb130fc93059bdf02d3a83950ddabc5d119f9de (patch) | |
tree | bf01da5d63078db50663c018f9514d46833236e4 /llvm/lib/Transforms/Utils/LoopUtils.cpp | |
parent | eec36909c18b8788773abc95d199e6acde6eb42c (diff) | |
download | llvm-efb130fc93059bdf02d3a83950ddabc5d119f9de.zip llvm-efb130fc93059bdf02d3a83950ddabc5d119f9de.tar.gz llvm-efb130fc93059bdf02d3a83950ddabc5d119f9de.tar.bz2 |
[LoopDeletion] Teach LoopDeletion to preserve MemorySSA if available.
If MemorySSA analysis is analysis, LoopDeletion now preserves it.
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 88b0f8ef..b1d0c83 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -506,13 +506,16 @@ llvm::collectChildrenInLoop(DomTreeNode *N, const Loop *CurLoop) { return Worklist; } -void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, - ScalarEvolution *SE = nullptr, - LoopInfo *LI = nullptr) { +void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, + LoopInfo *LI, MemorySSA *MSSA) { assert((!DT || L->isLCSSAForm(*DT)) && "Expected LCSSA!"); auto *Preheader = L->getLoopPreheader(); assert(Preheader && "Preheader should exist!"); + std::unique_ptr<MemorySSAUpdater> MSSAU; + if (MSSA) + MSSAU = std::make_unique<MemorySSAUpdater>(MSSA); + // Now that we know the removal is safe, remove the loop by changing the // branch from the preheader to go to the single exit block. // @@ -585,18 +588,33 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, "Should have exactly one value and that's from the preheader!"); } + DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); + if (DT) { + DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}}); + if (MSSA) { + MSSAU->applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}}, *DT); + if (VerifyMemorySSA) + MSSA->verifyMemorySSA(); + } + } + // Disconnect the loop body by branching directly to its exit. Builder.SetInsertPoint(Preheader->getTerminator()); Builder.CreateBr(ExitBlock); // Remove the old branch. Preheader->getTerminator()->eraseFromParent(); - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); if (DT) { - // Update the dominator tree by informing it about the new edge from the - // preheader to the exit and the removed edge. - DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}, - {DominatorTree::Delete, Preheader, L->getHeader()}}); + DTU.applyUpdates({{DominatorTree::Delete, Preheader, L->getHeader()}}); + if (MSSA) { + MSSAU->applyUpdates({{DominatorTree::Delete, Preheader, L->getHeader()}}, + *DT); + if (VerifyMemorySSA) + MSSA->verifyMemorySSA(); + SmallSetVector<BasicBlock *, 8> DeadBlockSet(L->block_begin(), + L->block_end()); + MSSAU->removeBlocks(DeadBlockSet); + } } // Use a map to unique and a vector to guarantee deterministic ordering. @@ -657,6 +675,9 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, for (auto *Block : L->blocks()) Block->dropAllReferences(); + if (MSSA && VerifyMemorySSA) + MSSA->verifyMemorySSA(); + if (LI) { // Erase the instructions and the blocks without having to worry // about ordering because we already dropped the references. |