blob: 8bddb1007a130ba13474356636afc7b4b8b60b30 [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 Pateld65e9e92006-11-08 01:31:28 +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 Patelf68a3492006-11-07 22:35:17 +000020// PassManagerAnalysisHelper implementation
21
Devang Pateld65e9e92006-11-08 01:31:28 +000022/// Return true IFF pass P's required analysis set does not required new
Devang Patelf68a3492006-11-07 22:35:17 +000023/// manager.
24bool PassManagerAnalysisHelper::manageablePass(Pass *P) {
25
26 AnalysisUsage AnUsage;
27 P->getAnalysisUsage(AnUsage);
28
29 // If this pass is not preserving information that is required by the other passes
30 // managed by this manager then use new manager
31 // TODO
32 return true;
33}
34
Devang Pateld65e9e92006-11-08 01:31:28 +000035/// Return true IFF AnalysisID AID is currently available.
Devang Patelf68a3492006-11-07 22:35:17 +000036bool PassManagerAnalysisHelper::analysisCurrentlyAvailable(AnalysisID AID) {
37
38 // TODO
39 return false;
40}
41
42/// Augment RequiredSet by adding analysis required by pass P.
43void PassManagerAnalysisHelper::noteDownRequiredAnalysis(Pass *P) {
44
45 // TODO
46}
47
48/// Remove AnalysisID from the RequiredSet
49void PassManagerAnalysisHelper::removeAnalysis(AnalysisID AID) {
50
51 // TODO
52}
53
54/// Remove Analyss not preserved by Pass P
55void PassManagerAnalysisHelper::removeNotPreservedAnalysis(Pass *P) {
56
57 // TODO
58}
59
Devang Patel6e5a1132006-11-07 21:31:57 +000060/// BasicBlockPassManager implementation
61
Devang Pateld65e9e92006-11-08 01:31:28 +000062/// Add pass P into PassVector and return true. If this pass is not
63/// manageable by this manager then return false.
Devang Patel6e5a1132006-11-07 21:31:57 +000064bool
Devang Pateld65e9e92006-11-08 01:31:28 +000065BasicBlockPassManager_New::addPass(Pass *P) {
Devang Patel6e5a1132006-11-07 21:31:57 +000066
67 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
68 if (!BP)
69 return false;
70
Devang Patel3c8eb622006-11-07 22:56:50 +000071 // If this pass does not preserve anlysis that is used by other passes
72 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +000073 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +000074 return false;
75
76 // Take a note of analysis required by this pass.
77 noteDownRequiredAnalysis(P);
Devang Patel6e5a1132006-11-07 21:31:57 +000078
79 // Add pass
80 PassVector.push_back(BP);
81 return true;
82}
83
84/// Execute all of the passes scheduled for execution by invoking
85/// runOnBasicBlock method. Keep track of whether any of the passes modifies
86/// the function, and if so, return true.
87bool
88BasicBlockPassManager_New::runOnFunction(Function &F) {
89
90 bool Changed = false;
91 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
92 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
93 e = PassVector.end(); itr != e; ++itr) {
94 Pass *P = *itr;
95 BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
96 Changed |= BP->runOnBasicBlock(*I);
97 }
98 return Changed;
99}
100
Devang Patel0c2012f2006-11-07 21:49:50 +0000101// FunctionPassManager_New implementation
102
Devang Patel0c2012f2006-11-07 21:49:50 +0000103// FunctionPassManager
104
105/// Add pass P into the pass manager queue. If P is a BasicBlockPass then
106/// either use it into active basic block pass manager or create new basic
107/// block pass manager to handle pass P.
108bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000109FunctionPassManager_New::addPass(Pass *P) {
Devang Patel0c2012f2006-11-07 21:49:50 +0000110
111 // If P is a BasicBlockPass then use BasicBlockPassManager_New.
112 if (BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P)) {
113
114 if (!activeBBPassManager
115 || !activeBBPassManager->addPass(BP)) {
116
117 activeBBPassManager = new BasicBlockPassManager_New();
118
119 PassVector.push_back(activeBBPassManager);
Devang Pateld65e9e92006-11-08 01:31:28 +0000120 if (!activeBBPassManager->addPass(BP))
121 assert(0 && "Unable to add Pass");
Devang Patel0c2012f2006-11-07 21:49:50 +0000122 }
123 return true;
124 }
125
126 FunctionPass *FP = dynamic_cast<FunctionPass *>(P);
127 if (!FP)
128 return false;
129
Devang Patel3c8eb622006-11-07 22:56:50 +0000130 // If this pass does not preserve anlysis that is used by other passes
131 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +0000132 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +0000133 return false;
134
135 // Take a note of analysis required by this pass.
136 noteDownRequiredAnalysis(P);
Devang Patel0c2012f2006-11-07 21:49:50 +0000137
138 PassVector.push_back(FP);
139 activeBBPassManager = NULL;
140 return true;
141}
142
143/// Execute all of the passes scheduled for execution by invoking
144/// runOnFunction method. Keep track of whether any of the passes modifies
145/// the function, and if so, return true.
146bool
147FunctionPassManager_New::runOnModule(Module &M) {
148
149 bool Changed = false;
150 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
151 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
152 e = PassVector.end(); itr != e; ++itr) {
153 Pass *P = *itr;
154 FunctionPass *FP = dynamic_cast<FunctionPass*>(P);
155 Changed |= FP->runOnFunction(*I);
156 }
157 return Changed;
158}
159
160
Devang Patel05e1a972006-11-07 22:03:15 +0000161// ModulePassManager implementation
162
163/// Add P into pass vector if it is manageble. If P is a FunctionPass
Devang Pateld65e9e92006-11-08 01:31:28 +0000164/// then use FunctionPassManager_New to manage it. Return false if P
Devang Patel05e1a972006-11-07 22:03:15 +0000165/// is not manageable by this manager.
166bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000167ModulePassManager_New::addPass(Pass *P) {
Devang Patel05e1a972006-11-07 22:03:15 +0000168
169 // If P is FunctionPass then use function pass maanager.
170 if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P)) {
171
172 activeFunctionPassManager = NULL;
173
174 if (!activeFunctionPassManager
175 || !activeFunctionPassManager->addPass(P)) {
176
177 activeFunctionPassManager = new FunctionPassManager_New();
178
179 PassVector.push_back(activeFunctionPassManager);
Devang Pateld65e9e92006-11-08 01:31:28 +0000180 if (!activeFunctionPassManager->addPass(FP))
181 assert(0 && "Unable to add pass");
Devang Patel05e1a972006-11-07 22:03:15 +0000182 }
183 return true;
184 }
185
186 ModulePass *MP = dynamic_cast<ModulePass *>(P);
187 if (!MP)
188 return false;
189
Devang Patel3c8eb622006-11-07 22:56:50 +0000190 // If this pass does not preserve anlysis that is used by other passes
191 // managed by this manager than it is not a suiable pass for this manager.
Devang Pateld65e9e92006-11-08 01:31:28 +0000192 if (!manageablePass(P))
Devang Patel3c8eb622006-11-07 22:56:50 +0000193 return false;
194
195 // Take a note of analysis required by this pass.
196 noteDownRequiredAnalysis(P);
Devang Patel05e1a972006-11-07 22:03:15 +0000197
198 PassVector.push_back(MP);
199 activeFunctionPassManager = NULL;
200 return true;
201}
202
203
204/// Execute all of the passes scheduled for execution by invoking
205/// runOnModule method. Keep track of whether any of the passes modifies
206/// the module, and if so, return true.
207bool
208ModulePassManager_New::runOnModule(Module &M) {
209 bool Changed = false;
210 for (std::vector<Pass *>::iterator itr = PassVector.begin(),
211 e = PassVector.end(); itr != e; ++itr) {
212 Pass *P = *itr;
213 ModulePass *MP = dynamic_cast<ModulePass*>(P);
214 Changed |= MP->runOnModule(M);
215 }
216 return Changed;
217}
218
Devang Patelc290c8a2006-11-07 22:23:34 +0000219/// Schedule all passes from the queue by adding them in their
220/// respective manager's queue.
221void
222PassManager_New::schedulePasses() {
223 /* TODO */
224}
225
226/// Add pass P to the queue of passes to run.
227void
228PassManager_New::add(Pass *P) {
229 /* TODO */
230}
231
232// PassManager_New implementation
233/// Add P into active pass manager or use new module pass manager to
234/// manage it.
235bool
Devang Pateld65e9e92006-11-08 01:31:28 +0000236PassManager_New::addPass(Pass *P) {
Devang Patelc290c8a2006-11-07 22:23:34 +0000237
238 if (!activeManager) {
239 activeManager = new ModulePassManager_New();
240 PassManagers.push_back(activeManager);
241 }
242
243 return activeManager->addPass(P);
244}
245
246/// run - Execute all of the passes scheduled for execution. Keep track of
247/// whether any of the passes modifies the module, and if so, return true.
248bool
249PassManager_New::run(Module &M) {
250
251 schedulePasses();
252 bool Changed = false;
253 for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(),
254 e = PassManagers.end(); itr != e; ++itr) {
255 ModulePassManager_New *pm = *itr;
256 Changed |= pm->runOnModule(M);
257 }
258 return Changed;
259}