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(Val: TI); |
38 | } |
39 | |
40 | const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { |
41 | sys::SmartScopedReader<true> Guard(Lock); |
42 | return PassInfoStringMap.lookup(Key: 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(KV: std::make_pair(x: PI.getTypeInfo(), y: &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(x: 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(TI: InterfaceID)); |
77 | if (!InterfaceInfo) { |
78 | // First reference to Interface, register it now. |
79 | registerPass(PI: 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(TI: 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(ItfPI: 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(x: std::unique_ptr<const PassInfo>(&Registeree)); |
108 | } |
109 | |
110 | void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { |
111 | sys::SmartScopedWriter<true> Guard(Lock); |
112 | Listeners.push_back(x: L); |
113 | } |
114 | |
115 | void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { |
116 | sys::SmartScopedWriter<true> Guard(Lock); |
117 | |
118 | auto I = llvm::find(Range&: Listeners, Val: L); |
119 | Listeners.erase(position: I); |
120 | } |
121 | |