summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-12-06 05:45:02 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-12-06 05:45:02 +0000
commit0b1d069d64a394e81baf7ed022f44323095389c9 (patch)
tree9dcdcdfed929e7d67cdf56cf841cde0fa2ceb1c6 /llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
parentca8631ba6efda542476425891a43b8f1d52f3d0f (diff)
downloadbcm5719-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.cpp42
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();
OpenPOWER on IntegriCloud