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