diff options
author | Cameron Zwarich <zwarich@apple.com> | 2011-01-05 05:15:53 +0000 |
---|---|---|
committer | Cameron Zwarich <zwarich@apple.com> | 2011-01-05 05:15:53 +0000 |
commit | 4c51d122d59145706e3033162d4686da20d9c97a (patch) | |
tree | f7ec098d249dde3cbbc176ecfc68a8ff3789dfe7 /llvm/lib/Transforms | |
parent | 78edf99f46c6e07631a03527610bb3d4a7551d91 (diff) | |
download | bcm5719-llvm-4c51d122d59145706e3033162d4686da20d9c97a.tar.gz bcm5719-llvm-4c51d122d59145706e3033162d4686da20d9c97a.zip |
Change LoopInstSimplify back to a LoopPass. It revisits subloops rather than
skipping them, but it should probably use a worklist and only revisit those
instructions in subloops that have actually changed. It should probably also
use a worklist after the first iteration like instsimplify now does. Regardless,
it's only 0.3% of opt -O2 time on 403.gcc if it replaces the instcombine placed
in the middle of the loop passes.
llvm-svn: 122868
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp b/llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp index b61574b21e0..848dc402cad 100644 --- a/llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInstSimplify.cpp @@ -12,11 +12,11 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-instsimplify" -#include "llvm/Function.h" -#include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" @@ -26,19 +26,19 @@ using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions simplified"); namespace { - class LoopInstSimplify : public FunctionPass { + class LoopInstSimplify : public LoopPass { public: static char ID; // Pass ID, replacement for typeid - LoopInstSimplify() : FunctionPass(ID) { + LoopInstSimplify() : LoopPass(ID) { initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function &); + bool runOnLoop(Loop*, LPPassManager&); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<LoopInfo>(); - AU.addPreserved<LoopInfo>(); + AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LCSSAID); } }; @@ -57,19 +57,34 @@ Pass* llvm::createLoopInstSimplifyPass() { return new LoopInstSimplify(); } -bool LoopInstSimplify::runOnFunction(Function &F) { +bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>(); LoopInfo *LI = &getAnalysis<LoopInfo>(); const TargetData *TD = getAnalysisIfAvailable<TargetData>(); + SmallVector<BasicBlock*, 8> ExitBlocks; + L->getUniqueExitBlocks(ExitBlocks); + array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); + + SmallVector<BasicBlock*, 16> VisitStack; + SmallPtrSet<BasicBlock*, 32> Visited; + bool Changed = false; bool LocalChanged; do { LocalChanged = false; - for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()), - DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) - for (BasicBlock::iterator BI = DI->begin(), BE = DI->end(); BI != BE;) { + VisitStack.clear(); + Visited.clear(); + + VisitStack.push_back(L->getHeader()); + + while (!VisitStack.empty()) { + BasicBlock *BB = VisitStack.back(); + VisitStack.pop_back(); + + // Simplify instructions in the current basic block. + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { Instruction *I = BI++; // Don't bother simplifying unused instructions. if (!I->use_empty()) { @@ -83,6 +98,17 @@ bool LoopInstSimplify::runOnFunction(Function &F) { LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I); } + // Add all successors to the worklist, except for loop exit blocks. + for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; + ++SI) { + BasicBlock *SuccBB = *SI; + bool IsExitBlock = std::binary_search(ExitBlocks.begin(), + ExitBlocks.end(), SuccBB); + if (!IsExitBlock && Visited.insert(SuccBB)) + VisitStack.push_back(SuccBB); + } + } + Changed |= LocalChanged; } while (LocalChanged); |