summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorFedor Sergeev <fedor.sergeev@azul.com>2018-09-04 20:19:41 +0000
committerFedor Sergeev <fedor.sergeev@azul.com>2018-09-04 20:19:41 +0000
commit8b6effd9690024d8138de9c903d88a0c3f706487 (patch)
treeb82c48d08fe2ac9865fffb191afdf2e112132cfe /llvm/lib/Transforms/Scalar
parentc43f006bc22b59b6eb7a906580cf567000d6e41d (diff)
downloadbcm5719-llvm-8b6effd9690024d8138de9c903d88a0c3f706487.tar.gz
bcm5719-llvm-8b6effd9690024d8138de9c903d88a0c3f706487.zip
[SimpleLoopUnswitch] remove a chain of dead blocks at once
Recent change to deleteDeadBlocksFromLoop was not enough to fix all the problems related to dead blocks after nontrivial unswitching of switches. We need to delete all the dead blocks that were created during unswitching, otherwise we will keep having problems with phi's or dead blocks. This change removes all the dead blocks that are reachable from the loop, not trying to track whether these blocks are newly created by unswitching or not. While not completely correct, we are unlikely to get loose but reachable dead blocks that do not belong to our loop nest. It does fix all the failures currently known, in particular PR38778. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D51519 llvm-svn: 341398
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r--llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp38
1 files changed, 19 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index 3cc2c651f6c..57799c8cd8c 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -1378,25 +1378,25 @@ static void
deleteDeadBlocksFromLoop(Loop &L,
SmallVectorImpl<BasicBlock *> &ExitBlocks,
DominatorTree &DT, LoopInfo &LI) {
- // Find all the dead blocks, and remove them from their successors.
- SmallVector<BasicBlock *, 16> DeadBlocks;
- for (BasicBlock *BB : ExitBlocks)
- if (!DT.isReachableFromEntry(BB)) {
- for (BasicBlock *SuccBB : successors(BB))
+ // Find all the dead blocks tied to this loop, and remove them from their
+ // successors.
+ SmallPtrSet<BasicBlock *, 16> DeadBlockSet;
+
+ // Start with loop/exit blocks and get a transitive closure of reachable dead
+ // blocks.
+ SmallVector<BasicBlock *, 16> DeathCandidates(ExitBlocks.begin(),
+ ExitBlocks.end());
+ DeathCandidates.append(L.blocks().begin(), L.blocks().end());
+ while (!DeathCandidates.empty()) {
+ auto *BB = DeathCandidates.pop_back_val();
+ if (!DeadBlockSet.count(BB) && !DT.isReachableFromEntry(BB)) {
+ for (BasicBlock *SuccBB : successors(BB)) {
SuccBB->removePredecessor(BB);
- DeadBlocks.push_back(BB);
- }
-
- for (Loop *ParentL = &L; ParentL; ParentL = ParentL->getParentLoop())
- for (BasicBlock *BB : ParentL->blocks())
- if (!DT.isReachableFromEntry(BB)) {
- for (BasicBlock *SuccBB : successors(BB))
- SuccBB->removePredecessor(BB);
- DeadBlocks.push_back(BB);
+ DeathCandidates.push_back(SuccBB);
}
-
- SmallPtrSet<BasicBlock *, 16> DeadBlockSet(DeadBlocks.begin(),
- DeadBlocks.end());
+ DeadBlockSet.insert(BB);
+ }
+ }
// Filter out the dead blocks from the exit blocks list so that it can be
// used in the caller.
@@ -1405,7 +1405,7 @@ deleteDeadBlocksFromLoop(Loop &L,
// Walk from this loop up through its parents removing all of the dead blocks.
for (Loop *ParentL = &L; ParentL; ParentL = ParentL->getParentLoop()) {
- for (auto *BB : DeadBlocks)
+ for (auto *BB : DeadBlockSet)
ParentL->getBlocksSet().erase(BB);
llvm::erase_if(ParentL->getBlocksVector(),
[&](BasicBlock *BB) { return DeadBlockSet.count(BB); });
@@ -1430,7 +1430,7 @@ deleteDeadBlocksFromLoop(Loop &L,
// Remove the loop mappings for the dead blocks and drop all the references
// from these blocks to others to handle cyclic references as we start
// deleting the blocks themselves.
- for (auto *BB : DeadBlocks) {
+ for (auto *BB : DeadBlockSet) {
// Check that the dominator tree has already been updated.
assert(!DT.getNode(BB) && "Should already have cleared domtree!");
LI.changeLoopFor(BB, nullptr);
OpenPOWER on IntegriCloud