PassManager.cpp revision c67c938de2097f26dba71d9436e4707dd8a5012d
1//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===//
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 the LLVM Pass Manager infrastructure.
11//
12//===----------------------------------------------------------------------===//
13
14
15#include "llvm/PassManager.h"
16#include "llvm/Module.h"
17
18using namespace llvm;
19
20namespace 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
105// PassManagerAnalysisHelper implementation
106
107/// Return true IFF pass P's required analysis set does not required new
108/// 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
120/// Return true IFF AnalysisID AID is currently available.
121bool 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
145/// BasicBlockPassManager implementation
146
147/// Add pass P into PassVector and return true. If this pass is not
148/// manageable by this manager then return false.
149bool
150BasicBlockPassManager_New::addPass(Pass *P) {
151
152  BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
153  if (!BP)
154    return false;
155
156  // 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.
158  if (!manageablePass(P))
159    return false;
160
161  // Take a note of analysis required by this pass.
162  noteDownRequiredAnalysis(P);
163
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
186// FunctionPassManager_New implementation
187
188// 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
194FunctionPassManager_New::addPass(Pass *P) {
195
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);
205      if (!activeBBPassManager->addPass(BP))
206        assert(0 && "Unable to add Pass");
207    }
208    return true;
209  }
210
211  FunctionPass *FP = dynamic_cast<FunctionPass *>(P);
212  if (!FP)
213    return false;
214
215  // 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.
217  if (!manageablePass(P))
218    return false;
219
220  // Take a note of analysis required by this pass.
221  noteDownRequiredAnalysis(P);
222
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
246// ModulePassManager implementation
247
248/// Add P into pass vector if it is manageble. If P is a FunctionPass
249/// then use FunctionPassManager_New to manage it. Return false if P
250/// is not manageable by this manager.
251bool
252ModulePassManager_New::addPass(Pass *P) {
253
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);
265      if (!activeFunctionPassManager->addPass(FP))
266        assert(0 && "Unable to add pass");
267    }
268    return true;
269  }
270
271  ModulePass *MP = dynamic_cast<ModulePass *>(P);
272  if (!MP)
273    return false;
274
275  // 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.
277  if (!manageablePass(P))
278    return false;
279
280  // Take a note of analysis required by this pass.
281  noteDownRequiredAnalysis(P);
282
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
304/// 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
321PassManager_New::addPass(Pass *P) {
322
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}
345