blob: c9b97c879a600633a2af2fce0ec69a5bd953ffc8 [file] [log] [blame]
Chris Lattnerab16a652003-10-13 05:33:01 +00001//===- Pass.cpp - LLVM Pass Infrastructure Implementation -----------------===//
Chris Lattner26e4f892002-01-21 07:37:31 +00002//
3// This file implements the LLVM Pass infrastructure. It is primarily
4// responsible with ensuring that passes are executed and batched together
5// optimally.
6//
7//===----------------------------------------------------------------------===//
8
Chris Lattnercdd09c22002-01-31 00:45:31 +00009#include "llvm/PassManager.h"
Chris Lattner37c86672002-04-28 20:46:05 +000010#include "PassManagerT.h" // PassManagerT implementation
Chris Lattnercdd09c22002-01-31 00:45:31 +000011#include "llvm/Module.h"
Chris Lattner26e4f892002-01-21 07:37:31 +000012#include "Support/STLExtras.h"
Chris Lattner37d3c952002-07-23 18:08:00 +000013#include "Support/TypeInfo.h"
Chris Lattner6e041bd2002-08-21 22:17:09 +000014#include <set>
Chris Lattnerd013ba92002-01-23 05:49:41 +000015
Chris Lattner675e7a92002-08-21 23:51:51 +000016// IncludeFile - Stub function used to help linking out.
17IncludeFile::IncludeFile(void*) {}
18
Chris Lattner7e0dbe62002-05-06 19:31:52 +000019//===----------------------------------------------------------------------===//
20// AnalysisID Class Implementation
21//
22
Chris Lattnerab16a652003-10-13 05:33:01 +000023// getCFGOnlyAnalyses - A wrapper around the CFGOnlyAnalyses which make it
24// initializer order independent.
25static std::vector<const PassInfo*> &getCFGOnlyAnalyses() {
26 static std::vector<const PassInfo*> CFGOnlyAnalyses;
27 return CFGOnlyAnalyses;
28}
Chris Lattnercdd09c22002-01-31 00:45:31 +000029
Chris Lattnerdd99f5b2003-10-12 18:52:12 +000030void RegisterPassBase::setOnlyUsesCFG() {
Chris Lattnerab16a652003-10-13 05:33:01 +000031 getCFGOnlyAnalyses().push_back(PIObj);
Chris Lattner7e0dbe62002-05-06 19:31:52 +000032}
33
34//===----------------------------------------------------------------------===//
35// AnalysisResolver Class Implementation
36//
37
Chris Lattnercdd09c22002-01-31 00:45:31 +000038void AnalysisResolver::setAnalysisResolver(Pass *P, AnalysisResolver *AR) {
39 assert(P->Resolver == 0 && "Pass already in a PassManager!");
40 P->Resolver = AR;
41}
42
Chris Lattner7e0dbe62002-05-06 19:31:52 +000043//===----------------------------------------------------------------------===//
44// AnalysisUsage Class Implementation
45//
Chris Lattneree2ff5d2002-04-28 21:25:41 +000046
Chris Lattner820d9712002-10-21 20:00:28 +000047// setPreservesCFG - This function should be called to by the pass, iff they do
Chris Lattneree2ff5d2002-04-28 21:25:41 +000048// not:
49//
50// 1. Add or remove basic blocks from the function
51// 2. Modify terminator instructions in any way.
52//
53// This function annotates the AnalysisUsage info object to say that analyses
54// that only depend on the CFG are preserved by this pass.
55//
Chris Lattner820d9712002-10-21 20:00:28 +000056void AnalysisUsage::setPreservesCFG() {
Chris Lattner7e0dbe62002-05-06 19:31:52 +000057 // Since this transformation doesn't modify the CFG, it preserves all analyses
58 // that only depend on the CFG (like dominators, loop info, etc...)
59 //
60 Preserved.insert(Preserved.end(),
Chris Lattnerab16a652003-10-13 05:33:01 +000061 getCFGOnlyAnalyses().begin(), getCFGOnlyAnalyses().end());
Chris Lattneree2ff5d2002-04-28 21:25:41 +000062}
63
64
Chris Lattner37c86672002-04-28 20:46:05 +000065//===----------------------------------------------------------------------===//
66// PassManager implementation - The PassManager class is a simple Pimpl class
67// that wraps the PassManagerT template.
68//
69PassManager::PassManager() : PM(new PassManagerT<Module>()) {}
70PassManager::~PassManager() { delete PM; }
71void PassManager::add(Pass *P) { PM->add(P); }
Chris Lattner113f4f42002-06-25 16:13:24 +000072bool PassManager::run(Module &M) { return PM->run(M); }
Chris Lattnercdd09c22002-01-31 00:45:31 +000073
Brian Gaekeb7a83882003-08-12 17:22:39 +000074//===----------------------------------------------------------------------===//
75// FunctionPassManager implementation - The FunctionPassManager class
76// is a simple Pimpl class that wraps the PassManagerT template. It
77// is like PassManager, but only deals in FunctionPasses.
78//
79FunctionPassManager::FunctionPassManager() : PM(new PassManagerT<Function>()) {}
80FunctionPassManager::~FunctionPassManager() { delete PM; }
81void FunctionPassManager::add(FunctionPass *P) { PM->add(P); }
Brian Gaeke2cc4b9d2003-08-14 06:07:57 +000082void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); }
Brian Gaekeb7a83882003-08-12 17:22:39 +000083bool FunctionPassManager::run(Function &F) { return PM->run(F); }
84
Chris Lattner37c86672002-04-28 20:46:05 +000085
86//===----------------------------------------------------------------------===//
Chris Lattnere2eb99e2002-04-29 04:04:29 +000087// TimingInfo Class - This class is used to calculate information about the
88// amount of time each pass takes to execute. This only happens with
89// -time-passes is enabled on the command line.
90//
Chris Lattnerf5cad152002-07-22 02:10:13 +000091static cl::opt<bool>
92EnableTiming("time-passes",
93 cl::desc("Time each pass, printing elapsed time for each on exit"));
Chris Lattnere2eb99e2002-04-29 04:04:29 +000094
Chris Lattnere7e09442003-08-14 05:20:28 +000095// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to
96// a non null value (if the -time-passes option is enabled) or it leaves it
97// null. It may be called multiple times.
98void TimingInfo::createTheTimeInfo() {
99 if (!EnableTiming || TheTimeInfo) return;
100
101 // Constructed the first time this is called, iff -time-passes is enabled.
102 // This guarantees that the object will be constructed before static globals,
103 // thus it will be destroyed before them.
104 static TimingInfo TTI;
105 TheTimeInfo = &TTI;
Chris Lattnere2eb99e2002-04-29 04:04:29 +0000106}
107
Chris Lattner1e4867f2002-07-30 19:51:02 +0000108void PMDebug::PrintArgumentInformation(const Pass *P) {
109 // Print out passes in pass manager...
110 if (const AnalysisResolver *PM = dynamic_cast<const AnalysisResolver*>(P)) {
111 for (unsigned i = 0, e = PM->getNumContainedPasses(); i != e; ++i)
112 PrintArgumentInformation(PM->getContainedPass(i));
113
114 } else { // Normal pass. Print argument information...
115 // Print out arguments for registered passes that are _optimizations_
116 if (const PassInfo *PI = P->getPassInfo())
117 if (PI->getPassType() & PassInfo::Optimization)
118 std::cerr << " -" << PI->getPassArgument();
119 }
120}
Chris Lattnercdd09c22002-01-31 00:45:31 +0000121
122void PMDebug::PrintPassInformation(unsigned Depth, const char *Action,
Chris Lattnera454b5b2002-04-28 05:14:06 +0000123 Pass *P, Annotable *V) {
Chris Lattnerf5cad152002-07-22 02:10:13 +0000124 if (PassDebugging >= Executions) {
Chris Lattnerac3e0602002-01-31 18:32:27 +0000125 std::cerr << (void*)P << std::string(Depth*2+1, ' ') << Action << " '"
Chris Lattner37104aa2002-04-29 14:57:45 +0000126 << P->getPassName();
Chris Lattnercdd09c22002-01-31 00:45:31 +0000127 if (V) {
128 std::cerr << "' on ";
Chris Lattnera454b5b2002-04-28 05:14:06 +0000129
130 if (dynamic_cast<Module*>(V)) {
Chris Lattnercdd09c22002-01-31 00:45:31 +0000131 std::cerr << "Module\n"; return;
Chris Lattnera454b5b2002-04-28 05:14:06 +0000132 } else if (Function *F = dynamic_cast<Function*>(V))
133 std::cerr << "Function '" << F->getName();
134 else if (BasicBlock *BB = dynamic_cast<BasicBlock*>(V))
135 std::cerr << "BasicBlock '" << BB->getName();
136 else if (Value *Val = dynamic_cast<Value*>(V))
137 std::cerr << typeid(*Val).name() << " '" << Val->getName();
Chris Lattnercdd09c22002-01-31 00:45:31 +0000138 }
139 std::cerr << "'...\n";
140 }
141}
142
143void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg,
Chris Lattnerc8e66542002-04-27 06:56:12 +0000144 Pass *P, const std::vector<AnalysisID> &Set){
Chris Lattnerf5cad152002-07-22 02:10:13 +0000145 if (PassDebugging >= Details && !Set.empty()) {
Chris Lattnerac3e0602002-01-31 18:32:27 +0000146 std::cerr << (void*)P << std::string(Depth*2+3, ' ') << Msg << " Analyses:";
Chris Lattnerb3708e22002-08-30 20:23:45 +0000147 for (unsigned i = 0; i != Set.size(); ++i) {
148 if (i) std::cerr << ",";
149 std::cerr << " " << Set[i]->getPassName();
150 }
Chris Lattnercdd09c22002-01-31 00:45:31 +0000151 std::cerr << "\n";
152 }
153}
154
Chris Lattnercdd09c22002-01-31 00:45:31 +0000155//===----------------------------------------------------------------------===//
156// Pass Implementation
Chris Lattner654b5bc2002-01-22 00:17:48 +0000157//
Chris Lattnercdd09c22002-01-31 00:45:31 +0000158
Chris Lattnerc8e66542002-04-27 06:56:12 +0000159void Pass::addToPassManager(PassManagerT<Module> *PM, AnalysisUsage &AU) {
160 PM->addPass(this, AU);
Chris Lattner654b5bc2002-01-22 00:17:48 +0000161}
Chris Lattner26e4f892002-01-21 07:37:31 +0000162
Chris Lattner9ad77572003-03-21 21:41:02 +0000163bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
164 return Resolver->getAnalysisToUpdate(AnalysisID) != 0;
165}
166
Chris Lattner198cf422002-07-30 16:27:02 +0000167// dumpPassStructure - Implement the -debug-passes=Structure option
168void Pass::dumpPassStructure(unsigned Offset) {
169 std::cerr << std::string(Offset*2, ' ') << getPassName() << "\n";
170}
Chris Lattner37104aa2002-04-29 14:57:45 +0000171
172// getPassName - Use C++ RTTI to get a SOMEWHAT intelligable name for the pass.
173//
Chris Lattner071577d2002-07-29 21:02:31 +0000174const char *Pass::getPassName() const {
175 if (const PassInfo *PI = getPassInfo())
176 return PI->getPassName();
177 return typeid(*this).name();
178}
Chris Lattner37104aa2002-04-29 14:57:45 +0000179
Chris Lattner26750072002-07-27 01:12:17 +0000180// print - Print out the internal state of the pass. This is called by Analyse
Misha Brukman7eb05a12003-08-18 14:43:39 +0000181// to print out the contents of an analysis. Otherwise it is not necessary to
Chris Lattner26750072002-07-27 01:12:17 +0000182// implement this method.
183//
184void Pass::print(std::ostream &O) const {
185 O << "Pass::print not implemented for pass: '" << getPassName() << "'!\n";
186}
187
188// dump - call print(std::cerr);
189void Pass::dump() const {
190 print(std::cerr, 0);
191}
192
Chris Lattnercdd09c22002-01-31 00:45:31 +0000193//===----------------------------------------------------------------------===//
Chris Lattneree0788d2002-09-25 21:59:11 +0000194// ImmutablePass Implementation
195//
196void ImmutablePass::addToPassManager(PassManagerT<Module> *PM,
197 AnalysisUsage &AU) {
198 PM->addPass(this, AU);
199}
200
201
202//===----------------------------------------------------------------------===//
Chris Lattnerc8e66542002-04-27 06:56:12 +0000203// FunctionPass Implementation
Chris Lattner26e4f892002-01-21 07:37:31 +0000204//
Chris Lattnercdd09c22002-01-31 00:45:31 +0000205
Chris Lattnerc8e66542002-04-27 06:56:12 +0000206// run - On a module, we run this pass by initializing, runOnFunction'ing once
207// for every function in the module, then by finalizing.
Chris Lattnercdd09c22002-01-31 00:45:31 +0000208//
Chris Lattner113f4f42002-06-25 16:13:24 +0000209bool FunctionPass::run(Module &M) {
Chris Lattnercdd09c22002-01-31 00:45:31 +0000210 bool Changed = doInitialization(M);
211
Chris Lattner113f4f42002-06-25 16:13:24 +0000212 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
213 if (!I->isExternal()) // Passes are not run on external functions!
Chris Lattnerc8e66542002-04-27 06:56:12 +0000214 Changed |= runOnFunction(*I);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000215
216 return Changed | doFinalization(M);
Chris Lattner26e4f892002-01-21 07:37:31 +0000217}
218
Chris Lattnerc8e66542002-04-27 06:56:12 +0000219// run - On a function, we simply initialize, run the function, then finalize.
Chris Lattnercdd09c22002-01-31 00:45:31 +0000220//
Chris Lattner113f4f42002-06-25 16:13:24 +0000221bool FunctionPass::run(Function &F) {
222 if (F.isExternal()) return false;// Passes are not run on external functions!
Chris Lattnercdd09c22002-01-31 00:45:31 +0000223
Chris Lattner113f4f42002-06-25 16:13:24 +0000224 return doInitialization(*F.getParent()) | runOnFunction(F)
225 | doFinalization(*F.getParent());
Chris Lattner26e4f892002-01-21 07:37:31 +0000226}
Chris Lattnerd013ba92002-01-23 05:49:41 +0000227
Chris Lattnerc8e66542002-04-27 06:56:12 +0000228void FunctionPass::addToPassManager(PassManagerT<Module> *PM,
229 AnalysisUsage &AU) {
230 PM->addPass(this, AU);
Chris Lattnerd013ba92002-01-23 05:49:41 +0000231}
Chris Lattnercdd09c22002-01-31 00:45:31 +0000232
Chris Lattnerc8e66542002-04-27 06:56:12 +0000233void FunctionPass::addToPassManager(PassManagerT<Function> *PM,
234 AnalysisUsage &AU) {
235 PM->addPass(this, AU);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000236}
237
238//===----------------------------------------------------------------------===//
239// BasicBlockPass Implementation
240//
241
Chris Lattnerc8e66542002-04-27 06:56:12 +0000242// To run this pass on a function, we simply call runOnBasicBlock once for each
243// function.
Chris Lattnercdd09c22002-01-31 00:45:31 +0000244//
Chris Lattner113f4f42002-06-25 16:13:24 +0000245bool BasicBlockPass::runOnFunction(Function &F) {
Chris Lattnerbae3c672002-09-12 17:06:40 +0000246 bool Changed = doInitialization(F);
Chris Lattner113f4f42002-06-25 16:13:24 +0000247 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
Chris Lattnercdd09c22002-01-31 00:45:31 +0000248 Changed |= runOnBasicBlock(*I);
Chris Lattnerbae3c672002-09-12 17:06:40 +0000249 return Changed | doFinalization(F);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000250}
251
252// To run directly on the basic block, we initialize, runOnBasicBlock, then
253// finalize.
254//
Chris Lattner113f4f42002-06-25 16:13:24 +0000255bool BasicBlockPass::run(BasicBlock &BB) {
Chris Lattnerbae3c672002-09-12 17:06:40 +0000256 Function &F = *BB.getParent();
257 Module &M = *F.getParent();
258 return doInitialization(M) | doInitialization(F) | runOnBasicBlock(BB) |
259 doFinalization(F) | doFinalization(M);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000260}
261
Chris Lattner57698e22002-03-26 18:01:55 +0000262void BasicBlockPass::addToPassManager(PassManagerT<Function> *PM,
Chris Lattnerc8e66542002-04-27 06:56:12 +0000263 AnalysisUsage &AU) {
264 PM->addPass(this, AU);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000265}
266
267void BasicBlockPass::addToPassManager(PassManagerT<BasicBlock> *PM,
Chris Lattnerc8e66542002-04-27 06:56:12 +0000268 AnalysisUsage &AU) {
269 PM->addPass(this, AU);
Chris Lattnercdd09c22002-01-31 00:45:31 +0000270}
271
Chris Lattner37d3c952002-07-23 18:08:00 +0000272
273//===----------------------------------------------------------------------===//
274// Pass Registration mechanism
275//
276static std::map<TypeInfo, PassInfo*> *PassInfoMap = 0;
277static std::vector<PassRegistrationListener*> *Listeners = 0;
278
279// getPassInfo - Return the PassInfo data structure that corresponds to this
280// pass...
281const PassInfo *Pass::getPassInfo() const {
Chris Lattner071577d2002-07-29 21:02:31 +0000282 if (PassInfoCache) return PassInfoCache;
Chris Lattner4b169632002-08-21 17:08:37 +0000283 return lookupPassInfo(typeid(*this));
284}
285
286const PassInfo *Pass::lookupPassInfo(const std::type_info &TI) {
Chris Lattner071577d2002-07-29 21:02:31 +0000287 if (PassInfoMap == 0) return 0;
Chris Lattner4b169632002-08-21 17:08:37 +0000288 std::map<TypeInfo, PassInfo*>::iterator I = PassInfoMap->find(TI);
Chris Lattner071577d2002-07-29 21:02:31 +0000289 return (I != PassInfoMap->end()) ? I->second : 0;
Chris Lattner37d3c952002-07-23 18:08:00 +0000290}
291
292void RegisterPassBase::registerPass(PassInfo *PI) {
293 if (PassInfoMap == 0)
294 PassInfoMap = new std::map<TypeInfo, PassInfo*>();
295
296 assert(PassInfoMap->find(PI->getTypeInfo()) == PassInfoMap->end() &&
297 "Pass already registered!");
298 PIObj = PI;
299 PassInfoMap->insert(std::make_pair(TypeInfo(PI->getTypeInfo()), PI));
300
301 // Notify any listeners...
302 if (Listeners)
303 for (std::vector<PassRegistrationListener*>::iterator
304 I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
305 (*I)->passRegistered(PI);
306}
307
Chris Lattner6e041bd2002-08-21 22:17:09 +0000308void RegisterPassBase::unregisterPass(PassInfo *PI) {
Chris Lattner37d3c952002-07-23 18:08:00 +0000309 assert(PassInfoMap && "Pass registered but not in map!");
310 std::map<TypeInfo, PassInfo*>::iterator I =
Chris Lattner6e041bd2002-08-21 22:17:09 +0000311 PassInfoMap->find(PI->getTypeInfo());
Chris Lattner37d3c952002-07-23 18:08:00 +0000312 assert(I != PassInfoMap->end() && "Pass registered but not in map!");
313
314 // Remove pass from the map...
315 PassInfoMap->erase(I);
316 if (PassInfoMap->empty()) {
317 delete PassInfoMap;
318 PassInfoMap = 0;
319 }
320
321 // Notify any listeners...
322 if (Listeners)
323 for (std::vector<PassRegistrationListener*>::iterator
324 I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
Chris Lattner6e041bd2002-08-21 22:17:09 +0000325 (*I)->passUnregistered(PI);
Chris Lattner37d3c952002-07-23 18:08:00 +0000326
327 // Delete the PassInfo object itself...
Chris Lattner6e041bd2002-08-21 22:17:09 +0000328 delete PI;
Chris Lattner37d3c952002-07-23 18:08:00 +0000329}
330
Chris Lattner6e041bd2002-08-21 22:17:09 +0000331//===----------------------------------------------------------------------===//
332// Analysis Group Implementation Code
333//===----------------------------------------------------------------------===//
334
335struct AnalysisGroupInfo {
336 const PassInfo *DefaultImpl;
337 std::set<const PassInfo *> Implementations;
338 AnalysisGroupInfo() : DefaultImpl(0) {}
339};
340
341static std::map<const PassInfo *, AnalysisGroupInfo> *AnalysisGroupInfoMap = 0;
342
343// RegisterAGBase implementation
344//
345RegisterAGBase::RegisterAGBase(const std::type_info &Interface,
346 const std::type_info *Pass, bool isDefault)
347 : ImplementationInfo(0), isDefaultImplementation(isDefault) {
348
Chris Lattner6e041bd2002-08-21 22:17:09 +0000349 InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(Interface));
350 if (InterfaceInfo == 0) { // First reference to Interface, add it now.
351 InterfaceInfo = // Create the new PassInfo for the interface...
352 new PassInfo("", "", Interface, PassInfo::AnalysisGroup, 0, 0);
353 registerPass(InterfaceInfo);
354 PIObj = 0;
355 }
356 assert(InterfaceInfo->getPassType() == PassInfo::AnalysisGroup &&
357 "Trying to join an analysis group that is a normal pass!");
358
359 if (Pass) {
Chris Lattner6e041bd2002-08-21 22:17:09 +0000360 ImplementationInfo = Pass::lookupPassInfo(*Pass);
361 assert(ImplementationInfo &&
362 "Must register pass before adding to AnalysisGroup!");
363
Chris Lattnerb3708e22002-08-30 20:23:45 +0000364 // Make sure we keep track of the fact that the implementation implements
365 // the interface.
366 PassInfo *IIPI = const_cast<PassInfo*>(ImplementationInfo);
367 IIPI->addInterfaceImplemented(InterfaceInfo);
368
Chris Lattner6e041bd2002-08-21 22:17:09 +0000369 // Lazily allocate to avoid nasty initialization order dependencies
370 if (AnalysisGroupInfoMap == 0)
371 AnalysisGroupInfoMap = new std::map<const PassInfo *,AnalysisGroupInfo>();
372
373 AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo];
374 assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
375 "Cannot add a pass to the same analysis group more than once!");
376 AGI.Implementations.insert(ImplementationInfo);
377 if (isDefault) {
378 assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 &&
379 "Default implementation for analysis group already specified!");
380 assert(ImplementationInfo->getNormalCtor() &&
381 "Cannot specify pass as default if it does not have a default ctor");
382 AGI.DefaultImpl = ImplementationInfo;
383 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
384 }
385 }
386}
387
388void RegisterAGBase::setGroupName(const char *Name) {
389 assert(InterfaceInfo->getPassName()[0] == 0 && "Interface Name already set!");
390 InterfaceInfo->setPassName(Name);
391}
392
393RegisterAGBase::~RegisterAGBase() {
394 if (ImplementationInfo) {
395 assert(AnalysisGroupInfoMap && "Inserted into map, but map doesn't exist?");
396 AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo];
397
398 assert(AGI.Implementations.count(ImplementationInfo) &&
399 "Pass not a member of analysis group?");
400
401 if (AGI.DefaultImpl == ImplementationInfo)
402 AGI.DefaultImpl = 0;
403
404 AGI.Implementations.erase(ImplementationInfo);
405
406 // Last member of this analysis group? Unregister PassInfo, delete map entry
407 if (AGI.Implementations.empty()) {
408 assert(AGI.DefaultImpl == 0 &&
409 "Default implementation didn't unregister?");
410 AnalysisGroupInfoMap->erase(InterfaceInfo);
411 if (AnalysisGroupInfoMap->empty()) { // Delete map if empty
412 delete AnalysisGroupInfoMap;
413 AnalysisGroupInfoMap = 0;
414 }
415
416 unregisterPass(InterfaceInfo);
417 }
418 }
419}
420
421
Chris Lattner37d3c952002-07-23 18:08:00 +0000422//===----------------------------------------------------------------------===//
423// PassRegistrationListener implementation
424//
425
426// PassRegistrationListener ctor - Add the current object to the list of
427// PassRegistrationListeners...
428PassRegistrationListener::PassRegistrationListener() {
429 if (!Listeners) Listeners = new std::vector<PassRegistrationListener*>();
430 Listeners->push_back(this);
431}
432
433// dtor - Remove object from list of listeners...
434PassRegistrationListener::~PassRegistrationListener() {
435 std::vector<PassRegistrationListener*>::iterator I =
436 std::find(Listeners->begin(), Listeners->end(), this);
437 assert(Listeners && I != Listeners->end() &&
438 "PassRegistrationListener not registered!");
439 Listeners->erase(I);
440
441 if (Listeners->empty()) {
442 delete Listeners;
443 Listeners = 0;
444 }
445}
446
447// enumeratePasses - Iterate over the registered passes, calling the
448// passEnumerate callback on each PassInfo object.
449//
450void PassRegistrationListener::enumeratePasses() {
451 if (PassInfoMap)
452 for (std::map<TypeInfo, PassInfo*>::iterator I = PassInfoMap->begin(),
453 E = PassInfoMap->end(); I != E; ++I)
454 passEnumerate(I->second);
455}