diff options
Diffstat (limited to 'lib/Transforms/Utils/SimplifyInstructions.cpp')
-rw-r--r-- | lib/Transforms/Utils/SimplifyInstructions.cpp | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/Transforms/Utils/SimplifyInstructions.cpp b/lib/Transforms/Utils/SimplifyInstructions.cpp index 548bc51024..6074a5f2c2 100644 --- a/lib/Transforms/Utils/SimplifyInstructions.cpp +++ b/lib/Transforms/Utils/SimplifyInstructions.cpp @@ -23,6 +23,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions removed"); @@ -40,19 +41,46 @@ namespace { /// runOnFunction - Remove instructions that simplify. bool runOnFunction(Function &F) { - bool Changed = false; const TargetData *TD = getAnalysisIfAvailable<TargetData>(); const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>(); + bool Changed = false; + + // Add all interesting instructions to the worklist. + std::set<Instruction*> Worklist; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; - if (Value *V = SimplifyInstruction(I, TD, DT)) { - I->replaceAllUsesWith(V); + // Zap any dead instructions. + if (isInstructionTriviallyDead(I)) { I->eraseFromParent(); Changed = true; - ++NumSimplified; + continue; } + // Add all others to the worklist. + Worklist.insert(I); } + + // Simplify everything in the worklist until the cows come home. + while (!Worklist.empty()) { + Instruction *I = *Worklist.begin(); + Worklist.erase(Worklist.begin()); + Value *V = SimplifyInstruction(I, TD, DT); + if (!V) continue; + + // This instruction simplifies! Replace it with its simplification and + // add all uses to the worklist, since they may now simplify. + I->replaceAllUsesWith(V); + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) + // In unreachable code an instruction can use itself, in which case + // don't add it to the worklist since we are about to erase it. + if (*UI != I) Worklist.insert(cast<Instruction>(*UI)); + if (isInstructionTriviallyDead(I)) + I->eraseFromParent(); + ++NumSimplified; + Changed = true; + } + return Changed; } }; |