LLVM API Documentation

PassRegistry.cpp
Go to the documentation of this file.
00001 //===- PassRegistry.cpp - Pass Registration Implementation ----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the PassRegistry, with which passes are registered on
00011 // initialization, and supports the PassManager in dependency resolution.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/PassRegistry.h"
00016 #include "llvm/IR/Function.h"
00017 #include "llvm/PassSupport.h"
00018 #include "llvm/Support/Compiler.h"
00019 #include "llvm/Support/ManagedStatic.h"
00020 #include "llvm/Support/RWMutex.h"
00021 #include <vector>
00022 
00023 using namespace llvm;
00024 
00025 // FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
00026 // Unfortunately, passes are registered with static ctors, and having
00027 // llvm_shutdown clear this map prevents successful resurrection after
00028 // llvm_shutdown is run.  Ideally we should find a solution so that we don't
00029 // leak the map, AND can still resurrect after shutdown.
00030 static ManagedStatic<PassRegistry> PassRegistryObj;
00031 PassRegistry *PassRegistry::getPassRegistry() {
00032   return &*PassRegistryObj;
00033 }
00034 
00035 //===----------------------------------------------------------------------===//
00036 // Accessors
00037 //
00038 
00039 PassRegistry::~PassRegistry() {
00040 }
00041 
00042 const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
00043   sys::SmartScopedReader<true> Guard(Lock);
00044   MapType::const_iterator I = PassInfoMap.find(TI);
00045   return I != PassInfoMap.end() ? I->second : nullptr;
00046 }
00047 
00048 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
00049   sys::SmartScopedReader<true> Guard(Lock);
00050   StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
00051   return I != PassInfoStringMap.end() ? I->second : nullptr;
00052 }
00053 
00054 //===----------------------------------------------------------------------===//
00055 // Pass Registration mechanism
00056 //
00057 
00058 void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
00059   sys::SmartScopedWriter<true> Guard(Lock);
00060   bool Inserted =
00061     PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
00062   assert(Inserted && "Pass registered multiple times!");
00063   (void)Inserted;
00064   PassInfoStringMap[PI.getPassArgument()] = &PI;
00065   
00066   // Notify any listeners.
00067   for (std::vector<PassRegistrationListener*>::iterator
00068        I = Listeners.begin(), E = Listeners.end(); I != E; ++I)
00069     (*I)->passRegistered(&PI);
00070   
00071   if (ShouldFree) ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));
00072 }
00073 
00074 void PassRegistry::unregisterPass(const PassInfo &PI) {
00075   sys::SmartScopedWriter<true> Guard(Lock);
00076   MapType::iterator I = PassInfoMap.find(PI.getTypeInfo());
00077   assert(I != PassInfoMap.end() && "Pass registered but not in map!");
00078   
00079   // Remove pass from the map.
00080   PassInfoMap.erase(I);
00081   PassInfoStringMap.erase(PI.getPassArgument());
00082 }
00083 
00084 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
00085   sys::SmartScopedReader<true> Guard(Lock);
00086   for (auto I = PassInfoMap.begin(), E = PassInfoMap.end(); I != E; ++I)
00087     L->passEnumerate(I->second);
00088 }
00089 
00090 
00091 /// Analysis Group Mechanisms.
00092 void PassRegistry::registerAnalysisGroup(const void *InterfaceID, 
00093                                          const void *PassID,
00094                                          PassInfo& Registeree,
00095                                          bool isDefault,
00096                                          bool ShouldFree) {
00097   PassInfo *InterfaceInfo =  const_cast<PassInfo*>(getPassInfo(InterfaceID));
00098   if (!InterfaceInfo) {
00099     // First reference to Interface, register it now.
00100     registerPass(Registeree);
00101     InterfaceInfo = &Registeree;
00102   }
00103   assert(Registeree.isAnalysisGroup() && 
00104          "Trying to join an analysis group that is a normal pass!");
00105 
00106   if (PassID) {
00107     PassInfo *ImplementationInfo = const_cast<PassInfo*>(getPassInfo(PassID));
00108     assert(ImplementationInfo &&
00109            "Must register pass before adding to AnalysisGroup!");
00110 
00111     sys::SmartScopedWriter<true> Guard(Lock);
00112     
00113     // Make sure we keep track of the fact that the implementation implements
00114     // the interface.
00115     ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
00116 
00117     AnalysisGroupInfo &AGI = AnalysisGroupInfoMap[InterfaceInfo];
00118     assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
00119            "Cannot add a pass to the same analysis group more than once!");
00120     AGI.Implementations.insert(ImplementationInfo);
00121     if (isDefault) {
00122       assert(InterfaceInfo->getNormalCtor() == nullptr &&
00123              "Default implementation for analysis group already specified!");
00124       assert(ImplementationInfo->getNormalCtor() &&
00125            "Cannot specify pass as default if it does not have a default ctor");
00126       InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
00127       InterfaceInfo->setTargetMachineCtor(
00128           ImplementationInfo->getTargetMachineCtor());
00129     }
00130   }
00131   
00132   if (ShouldFree)
00133     ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree));
00134 }
00135 
00136 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
00137   sys::SmartScopedWriter<true> Guard(Lock);
00138   Listeners.push_back(L);
00139 }
00140 
00141 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
00142   sys::SmartScopedWriter<true> Guard(Lock);
00143   
00144   auto I = std::find(Listeners.begin(), Listeners.end(), L);
00145   Listeners.erase(I);
00146 }