blob: 9196d42114461d2f0e568ac86a8b3d5ea266d185 [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 Andersona74fa152010-09-07 19:16:25 +000019#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include <vector>
Owen Anderson41540612010-07-20 21:22:24 +000022
Owen Anderson7fc9fe72010-07-20 23:41:56 +000023using namespace llvm;
24
Owen Andersond12ea002010-09-07 20:48:10 +000025// FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
Owen Anderson41540612010-07-20 21:22:24 +000026// Unfortunately, passes are registered with static ctors, and having
27// llvm_shutdown clear this map prevents successful ressurection after
28// llvm_shutdown is run. Ideally we should find a solution so that we don't
29// leak the map, AND can still resurrect after shutdown.
Owen Andersond12ea002010-09-07 20:48:10 +000030static ManagedStatic<PassRegistry> PassRegistryObj;
31PassRegistry *PassRegistry::getPassRegistry() {
32 return &*PassRegistryObj;
Owen Anderson41540612010-07-20 21:22:24 +000033}
Owen Anderson660466e2010-07-20 19:23:55 +000034
Owen Andersona74fa152010-09-07 19:16:25 +000035//===----------------------------------------------------------------------===//
36// PassRegistryImpl
37//
38
39struct PassRegistryImpl {
40 /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
41 typedef DenseMap<const void*, const PassInfo*> MapType;
42 MapType PassInfoMap;
43
44 typedef StringMap<const PassInfo*> StringMapType;
45 StringMapType PassInfoStringMap;
46
47 /// AnalysisGroupInfo - Keep track of information for each analysis group.
48 struct AnalysisGroupInfo {
49 SmallPtrSet<const PassInfo *, 8> Implementations;
50 };
51 DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
52
53 std::vector<PassRegistrationListener*> Listeners;
54};
55
56void *PassRegistry::getImpl() const {
57 if (!pImpl)
58 pImpl = new PassRegistryImpl();
59 return pImpl;
60}
61
62//===----------------------------------------------------------------------===//
63// Accessors
64//
65
Owen Andersond12ea002010-09-07 20:48:10 +000066PassRegistry::~PassRegistry() {
67 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl);
68 if (Impl) delete Impl;
69 pImpl = 0;
70}
71
Owen Andersona7aed182010-08-06 18:33:48 +000072const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
Owen Andersona74fa152010-09-07 19:16:25 +000073 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
74 PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
75 return I != Impl->PassInfoMap.end() ? I->second : 0;
Owen Anderson660466e2010-07-20 19:23:55 +000076}
77
78const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
Owen Andersona74fa152010-09-07 19:16:25 +000079 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
80 PassRegistryImpl::StringMapType::const_iterator
81 I = Impl->PassInfoStringMap.find(Arg);
82 return I != Impl->PassInfoStringMap.end() ? I->second : 0;
Owen Anderson660466e2010-07-20 19:23:55 +000083}
84
Owen Anderson7fc9fe72010-07-20 23:41:56 +000085//===----------------------------------------------------------------------===//
86// Pass Registration mechanism
87//
88
Owen Anderson660466e2010-07-20 19:23:55 +000089void PassRegistry::registerPass(const PassInfo &PI) {
Owen Andersona74fa152010-09-07 19:16:25 +000090 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson660466e2010-07-20 19:23:55 +000091 bool Inserted =
Owen Andersona74fa152010-09-07 19:16:25 +000092 Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
Owen Anderson660466e2010-07-20 19:23:55 +000093 assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted;
Owen Andersona74fa152010-09-07 19:16:25 +000094 Impl->PassInfoStringMap[PI.getPassArgument()] = &PI;
Owen Anderson7fc9fe72010-07-20 23:41:56 +000095
96 // Notify any listeners.
97 for (std::vector<PassRegistrationListener*>::iterator
Owen Andersona74fa152010-09-07 19:16:25 +000098 I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I)
Owen Anderson7fc9fe72010-07-20 23:41:56 +000099 (*I)->passRegistered(&PI);
Owen Anderson660466e2010-07-20 19:23:55 +0000100}
101
102void PassRegistry::unregisterPass(const PassInfo &PI) {
Owen Andersona74fa152010-09-07 19:16:25 +0000103 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
104 PassRegistryImpl::MapType::iterator I =
105 Impl->PassInfoMap.find(PI.getTypeInfo());
106 assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!");
Owen Anderson660466e2010-07-20 19:23:55 +0000107
108 // Remove pass from the map.
Owen Andersona74fa152010-09-07 19:16:25 +0000109 Impl->PassInfoMap.erase(I);
110 Impl->PassInfoStringMap.erase(PI.getPassArgument());
Owen Anderson660466e2010-07-20 19:23:55 +0000111}
112
113void PassRegistry::enumerateWith(PassRegistrationListener *L) {
Owen Andersona74fa152010-09-07 19:16:25 +0000114 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
115 for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
116 E = Impl->PassInfoMap.end(); I != E; ++I)
Owen Anderson660466e2010-07-20 19:23:55 +0000117 L->passEnumerate(I->second);
118}
119
120
121/// Analysis Group Mechanisms.
Owen Andersona7aed182010-08-06 18:33:48 +0000122void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
123 const void *PassID,
Owen Anderson845b14e2010-07-21 17:52:45 +0000124 PassInfo& Registeree,
Owen Anderson660466e2010-07-20 19:23:55 +0000125 bool isDefault) {
Owen Anderson845b14e2010-07-21 17:52:45 +0000126 PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID));
127 if (InterfaceInfo == 0) {
128 // First reference to Interface, register it now.
129 registerPass(Registeree);
130 InterfaceInfo = &Registeree;
131 }
132 assert(Registeree.isAnalysisGroup() &&
133 "Trying to join an analysis group that is a normal pass!");
134
135 if (PassID) {
136 PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
137 assert(ImplementationInfo &&
138 "Must register pass before adding to AnalysisGroup!");
139
140 // Make sure we keep track of the fact that the implementation implements
141 // the interface.
142 ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
143
Owen Andersona74fa152010-09-07 19:16:25 +0000144 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
145 PassRegistryImpl::AnalysisGroupInfo &AGI =
146 Impl->AnalysisGroupInfoMap[InterfaceInfo];
Owen Anderson845b14e2010-07-21 17:52:45 +0000147 assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
148 "Cannot add a pass to the same analysis group more than once!");
149 AGI.Implementations.insert(ImplementationInfo);
150 if (isDefault) {
151 assert(InterfaceInfo->getNormalCtor() == 0 &&
152 "Default implementation for analysis group already specified!");
153 assert(ImplementationInfo->getNormalCtor() &&
154 "Cannot specify pass as default if it does not have a default ctor");
155 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
156 }
Owen Anderson660466e2010-07-20 19:23:55 +0000157 }
158}
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000159
160void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
Owen Andersona74fa152010-09-07 19:16:25 +0000161 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
162 Impl->Listeners.push_back(L);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000163}
164
165void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
Owen Andersond12ea002010-09-07 20:48:10 +0000166 // NOTE: This is necessary, because removeRegistrationListener() can be called
167 // as part of the llvm_shutdown sequence. Since we have no control over the
168 // order of that sequence, we need to gracefully handle the case where the
169 // PassRegistry is destructed before the object that triggers this call.
170 if (!pImpl) return;
171
Owen Andersona74fa152010-09-07 19:16:25 +0000172 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000173 std::vector<PassRegistrationListener*>::iterator I =
Owen Andersona74fa152010-09-07 19:16:25 +0000174 std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);
175 assert(I != Impl->Listeners.end() &&
176 "PassRegistrationListener not registered!");
177 Impl->Listeners.erase(I);
Owen Anderson7fc9fe72010-07-20 23:41:56 +0000178}