Index: include/llvm/Transforms/Utils/BasicBlockUtils.h =================================================================== --- include/llvm/Transforms/Utils/BasicBlockUtils.h +++ include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -43,6 +43,13 @@ /// Delete the specified block, which must have no predecessors. void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU = nullptr); +/// Delete the specified blocks from \p BB. The set of deleted blocks must have +/// no predecessors that are not being deleted themselves. \p BBs must have no +/// duplicating blocks. If there are loops among this set of blocks, all +/// relevant loop info updates should be done before this function is called. +void DeleteDeadBlocks(SmallVectorImpl &BBs, + DomTreeUpdater *DTU = nullptr); + /// We know that BB has one predecessor. If there are any single-entry PHI nodes /// in it, fold them away. This handles the case when all entries to the PHI /// nodes in a block are guaranteed equal, such as when the block has exactly Index: lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- lib/Transforms/Utils/BasicBlockUtils.cpp +++ lib/Transforms/Utils/BasicBlockUtils.cpp @@ -49,46 +49,57 @@ using namespace llvm; void llvm::DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU) { - assert((pred_begin(BB) == pred_end(BB) || - // Can delete self loop. - BB->getSinglePredecessor() == BB) && "Block is not dead!"); - Instruction *BBTerm = BB->getTerminator(); - std::vector Updates; + SmallVector BBs = {BB}; + DeleteDeadBlocks(BBs, DTU); +} - // Loop through all of our successors and make sure they know that one - // of their predecessors is going away. - if (DTU) - Updates.reserve(BBTerm->getNumSuccessors()); - for (BasicBlock *Succ : successors(BBTerm)) { - Succ->removePredecessor(BB); - if (DTU) - Updates.push_back({DominatorTree::Delete, BB, Succ}); - } +void llvm::DeleteDeadBlocks(SmallVectorImpl &BBs, + DomTreeUpdater *DTU) { +#ifndef NDEBUG + // Make sure that all predecessors of each dead block is also dead. + SmallPtrSet Dead(BBs.begin(), BBs.end()); + assert(Dead.size() == BBs.size() && "Duplicating blocks?"); + for (auto *BB : Dead) + for (BasicBlock *Pred : predecessors(BB)) + assert(Dead.count(Pred) && "All predecessors must be dead!"); +#endif + + SmallVector Updates; + for (auto *BB : BBs) { + // Loop through all of our successors and make sure they know that one + // of their predecessors is going away. + for (BasicBlock *Succ : successors(BB)) { + Succ->removePredecessor(BB); + if (DTU) + Updates.push_back({DominatorTree::Delete, BB, Succ}); + } - // Zap all the instructions in the block. - while (!BB->empty()) { - Instruction &I = BB->back(); - // If this instruction is used, replace uses with an arbitrary value. - // Because control flow can't get here, we don't care what we replace the - // value with. Note that since this block is unreachable, and all values - // contained within it must dominate their uses, that all uses will - // eventually be removed (they are themselves dead). - if (!I.use_empty()) - I.replaceAllUsesWith(UndefValue::get(I.getType())); - BB->getInstList().pop_back(); + // Zap all the instructions in the block. + while (!BB->empty()) { + Instruction &I = BB->back(); + // If this instruction is used, replace uses with an arbitrary value. + // Because control flow can't get here, we don't care what we replace the + // value with. Note that since this block is unreachable, and all values + // contained within it must dominate their uses, that all uses will + // eventually be removed (they are themselves dead). + if (!I.use_empty()) + I.replaceAllUsesWith(UndefValue::get(I.getType())); + BB->getInstList().pop_back(); + } + new UnreachableInst(BB->getContext(), BB); + assert(BB->getInstList().size() == 1 && + isa(BB->getTerminator()) && + "The successor list of BB isn't empty before " + "applying corresponding DTU updates."); } - new UnreachableInst(BB->getContext(), BB); - assert(BB->getInstList().size() == 1 && - isa(BB->getTerminator()) && - "The successor list of BB isn't empty before " - "applying corresponding DTU updates."); - - if (DTU) { + if (DTU) DTU->applyUpdates(Updates, /*ForceRemoveDuplicates*/ true); - DTU->deleteBB(BB); - } else { - BB->eraseFromParent(); // Zap the block! - } + + for (BasicBlock *BB : BBs) + if (DTU) + DTU->deleteBB(BB); + else + BB->eraseFromParent(); } void llvm::FoldSingleEntryPHINodes(BasicBlock *BB,