/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/IR/PassRegistry.cpp
Line | Count | Source (jump to first uncovered line) |
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/PassInfo.h" |
17 | | #include "llvm/PassSupport.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 | 179M | PassRegistry *PassRegistry::getPassRegistry() { |
32 | 179M | return &*PassRegistryObj; |
33 | 179M | } |
34 | | |
35 | | //===----------------------------------------------------------------------===// |
36 | | // Accessors |
37 | | // |
38 | | |
39 | 114k | PassRegistry::~PassRegistry() = default; |
40 | | |
41 | 165M | const PassInfo *PassRegistry::getPassInfo(const void *TI) const { |
42 | 165M | sys::SmartScopedReader<true> Guard(Lock); |
43 | 165M | MapType::const_iterator I = PassInfoMap.find(TI); |
44 | 165M | return I != PassInfoMap.end() ? I->second153M : nullptr11.9M ; |
45 | 165M | } |
46 | | |
47 | 2.31k | const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { |
48 | 2.31k | sys::SmartScopedReader<true> Guard(Lock); |
49 | 2.31k | StringMapType::const_iterator I = PassInfoStringMap.find(Arg); |
50 | 2.31k | return I != PassInfoStringMap.end() ? I->second2.31k : nullptr5 ; |
51 | 2.31k | } |
52 | | |
53 | | //===----------------------------------------------------------------------===// |
54 | | // Pass Registration mechanism |
55 | | // |
56 | | |
57 | 32.8M | void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { |
58 | 32.8M | sys::SmartScopedWriter<true> Guard(Lock); |
59 | 32.8M | bool Inserted = |
60 | 32.8M | PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second; |
61 | 32.8M | assert(Inserted && "Pass registered multiple times!"); |
62 | 32.8M | (void)Inserted; |
63 | 32.8M | PassInfoStringMap[PI.getPassArgument()] = &PI; |
64 | 32.8M | |
65 | 32.8M | // Notify any listeners. |
66 | 32.8M | for (auto *Listener : Listeners) |
67 | 70.8M | Listener->passRegistered(&PI); |
68 | 32.8M | |
69 | 32.8M | if (ShouldFree) |
70 | 32.4M | ToFree.push_back(std::unique_ptr<const PassInfo>(&PI)); |
71 | 32.8M | } |
72 | | |
73 | 2.08M | void PassRegistry::enumerateWith(PassRegistrationListener *L) { |
74 | 2.08M | sys::SmartScopedReader<true> Guard(Lock); |
75 | 2.08M | for (auto PassInfoPair : PassInfoMap) |
76 | 665M | L->passEnumerate(PassInfoPair.second); |
77 | 2.08M | } |
78 | | |
79 | | /// Analysis Group Mechanisms. |
80 | | void PassRegistry::registerAnalysisGroup(const void *InterfaceID, |
81 | | const void *PassID, |
82 | | PassInfo &Registeree, bool isDefault, |
83 | 0 | bool ShouldFree) { |
84 | 0 | PassInfo *InterfaceInfo = const_cast<PassInfo *>(getPassInfo(InterfaceID)); |
85 | 0 | if (!InterfaceInfo) { |
86 | 0 | // First reference to Interface, register it now. |
87 | 0 | registerPass(Registeree); |
88 | 0 | InterfaceInfo = &Registeree; |
89 | 0 | } |
90 | 0 | assert(Registeree.isAnalysisGroup() && |
91 | 0 | "Trying to join an analysis group that is a normal pass!"); |
92 | 0 |
|
93 | 0 | if (PassID) { |
94 | 0 | PassInfo *ImplementationInfo = const_cast<PassInfo *>(getPassInfo(PassID)); |
95 | 0 | assert(ImplementationInfo && |
96 | 0 | "Must register pass before adding to AnalysisGroup!"); |
97 | 0 |
|
98 | 0 | sys::SmartScopedWriter<true> Guard(Lock); |
99 | 0 |
|
100 | 0 | // Make sure we keep track of the fact that the implementation implements |
101 | 0 | // the interface. |
102 | 0 | ImplementationInfo->addInterfaceImplemented(InterfaceInfo); |
103 | 0 |
|
104 | 0 | if (isDefault) { |
105 | 0 | assert(InterfaceInfo->getNormalCtor() == nullptr && |
106 | 0 | "Default implementation for analysis group already specified!"); |
107 | 0 | assert( |
108 | 0 | ImplementationInfo->getNormalCtor() && |
109 | 0 | "Cannot specify pass as default if it does not have a default ctor"); |
110 | 0 | InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); |
111 | 0 | } |
112 | 0 | } |
113 | 0 |
|
114 | 0 | if (ShouldFree) |
115 | 0 | ToFree.push_back(std::unique_ptr<const PassInfo>(&Registeree)); |
116 | 0 | } |
117 | | |
118 | 252k | void PassRegistry::addRegistrationListener(PassRegistrationListener *L) { |
119 | 252k | sys::SmartScopedWriter<true> Guard(Lock); |
120 | 252k | Listeners.push_back(L); |
121 | 252k | } |
122 | | |
123 | 0 | void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) { |
124 | 0 | sys::SmartScopedWriter<true> Guard(Lock); |
125 | 0 |
|
126 | 0 | auto I = llvm::find(Listeners, L); |
127 | 0 | Listeners.erase(I); |
128 | 0 | } |