diff options
author | Chris Lattner <sabre@nondot.org> | 2006-08-03 21:40:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-08-03 21:40:24 +0000 |
commit | c9009d917d1cecc00a585c8200a0aa743de9fb64 (patch) | |
tree | 70acf3f47ae64a8a58f513123895c47e17c3d3af /llvm/lib | |
parent | 64de8fb7e8e545b3bcb5b05790c036b5d8b53ac8 (diff) | |
download | bcm5719-llvm-c9009d917d1cecc00a585c8200a0aa743de9fb64.tar.gz bcm5719-llvm-c9009d917d1cecc00a585c8200a0aa743de9fb64.zip |
Fix PR867 (and maybe 868) and testcsae:
Transforms/SimplifyCFG/2006-08-03-Crash.ll
llvm-svn: 29515
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 8f7a154cf48..7ac944446e2 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -459,12 +459,31 @@ static bool GatherValueComparisons(Instruction *Cond, Value *&CompVal, /// has no side effects, nuke it. If it uses any instructions that become dead /// because the instruction is now gone, nuke them too. static void ErasePossiblyDeadInstructionTree(Instruction *I) { - if (isInstructionTriviallyDead(I)) { - std::vector<Value*> Operands(I->op_begin(), I->op_end()); - I->getParent()->getInstList().erase(I); - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - if (Instruction *OpI = dyn_cast<Instruction>(Operands[i])) - ErasePossiblyDeadInstructionTree(OpI); + if (!isInstructionTriviallyDead(I)) return; + + std::vector<Instruction*> InstrsToInspect; + InstrsToInspect.push_back(I); + + while (!InstrsToInspect.empty()) { + I = InstrsToInspect.back(); + InstrsToInspect.pop_back(); + + if (!isInstructionTriviallyDead(I)) continue; + + // If I is in the work list multiple times, remove previous instances. + for (unsigned i = 0, e = InstrsToInspect.size(); i != e; ++i) + if (InstrsToInspect[i] == I) { + InstrsToInspect.erase(InstrsToInspect.begin()+i); + --i, --e; + } + + // Add operands of dead instruction to worklist. + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i))) + InstrsToInspect.push_back(OpI); + + // Remove dead instruction. + I->eraseFromParent(); } } |