diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 7b633b20077..964fcc083d2 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Constant.h" #include "llvm/Type.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -31,7 +32,7 @@ void llvm::DeleteDeadBlock(BasicBlock *BB) { // Can delete self loop. BB->getSinglePredecessor() == BB) && "Block is not dead!"); TerminatorInst *BBTerm = BB->getTerminator(); - + Value *DbgRegionEndContext = NULL; // 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) @@ -40,6 +41,10 @@ void llvm::DeleteDeadBlock(BasicBlock *BB) { // Zap all the instructions in the block. while (!BB->empty()) { Instruction &I = BB->back(); + // It is possible to have multiple llvm.dbg.region.end in a block. + if (DbgRegionEndInst *DREI = dyn_cast(&I)) + DbgRegionEndContext = DREI->getContext(); + // 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 @@ -49,7 +54,22 @@ void llvm::DeleteDeadBlock(BasicBlock *BB) { I.replaceAllUsesWith(UndefValue::get(I.getType())); BB->getInstList().pop_back(); } - + + if (DbgRegionEndContext) { + // Delete corresponding llvm.dbg.func.start from entry block. + BasicBlock &Entry = BB->getParent()->getEntryBlock(); + DbgFuncStartInst *DbgFuncStart = NULL; + for (BasicBlock::iterator BI = Entry.begin(), BE = Entry.end(); + BI != BE; ++BI) { + if (DbgFuncStartInst *DFSI = dyn_cast(BI)) { + DbgFuncStart = DFSI; + break; + } + } + if (DbgFuncStart && DbgFuncStart->getSubprogram() == DbgRegionEndContext) + DbgFuncStart->eraseFromParent(); + } + // Zap the block! BB->eraseFromParent(); } diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index b5d74232fee..86d4a7508c5 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1806,7 +1806,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { // If we eliminated all predecessors of the block, delete the block now. if (pred_begin(BB) == pred_end(BB)) // We know there are no successors, so just nuke the block. - M->getBasicBlockList().erase(BB); + DeleteDeadBlock(BB); return true; } diff --git a/test/Transforms/SimplifyCFG/dbginfo.ll b/test/Transforms/SimplifyCFG/dbginfo.ll index c8f39545a9c..ddbaccb1658 100644 --- a/test/Transforms/SimplifyCFG/dbginfo.ll +++ b/test/Transforms/SimplifyCFG/dbginfo.ll @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | grep region | count 1 +; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | grep func.start | count 1 %llvm.dbg.anchor.type = type { i32, i32 } %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }