Author: Roman Lebedev Date: 2021-01-12T02:09:47+03:00 New Revision: 90a92f8b4d783cb08443a22f0dd2fa3adcb43807
URL: https://github.com/llvm/llvm-project/commit/90a92f8b4d783cb08443a22f0dd2fa3adcb43807 DIFF: https://github.com/llvm/llvm-project/commit/90a92f8b4d783cb08443a22f0dd2fa3adcb43807.diff LOG: [NFCI][Utils/Local] removeUnreachableBlocks(): cleanup support for lazy DomTreeUpdater When DomTreeUpdater is in lazy update mode, the blocks that were scheduled to be removed, won't be removed until the updates are flushed, e.g. by asking DomTreeUpdater for a up-to-date DomTree. >From the function's current code, it is pretty evident that the support for the lazy mode is an afterthought, see e.g. how we roll-back NumRemoved statistic.. So instead of considering all the unreachable blocks as the blocks-to-be-removed, simply additionally skip all the blocks that are already scheduled to be removed Added: Modified: llvm/lib/Transforms/Utils/Local.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 52e71ad164a5..6e526cc4f105 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2362,33 +2362,40 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU, return Changed; assert(Reachable.size() < F.size()); - NumRemoved += F.size() - Reachable.size(); - SmallSetVector<BasicBlock *, 8> DeadBlockSet; + // Are there any blocks left to actually delete? + SmallSetVector<BasicBlock *, 8> BlocksToRemove; for (BasicBlock &BB : F) { // Skip reachable basic blocks if (Reachable.count(&BB)) continue; - DeadBlockSet.insert(&BB); + // Skip already-deleted blocks + if (DTU && DTU->isBBPendingDeletion(&BB)) + continue; + BlocksToRemove.insert(&BB); } + if (BlocksToRemove.empty()) + return Changed; + + Changed = true; + NumRemoved += BlocksToRemove.size(); + if (MSSAU) - MSSAU->removeBlocks(DeadBlockSet); + MSSAU->removeBlocks(BlocksToRemove); - // Loop over all of the basic blocks that are not reachable, dropping all of + // Loop over all of the basic blocks that are up for removal, dropping all of // their internal references. Update DTU if available. std::vector<DominatorTree::UpdateType> Updates; - for (auto *BB : DeadBlockSet) { + for (auto *BB : BlocksToRemove) { SmallSetVector<BasicBlock *, 8> UniqueSuccessors; for (BasicBlock *Successor : successors(BB)) { - if (!DeadBlockSet.count(Successor)) + // Only remove references to BB in reachable successors of BB. + if (Reachable.count(Successor)) Successor->removePredecessor(BB); if (DTU) UniqueSuccessors.insert(Successor); } - if (DTU) - for (auto *UniqueSuccessor : UniqueSuccessors) - Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor}); BB->dropAllReferences(); if (DTU) { Instruction *TI = BB->getTerminator(); @@ -2401,27 +2408,22 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU, new UnreachableInst(BB->getContext(), BB); assert(succ_empty(BB) && "The successor list of BB isn't empty before " "applying corresponding DTU updates."); + Updates.reserve(Updates.size() + UniqueSuccessors.size()); + for (auto *UniqueSuccessor : UniqueSuccessors) + Updates.push_back({DominatorTree::Delete, BB, UniqueSuccessor}); } } if (DTU) { DTU->applyUpdates(Updates); - bool Deleted = false; - for (auto *BB : DeadBlockSet) { - if (DTU->isBBPendingDeletion(BB)) - --NumRemoved; - else - Deleted = true; + for (auto *BB : BlocksToRemove) DTU->deleteBB(BB); - } - if (!Deleted) - return false; } else { - for (auto *BB : DeadBlockSet) + for (auto *BB : BlocksToRemove) BB->eraseFromParent(); } - return true; + return Changed; } void llvm::combineMetadata(Instruction *K, const Instruction *J, _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits