Home | History | Annotate | Line # | Download | only in IR
      1 //===- PassRegistry.cpp - Pass Registration Implementation ----------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file implements the PassRegistry, with which passes are registered on
     10 // initialization, and supports the PassManager in dependency resolution.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/PassRegistry.h"
     15 #include "llvm/ADT/STLExtras.h"
     16 #include "llvm/Pass.h"
     17 #include "llvm/PassInfo.h"
     18 #include "llvm/Support/ManagedStatic.h"
     19 #include <cassert>
     20 #include <memory>
     21 #include <utility>
     22 
     23 using namespace llvm;
     24 
     25 // FIXME: We use ManagedStatic to erase the pass registrar on shutdown.
     26 // Unfortunately, passes are registered with static ctors, and having
     27 // llvm_shutdown clear this map prevents successful resurrection after
     28 // llvm_shutdown is run.  Ideally we should find a solution so that we don't
     29 // leak the map, AND can still resurrect after shutdown.
     30 static ManagedStatic<PassRegistry> PassRegistryObj;
     31 PassRegistry *PassRegistry::getPassRegistry() {
     32   return &*PassRegistryObj;
     33 }
     34 
     35 //===----------------------------------------------------------------------===//
     36 // Accessors
     37 //
     38 
     39 PassRegistry::~PassRegistry() = default;
     40 
     41 const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
     42   sys::SmartScopedReader<true> Guard(Lock);
     43   return PassInfoMap.lookup(TI);
     44 }
     45 
     46 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
     47   sys::SmartScopedReader<true> Guard(Lock);
     48   return PassInfoStringMap.lookup(Arg);
     49 }
     50 
     51 //===----------------------------------------------------------------------===//
     52 // Pass Registration mechanism
     53 //
     54 
     55 void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
     56   sys::SmartScopedWriter<true> Guard(Lock);
     57   bool Inserted =
     58       PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second;
     59   assert(Inserted && "Pass registered multiple times!");
     60   (void)Inserted;
     61   PassInfoStringMap[PI.getPassArgument()] = &PI;
     62 
     63   // Notify any listeners.
     64   for (auto *Listener : Listeners)
     65     Listener->passRegistered(&PI);
     66 
     67   if (ShouldFree)
     68     ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));
     69 }
     70 
     71 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
     72   sys::SmartScopedReader<true> Guard(Lock);
     73   for (auto PassInfoPair : PassInfoMap)
     74     L->passEnumerate(PassInfoPair.second);
     75 }
     76 
     77 /// Analysis Group Mechanisms.
     78 void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
     79                                          const void *PassID,
     80                                          PassInfo &Registeree, bool isDefault,
     81                                          bool ShouldFree) {
     82   PassInfo *InterfaceInfo = const_cast<PassInfo *>(getPassInfo(InterfaceID));
     83   if (!InterfaceInfo) {
     84     // First reference to Interface, register it now.
     85     registerPass(Registeree);
     86     InterfaceInfo = &Registeree;
     87   }
     88   assert(Registeree.isAnalysisGroup() &&
     89          "Trying to join an analysis group that is a normal pass!");
     90 
     91   if (PassID) {
     92     PassInfo *ImplementationInfo = const_cast<PassInfo *>(getPassInfo(PassID));
     93     assert(ImplementationInfo &&
     94            "Must register pass before adding to AnalysisGroup!");
     95 
     96     sys::SmartScopedWriter<true> Guard(Lock);
     97 
     98     // Make sure we keep track of the fact that the implementation implements
     99     // the interface.
    100     ImplementationInfo->addInterfaceImplemented(InterfaceInfo);
    101 
    102     if (isDefault) {
    103       assert(InterfaceInfo->getNormalCtor() == nullptr &&
    104              "Default implementation for analysis group already specified!");
    105       assert(
    106           ImplementationInfo->getNormalCtor() &&
    107           "Cannot specify pass as default if it does not have a default ctor");
    108       InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
    109     }
    110   }
    111 
    112   if (ShouldFree)
    113     ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree));
    114 }
    115 
    116 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
    117   sys::SmartScopedWriter<true> Guard(Lock);
    118   Listeners.push_back(L);
    119 }
    120 
    121 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
    122   sys::SmartScopedWriter<true> Guard(Lock);
    123 
    124   auto I = llvm::find(Listeners, L);
    125   Listeners.erase(I);
    126 }
    127