//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This pass performs lightweight instruction simplification on loop bodies. // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-instsimplify" #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" #include "llvm/ADT/Statistic.h" using namespace llvm; STATISTIC(NumSimplified, "Number of redundant instructions simplified"); namespace { class LoopInstSimplify : public LoopPass { public: static char ID; // Pass ID, replacement for typeid LoopInstSimplify() : LoopPass(ID) { initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry()); } bool runOnLoop(Loop*, LPPassManager&); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LCSSAID); } }; } char LoopInstSimplify::ID = 0; INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify", "Simplify instructions in loops", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LCSSA) INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify", "Simplify instructions in loops", false, false) Pass* llvm::createLoopInstSimplifyPass() { return new LoopInstSimplify(); } 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; 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()) { Value *V = SimplifyInstruction(I, TD, DT); if (V && LI->replacementPreservesLCSSAForm(I, V)) { I->replaceAllUsesWith(V); LocalChanged = true; ++NumSimplified; } } 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); return Changed; }