Teach LoopPass to assign itself one Loop Pass Manager.
[oota-llvm.git] / lib / Analysis / LoopPass.cpp
1 //===- LoopPass.cpp - Loop Pass and Loop Pass Manager ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Devang Patel and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements LoopPass and LPPassManager. All loop optimization
11 // and transformation passes are derived from LoopPass. LPPassManager is
12 // responsible for managing LoopPasses.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Analysis/LoopPass.h"
17 #include <queue>
18 using namespace llvm;
19
20 //===----------------------------------------------------------------------===//
21 // LoopQueue
22
23 namespace llvm {
24
25 // Compare Two loops based on their depth in loop nest.
26 class LoopCompare {
27 public:
28   bool operator()( Loop *L1, Loop *L2) const {
29     return L1->getLoopDepth() > L2->getLoopDepth();
30   }
31 };
32
33 // Loop queue used by Loop Pass Manager. This is a wrapper class
34 // that hides implemenation detail (use of priority_queue) inside .cpp file.
35 class LoopQueue {
36 public:
37   inline void push(Loop *L) { LPQ.push(L); }
38   inline void pop() { LPQ.pop(); }
39   inline Loop *top() { return LPQ.top(); }
40   inline bool empty() { return LPQ.empty(); }
41 private:
42   std::priority_queue<Loop *, std::vector<Loop *>, LoopCompare> LPQ;
43 };
44
45 } // End of LLVM namespace
46
47 //===----------------------------------------------------------------------===//
48 // LPPassManager
49 //
50 /// LPPassManager manages FPPassManagers and CalLGraphSCCPasses.
51
52 LPPassManager::LPPassManager(int Depth) : PMDataManager(Depth) { 
53   skipThisLoop = false;
54   redoThisLoop = false;
55   LQ = new LoopQueue(); 
56 }
57
58 LPPassManager::~LPPassManager() {
59   delete LQ;
60 }
61
62 /// Delete loop from the loop queue. This is used by Loop pass to inform
63 /// Loop Pass Manager that it should skip rest of the passes for this loop.
64 void LPPassManager::deleteLoopFromQueue(Loop *L) {
65   // Do not pop loop from LQ here. It will be done by runOnFunction while loop.
66   skipThisLoop = true;
67 }
68
69 // Reoptimize this loop. LPPassManager will re-insert this loop into the
70 // queue. This allows LoopPass to change loop nest for the loop. This
71 // utility may send LPPassManager into infinite loops so use caution.
72 void LPPassManager::redoLoop(Loop *L) {
73   redoThisLoop = true;
74 }
75
76 // Recurse through all subloops and all loops  into LQ.
77 static void addLoopIntoQueue(Loop *L, LoopQueue *LQ) {
78   for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
79     addLoopIntoQueue(*I, LQ);
80   LQ->push(L);
81 }
82
83 /// run - Execute all of the passes scheduled for execution.  Keep track of
84 /// whether any of the passes modifies the function, and if so, return true.
85 bool LPPassManager::runOnFunction(Function &F) {
86   LoopInfo &LI = getAnalysis<LoopInfo>();
87   bool Changed = false;
88
89   // Populate Loop Queue
90   for (LoopInfo::iterator I = LI.begin(), E = LI.end(); I != E; ++I)
91     addLoopIntoQueue(*I, LQ);
92
93   std::string Msg1 = "Executing Pass '";
94   std::string Msg3 = "' Made Modification '";
95
96   // Walk Loops
97   while (!LQ->empty()) {
98       
99     Loop *L  = LQ->top();
100     skipThisLoop = false;
101     redoThisLoop = false;
102
103     // Run all passes on current SCC
104     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
105         
106       Pass *P = getContainedPass(Index);
107       AnalysisUsage AnUsage;
108       P->getAnalysisUsage(AnUsage);
109
110       std::string Msg2 = "' on Loop ...\n'";
111       dumpPassInfo(P, Msg1, Msg2);
112       dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet());
113
114       initializeAnalysisImpl(P);
115
116       StartPassTimer(P);
117       LoopPass *LP = dynamic_cast<LoopPass *>(P);
118       assert (LP && "Invalid LPPassManager member");
119       LP->runOnLoop(*L, *this);
120       StopPassTimer(P);
121
122       if (Changed)
123         dumpPassInfo(P, Msg3, Msg2);
124       dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet());
125       
126       removeNotPreservedAnalysis(P);
127       recordAvailableAnalysis(P);
128       removeDeadPasses(P, Msg2);
129
130       if (skipThisLoop)
131         // Do not run other passes on this loop.
132         break;
133     }
134     
135     // Pop the loop from queue after running all passes.
136     LQ->pop();
137     
138     if (redoThisLoop)
139       LQ->push(L);
140   }
141
142   return Changed;
143 }
144
145
146 //===----------------------------------------------------------------------===//
147 // LoopPass
148
149 /// Assign pass manager to manage this pass.
150 void LoopPass::assignPassManager(PMStack &PMS,
151                                  PassManagerType PreferredType) {
152   // Find LPPassManager 
153   while (!PMS.empty()) {
154     if (PMS.top()->getPassManagerType() > PMT_LoopPassManager)
155       PMS.pop();
156     else;
157     break;
158   }
159
160   LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top());
161
162   // Create new Loop Pass Manager if it does not exist. 
163   if (!LPPM) {
164
165     assert (!PMS.empty() && "Unable to create Loop Pass Manager");
166     PMDataManager *PMD = PMS.top();
167
168     // [1] Create new Call Graph Pass Manager
169     LPPM = new LPPassManager(PMD->getDepth() + 1);
170
171     // [2] Set up new manager's top level manager
172     PMTopLevelManager *TPM = PMD->getTopLevelManager();
173     TPM->addIndirectPassManager(LPPM);
174
175     // [3] Assign manager to manage this new manager. This may create
176     // and push new managers into PMS
177     Pass *P = dynamic_cast<Pass *>(LPPM);
178     P->assignPassManager(PMS);
179
180     // [4] Push new manager into PMS
181     PMS.push(LPPM);
182   }
183
184   LPPM->add(this);
185 }
186