//===- LoopPass.cpp - Loop Pass and Loop Pass Manager ---------------------===// // // The LLVM Compiler Infrastructure // // This file was developed by Devang Patel and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements LoopPass and LPPassManager. All loop optimization // and transformation passes are derived from LoopPass. LPPassManager is // responsible for managing LoopPasses. // //===----------------------------------------------------------------------===// #include "llvm/Analysis/LoopPass.h" #include using namespace llvm; //===----------------------------------------------------------------------===// // LoopQueue namespace llvm { // Compare Two loops based on their depth in loop nest. class LoopCompare { public: bool operator()( Loop *L1, Loop *L2) const { return L1->getLoopDepth() > L2->getLoopDepth(); } }; // Loop queue used by Loop Pass Manager. This is a wrapper class // that hides implemenation detail (use of priority_queue) inside .cpp file. class LoopQueue { public: inline void push(Loop *L) { LPQ.push(L); } inline void pop() { LPQ.pop(); } inline Loop *top() { return LPQ.top(); } inline bool empty() { return LPQ.empty(); } private: std::priority_queue, LoopCompare> LPQ; }; } // End of LLVM namespace //===----------------------------------------------------------------------===// // LPPassManager // /// LPPassManager manages FPPassManagers and CalLGraphSCCPasses. LPPassManager::LPPassManager(int Depth) : PMDataManager(Depth) { LQ = new LoopQueue(); } LPPassManager::~LPPassManager() { delete LQ; } // Recurse through all subloops and all loops into LQ. static void addLoopIntoQueue(Loop *L, LoopQueue *LQ) { for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) addLoopIntoQueue(*I, LQ); LQ->push(L); } /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the function, and if so, return true. bool LPPassManager::runOnFunction(Function &F) { LoopInfo &LI = getAnalysis(); bool Changed = false; // Populate Loop Queue for (LoopInfo::iterator I = LI.begin(), E = LI.end(); I != E; ++I) addLoopIntoQueue(*I, LQ); std::string Msg1 = "Executing Pass '"; std::string Msg3 = "' Made Modification '"; // Walk Loops while (!LQ->empty()) { Loop *L = LQ->top(); // Run all passes on current SCC for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { Pass *P = getContainedPass(Index); AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); std::string Msg2 = "' on Loop ...\n'"; dumpPassInfo(P, Msg1, Msg2); dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet()); initializeAnalysisImpl(P); StartPassTimer(P); LoopPass *LP = dynamic_cast(P); assert (LP && "Invalid LPPassManager member"); LP->runOnLoop(*L, *this); StopPassTimer(P); if (Changed) dumpPassInfo(P, Msg3, Msg2); dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet()); removeNotPreservedAnalysis(P); recordAvailableAnalysis(P); removeDeadPasses(P, Msg2); } // Pop the loop from queue after running all passes. LQ->pop(); } return Changed; }