Speed up instsimplify by about 10-15% by not bothering to retry

InstructionSimplify on instructions that didn't change since the
last time round the loop.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122745 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2011-01-03 10:50:04 +00:00
parent cc3d8e3c22
commit dc615e41b5

View File

@ -19,6 +19,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
@ -44,28 +45,38 @@ namespace {
bool runOnFunction(Function &F) { bool runOnFunction(Function &F) {
const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>(); const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
const TargetData *TD = getAnalysisIfAvailable<TargetData>(); const TargetData *TD = getAnalysisIfAvailable<TargetData>();
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
bool Changed = false; bool Changed = false;
bool LocalChanged;
do { do {
LocalChanged = false;
for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()), for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()),
DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) DE = df_end(&F.getEntryBlock()); DI != DE; ++DI)
for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) {
Instruction *I = BI++; Instruction *I = BI++;
// Don't bother simplifying unused instructions. // The first time through the loop ToSimplify is empty and we try to
// simplify all instructions. On later iterations ToSimplify is not
// empty and we only bother simplifying instructions that are in it.
if (!ToSimplify->empty() && !ToSimplify->count(I))
continue;
// Don't waste time simplifying unused instructions.
if (!I->use_empty()) if (!I->use_empty())
if (Value *V = SimplifyInstruction(I, TD, DT)) { if (Value *V = SimplifyInstruction(I, TD, DT)) {
// Mark all uses for resimplification next time round the loop.
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI)
Next->insert(cast<Instruction>(*UI));
I->replaceAllUsesWith(V); I->replaceAllUsesWith(V);
LocalChanged = true;
++NumSimplified; ++NumSimplified;
Changed = true;
} }
LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); Changed |= RecursivelyDeleteTriviallyDeadInstructions(I);
} }
Changed |= LocalChanged; // Place the list of instructions to simplify on the next loop iteration
} while (LocalChanged); // into ToSimplify.
std::swap(ToSimplify, Next);
Next->clear();
} while (!ToSimplify->empty());
return Changed; return Changed;
} }