Move the handling of PassRegistrationListener's to PassRegistry.
[oota-llvm.git] / lib / VMCore / PassRegistry.cpp
1 //===- PassRegistry.cpp - Pass Registration Implementation ----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the PassRegistry, with which passes are registered on
11 // initialization, and supports the PassManager in dependency resolution.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/PassRegistry.h"
16 #include "llvm/PassSupport.h"
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/ManagedStatic.h"
19
20 using namespace llvm;
21
22 static PassRegistry *PassRegistryObj = 0;
23 PassRegistry *PassRegistry::getPassRegistry() {
24   // Use double-checked locking to safely initialize the registrar when
25   // we're running in multithreaded mode.
26   PassRegistry* tmp = PassRegistryObj;
27   if (llvm_is_multithreaded()) {
28     sys::MemoryFence();
29     if (!tmp) {
30       llvm_acquire_global_lock();
31       tmp = PassRegistryObj;
32       if (!tmp) {
33         tmp = new PassRegistry();
34         sys::MemoryFence();
35         PassRegistryObj = tmp;
36       }
37       llvm_release_global_lock();
38     }
39   } else if (!tmp) {
40     PassRegistryObj = new PassRegistry();
41   }
42   
43   return PassRegistryObj;
44 }
45
46 namespace {
47
48 // FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
49 // Unfortunately, passes are registered with static ctors, and having
50 // llvm_shutdown clear this map prevents successful ressurection after 
51 // llvm_shutdown is run.  Ideally we should find a solution so that we don't
52 // leak the map, AND can still resurrect after shutdown.
53 void cleanupPassRegistry(void*) {
54   if (PassRegistryObj) {
55     delete PassRegistryObj;
56     PassRegistryObj = 0;
57   }
58 }
59 ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
60
61 }
62
63 const PassInfo *PassRegistry::getPassInfo(intptr_t TI) const {
64   sys::SmartScopedLock<true> Guard(Lock);
65   MapType::const_iterator I = PassInfoMap.find(TI);
66   return I != PassInfoMap.end() ? I->second : 0;
67 }
68
69 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
70   sys::SmartScopedLock<true> Guard(Lock);
71   StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
72   return I != PassInfoStringMap.end() ? I->second : 0;
73 }
74
75 //===----------------------------------------------------------------------===//
76 // Pass Registration mechanism
77 //
78
79 void PassRegistry::registerPass(const PassInfo &PI) {
80   sys::SmartScopedLock<true> Guard(Lock);
81   bool Inserted =
82     PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
83   assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
84   PassInfoStringMap[PI.getPassArgument()] = &PI;
85   
86   // Notify any listeners.
87   for (std::vector<PassRegistrationListener*>::iterator
88        I = Listeners.begin(), E = Listeners.end(); I != E; ++I)
89     (*I)->passRegistered(&PI);
90 }
91
92 void PassRegistry::unregisterPass(const PassInfo &PI) {
93   sys::SmartScopedLock<true> Guard(Lock);
94   MapType::iterator I = PassInfoMap.find(PI.getTypeInfo());
95   assert(I != PassInfoMap.end() && "Pass registered but not in map!");
96   
97   // Remove pass from the map.
98   PassInfoMap.erase(I);
99   PassInfoStringMap.erase(PI.getPassArgument());
100 }
101
102 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
103   sys::SmartScopedLock<true> Guard(Lock);
104   for (MapType::const_iterator I = PassInfoMap.begin(),
105        E = PassInfoMap.end(); I != E; ++I)
106     L->passEnumerate(I->second);
107 }
108
109
110 /// Analysis Group Mechanisms.
111 void PassRegistry::registerAnalysisGroup(PassInfo *InterfaceInfo,
112                                          const PassInfo *ImplementationInfo,
113                                          bool isDefault) {
114   sys::SmartScopedLock<true> Guard(Lock);
115   AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
116   assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
117          "Cannot add a pass to the same analysis group more than once!");
118   AGI.Implementations.insert(ImplementationInfo);
119   if (isDefault) {
120     assert(InterfaceInfo->getNormalCtor() == 0 &&
121            "Default implementation for analysis group already specified!");
122     assert(ImplementationInfo->getNormalCtor() &&
123          "Cannot specify pass as default if it does not have a default ctor");
124     InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
125   }
126 }
127
128 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
129   sys::SmartScopedLock<true> Guard(Lock);
130   Listeners.push_back(L);
131 }
132
133 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
134   sys::SmartScopedLock<true> Guard(Lock);
135   std::vector<PassRegistrationListener*>::iterator I =
136     std::find(Listeners.begin(), Listeners.end(), L);
137   assert(I != Listeners.end() && "PassRegistrationListener not registered!");
138   Listeners.erase(I);
139 }