blob: d3b2f1fce1c5f3c71f0804d71bd7cafeb38b2854 [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 Andersona74fa152010-09-07 19:16:25 +000016#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/SmallPtrSet.h"
Owen Anderson0bf2a922010-09-13 18:47:42 +000018#include "llvm/ADT/StringMap.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000019#include "llvm/IR/Function.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/PassSupport.h"
21#include "llvm/Support/Compiler.h"
22#include "llvm/Support/ManagedStatic.h"
23#include "llvm/Support/Mutex.h"
Chad Rosier673a7db2013-07-03 18:38:08 +000024#include "llvm/Support/RWMutex.h"
Owen Andersona74fa152010-09-07 19:16:25 +000025#include <vector>
Owen Anderson41540612010-07-20 21:22:24 +000026
Owen Anderson7fc9fe72010-07-20 23:41:56 +000027using namespace llvm;
28
Owen Andersond12ea002010-09-07 20:48:10 +000029// FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
Owen Anderson41540612010-07-20 21:22:24 +000030// Unfortunately, passes are registered with static ctors, and having
Chris Lattner0ab5e2c2011-04-15 05:18:47 +000031// llvm_shutdown clear this map prevents successful resurrection after
Owen Anderson41540612010-07-20 21:22:24 +000032// llvm_shutdown is run. Ideally we should find a solution so that we don't
33// leak the map, AND can still resurrect after shutdown.
Owen Andersond12ea002010-09-07 20:48:10 +000034static ManagedStatic<PassRegistry> PassRegistryObj;
35PassRegistry *PassRegistry::getPassRegistry() {
36 return &*PassRegistryObj;
Owen Anderson41540612010-07-20 21:22:24 +000037}
Owen Anderson660466e2010-07-20 19:23:55 +000038
Chad Rosier673a7db2013-07-03 18:38:08 +000039static ManagedStatic<sys::SmartRWMutex<true> > Lock;
Owen Andersond8788272010-09-16 23:32:35 +000040
Owen Andersona74fa152010-09-07 19:16:25 +000041//===----------------------------------------------------------------------===//
42// PassRegistryImpl
43//
44
Benjamin Kramer9192e7a2010-10-22 17:35:07 +000045namespace {
Owen Andersona74fa152010-09-07 19:16:25 +000046struct PassRegistryImpl {
47 /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
48 typedef DenseMap<const void*, const PassInfo*> MapType;
49 MapType PassInfoMap;
50
51 typedef StringMap<const PassInfo*> StringMapType;
52 StringMapType PassInfoStringMap;
53
54 /// AnalysisGroupInfo - Keep track of information for each analysis group.
55 struct AnalysisGroupInfo {
56 SmallPtrSet<const PassInfo *, 8> Implementations;
57 };
58 DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
59
Owen Anderson80b88172010-10-20 22:22:30 +000060 std::vector<const PassInfo*> ToFree;
Owen Andersona74fa152010-09-07 19:16:25 +000061 std::vector<PassRegistrationListener*> Listeners;
62};
Benjamin Kramer9192e7a2010-10-22 17:35:07 +000063} // end anonymous namespace
Owen Andersona74fa152010-09-07 19:16:25 +000064
65void *PassRegistry::getImpl() const {
66 if (!pImpl)
67 pImpl = new PassRegistryImpl();
68 return pImpl;
69}
70
71//===----------------------------------------------------------------------===//
72// Accessors
73//
74
Owen Andersond12ea002010-09-07 20:48:10 +000075PassRegistry::~PassRegistry() {
Chad Rosier673a7db2013-07-03 18:38:08 +000076 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersond12ea002010-09-07 20:48:10 +000077 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl);
Owen Anderson80b88172010-10-20 22:22:30 +000078
79 for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(),
80 E = Impl->ToFree.end(); I != E; ++I)
81 delete *I;
82
Dan Gohmancb854972010-10-12 00:19:24 +000083 delete Impl;
Owen Andersond12ea002010-09-07 20:48:10 +000084 pImpl = 0;
85}
86
Owen Andersona7aed182010-08-06 18:33:48 +000087const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
Chad Rosier673a7db2013-07-03 18:38:08 +000088 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000089 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
90 PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
91 return I != Impl->PassInfoMap.end() ? I->second : 0;
Owen Anderson660466e2010-07-20 19:23:55 +000092}
93
94const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
Chad Rosier673a7db2013-07-03 18:38:08 +000095 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000096 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
97 PassRegistryImpl::StringMapType::const_iterator
98 I = Impl->PassInfoStringMap.find(Arg);
99 return I != Impl->PassInfoStringMap.end() ? I->second : 0;
Owen Anderson660466e2010-07-20 19:23:55 +0000100}
101
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000102//===----------------------------------------------------------------------===//
103// Pass Registration mechanism
104//
105
Owen Anderson80b88172010-10-20 22:22:30 +0000106void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000107 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000108 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson660466e2010-07-20 19:23:55 +0000109 bool Inserted =
Owen Andersona74fa152010-09-07 19:16:25 +0000110 Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
Jakob Stoklund Olesen88b4b272011-01-05 21:50:21 +0000111 assert(Inserted && "Pass registered multiple times!");
112 (void)Inserted;
Owen Andersona74fa152010-09-07 19:16:25 +0000113 Impl->PassInfoStringMap[PI.getPassArgument()] = &PI;
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000114
115 // Notify any listeners.
116 for (std::vector<PassRegistrationListener*>::iterator
Owen Andersona74fa152010-09-07 19:16:25 +0000117 I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I)
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000118 (*I)->passRegistered(&PI);
Owen Anderson80b88172010-10-20 22:22:30 +0000119
120 if (ShouldFree) Impl->ToFree.push_back(&PI);
Owen Anderson660466e2010-07-20 19:23:55 +0000121}
122
123void PassRegistry::unregisterPass(const PassInfo &PI) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000124 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000125 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
126 PassRegistryImpl::MapType::iterator I =
127 Impl->PassInfoMap.find(PI.getTypeInfo());
128 assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!");
Owen Anderson660466e2010-07-20 19:23:55 +0000129
130 // Remove pass from the map.
Owen Andersona74fa152010-09-07 19:16:25 +0000131 Impl->PassInfoMap.erase(I);
132 Impl->PassInfoStringMap.erase(PI.getPassArgument());
Owen Anderson660466e2010-07-20 19:23:55 +0000133}
134
135void PassRegistry::enumerateWith(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000136 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000137 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
138 for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
139 E = Impl->PassInfoMap.end(); I != E; ++I)
Owen Anderson660466e2010-07-20 19:23:55 +0000140 L->passEnumerate(I->second);
141}
142
143
144/// Analysis Group Mechanisms.
Owen Andersona7aed182010-08-06 18:33:48 +0000145void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
146 const void *PassID,
Owen Anderson845b14e2010-07-21 17:52:45 +0000147 PassInfo& Registeree,
Owen Anderson80b88172010-10-20 22:22:30 +0000148 bool isDefault,
149 bool ShouldFree) {
Owen Anderson845b14e2010-07-21 17:52:45 +0000150 PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID));
151 if (InterfaceInfo == 0) {
152 // First reference to Interface, register it now.
153 registerPass(Registeree);
154 InterfaceInfo = &Registeree;
155 }
156 assert(Registeree.isAnalysisGroup() &&
157 "Trying to join an analysis group that is a normal pass!");
158
159 if (PassID) {
160 PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
161 assert(ImplementationInfo &&
162 "Must register pass before adding to AnalysisGroup!");
163
Chad Rosier673a7db2013-07-03 18:38:08 +0000164 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersond8788272010-09-16 23:32:35 +0000165
Owen Anderson845b14e2010-07-21 17:52:45 +0000166 // Make sure we keep track of the fact that the implementation implements
167 // the interface.
168 ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
169
Owen Andersona74fa152010-09-07 19:16:25 +0000170 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
171 PassRegistryImpl::AnalysisGroupInfo &AGI =
172 Impl->AnalysisGroupInfoMap[InterfaceInfo];
Owen Anderson845b14e2010-07-21 17:52:45 +0000173 assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
174 "Cannot add a pass to the same analysis group more than once!");
175 AGI.Implementations.insert(ImplementationInfo);
176 if (isDefault) {
177 assert(InterfaceInfo->getNormalCtor() == 0 &&
178 "Default implementation for analysis group already specified!");
179 assert(ImplementationInfo->getNormalCtor() &&
180 "Cannot specify pass as default if it does not have a default ctor");
181 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
182 }
Owen Anderson660466e2010-07-20 19:23:55 +0000183 }
Owen Anderson80b88172010-10-20 22:22:30 +0000184
185 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
186 if (ShouldFree) Impl->ToFree.push_back(&Registeree);
Owen Anderson660466e2010-07-20 19:23:55 +0000187}
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000188
189void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000190 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000191 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
192 Impl->Listeners.push_back(L);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000193}
194
195void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000196 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersond4754972010-09-15 23:03:33 +0000197
Owen Andersond12ea002010-09-07 20:48:10 +0000198 // NOTE: This is necessary, because removeRegistrationListener() can be called
199 // as part of the llvm_shutdown sequence. Since we have no control over the
200 // order of that sequence, we need to gracefully handle the case where the
201 // PassRegistry is destructed before the object that triggers this call.
202 if (!pImpl) return;
203
Owen Andersona74fa152010-09-07 19:16:25 +0000204 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000205 std::vector<PassRegistrationListener*>::iterator I =
Owen Andersona74fa152010-09-07 19:16:25 +0000206 std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);
207 assert(I != Impl->Listeners.end() &&
208 "PassRegistrationListener not registered!");
209 Impl->Listeners.erase(I);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000210}