blob: 6a5bee2f57b16da0a7d0ff1da047210261c2db63 [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
David Blaikie0afad5e2014-04-15 15:17:14 +000060 std::vector<std::unique_ptr<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);
Dan Gohmancb854972010-10-12 00:19:24 +000078 delete Impl;
Craig Topperc6207612014-04-09 06:08:46 +000079 pImpl = nullptr;
Owen Andersond12ea002010-09-07 20:48:10 +000080}
81
Owen Andersona7aed182010-08-06 18:33:48 +000082const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
Chad Rosier673a7db2013-07-03 18:38:08 +000083 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000084 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
85 PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
Craig Topperc6207612014-04-09 06:08:46 +000086 return I != Impl->PassInfoMap.end() ? I->second : nullptr;
Owen Anderson660466e2010-07-20 19:23:55 +000087}
88
89const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
Chad Rosier673a7db2013-07-03 18:38:08 +000090 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +000091 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
92 PassRegistryImpl::StringMapType::const_iterator
93 I = Impl->PassInfoStringMap.find(Arg);
Craig Topperc6207612014-04-09 06:08:46 +000094 return I != Impl->PassInfoStringMap.end() ? I->second : nullptr;
Owen Anderson660466e2010-07-20 19:23:55 +000095}
96
Owen Anderson7fc9fe72010-07-20 23:41:56 +000097//===----------------------------------------------------------------------===//
98// Pass Registration mechanism
99//
100
Owen Anderson80b88172010-10-20 22:22:30 +0000101void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000102 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000103 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson660466e2010-07-20 19:23:55 +0000104 bool Inserted =
Owen Andersona74fa152010-09-07 19:16:25 +0000105 Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
Jakob Stoklund Olesen88b4b272011-01-05 21:50:21 +0000106 assert(Inserted && "Pass registered multiple times!");
107 (void)Inserted;
Owen Andersona74fa152010-09-07 19:16:25 +0000108 Impl->PassInfoStringMap[PI.getPassArgument()] = &PI;
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000109
110 // Notify any listeners.
111 for (std::vector<PassRegistrationListener*>::iterator
Owen Andersona74fa152010-09-07 19:16:25 +0000112 I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I)
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000113 (*I)->passRegistered(&PI);
Owen Anderson80b88172010-10-20 22:22:30 +0000114
David Blaikie0afad5e2014-04-15 15:17:14 +0000115 if (ShouldFree) Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));
Owen Anderson660466e2010-07-20 19:23:55 +0000116}
117
118void PassRegistry::unregisterPass(const PassInfo &PI) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000119 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000120 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
121 PassRegistryImpl::MapType::iterator I =
122 Impl->PassInfoMap.find(PI.getTypeInfo());
123 assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!");
Owen Anderson660466e2010-07-20 19:23:55 +0000124
125 // Remove pass from the map.
Owen Andersona74fa152010-09-07 19:16:25 +0000126 Impl->PassInfoMap.erase(I);
127 Impl->PassInfoStringMap.erase(PI.getPassArgument());
Owen Anderson660466e2010-07-20 19:23:55 +0000128}
129
130void PassRegistry::enumerateWith(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000131 sys::SmartScopedReader<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000132 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
133 for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
134 E = Impl->PassInfoMap.end(); I != E; ++I)
Owen Anderson660466e2010-07-20 19:23:55 +0000135 L->passEnumerate(I->second);
136}
137
138
139/// Analysis Group Mechanisms.
Owen Andersona7aed182010-08-06 18:33:48 +0000140void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
141 const void *PassID,
Owen Anderson845b14e2010-07-21 17:52:45 +0000142 PassInfo& Registeree,
Owen Anderson80b88172010-10-20 22:22:30 +0000143 bool isDefault,
144 bool ShouldFree) {
Owen Anderson845b14e2010-07-21 17:52:45 +0000145 PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID));
Craig Topperc6207612014-04-09 06:08:46 +0000146 if (!InterfaceInfo) {
Owen Anderson845b14e2010-07-21 17:52:45 +0000147 // First reference to Interface, register it now.
148 registerPass(Registeree);
149 InterfaceInfo = &Registeree;
150 }
151 assert(Registeree.isAnalysisGroup() &&
152 "Trying to join an analysis group that is a normal pass!");
153
154 if (PassID) {
155 PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
156 assert(ImplementationInfo &&
157 "Must register pass before adding to AnalysisGroup!");
158
Chad Rosier673a7db2013-07-03 18:38:08 +0000159 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersond8788272010-09-16 23:32:35 +0000160
Owen Anderson845b14e2010-07-21 17:52:45 +0000161 // Make sure we keep track of the fact that the implementation implements
162 // the interface.
163 ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
164
Owen Andersona74fa152010-09-07 19:16:25 +0000165 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
166 PassRegistryImpl::AnalysisGroupInfo &AGI =
167 Impl->AnalysisGroupInfoMap[InterfaceInfo];
Owen Anderson845b14e2010-07-21 17:52:45 +0000168 assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
169 "Cannot add a pass to the same analysis group more than once!");
170 AGI.Implementations.insert(ImplementationInfo);
171 if (isDefault) {
Craig Topper2617dcc2014-04-15 06:32:26 +0000172 assert(InterfaceInfo->getNormalCtor() == nullptr &&
Owen Anderson845b14e2010-07-21 17:52:45 +0000173 "Default implementation for analysis group already specified!");
174 assert(ImplementationInfo->getNormalCtor() &&
175 "Cannot specify pass as default if it does not have a default ctor");
176 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
Quentin Colombetdc0b2ea2014-01-16 21:44:34 +0000177 InterfaceInfo->setTargetMachineCtor(
178 ImplementationInfo->getTargetMachineCtor());
Owen Anderson845b14e2010-07-21 17:52:45 +0000179 }
Owen Anderson660466e2010-07-20 19:23:55 +0000180 }
Owen Anderson80b88172010-10-20 22:22:30 +0000181
182 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
David Blaikie0afad5e2014-04-15 15:17:14 +0000183 if (ShouldFree)
184 Impl->ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree));
Owen Anderson660466e2010-07-20 19:23:55 +0000185}
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000186
187void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000188 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersona74fa152010-09-07 19:16:25 +0000189 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
190 Impl->Listeners.push_back(L);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000191}
192
193void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
Chad Rosier673a7db2013-07-03 18:38:08 +0000194 sys::SmartScopedWriter<true> Guard(*Lock);
Owen Andersond4754972010-09-15 23:03:33 +0000195
Owen Andersond12ea002010-09-07 20:48:10 +0000196 // 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.
200 if (!pImpl) return;
201
Owen Andersona74fa152010-09-07 19:16:25 +0000202 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000203 std::vector<PassRegistrationListener*>::iterator I =
Owen Andersona74fa152010-09-07 19:16:25 +0000204 std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);
205 assert(I != Impl->Listeners.end() &&
206 "PassRegistrationListener not registered!");
207 Impl->Listeners.erase(I);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000208}