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/Support/Mutex.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/StringMap.h"
27 // FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
28 // Unfortunately, passes are registered with static ctors, and having
29 // llvm_shutdown clear this map prevents successful resurrection after
30 // llvm_shutdown is run. Ideally we should find a solution so that we don't
31 // leak the map, AND can still resurrect after shutdown.
32 static ManagedStatic
<PassRegistry
> PassRegistryObj
;
33 PassRegistry
*PassRegistry::getPassRegistry() {
34 return &*PassRegistryObj
;
37 static ManagedStatic
<sys::SmartMutex
<true> > Lock
;
39 //===----------------------------------------------------------------------===//
44 struct PassRegistryImpl
{
45 /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
46 typedef DenseMap
<const void*, const PassInfo
*> MapType
;
49 typedef StringMap
<const PassInfo
*> StringMapType
;
50 StringMapType PassInfoStringMap
;
52 /// AnalysisGroupInfo - Keep track of information for each analysis group.
53 struct AnalysisGroupInfo
{
54 SmallPtrSet
<const PassInfo
*, 8> Implementations
;
56 DenseMap
<const PassInfo
*, AnalysisGroupInfo
> AnalysisGroupInfoMap
;
58 std::vector
<const PassInfo
*> ToFree
;
59 std::vector
<PassRegistrationListener
*> Listeners
;
61 } // end anonymous namespace
63 void *PassRegistry::getImpl() const {
65 pImpl
= new PassRegistryImpl();
69 //===----------------------------------------------------------------------===//
73 PassRegistry::~PassRegistry() {
74 sys::SmartScopedLock
<true> Guard(*Lock
);
75 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(pImpl
);
77 for (std::vector
<const PassInfo
*>::iterator I
= Impl
->ToFree
.begin(),
78 E
= Impl
->ToFree
.end(); I
!= E
; ++I
)
85 const PassInfo
*PassRegistry::getPassInfo(const void *TI
) const {
86 sys::SmartScopedLock
<true> Guard(*Lock
);
87 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
88 PassRegistryImpl::MapType::const_iterator I
= Impl
->PassInfoMap
.find(TI
);
89 return I
!= Impl
->PassInfoMap
.end() ? I
->second
: 0;
92 const PassInfo
*PassRegistry::getPassInfo(StringRef Arg
) const {
93 sys::SmartScopedLock
<true> Guard(*Lock
);
94 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
95 PassRegistryImpl::StringMapType::const_iterator
96 I
= Impl
->PassInfoStringMap
.find(Arg
);
97 return I
!= Impl
->PassInfoStringMap
.end() ? I
->second
: 0;
100 //===----------------------------------------------------------------------===//
101 // Pass Registration mechanism
104 void PassRegistry::registerPass(const PassInfo
&PI
, bool ShouldFree
) {
105 sys::SmartScopedLock
<true> Guard(*Lock
);
106 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
108 Impl
->PassInfoMap
.insert(std::make_pair(PI
.getTypeInfo(),&PI
)).second
;
109 assert(Inserted
&& "Pass registered multiple times!");
111 Impl
->PassInfoStringMap
[PI
.getPassArgument()] = &PI
;
113 // Notify any listeners.
114 for (std::vector
<PassRegistrationListener
*>::iterator
115 I
= Impl
->Listeners
.begin(), E
= Impl
->Listeners
.end(); I
!= E
; ++I
)
116 (*I
)->passRegistered(&PI
);
118 if (ShouldFree
) Impl
->ToFree
.push_back(&PI
);
121 void PassRegistry::unregisterPass(const PassInfo
&PI
) {
122 sys::SmartScopedLock
<true> Guard(*Lock
);
123 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
124 PassRegistryImpl::MapType::iterator I
=
125 Impl
->PassInfoMap
.find(PI
.getTypeInfo());
126 assert(I
!= Impl
->PassInfoMap
.end() && "Pass registered but not in map!");
128 // Remove pass from the map.
129 Impl
->PassInfoMap
.erase(I
);
130 Impl
->PassInfoStringMap
.erase(PI
.getPassArgument());
133 void PassRegistry::enumerateWith(PassRegistrationListener
*L
) {
134 sys::SmartScopedLock
<true> Guard(*Lock
);
135 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
136 for (PassRegistryImpl::MapType::const_iterator I
= Impl
->PassInfoMap
.begin(),
137 E
= Impl
->PassInfoMap
.end(); I
!= E
; ++I
)
138 L
->passEnumerate(I
->second
);
142 /// Analysis Group Mechanisms.
143 void PassRegistry::registerAnalysisGroup(const void *InterfaceID
,
145 PassInfo
& Registeree
,
148 PassInfo
*InterfaceInfo
= const_cast<PassInfo
*>(getPassInfo(InterfaceID
));
149 if (InterfaceInfo
== 0) {
150 // First reference to Interface, register it now.
151 registerPass(Registeree
);
152 InterfaceInfo
= &Registeree
;
154 assert(Registeree
.isAnalysisGroup() &&
155 "Trying to join an analysis group that is a normal pass!");
158 PassInfo
*ImplementationInfo
= const_cast<PassInfo
*>(getPassInfo(PassID
));
159 assert(ImplementationInfo
&&
160 "Must register pass before adding to AnalysisGroup!");
162 sys::SmartScopedLock
<true> Guard(*Lock
);
164 // Make sure we keep track of the fact that the implementation implements
166 ImplementationInfo
->addInterfaceImplemented(InterfaceInfo
);
168 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
169 PassRegistryImpl::AnalysisGroupInfo
&AGI
=
170 Impl
->AnalysisGroupInfoMap
[InterfaceInfo
];
171 assert(AGI
.Implementations
.count(ImplementationInfo
) == 0 &&
172 "Cannot add a pass to the same analysis group more than once!");
173 AGI
.Implementations
.insert(ImplementationInfo
);
175 assert(InterfaceInfo
->getNormalCtor() == 0 &&
176 "Default implementation for analysis group already specified!");
177 assert(ImplementationInfo
->getNormalCtor() &&
178 "Cannot specify pass as default if it does not have a default ctor");
179 InterfaceInfo
->setNormalCtor(ImplementationInfo
->getNormalCtor());
183 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
184 if (ShouldFree
) Impl
->ToFree
.push_back(&Registeree
);
187 void PassRegistry::addRegistrationListener(PassRegistrationListener
*L
) {
188 sys::SmartScopedLock
<true> Guard(*Lock
);
189 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
190 Impl
->Listeners
.push_back(L
);
193 void PassRegistry::removeRegistrationListener(PassRegistrationListener
*L
) {
194 sys::SmartScopedLock
<true> Guard(*Lock
);
196 // NOTE: This is necessary, because removeRegistrationListener() can be called
197 // as part of the llvm_shutdown sequence. Since we have no control over the
198 // order of that sequence, we need to gracefully handle the case where the
199 // PassRegistry is destructed before the object that triggers this call.
202 PassRegistryImpl
*Impl
= static_cast<PassRegistryImpl
*>(getImpl());
203 std::vector
<PassRegistrationListener
*>::iterator I
=
204 std::find(Impl
->Listeners
.begin(), Impl
->Listeners
.end(), L
);
205 assert(I
!= Impl
->Listeners
.end() &&
206 "PassRegistrationListener not registered!");
207 Impl
->Listeners
.erase(I
);