1 //===- PassRegistry.cpp - Pass Registration Implementation ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the PassRegistry, with which passes are registered on
11 // initialization, and supports the PassManager in dependency resolution.
13 //===----------------------------------------------------------------------===//
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"
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()) {
33 llvm_acquire_global_lock();
34 tmp = PassRegistryObj;
36 tmp = new PassRegistry();
38 PassRegistryObj = tmp;
40 llvm_release_global_lock();
43 PassRegistryObj = new PassRegistry();
46 return PassRegistryObj;
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;
62 ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
66 //===----------------------------------------------------------------------===//
70 struct PassRegistryImpl {
71 /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
72 typedef DenseMap<const void*, const PassInfo*> MapType;
75 typedef StringMap<const PassInfo*> StringMapType;
76 StringMapType PassInfoStringMap;
78 /// AnalysisGroupInfo - Keep track of information for each analysis group.
79 struct AnalysisGroupInfo {
80 SmallPtrSet<const PassInfo *, 8> Implementations;
82 DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
84 std::vector<PassRegistrationListener*> Listeners;
87 void *PassRegistry::getImpl() const {
89 pImpl = new PassRegistryImpl();
93 //===----------------------------------------------------------------------===//
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;
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;
110 //===----------------------------------------------------------------------===//
111 // Pass Registration mechanism
114 void PassRegistry::registerPass(const PassInfo &PI) {
115 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
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;
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);
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!");
133 // Remove pass from the map.
134 Impl->PassInfoMap.erase(I);
135 Impl->PassInfoStringMap.erase(PI.getPassArgument());
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);
146 /// Analysis Group Mechanisms.
147 void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
149 PassInfo& Registeree,
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;
157 assert(Registeree.isAnalysisGroup() &&
158 "Trying to join an analysis group that is a normal pass!");
161 PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
162 assert(ImplementationInfo &&
163 "Must register pass before adding to AnalysisGroup!");
165 // Make sure we keep track of the fact that the implementation implements
167 ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
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);
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());
185 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
186 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
187 Impl->Listeners.push_back(L);
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);