diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 0de82433be2..881bcffc127 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -26,6 +26,11 @@ class Instruction; class Pass; class AliasAnalysis; +/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no +/// predecessors and not the entry block), delete it and return true. Otherwise +/// return false. +bool DeleteBlockIfDead(BasicBlock *BB); + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0); diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index bd32a99516e..bfcf375f51a 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -24,6 +24,39 @@ #include using namespace llvm; +/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no +/// predecessors and not the entry block), delete it and return true. Otherwise +/// return false. +bool llvm::DeleteBlockIfDead(BasicBlock *BB) { + if (pred_begin(BB) != pred_end(BB) || + BB == &BB->getParent()->getEntryBlock()) + return false; + + TerminatorInst *BBTerm = BB->getTerminator(); + + // Loop through all of our successors and make sure they know that one + // of their predecessors is going away. + for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) + BBTerm->getSuccessor(i)->removePredecessor(BB); + + // 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 the block! + BB->eraseFromParent(); + return true; +} + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) { diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 9ba75502e7d..7077436a1dd 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1681,27 +1681,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { // as a predecessor. These are unreachable. if (pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) { DOUT << "Removing BB: \n" << *BB; - - // Loop through all of our successors and make sure they know that one - // of their predecessors is going away. - for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) - SI->removePredecessor(BB); - - 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. - if (!I.use_empty()) - // Make all users of this instruction use undef instead - I.replaceAllUsesWith(UndefValue::get(I.getType())); - - // Remove the instruction from the basic block - BB->getInstList().pop_back(); - } - BB->eraseFromParent(); + DeleteBlockIfDead(BB); return true; }