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