mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-06 03:38:34 +00:00
[Dominators] Make RemoveUnreachableBlocks return false if the BasicBlock is already awaiting deletion
Summary: Previously, `removeUnreachableBlocks` still returns true (which indicates the CFG is changed) even when all the unreachable blocks found is awaiting deletion in the DDT class. This makes code pattern like ``` // Code modified from lib/Transforms/Scalar/SimplifyCFGPass.cpp bool EverChanged = removeUnreachableBlocks(F, nullptr, DDT); ... do { EverChanged = someMightHappenModifications(); EverChanged |= removeUnreachableBlocks(F, nullptr, DDT); } while (EverChanged); ``` become a dead loop. Fix this by detecting whether a BasicBlock is already awaiting deletion. Reviewers: kuhar, brzycki, dmgreen, grosser, davide Reviewed By: kuhar, brzycki Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D49738 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338882 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
614e6127d2
commit
1a16c79be0
@ -2264,8 +2264,16 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI,
|
|||||||
|
|
||||||
if (DTU) {
|
if (DTU) {
|
||||||
DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true);
|
DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true);
|
||||||
for (auto *BB : ToDeleteBBs)
|
bool Deleted = false;
|
||||||
|
for (auto *BB : ToDeleteBBs) {
|
||||||
|
if (DTU->isBBPendingDeletion(BB))
|
||||||
|
--NumRemoved;
|
||||||
|
else
|
||||||
|
Deleted = true;
|
||||||
DTU->deleteBB(BB);
|
DTU->deleteBB(BB);
|
||||||
|
}
|
||||||
|
if (!Deleted)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -844,4 +844,23 @@ TEST(Local, RemoveUnreachableBlocks) {
|
|||||||
runWithDomTree(*M, "br_self_loop", runLazy);
|
runWithDomTree(*M, "br_self_loop", runLazy);
|
||||||
runWithDomTree(*M, "br_constant", runLazy);
|
runWithDomTree(*M, "br_constant", runLazy);
|
||||||
runWithDomTree(*M, "br_loop", runLazy);
|
runWithDomTree(*M, "br_loop", runLazy);
|
||||||
|
|
||||||
|
M = parseIR(C,
|
||||||
|
R"(
|
||||||
|
define void @f() {
|
||||||
|
entry:
|
||||||
|
ret void
|
||||||
|
bb0:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
auto checkRUBlocksRetVal = [&](Function &F, DominatorTree *DT) {
|
||||||
|
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
|
||||||
|
EXPECT_TRUE(removeUnreachableBlocks(F, nullptr, &DTU));
|
||||||
|
EXPECT_FALSE(removeUnreachableBlocks(F, nullptr, &DTU));
|
||||||
|
EXPECT_TRUE(DTU.getDomTree().verify());
|
||||||
|
};
|
||||||
|
|
||||||
|
runWithDomTree(*M, "f", checkRUBlocksRetVal);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user