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 <cassert> 19 #include <memory> 20 #include <utility> 21 22 using namespace llvm; 23 24 PassRegistry *PassRegistry::getPassRegistry() { 25 static PassRegistry PassRegistryObj; 26 return &PassRegistryObj; 27 } 28 29 //===----------------------------------------------------------------------===// 30 // Accessors 31 // 32 33 PassRegistry::~PassRegistry() = default; 34 35 const PassInfo *PassRegistry::getPassInfo(const void *TI) const { 36 sys::SmartScopedReader<true> Guard(Lock); 37 return PassInfoMap.lookup(TI); 38 } 39 40 const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { 41 sys::SmartScopedReader<true> Guard(Lock); 42 return PassInfoStringMap.lookup(Arg); 43 } 44 45 //===----------------------------------------------------------------------===// 46 // Pass Registration mechanism 47 // 48 49 void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { 50 sys::SmartScopedWriter<true> Guard(Lock); 51 bool Inserted = 52 PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second; 53 assert(Inserted && "Pass registered multiple times!"); 54 (void)Inserted; 55 PassInfoStringMap[PI.getPassArgument()] = &PI; 56 57 // Notify any listeners. 58 for (auto *Listener : Listeners) 59 Listener->passRegistered(&PI); 60 61 if (ShouldFree) 62 ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); 63 } 64 65 void PassRegistry::enumerateWith(PassRegistrationListener *L) { 66 sys::SmartScopedReader<true> Guard(Lock); 67 for (auto PassInfoPair : PassInfoMap) 68 L->passEnumerate(PassInfoPair.second); 69 } 70 71 /// Analysis Group Mechanisms. 72 void PassRegistry::registerAnalysisGroup(const void *InterfaceID, 73 const void *PassID, 74 PassInfo &Registeree, bool isDefault, 75 bool ShouldFree) { 76 PassInfo *InterfaceInfo = const_cast<PassInfo *>(getPassInfo(InterfaceID)); 77 if (!InterfaceInfo) { 78 // First reference to Interface, register it now. 79 registerPass(Registeree); 80 InterfaceInfo = &Registeree; 81 } 82 assert(Registeree.isAnalysisGroup() && 83 "Trying to join an analysis group that is a normal pass!"); 84 85 if (PassID) { 86 PassInfo *ImplementationInfo = const_cast<PassInfo *>(getPassInfo(PassID)); 87 assert(ImplementationInfo && 88 "Must register pass before adding to AnalysisGroup!"); 89 90 sys::SmartScopedWriter<true> Guard(Lock); 91 92 // Make sure we keep track of the fact that the implementation implements 93 // the interface. 94 ImplementationInfo->addInterfaceImplemented(InterfaceInfo); 95 96 if (isDefault) { 97 assert(InterfaceInfo->getNormalCtor() == nullptr && 98 "Default implementation for analysis group already specified!"); 99 assert( 100 ImplementationInfo->getNormalCtor() && 101 "Cannot specify pass as default if it does not have a default ctor"); 102 InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); 103 } 104 } 105 106 if (ShouldFree) 107 ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); 108 } 109 110 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { 111 sys::SmartScopedWriter<true> Guard(Lock); 112 Listeners.push_back(L); 113 } 114 115 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { 116 sys::SmartScopedWriter<true> Guard(Lock); 117 118 auto I = llvm::find(Listeners, L); 119 Listeners.erase(I); 120 } 121