From e389ab16f3d98c2491dd2d8649b782203590a938 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 5 Jan 2011 05:15:53 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122868 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopInstSimplify.cpp | 46 +++++++++++++++++----- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/Transforms/Scalar/LoopInstSimplify.cpp b/lib/Transforms/Scalar/LoopInstSimplify.cpp index b61574b21e0..848dc402cad 100644 --- a/lib/Transforms/Scalar/LoopInstSimplify.cpp +++ b/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(); - AU.addPreserved(); + 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(); LoopInfo *LI = &getAnalysis(); const TargetData *TD = getAnalysisIfAvailable(); + SmallVector ExitBlocks; + L->getUniqueExitBlocks(ExitBlocks); + array_pod_sort(ExitBlocks.begin(), ExitBlocks.end()); + + SmallVector VisitStack; + SmallPtrSet Visited; + bool Changed = false; bool LocalChanged; do { LocalChanged = false; - for (df_iterator 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); -- 2.34.1