blob: 2592c4e907a24ecc98c842f1657643f1869ec27d [file] [log] [blame]
Devang Patel6e5a1132006-11-07 21:31:57 +00001//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
Devang Patelca58e352006-11-08 10:05:38 +00005// This file was developed by Devang Patel and is distributed under
Devang Patel6e5a1132006-11-07 21:31:57 +00006// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the LLVM Pass Manager infrastructure.
11//
12//===----------------------------------------------------------------------===//
13
14
15#include "llvm/PassManager.h"
Devang Patel6e5a1132006-11-07 21:31:57 +000016#include "llvm/Module.h"
17
18using namespace llvm;
19
Devang Patelca58e352006-11-08 10:05:38 +000020namespace llvm {
21
22/// BasicBlockPassManager_New manages BasicBlockPass. It batches all the
23/// pass together and sequence them to process one basic block before
24/// processing next basic block.
25class BasicBlockPassManager_New : public Pass,
26 public PassManagerAnalysisHelper {
27
28public:
29 BasicBlockPassManager_New() { }
30
31 /// Add a pass into a passmanager queue.
32 bool addPass(Pass *p);
33
34 /// Execute all of the passes scheduled for execution. Keep track of
35 /// whether any of the passes modifies the function, and if so, return true.
36 bool runOnFunction(Function &F);
37
38private:
39 // Collection of pass that are managed by this manager
40 std::vector<Pass *> PassVector;
41};
42
43/// FunctionPassManager_New manages FunctionPasses and BasicBlockPassManagers.
44/// It batches all function passes and basic block pass managers together and
45/// sequence them to process one function at a time before processing next
46/// function.
47class FunctionPassManager_New : public Pass,
48 public PassManagerAnalysisHelper {
49public:
50 FunctionPassManager_New(ModuleProvider *P) { /* TODO */ }
51 FunctionPassManager_New() {
52 activeBBPassManager = NULL;
53 }
54 ~FunctionPassManager_New() { /* TODO */ };
55
56 /// add - Add a pass to the queue of passes to run. This passes
57 /// ownership of the Pass to the PassManager. When the
58 /// PassManager_X is destroyed, the pass will be destroyed as well, so
59 /// there is no need to delete the pass. (TODO delete passes.)
60 /// This implies that all passes MUST be allocated with 'new'.
61 void add(Pass *P) { /* TODO*/ }
62
63 /// Add pass into the pass manager queue.
64 bool addPass(Pass *P);
65
66 /// Execute all of the passes scheduled for execution. Keep
67 /// track of whether any of the passes modifies the function, and if
68 /// so, return true.
69 bool runOnModule(Module &M);
70
71private:
72 // Collection of pass that are manged by this manager
73 std::vector<Pass *> PassVector;
74
75 // Active Pass Managers
76 BasicBlockPassManager_New *activeBBPassManager;
77};
78
79/// ModulePassManager_New manages ModulePasses and function pass managers.
80/// It batches all Module passes passes and function pass managers together and
81/// sequence them to process one module.
82class ModulePassManager_New : public Pass,
83 public PassManagerAnalysisHelper {
84
85public:
86 ModulePassManager_New() { activeFunctionPassManager = NULL; }
87
88 /// Add a pass into a passmanager queue.
89 bool addPass(Pass *p);
90
91 /// run - Execute all of the passes scheduled for execution. Keep track of
92 /// whether any of the passes modifies the module, and if so, return true.
93 bool runOnModule(Module &M);
94
95private:
96 // Collection of pass that are managed by this manager
97 std::vector<Pass *> PassVector;
98
99 // Active Pass Manager
100 FunctionPassManager_New *activeFunctionPassManager;
101};
102
103} // End of llvm namespace
104
Devang Patelf68a3492006-11-07 22:35:17 +0000105// PassManagerAnalysisHelper implementation
106
Devang Pateld65e9e92006-11-08 01:31:28 +0000107/// Return true IFF pass P's required analysis set does not required new
Devang Patelf68a3492006-11-07 22:35:17 +0000108/// manager.
109bool PassManagerAnalysisHelper::manageablePass(Pass *P) {
110
111 AnalysisUsage AnUsage;
112 P->getAnalysisUsage(AnUsage);
113
114 // If this pass is not preserving information that is required by the other passes
115 // managed by this manager then use new manager
116 // TODO
117 return true;
118}
119
Devang Pateld65e9e92006-11-08 01:31:28 +0000120/// Return true IFF AnalysisID AID is currently available.
Devang Patelf68a3492006-11-07 22:35:17 +0000121bool PassManagerAnalysisHelper::analysisCurrentlyAvailable(AnalysisID AID) {
122
123 // TODO
124 return false;
125}
126
127/// Augment RequiredSet by adding analysis required by pass P.
128void PassManagerAnalysisHelper::noteDownRequiredAnalysis(Pass *P) {
129
130 // TODO
131}
132
133/// Remove AnalysisID from the RequiredSet
134void PassManagerAnalysisHelper::removeAnalysis(AnalysisID AID) {
135
136 // TODO
137}
138
139/// Remove Analyss not preserved by Pass P
140void PassManagerAnalysisHelper::removeNotPreservedAnalysis(Pass *P) {
141
142 // TODO
143}
144
Devang Patel6e5a1132006-11-07 21:31:57 +0000145/// BasicBlockPassManager implementation
146
Devang Pateld65e9e92006-11-08 01:31:28 +0000147/// Add pass P into PassVector and return true. If this pass is not
148/// manageable by this manager then return false.
Devang Patel6e5a1132006-11-07 21:31:57 +0000149bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000150BasicBlockPassManager_New::addPass(Pass *P) {
Devang Patel6e5a1132006-11-07 21:31:57 +0000151
152 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
153 if (!BP)
154 return false;
155
Devang Patel3c8eb622006-11-07 22:56:50 +0000156 // If this pass does not preserve anlysis that is used by other passes
157 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +0000158 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +0000159 return false;
160
161 // Take a note of analysis required by this pass.
162 noteDownRequiredAnalysis(P);
Devang Patel6e5a1132006-11-07 21:31:57 +0000163
164 // Add pass
165 PassVector.push_back(BP);
166 return true;
167}
168
169/// Execute all of the passes scheduled for execution by invoking
170/// runOnBasicBlock method. Keep track of whether any of the passes modifies
171/// the function, and if so, return true.
172bool
173BasicBlockPassManager_New::runOnFunction(Function &F) {
174
175 bool Changed = false;
176 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
177 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
178 e = PassVector.end(); itr != e; ++itr) {
179 Pass *P = *itr;
180 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
181 Changed |= BP->runOnBasicBlock(*I);
182 }
183 return Changed;
184}
185
Devang Patel0c2012f2006-11-07 21:49:50 +0000186// FunctionPassManager_New implementation
187
Devang Patel0c2012f2006-11-07 21:49:50 +0000188// FunctionPassManager
189
190/// Add pass P into the pass manager queue. If P is a BasicBlockPass then
191/// either use it into active basic block pass manager or create new basic
192/// block pass manager to handle pass P.
193bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000194FunctionPassManager_New::addPass(Pass *P) {
Devang Patel0c2012f2006-11-07 21:49:50 +0000195
196 // If P is a BasicBlockPass then use BasicBlockPassManager_New.
197 if (BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P)) {
198
199 if (!activeBBPassManager
200 || !activeBBPassManager->addPass(BP)) {
201
202 activeBBPassManager = new BasicBlockPassManager_New();
203
204 PassVector.push_back(activeBBPassManager);
Devang Pateld65e9e92006-11-08 01:31:28 +0000205 if (!activeBBPassManager->addPass(BP))
206 assert(0 && "Unable to add Pass");
Devang Patel0c2012f2006-11-07 21:49:50 +0000207 }
208 return true;
209 }
210
211 FunctionPass *FP = dynamic_cast<FunctionPass *>(P);
212 if (!FP)
213 return false;
214
Devang Patel3c8eb622006-11-07 22:56:50 +0000215 // If this pass does not preserve anlysis that is used by other passes
216 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +0000217 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +0000218 return false;
219
220 // Take a note of analysis required by this pass.
221 noteDownRequiredAnalysis(P);
Devang Patel0c2012f2006-11-07 21:49:50 +0000222
223 PassVector.push_back(FP);
224 activeBBPassManager = NULL;
225 return true;
226}
227
228/// Execute all of the passes scheduled for execution by invoking
229/// runOnFunction method. Keep track of whether any of the passes modifies
230/// the function, and if so, return true.
231bool
232FunctionPassManager_New::runOnModule(Module &M) {
233
234 bool Changed = false;
235 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
236 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
237 e = PassVector.end(); itr != e; ++itr) {
238 Pass *P = *itr;
239 FunctionPass *FP = dynamic_cast<FunctionPass*>(P);
240 Changed |= FP->runOnFunction(*I);
241 }
242 return Changed;
243}
244
245
Devang Patel05e1a972006-11-07 22:03:15 +0000246// ModulePassManager implementation
247
248/// Add P into pass vector if it is manageble. If P is a FunctionPass
Devang Pateld65e9e92006-11-08 01:31:28 +0000249/// then use FunctionPassManager_New to manage it. Return false if P
Devang Patel05e1a972006-11-07 22:03:15 +0000250/// is not manageable by this manager.
251bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000252ModulePassManager_New::addPass(Pass *P) {
Devang Patel05e1a972006-11-07 22:03:15 +0000253
254 // If P is FunctionPass then use function pass maanager.
255 if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P)) {
256
257 activeFunctionPassManager = NULL;
258
259 if (!activeFunctionPassManager
260 || !activeFunctionPassManager->addPass(P)) {
261
262 activeFunctionPassManager = new FunctionPassManager_New();
263
264 PassVector.push_back(activeFunctionPassManager);
Devang Pateld65e9e92006-11-08 01:31:28 +0000265 if (!activeFunctionPassManager->addPass(FP))
266 assert(0 && "Unable to add pass");
Devang Patel05e1a972006-11-07 22:03:15 +0000267 }
268 return true;
269 }
270
271 ModulePass *MP = dynamic_cast<ModulePass *>(P);
272 if (!MP)
273 return false;
274
Devang Patel3c8eb622006-11-07 22:56:50 +0000275 // If this pass does not preserve anlysis that is used by other passes
276 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +0000277 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +0000278 return false;
279
280 // Take a note of analysis required by this pass.
281 noteDownRequiredAnalysis(P);
Devang Patel05e1a972006-11-07 22:03:15 +0000282
283 PassVector.push_back(MP);
284 activeFunctionPassManager = NULL;
285 return true;
286}
287
288
289/// Execute all of the passes scheduled for execution by invoking
290/// runOnModule method. Keep track of whether any of the passes modifies
291/// the module, and if so, return true.
292bool
293ModulePassManager_New::runOnModule(Module &M) {
294 bool Changed = false;
295 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
296 e = PassVector.end(); itr != e; ++itr) {
297 Pass *P = *itr;
298 ModulePass *MP = dynamic_cast<ModulePass*>(P);
299 Changed |= MP->runOnModule(M);
300 }
301 return Changed;
302}
303
Devang Patelc290c8a2006-11-07 22:23:34 +0000304/// Schedule all passes from the queue by adding them in their
305/// respective manager's queue.
306void
307PassManager_New::schedulePasses() {
308 /* TODO */
309}
310
311/// Add pass P to the queue of passes to run.
312void
313PassManager_New::add(Pass *P) {
314 /* TODO */
315}
316
317// PassManager_New implementation
318/// Add P into active pass manager or use new module pass manager to
319/// manage it.
320bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000321PassManager_New::addPass(Pass *P) {
Devang Patelc290c8a2006-11-07 22:23:34 +0000322
323 if (!activeManager) {
324 activeManager = new ModulePassManager_New();
325 PassManagers.push_back(activeManager);
326 }
327
328 return activeManager->addPass(P);
329}
330
331/// run - Execute all of the passes scheduled for execution. Keep track of
332/// whether any of the passes modifies the module, and if so, return true.
333bool
334PassManager_New::run(Module &M) {
335
336 schedulePasses();
337 bool Changed = false;
338 for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(),
339 e = PassManagers.end(); itr != e; ++itr) {
340 ModulePassManager_New *pm = *itr;
341 Changed |= pm->runOnModule(M);
342 }
343 return Changed;
344}