|  | //===- PassRegistry.cpp - Pass Registration Implementation ----------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file implements the PassRegistry, with which passes are registered on | 
|  | // initialization, and supports the PassManager in dependency resolution. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/PassRegistry.h" | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/PassInfo.h" | 
|  | #include "llvm/PassSupport.h" | 
|  | #include "llvm/Support/ManagedStatic.h" | 
|  | #include <cassert> | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | // FIXME: We use ManagedStatic to erase the pass registrar on shutdown. | 
|  | // Unfortunately, passes are registered with static ctors, and having | 
|  | // llvm_shutdown clear this map prevents successful resurrection after | 
|  | // llvm_shutdown is run.  Ideally we should find a solution so that we don't | 
|  | // leak the map, AND can still resurrect after shutdown. | 
|  | static ManagedStatic<PassRegistry> PassRegistryObj; | 
|  | PassRegistry *PassRegistry::getPassRegistry() { | 
|  | return &*PassRegistryObj; | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Accessors | 
|  | // | 
|  |  | 
|  | PassRegistry::~PassRegistry() = default; | 
|  |  | 
|  | const PassInfo *PassRegistry::getPassInfo(const void *TI) const { | 
|  | sys::SmartScopedReader<true> Guard(Lock); | 
|  | MapType::const_iterator I = PassInfoMap.find(TI); | 
|  | return I != PassInfoMap.end() ? I->second : nullptr; | 
|  | } | 
|  |  | 
|  | const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { | 
|  | sys::SmartScopedReader<true> Guard(Lock); | 
|  | StringMapType::const_iterator I = PassInfoStringMap.find(Arg); | 
|  | return I != PassInfoStringMap.end() ? I->second : nullptr; | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Pass Registration mechanism | 
|  | // | 
|  |  | 
|  | void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { | 
|  | sys::SmartScopedWriter<true> Guard(Lock); | 
|  | bool Inserted = | 
|  | PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second; | 
|  | assert(Inserted && "Pass registered multiple times!"); | 
|  | (void)Inserted; | 
|  | PassInfoStringMap[PI.getPassArgument()] = &PI; | 
|  |  | 
|  | // Notify any listeners. | 
|  | for (auto *Listener : Listeners) | 
|  | Listener->passRegistered(&PI); | 
|  |  | 
|  | if (ShouldFree) | 
|  | ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); | 
|  | } | 
|  |  | 
|  | void PassRegistry::enumerateWith(PassRegistrationListener *L) { | 
|  | sys::SmartScopedReader<true> Guard(Lock); | 
|  | for (auto PassInfoPair : PassInfoMap) | 
|  | L->passEnumerate(PassInfoPair.second); | 
|  | } | 
|  |  | 
|  | /// Analysis Group Mechanisms. | 
|  | void PassRegistry::registerAnalysisGroup(const void *InterfaceID, | 
|  | const void *PassID, | 
|  | PassInfo &Registeree, bool isDefault, | 
|  | bool ShouldFree) { | 
|  | PassInfo *InterfaceInfo = const_cast<PassInfo *>(getPassInfo(InterfaceID)); | 
|  | if (!InterfaceInfo) { | 
|  | // First reference to Interface, register it now. | 
|  | registerPass(Registeree); | 
|  | InterfaceInfo = &Registeree; | 
|  | } | 
|  | assert(Registeree.isAnalysisGroup() && | 
|  | "Trying to join an analysis group that is a normal pass!"); | 
|  |  | 
|  | if (PassID) { | 
|  | PassInfo *ImplementationInfo = const_cast<PassInfo *>(getPassInfo(PassID)); | 
|  | assert(ImplementationInfo && | 
|  | "Must register pass before adding to AnalysisGroup!"); | 
|  |  | 
|  | sys::SmartScopedWriter<true> Guard(Lock); | 
|  |  | 
|  | // Make sure we keep track of the fact that the implementation implements | 
|  | // the interface. | 
|  | ImplementationInfo->addInterfaceImplemented(InterfaceInfo); | 
|  |  | 
|  | if (isDefault) { | 
|  | assert(InterfaceInfo->getNormalCtor() == nullptr && | 
|  | "Default implementation for analysis group already specified!"); | 
|  | assert( | 
|  | ImplementationInfo->getNormalCtor() && | 
|  | "Cannot specify pass as default if it does not have a default ctor"); | 
|  | InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (ShouldFree) | 
|  | ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); | 
|  | } | 
|  |  | 
|  | void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { | 
|  | sys::SmartScopedWriter<true> Guard(Lock); | 
|  | Listeners.push_back(L); | 
|  | } | 
|  |  | 
|  | void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { | 
|  | sys::SmartScopedWriter<true> Guard(Lock); | 
|  |  | 
|  | auto I = llvm::find(Listeners, L); | 
|  | Listeners.erase(I); | 
|  | } |