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