diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -475,6 +475,10 @@ BasicBlock::iterator FromBeginIt, BasicBlock::iterator FromEndIt); + /// Erases a range of instructions from \p FromIt to (not including) \p ToIt. + /// \Returns \p ToIt. + BasicBlock::iterator erase(BasicBlock::iterator FromIt, BasicBlock::iterator ToIt); + /// Returns true if there are any uses of this basic block other than /// direct branches, switches, etc. to it. bool hasAddressTaken() const { diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -480,6 +480,11 @@ getInstList().splice(ToIt, FromBB->getInstList(), FromBeginIt, FromEndIt); } +BasicBlock::iterator BasicBlock::erase(BasicBlock::iterator FromIt, + BasicBlock::iterator ToIt) { + return getInstList().erase(FromIt, ToIt); +} + void BasicBlock::replacePhiUsesWith(BasicBlock *Old, BasicBlock *New) { // N.B. This might not be a complete BasicBlock, so don't assume // that it ends with a non-phi instruction. diff --git a/llvm/unittests/IR/BasicBlockTest.cpp b/llvm/unittests/IR/BasicBlockTest.cpp --- a/llvm/unittests/IR/BasicBlockTest.cpp +++ b/llvm/unittests/IR/BasicBlockTest.cpp @@ -507,5 +507,39 @@ } #endif //EXPENSIVE_CHECKS +TEST(BasicBlockTest, EraseRange) { + LLVMContext Ctx; + std::unique_ptr M = parseIR(Ctx, R"( + define void @f(i32 %a) { + bb0: + %instr1 = add i32 %a, %a + %instr2 = sub i32 %a, %a + ret void + } +)"); + Function *F = &*M->begin(); + + auto BB0It = F->begin(); + BasicBlock *BB0 = &*BB0It; + + auto It = BB0->begin(); + Instruction *Instr1 = &*It++; + Instruction *Instr2 = &*It++; + + EXPECT_EQ(BB0->size(), 3u); + + // Erase no instruction + BB0->erase(Instr1->getIterator(), Instr1->getIterator()); + EXPECT_EQ(BB0->size(), 3u); + + // Erase %instr1 + BB0->erase(Instr1->getIterator(), Instr2->getIterator()); + EXPECT_EQ(BB0->size(), 2u); + EXPECT_EQ(&*BB0->begin(), Instr2); + + // Erase all instructions + BB0->erase(BB0->begin(), BB0->end()); + EXPECT_TRUE(BB0->empty()); +} } // End anonymous namespace. } // End llvm namespace.