562c58c0b95203769962d2087ac23b668a755ab4
[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 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include <vector>
22
23 using namespace llvm;
24
25 static PassRegistry *PassRegistryObj = 0;
26 PassRegistry *PassRegistry::getPassRegistry() {
27   // Use double-checked locking to safely initialize the registrar when
28   // we're running in multithreaded mode.
29   PassRegistry* tmp = PassRegistryObj;
30   if (llvm_is_multithreaded()) {
31     sys::MemoryFence();
32     if (!tmp) {
33       llvm_acquire_global_lock();
34       tmp = PassRegistryObj;
35       if (!tmp) {
36         tmp = new PassRegistry();
37         sys::MemoryFence();
38         PassRegistryObj = tmp;
39       }
40       llvm_release_global_lock();
41     }
42   } else if (!tmp) {
43     PassRegistryObj = new PassRegistry();
44   }
45   
46   return PassRegistryObj;
47 }
48
49 namespace {
50
51 // FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
52 // Unfortunately, passes are registered with static ctors, and having
53 // llvm_shutdown clear this map prevents successful ressurection after 
54 // llvm_shutdown is run.  Ideally we should find a solution so that we don't
55 // leak the map, AND can still resurrect after shutdown.
56 void cleanupPassRegistry(void*) {
57   if (PassRegistryObj) {
58     delete PassRegistryObj;
59     PassRegistryObj = 0;
60   }
61 }
62 ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
63
64 }
65
66 //===----------------------------------------------------------------------===//
67 // PassRegistryImpl
68 //
69
70 struct PassRegistryImpl {
71   /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
72   typedef DenseMap<const void*, const PassInfo*> MapType;
73   MapType PassInfoMap;
74   
75   typedef StringMap<const PassInfo*> StringMapType;
76   StringMapType PassInfoStringMap;
77   
78   /// AnalysisGroupInfo - Keep track of information for each analysis group.
79   struct AnalysisGroupInfo {
80     SmallPtrSet<const PassInfo *, 8> Implementations;
81   };
82   DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
83   
84   std::vector<PassRegistrationListener*> Listeners;
85 };
86
87 void *PassRegistry::getImpl() const {
88   if (!pImpl)
89     pImpl = new PassRegistryImpl();
90   return pImpl;
91 }
92
93 //===----------------------------------------------------------------------===//
94 // Accessors
95 //
96
97 const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
98   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
99   PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
100   return I != Impl->PassInfoMap.end() ? I->second : 0;
101 }
102
103 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
104   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
105   PassRegistryImpl::StringMapType::const_iterator
106     I = Impl->PassInfoStringMap.find(Arg);
107   return I != Impl->PassInfoStringMap.end() ? I->second : 0;
108 }
109
110 //===----------------------------------------------------------------------===//
111 // Pass Registration mechanism
112 //
113
114 void PassRegistry::registerPass(const PassInfo &PI) {
115   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
116   bool Inserted =
117     Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
118   assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
119   Impl->PassInfoStringMap[PI.getPassArgument()] = &PI;
120   
121   // Notify any listeners.
122   for (std::vector<PassRegistrationListener*>::iterator
123        I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I)
124     (*I)->passRegistered(&PI);
125 }
126
127 void PassRegistry::unregisterPass(const PassInfo &PI) {
128   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
129   PassRegistryImpl::MapType::iterator I = 
130     Impl->PassInfoMap.find(PI.getTypeInfo());
131   assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!");
132   
133   // Remove pass from the map.
134   Impl->PassInfoMap.erase(I);
135   Impl->PassInfoStringMap.erase(PI.getPassArgument());
136 }
137
138 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
139   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
140   for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
141        E = Impl->PassInfoMap.end(); I != E; ++I)
142     L->passEnumerate(I->second);
143 }
144
145
146 /// Analysis Group Mechanisms.
147 void PassRegistry::registerAnalysisGroup(const void *InterfaceID, 
148                                          const void *PassID,
149                                          PassInfo& Registeree,
150                                          bool isDefault) {
151   PassInfo *InterfaceInfo =  const_cast<PassInfo*>(getPassInfo(InterfaceID));
152   if (InterfaceInfo == 0) {
153     // First reference to Interface, register it now.
154     registerPass(Registeree);
155     InterfaceInfo = &Registeree;
156   }
157   assert(Registeree.isAnalysisGroup() && 
158          "Trying to join an analysis group that is a normal pass!");
159
160   if (PassID) {
161     PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
162     assert(ImplementationInfo &&
163            "Must register pass before adding to AnalysisGroup!");
164
165     // Make sure we keep track of the fact that the implementation implements
166     // the interface.
167     ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
168
169     PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
170     PassRegistryImpl::AnalysisGroupInfo &AGI =
171       Impl->AnalysisGroupInfoMap[InterfaceInfo];
172     assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
173            "Cannot add a pass to the same analysis group more than once!");
174     AGI.Implementations.insert(ImplementationInfo);
175     if (isDefault) {
176       assert(InterfaceInfo->getNormalCtor() == 0 &&
177              "Default implementation for analysis group already specified!");
178       assert(ImplementationInfo->getNormalCtor() &&
179            "Cannot specify pass as default if it does not have a default ctor");
180       InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
181     }
182   }
183 }
184
185 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
186   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
187   Impl->Listeners.push_back(L);
188 }
189
190 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
191   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
192   std::vector<PassRegistrationListener*>::iterator I =
193     std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);
194   assert(I != Impl->Listeners.end() &&
195          "PassRegistrationListener not registered!");
196   Impl->Listeners.erase(I);
197 }