blob: 1fc26b0648db9c8f070f807b4c33f83c0e2a5c3a [file] [log] [blame]
Owen Anderson660466e2010-07-20 19:23:55 +00001//===- 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"
Owen Anderson7fc9fe72010-07-20 23:41:56 +000016#include "llvm/PassSupport.h"
Owen Anderson41540612010-07-20 21:22:24 +000017#include "llvm/Support/Compiler.h"
18#include "llvm/Support/ManagedStatic.h"
Owen Andersond8788272010-09-16 23:32:35 +000019#include "llvm/System/Mutex.h"
Owen Andersona74fa152010-09-07 19:16:25 +000020#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallPtrSet.h"
Owen Anderson0bf2a922010-09-13 18:47:42 +000022#include "llvm/ADT/StringMap.h"
Owen Andersona74fa152010-09-07 19:16:25 +000023#include <vector>
Owen Anderson41540612010-07-20 21:22:24 +000024
Owen Anderson7fc9fe72010-07-20 23:41:56 +000025using namespace llvm;
26
Owen Andersond12ea002010-09-07 20:48:10 +000027// FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
Owen Anderson41540612010-07-20 21:22:24 +000028// Unfortunately, passes are registered with static ctors, and having
29// llvm_shutdown clear this map prevents successful ressurection 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.
Owen Andersond12ea002010-09-07 20:48:10 +000032static ManagedStatic<PassRegistry> PassRegistryObj;
33PassRegistry *PassRegistry::getPassRegistry() {
34 return &*PassRegistryObj;
Owen Anderson41540612010-07-20 21:22:24 +000035}
Owen Anderson660466e2010-07-20 19:23:55 +000036
Owen Andersonc2fcd6102010-09-16 23:44:50 +000037static ManagedStatic<sys::SmartMutex<true> > Lock;
Owen Andersond8788272010-09-16 23:32:35 +000038
Owen Andersona74fa152010-09-07 19:16:25 +000039//===----------------------------------------------------------------------===//
40// PassRegistryImpl
41//
42
Benjamin Kramer9192e7a2010-10-22 17:35:07 +000043namespace {
Owen Andersona74fa152010-09-07 19:16:25 +000044struct PassRegistryImpl {
45 /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
46 typedef DenseMap<const void*, const PassInfo*> MapType;
47 MapType PassInfoMap;
48
49 typedef StringMap<const PassInfo*> StringMapType;
50 StringMapType PassInfoStringMap;
51
52 /// AnalysisGroupInfo - Keep track of information for each analysis group.
53 struct AnalysisGroupInfo {
54 SmallPtrSet<const PassInfo *, 8> Implementations;
55 };
56 DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
57
Owen Anderson80b88172010-10-20 22:22:30 +000058 std::vector<const PassInfo*> ToFree;
Owen Andersona74fa152010-09-07 19:16:25 +000059 std::vector<PassRegistrationListener*> Listeners;
60};
Benjamin Kramer9192e7a2010-10-22 17:35:07 +000061} // end anonymous namespace
Owen Andersona74fa152010-09-07 19:16:25 +000062
63void *PassRegistry::getImpl() const {
64 if (!pImpl)
65 pImpl = new PassRegistryImpl();
66 return pImpl;
67}
68
69//===----------------------------------------------------------------------===//
70// Accessors
71//
72
Owen Andersond12ea002010-09-07 20:48:10 +000073PassRegistry::~PassRegistry() {
Owen Andersonc2fcd6102010-09-16 23:44:50 +000074 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersond12ea002010-09-07 20:48:10 +000075 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl);
Owen Anderson80b88172010-10-20 22:22:30 +000076
77 for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(),
78 E = Impl->ToFree.end(); I != E; ++I)
79 delete *I;
80
Dan Gohmancb854972010-10-12 00:19:24 +000081 delete Impl;
Owen Andersond12ea002010-09-07 20:48:10 +000082 pImpl = 0;
83}
84
Owen Andersona7aed182010-08-06 18:33:48 +000085const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
Owen Andersonc2fcd6102010-09-16 23:44:50 +000086 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000087 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;
Owen Anderson660466e2010-07-20 19:23:55 +000090}
91
92const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
Owen Andersonc2fcd6102010-09-16 23:44:50 +000093 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000094 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;
Owen Anderson660466e2010-07-20 19:23:55 +000098}
99
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000100//===----------------------------------------------------------------------===//
101// Pass Registration mechanism
102//
103
Owen Anderson80b88172010-10-20 22:22:30 +0000104void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000105 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000106 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson660466e2010-07-20 19:23:55 +0000107 bool Inserted =
Owen Andersona74fa152010-09-07 19:16:25 +0000108 Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
Owen Anderson660466e2010-07-20 19:23:55 +0000109 assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
Owen Andersona74fa152010-09-07 19:16:25 +0000110 Impl->PassInfoStringMap[PI.getPassArgument()] = &PI;
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000111
112 // Notify any listeners.
113 for (std::vector<PassRegistrationListener*>::iterator
Owen Andersona74fa152010-09-07 19:16:25 +0000114 I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I)
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000115 (*I)->passRegistered(&PI);
Owen Anderson80b88172010-10-20 22:22:30 +0000116
117 if (ShouldFree) Impl->ToFree.push_back(&PI);
Owen Anderson660466e2010-07-20 19:23:55 +0000118}
119
120void PassRegistry::unregisterPass(const PassInfo &PI) {
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000121 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000122 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
123 PassRegistryImpl::MapType::iterator I =
124 Impl->PassInfoMap.find(PI.getTypeInfo());
125 assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!");
Owen Anderson660466e2010-07-20 19:23:55 +0000126
127 // Remove pass from the map.
Owen Andersona74fa152010-09-07 19:16:25 +0000128 Impl->PassInfoMap.erase(I);
129 Impl->PassInfoStringMap.erase(PI.getPassArgument());
Owen Anderson660466e2010-07-20 19:23:55 +0000130}
131
132void PassRegistry::enumerateWith(PassRegistrationListener *L) {
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000133 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000134 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
135 for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
136 E = Impl->PassInfoMap.end(); I != E; ++I)
Owen Anderson660466e2010-07-20 19:23:55 +0000137 L->passEnumerate(I->second);
138}
139
140
141/// Analysis Group Mechanisms.
Owen Andersona7aed182010-08-06 18:33:48 +0000142void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
143 const void *PassID,
Owen Anderson845b14e2010-07-21 17:52:45 +0000144 PassInfo& Registeree,
Owen Anderson80b88172010-10-20 22:22:30 +0000145 bool isDefault,
146 bool ShouldFree) {
Owen Anderson845b14e2010-07-21 17:52:45 +0000147 PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID));
148 if (InterfaceInfo == 0) {
149 // First reference to Interface, register it now.
150 registerPass(Registeree);
151 InterfaceInfo = &Registeree;
152 }
153 assert(Registeree.isAnalysisGroup() &&
154 "Trying to join an analysis group that is a normal pass!");
155
156 if (PassID) {
157 PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
158 assert(ImplementationInfo &&
159 "Must register pass before adding to AnalysisGroup!");
160
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000161 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersond8788272010-09-16 23:32:35 +0000162
Owen Anderson845b14e2010-07-21 17:52:45 +0000163 // Make sure we keep track of the fact that the implementation implements
164 // the interface.
165 ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
166
Owen Andersona74fa152010-09-07 19:16:25 +0000167 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
168 PassRegistryImpl::AnalysisGroupInfo &AGI =
169 Impl->AnalysisGroupInfoMap[InterfaceInfo];
Owen Anderson845b14e2010-07-21 17:52:45 +0000170 assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
171 "Cannot add a pass to the same analysis group more than once!");
172 AGI.Implementations.insert(ImplementationInfo);
173 if (isDefault) {
174 assert(InterfaceInfo->getNormalCtor() == 0 &&
175 "Default implementation for analysis group already specified!");
176 assert(ImplementationInfo->getNormalCtor() &&
177 "Cannot specify pass as default if it does not have a default ctor");
178 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
179 }
Owen Anderson660466e2010-07-20 19:23:55 +0000180 }
Owen Anderson80b88172010-10-20 22:22:30 +0000181
182 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
183 if (ShouldFree) Impl->ToFree.push_back(&Registeree);
Owen Anderson660466e2010-07-20 19:23:55 +0000184}
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000185
186void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000187 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000188 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
189 Impl->Listeners.push_back(L);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000190}
191
192void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
Owen Andersonc2fcd6102010-09-16 23:44:50 +0000193 sys::SmartScopedLock<true> Guard(*Lock);
Owen Andersond4754972010-09-15 23:03:33 +0000194
Owen Andersond12ea002010-09-07 20:48:10 +0000195 // NOTE: This is necessary, because removeRegistrationListener() can be called
196 // as part of the llvm_shutdown sequence. Since we have no control over the
197 // order of that sequence, we need to gracefully handle the case where the
198 // PassRegistry is destructed before the object that triggers this call.
199 if (!pImpl) return;
200
Owen Andersona74fa152010-09-07 19:16:25 +0000201 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000202 std::vector<PassRegistrationListener*>::iterator I =
Owen Andersona74fa152010-09-07 19:16:25 +0000203 std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);
204 assert(I != Impl->Listeners.end() &&
205 "PassRegistrationListener not registered!");
206 Impl->Listeners.erase(I);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000207}