PassRegistry.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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/ADT/DenseMap.h" 17#include "llvm/ADT/SmallPtrSet.h" 18#include "llvm/ADT/StringMap.h" 19#include "llvm/IR/Function.h" 20#include "llvm/PassSupport.h" 21#include "llvm/Support/Compiler.h" 22#include "llvm/Support/ManagedStatic.h" 23#include "llvm/Support/Mutex.h" 24#include "llvm/Support/RWMutex.h" 25#include <vector> 26 27using namespace llvm; 28 29// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. 30// Unfortunately, passes are registered with static ctors, and having 31// llvm_shutdown clear this map prevents successful resurrection after 32// 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. 34static ManagedStatic<PassRegistry> PassRegistryObj; 35PassRegistry *PassRegistry::getPassRegistry() { 36 return &*PassRegistryObj; 37} 38 39static ManagedStatic<sys::SmartRWMutex<true> > Lock; 40 41//===----------------------------------------------------------------------===// 42// PassRegistryImpl 43// 44 45namespace { 46struct 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 60 std::vector<const PassInfo*> ToFree; 61 std::vector<PassRegistrationListener*> Listeners; 62}; 63} // end anonymous namespace 64 65void *PassRegistry::getImpl() const { 66 if (!pImpl) 67 pImpl = new PassRegistryImpl(); 68 return pImpl; 69} 70 71//===----------------------------------------------------------------------===// 72// Accessors 73// 74 75PassRegistry::~PassRegistry() { 76 sys::SmartScopedWriter<true> Guard(*Lock); 77 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); 78 79 for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(), 80 E = Impl->ToFree.end(); I != E; ++I) 81 delete *I; 82 83 delete Impl; 84 pImpl = 0; 85} 86 87const PassInfo *PassRegistry::getPassInfo(const void *TI) const { 88 sys::SmartScopedReader<true> Guard(*Lock); 89 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; 92} 93 94const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { 95 sys::SmartScopedReader<true> Guard(*Lock); 96 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; 100} 101 102//===----------------------------------------------------------------------===// 103// Pass Registration mechanism 104// 105 106void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { 107 sys::SmartScopedWriter<true> Guard(*Lock); 108 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 109 bool Inserted = 110 Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; 111 assert(Inserted && "Pass registered multiple times!"); 112 (void)Inserted; 113 Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; 114 115 // Notify any listeners. 116 for (std::vector<PassRegistrationListener*>::iterator 117 I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) 118 (*I)->passRegistered(&PI); 119 120 if (ShouldFree) Impl->ToFree.push_back(&PI); 121} 122 123void PassRegistry::unregisterPass(const PassInfo &PI) { 124 sys::SmartScopedWriter<true> Guard(*Lock); 125 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!"); 129 130 // Remove pass from the map. 131 Impl->PassInfoMap.erase(I); 132 Impl->PassInfoStringMap.erase(PI.getPassArgument()); 133} 134 135void PassRegistry::enumerateWith(PassRegistrationListener *L) { 136 sys::SmartScopedReader<true> Guard(*Lock); 137 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 138 for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), 139 E = Impl->PassInfoMap.end(); I != E; ++I) 140 L->passEnumerate(I->second); 141} 142 143 144/// Analysis Group Mechanisms. 145void PassRegistry::registerAnalysisGroup(const void *InterfaceID, 146 const void *PassID, 147 PassInfo& Registeree, 148 bool isDefault, 149 bool ShouldFree) { 150 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 164 sys::SmartScopedWriter<true> Guard(*Lock); 165 166 // Make sure we keep track of the fact that the implementation implements 167 // the interface. 168 ImplementationInfo->addInterfaceImplemented(InterfaceInfo); 169 170 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 171 PassRegistryImpl::AnalysisGroupInfo &AGI = 172 Impl->AnalysisGroupInfoMap[InterfaceInfo]; 173 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 InterfaceInfo->setTargetMachineCtor( 183 ImplementationInfo->getTargetMachineCtor()); 184 } 185 } 186 187 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 188 if (ShouldFree) Impl->ToFree.push_back(&Registeree); 189} 190 191void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { 192 sys::SmartScopedWriter<true> Guard(*Lock); 193 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 194 Impl->Listeners.push_back(L); 195} 196 197void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { 198 sys::SmartScopedWriter<true> Guard(*Lock); 199 200 // NOTE: This is necessary, because removeRegistrationListener() can be called 201 // as part of the llvm_shutdown sequence. Since we have no control over the 202 // order of that sequence, we need to gracefully handle the case where the 203 // PassRegistry is destructed before the object that triggers this call. 204 if (!pImpl) return; 205 206 PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 207 std::vector<PassRegistrationListener*>::iterator I = 208 std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); 209 assert(I != Impl->Listeners.end() && 210 "PassRegistrationListener not registered!"); 211 Impl->Listeners.erase(I); 212} 213