diff options
author | Max Kazantsev <max.kazantsev@azul.com> | 2018-12-06 05:45:02 +0000 |
---|---|---|
committer | Max Kazantsev <max.kazantsev@azul.com> | 2018-12-06 05:45:02 +0000 |
commit | 0b1d069d64a394e81baf7ed022f44323095389c9 (patch) | |
tree | 9dcdcdfed929e7d67cdf56cf841cde0fa2ceb1c6 /llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp | |
parent | ca8631ba6efda542476425891a43b8f1d52f3d0f (diff) | |
download | bcm5719-llvm-0b1d069d64a394e81baf7ed022f44323095389c9.tar.gz bcm5719-llvm-0b1d069d64a394e81baf7ed022f44323095389c9.zip |
[LoopSimplifyCFG] Delete dead in-loop blocks
This patch teaches LoopSimplifyCFG to delete loop blocks that have
become unreachable after terminator folding has been done.
Differential Revision: https://reviews.llvm.org/D54023
Reviewed By: anna
llvm-svn: 348457
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp index 3de701e7887..9d5b33e6343 100644 --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -46,6 +46,8 @@ static cl::opt<bool> EnableTermFolding("enable-loop-simplifycfg-term-folding", STATISTIC(NumTerminatorsFolded, "Number of terminators folded to unconditional branches"); +STATISTIC(NumLoopBlocksDeleted, + "Number of loop blocks deleted"); /// If \p BB is a switch or a conditional branch, but only one of its successors /// can be reached from this block in runtime, return this successor. Otherwise, @@ -234,6 +236,27 @@ private: "All blocks that stay in loop should be live!"); } + /// 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) + MSSAU->removeBlocks(DeadLoopBlocks); + for (auto *BB : DeadLoopBlocks) { + assert(BB != L.getHeader() && + "Header of the current loop cannot be dead!"); + LLVM_DEBUG(dbgs() << "Deleting dead loop block " << BB->getName() + << "\n"); + if (LI.isLoopHeader(BB)) { + assert(LI.getLoopFor(BB) != &L && "Attempt to remove current loop!"); + LI.erase(LI.getLoopFor(BB)); + } + LI.removeBlock(BB); + DeleteDeadBlock(BB, &DTU); + ++NumLoopBlocksDeleted; + } + } + /// Constant-fold terminators of blocks acculumated in FoldCandidates into the /// unconditional branches. void foldTerminators() { @@ -318,15 +341,6 @@ public: return false; } - // TODO: Support deletion of dead loop blocks. - if (!DeadLoopBlocks.empty()) { - LLVM_DEBUG(dbgs() << "Give up constant terminator folding in loop " - << L.getHeader()->getName() - << ": we don't currently" - " support deletion of dead in-loop blocks.\n"); - return false; - } - // TODO: Support dead loop exits. if (!DeadExitBlocks.empty()) { LLVM_DEBUG(dbgs() << "Give up constant terminator folding in loop " @@ -337,7 +351,8 @@ public: // TODO: Support blocks that are not dead, but also not in loop after the // folding. - if (BlocksInLoopAfterFolding.size() != L.getNumBlocks()) { + if (BlocksInLoopAfterFolding.size() + DeadLoopBlocks.size() != + L.getNumBlocks()) { LLVM_DEBUG( dbgs() << "Give up constant terminator folding in loop " << L.getHeader()->getName() @@ -357,6 +372,13 @@ public: // Make the actual transforms. foldTerminators(); + if (!DeadLoopBlocks.empty()) { + LLVM_DEBUG(dbgs() << "Deleting " << DeadLoopBlocks.size() + << " dead blocks in loop " << L.getHeader()->getName() + << "\n"); + deleteDeadLoopBlocks(); + } + #ifndef NDEBUG // Make sure that we have preserved all data structures after the transform. DT.verify(); |