1249259Sdim//===- PassRegistry.cpp - Pass Registration Implementation ----------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file implements the PassRegistry, with which passes are registered on 11249259Sdim// initialization, and supports the PassManager in dependency resolution. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "llvm/PassRegistry.h" 16249259Sdim#include "llvm/ADT/DenseMap.h" 17249259Sdim#include "llvm/ADT/SmallPtrSet.h" 18249259Sdim#include "llvm/ADT/StringMap.h" 19249259Sdim#include "llvm/IR/Function.h" 20249259Sdim#include "llvm/PassSupport.h" 21249259Sdim#include "llvm/Support/Compiler.h" 22249259Sdim#include "llvm/Support/ManagedStatic.h" 23249259Sdim#include "llvm/Support/Mutex.h" 24263509Sdim#include "llvm/Support/RWMutex.h" 25249259Sdim#include <vector> 26249259Sdim 27249259Sdimusing namespace llvm; 28249259Sdim 29249259Sdim// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. 30249259Sdim// Unfortunately, passes are registered with static ctors, and having 31249259Sdim// llvm_shutdown clear this map prevents successful resurrection after 32249259Sdim// llvm_shutdown is run. Ideally we should find a solution so that we don't 33249259Sdim// leak the map, AND can still resurrect after shutdown. 34249259Sdimstatic ManagedStatic<PassRegistry> PassRegistryObj; 35249259SdimPassRegistry *PassRegistry::getPassRegistry() { 36249259Sdim return &*PassRegistryObj; 37249259Sdim} 38249259Sdim 39263509Sdimstatic ManagedStatic<sys::SmartRWMutex<true> > Lock; 40249259Sdim 41249259Sdim//===----------------------------------------------------------------------===// 42249259Sdim// PassRegistryImpl 43249259Sdim// 44249259Sdim 45249259Sdimnamespace { 46249259Sdimstruct PassRegistryImpl { 47249259Sdim /// PassInfoMap - Keep track of the PassInfo object for each registered pass. 48249259Sdim typedef DenseMap<const void*, const PassInfo*> MapType; 49249259Sdim MapType PassInfoMap; 50249259Sdim 51249259Sdim typedef StringMap<const PassInfo*> StringMapType; 52249259Sdim StringMapType PassInfoStringMap; 53249259Sdim 54249259Sdim /// AnalysisGroupInfo - Keep track of information for each analysis group. 55249259Sdim struct AnalysisGroupInfo { 56249259Sdim SmallPtrSet<const PassInfo *, 8> Implementations; 57249259Sdim }; 58249259Sdim DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap; 59249259Sdim 60249259Sdim std::vector<const PassInfo*> ToFree; 61249259Sdim std::vector<PassRegistrationListener*> Listeners; 62249259Sdim}; 63249259Sdim} // end anonymous namespace 64249259Sdim 65249259Sdimvoid *PassRegistry::getImpl() const { 66249259Sdim if (!pImpl) 67249259Sdim pImpl = new PassRegistryImpl(); 68249259Sdim return pImpl; 69249259Sdim} 70249259Sdim 71249259Sdim//===----------------------------------------------------------------------===// 72249259Sdim// Accessors 73249259Sdim// 74249259Sdim 75249259SdimPassRegistry::~PassRegistry() { 76263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 77249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl); 78249259Sdim 79249259Sdim for (std::vector<const PassInfo*>::iterator I = Impl->ToFree.begin(), 80249259Sdim E = Impl->ToFree.end(); I != E; ++I) 81249259Sdim delete *I; 82249259Sdim 83249259Sdim delete Impl; 84249259Sdim pImpl = 0; 85249259Sdim} 86249259Sdim 87249259Sdimconst PassInfo *PassRegistry::getPassInfo(const void *TI) const { 88263509Sdim sys::SmartScopedReader<true> Guard(*Lock); 89249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 90249259Sdim PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI); 91249259Sdim return I != Impl->PassInfoMap.end() ? I->second : 0; 92249259Sdim} 93249259Sdim 94249259Sdimconst PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { 95263509Sdim sys::SmartScopedReader<true> Guard(*Lock); 96249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 97249259Sdim PassRegistryImpl::StringMapType::const_iterator 98249259Sdim I = Impl->PassInfoStringMap.find(Arg); 99249259Sdim return I != Impl->PassInfoStringMap.end() ? I->second : 0; 100249259Sdim} 101249259Sdim 102249259Sdim//===----------------------------------------------------------------------===// 103249259Sdim// Pass Registration mechanism 104249259Sdim// 105249259Sdim 106249259Sdimvoid PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { 107263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 108249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 109249259Sdim bool Inserted = 110249259Sdim Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; 111249259Sdim assert(Inserted && "Pass registered multiple times!"); 112249259Sdim (void)Inserted; 113249259Sdim Impl->PassInfoStringMap[PI.getPassArgument()] = &PI; 114249259Sdim 115249259Sdim // Notify any listeners. 116249259Sdim for (std::vector<PassRegistrationListener*>::iterator 117249259Sdim I = Impl->Listeners.begin(), E = Impl->Listeners.end(); I != E; ++I) 118249259Sdim (*I)->passRegistered(&PI); 119249259Sdim 120249259Sdim if (ShouldFree) Impl->ToFree.push_back(&PI); 121249259Sdim} 122249259Sdim 123249259Sdimvoid PassRegistry::unregisterPass(const PassInfo &PI) { 124263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 125249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 126249259Sdim PassRegistryImpl::MapType::iterator I = 127249259Sdim Impl->PassInfoMap.find(PI.getTypeInfo()); 128249259Sdim assert(I != Impl->PassInfoMap.end() && "Pass registered but not in map!"); 129249259Sdim 130249259Sdim // Remove pass from the map. 131249259Sdim Impl->PassInfoMap.erase(I); 132249259Sdim Impl->PassInfoStringMap.erase(PI.getPassArgument()); 133249259Sdim} 134249259Sdim 135249259Sdimvoid PassRegistry::enumerateWith(PassRegistrationListener *L) { 136263509Sdim sys::SmartScopedReader<true> Guard(*Lock); 137249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 138249259Sdim for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(), 139249259Sdim E = Impl->PassInfoMap.end(); I != E; ++I) 140249259Sdim L->passEnumerate(I->second); 141249259Sdim} 142249259Sdim 143249259Sdim 144249259Sdim/// Analysis Group Mechanisms. 145249259Sdimvoid PassRegistry::registerAnalysisGroup(const void *InterfaceID, 146249259Sdim const void *PassID, 147249259Sdim PassInfo& Registeree, 148249259Sdim bool isDefault, 149249259Sdim bool ShouldFree) { 150249259Sdim PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID)); 151249259Sdim if (InterfaceInfo == 0) { 152249259Sdim // First reference to Interface, register it now. 153249259Sdim registerPass(Registeree); 154249259Sdim InterfaceInfo = &Registeree; 155249259Sdim } 156249259Sdim assert(Registeree.isAnalysisGroup() && 157249259Sdim "Trying to join an analysis group that is a normal pass!"); 158249259Sdim 159249259Sdim if (PassID) { 160249259Sdim PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID)); 161249259Sdim assert(ImplementationInfo && 162249259Sdim "Must register pass before adding to AnalysisGroup!"); 163249259Sdim 164263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 165249259Sdim 166249259Sdim // Make sure we keep track of the fact that the implementation implements 167249259Sdim // the interface. 168249259Sdim ImplementationInfo->addInterfaceImplemented(InterfaceInfo); 169249259Sdim 170249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 171249259Sdim PassRegistryImpl::AnalysisGroupInfo &AGI = 172249259Sdim Impl->AnalysisGroupInfoMap[InterfaceInfo]; 173249259Sdim assert(AGI.Implementations.count(ImplementationInfo) == 0 && 174249259Sdim "Cannot add a pass to the same analysis group more than once!"); 175249259Sdim AGI.Implementations.insert(ImplementationInfo); 176249259Sdim if (isDefault) { 177249259Sdim assert(InterfaceInfo->getNormalCtor() == 0 && 178249259Sdim "Default implementation for analysis group already specified!"); 179249259Sdim assert(ImplementationInfo->getNormalCtor() && 180249259Sdim "Cannot specify pass as default if it does not have a default ctor"); 181249259Sdim InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); 182249259Sdim } 183249259Sdim } 184249259Sdim 185249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 186249259Sdim if (ShouldFree) Impl->ToFree.push_back(&Registeree); 187249259Sdim} 188249259Sdim 189249259Sdimvoid PassRegistry::addRegistrationListener(PassRegistrationListener *L) { 190263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 191249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 192249259Sdim Impl->Listeners.push_back(L); 193249259Sdim} 194249259Sdim 195249259Sdimvoid PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { 196263509Sdim sys::SmartScopedWriter<true> Guard(*Lock); 197249259Sdim 198249259Sdim // NOTE: This is necessary, because removeRegistrationListener() can be called 199249259Sdim // as part of the llvm_shutdown sequence. Since we have no control over the 200249259Sdim // order of that sequence, we need to gracefully handle the case where the 201249259Sdim // PassRegistry is destructed before the object that triggers this call. 202249259Sdim if (!pImpl) return; 203249259Sdim 204249259Sdim PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl()); 205249259Sdim std::vector<PassRegistrationListener*>::iterator I = 206249259Sdim std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L); 207249259Sdim assert(I != Impl->Listeners.end() && 208249259Sdim "PassRegistrationListener not registered!"); 209249259Sdim Impl->Listeners.erase(I); 210249259Sdim} 211