1 | //===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===// |
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 defines stuff that is used to define and "use" Analysis Passes. |
10 | // This file is automatically #included by Pass.h, so: |
11 | // |
12 | // NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY |
13 | // |
14 | // Instead, #include Pass.h |
15 | // |
16 | //===----------------------------------------------------------------------===// |
17 | |
18 | #if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H) |
19 | #error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead" |
20 | #endif |
21 | |
22 | #ifndef LLVM_PASSANALYSISSUPPORT_H |
23 | #define LLVM_PASSANALYSISSUPPORT_H |
24 | |
25 | #include "llvm/ADT/STLExtras.h" |
26 | #include "llvm/ADT/SmallVector.h" |
27 | #include <cassert> |
28 | #include <tuple> |
29 | #include <utility> |
30 | #include <vector> |
31 | |
32 | namespace llvm { |
33 | |
34 | class Function; |
35 | class Pass; |
36 | class PMDataManager; |
37 | class StringRef; |
38 | |
39 | //===----------------------------------------------------------------------===// |
40 | /// Represent the analysis usage information of a pass. This tracks analyses |
41 | /// that the pass REQUIRES (must be available when the pass runs), REQUIRES |
42 | /// TRANSITIVE (must be available throughout the lifetime of the pass), and |
43 | /// analyses that the pass PRESERVES (the pass does not invalidate the results |
44 | /// of these analyses). This information is provided by a pass to the Pass |
45 | /// infrastructure through the getAnalysisUsage virtual function. |
46 | /// |
47 | class AnalysisUsage { |
48 | public: |
49 | using VectorType = SmallVectorImpl<AnalysisID>; |
50 | |
51 | private: |
52 | /// Sets of analyses required and preserved by a pass |
53 | // TODO: It's not clear that SmallVector is an appropriate data structure for |
54 | // this usecase. The sizes were picked to minimize wasted space, but are |
55 | // otherwise fairly meaningless. |
56 | SmallVector<AnalysisID, 8> Required; |
57 | SmallVector<AnalysisID, 2> RequiredTransitive; |
58 | SmallVector<AnalysisID, 2> Preserved; |
59 | SmallVector<AnalysisID, 0> Used; |
60 | bool PreservesAll = false; |
61 | |
62 | void pushUnique(VectorType &Set, AnalysisID ID) { |
63 | if (!llvm::is_contained(Range&: Set, Element: ID)) |
64 | Set.push_back(Elt: ID); |
65 | } |
66 | |
67 | public: |
68 | AnalysisUsage() = default; |
69 | |
70 | ///@{ |
71 | /// Add the specified ID to the required set of the usage info for a pass. |
72 | AnalysisUsage &addRequiredID(const void *ID); |
73 | AnalysisUsage &addRequiredID(char &ID); |
74 | template<class PassClass> |
75 | AnalysisUsage &addRequired() { |
76 | return addRequiredID(PassClass::ID); |
77 | } |
78 | |
79 | AnalysisUsage &addRequiredTransitiveID(char &ID); |
80 | template<class PassClass> |
81 | AnalysisUsage &addRequiredTransitive() { |
82 | return addRequiredTransitiveID(ID&: PassClass::ID); |
83 | } |
84 | ///@} |
85 | |
86 | ///@{ |
87 | /// Add the specified ID to the set of analyses preserved by this pass. |
88 | AnalysisUsage &addPreservedID(const void *ID) { |
89 | pushUnique(Set&: Preserved, ID); |
90 | return *this; |
91 | } |
92 | AnalysisUsage &addPreservedID(char &ID) { |
93 | pushUnique(Set&: Preserved, ID: &ID); |
94 | return *this; |
95 | } |
96 | /// Add the specified Pass class to the set of analyses preserved by this pass. |
97 | template<class PassClass> |
98 | AnalysisUsage &addPreserved() { |
99 | pushUnique(Set&: Preserved, ID: &PassClass::ID); |
100 | return *this; |
101 | } |
102 | ///@} |
103 | |
104 | ///@{ |
105 | /// Add the specified ID to the set of analyses used by this pass if they are |
106 | /// available.. |
107 | AnalysisUsage &addUsedIfAvailableID(const void *ID) { |
108 | pushUnique(Set&: Used, ID); |
109 | return *this; |
110 | } |
111 | AnalysisUsage &addUsedIfAvailableID(char &ID) { |
112 | pushUnique(Set&: Used, ID: &ID); |
113 | return *this; |
114 | } |
115 | /// Add the specified Pass class to the set of analyses used by this pass. |
116 | template<class PassClass> |
117 | AnalysisUsage &addUsedIfAvailable() { |
118 | pushUnique(Set&: Used, ID: &PassClass::ID); |
119 | return *this; |
120 | } |
121 | ///@} |
122 | |
123 | /// Add the Pass with the specified argument string to the set of analyses |
124 | /// preserved by this pass. If no such Pass exists, do nothing. This can be |
125 | /// useful when a pass is trivially preserved, but may not be linked in. Be |
126 | /// careful about spelling! |
127 | AnalysisUsage &addPreserved(StringRef Arg); |
128 | |
129 | /// Set by analyses that do not transform their input at all |
130 | void setPreservesAll() { PreservesAll = true; } |
131 | |
132 | /// Determine whether a pass said it does not transform its input at all |
133 | bool getPreservesAll() const { return PreservesAll; } |
134 | |
135 | /// This function should be called by the pass, iff they do not: |
136 | /// |
137 | /// 1. Add or remove basic blocks from the function |
138 | /// 2. Modify terminator instructions in any way. |
139 | /// |
140 | /// This function annotates the AnalysisUsage info object to say that analyses |
141 | /// that only depend on the CFG are preserved by this pass. |
142 | void setPreservesCFG(); |
143 | |
144 | const VectorType &getRequiredSet() const { return Required; } |
145 | const VectorType &getRequiredTransitiveSet() const { |
146 | return RequiredTransitive; |
147 | } |
148 | const VectorType &getPreservedSet() const { return Preserved; } |
149 | const VectorType &getUsedSet() const { return Used; } |
150 | }; |
151 | |
152 | //===----------------------------------------------------------------------===// |
153 | /// AnalysisResolver - Simple interface used by Pass objects to pull all |
154 | /// analysis information out of pass manager that is responsible to manage |
155 | /// the pass. |
156 | /// |
157 | class AnalysisResolver { |
158 | public: |
159 | AnalysisResolver() = delete; |
160 | explicit AnalysisResolver(PMDataManager &P) : PM(P) {} |
161 | |
162 | PMDataManager &getPMDataManager() { return PM; } |
163 | |
164 | /// Find pass that is implementing PI. |
165 | Pass *findImplPass(AnalysisID PI) { |
166 | Pass *ResultPass = nullptr; |
167 | for (const auto &AnalysisImpl : AnalysisImpls) { |
168 | if (AnalysisImpl.first == PI) { |
169 | ResultPass = AnalysisImpl.second; |
170 | break; |
171 | } |
172 | } |
173 | return ResultPass; |
174 | } |
175 | |
176 | /// Find pass that is implementing PI. Initialize pass for Function F. |
177 | std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F); |
178 | |
179 | void addAnalysisImplsPair(AnalysisID PI, Pass *P) { |
180 | if (findImplPass(PI) == P) |
181 | return; |
182 | std::pair<AnalysisID, Pass*> pir = std::make_pair(x&: PI,y&: P); |
183 | AnalysisImpls.push_back(x: pir); |
184 | } |
185 | |
186 | /// Clear cache that is used to connect a pass to the analysis (PassInfo). |
187 | void clearAnalysisImpls() { |
188 | AnalysisImpls.clear(); |
189 | } |
190 | |
191 | /// Return analysis result or null if it doesn't exist. |
192 | Pass *getAnalysisIfAvailable(AnalysisID ID) const; |
193 | |
194 | private: |
195 | /// This keeps track of which passes implements the interfaces that are |
196 | /// required by the current pass (to implement getAnalysis()). |
197 | std::vector<std::pair<AnalysisID, Pass *>> AnalysisImpls; |
198 | |
199 | /// PassManager that is used to resolve analysis info |
200 | PMDataManager &PM; |
201 | }; |
202 | |
203 | /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to |
204 | /// get analysis information that might be around, for example to update it. |
205 | /// This is different than getAnalysis in that it can fail (if the analysis |
206 | /// results haven't been computed), so should only be used if you can handle |
207 | /// the case when the analysis is not available. This method is often used by |
208 | /// transformation APIs to update analysis results for a pass automatically as |
209 | /// the transform is performed. |
210 | template<typename AnalysisType> |
211 | AnalysisType *Pass::getAnalysisIfAvailable() const { |
212 | assert(Resolver && "Pass not resident in a PassManager object!" ); |
213 | |
214 | const void *PI = &AnalysisType::ID; |
215 | |
216 | Pass *ResultPass = Resolver->getAnalysisIfAvailable(ID: PI); |
217 | if (!ResultPass) return nullptr; |
218 | |
219 | // Because the AnalysisType may not be a subclass of pass (for |
220 | // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially |
221 | // adjust the return pointer (because the class may multiply inherit, once |
222 | // from pass, once from AnalysisType). |
223 | return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(ID: PI); |
224 | } |
225 | |
226 | /// getAnalysis<AnalysisType>() - This function is used by subclasses to get |
227 | /// to the analysis information that they claim to use by overriding the |
228 | /// getAnalysisUsage function. |
229 | template<typename AnalysisType> |
230 | AnalysisType &Pass::getAnalysis() const { |
231 | assert(Resolver && "Pass has not been inserted into a PassManager object!" ); |
232 | return getAnalysisID<AnalysisType>(&AnalysisType::ID); |
233 | } |
234 | |
235 | template<typename AnalysisType> |
236 | AnalysisType &Pass::getAnalysisID(AnalysisID PI) const { |
237 | assert(PI && "getAnalysis for unregistered pass!" ); |
238 | assert(Resolver&&"Pass has not been inserted into a PassManager object!" ); |
239 | // PI *must* appear in AnalysisImpls. Because the number of passes used |
240 | // should be a small number, we just do a linear search over a (dense) |
241 | // vector. |
242 | Pass *ResultPass = Resolver->findImplPass(PI); |
243 | assert(ResultPass && |
244 | "getAnalysis*() called on an analysis that was not " |
245 | "'required' by pass!" ); |
246 | |
247 | // Because the AnalysisType may not be a subclass of pass (for |
248 | // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially |
249 | // adjust the return pointer (because the class may multiply inherit, once |
250 | // from pass, once from AnalysisType). |
251 | return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(ID: PI); |
252 | } |
253 | |
254 | /// getAnalysis<AnalysisType>() - This function is used by subclasses to get |
255 | /// to the analysis information that they claim to use by overriding the |
256 | /// getAnalysisUsage function. If as part of the dependencies, an IR |
257 | /// transformation is triggered (e.g. because the analysis requires |
258 | /// BreakCriticalEdges), and Changed is non null, *Changed is updated. |
259 | template <typename AnalysisType> |
260 | AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) { |
261 | assert(Resolver &&"Pass has not been inserted into a PassManager object!" ); |
262 | |
263 | return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed); |
264 | } |
265 | |
266 | template <typename AnalysisType> |
267 | AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) { |
268 | assert(PI && "getAnalysis for unregistered pass!" ); |
269 | assert(Resolver && "Pass has not been inserted into a PassManager object!" ); |
270 | // PI *must* appear in AnalysisImpls. Because the number of passes used |
271 | // should be a small number, we just do a linear search over a (dense) |
272 | // vector. |
273 | Pass *ResultPass; |
274 | bool LocalChanged; |
275 | std::tie(args&: ResultPass, args&: LocalChanged) = Resolver->findImplPass(P: this, PI, F); |
276 | |
277 | assert(ResultPass && "Unable to find requested analysis info" ); |
278 | if (Changed) |
279 | *Changed |= LocalChanged; |
280 | else |
281 | assert(!LocalChanged && |
282 | "A pass trigged a code update but the update status is lost" ); |
283 | |
284 | // Because the AnalysisType may not be a subclass of pass (for |
285 | // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially |
286 | // adjust the return pointer (because the class may multiply inherit, once |
287 | // from pass, once from AnalysisType). |
288 | return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(ID: PI); |
289 | } |
290 | |
291 | } // end namespace llvm |
292 | |
293 | #endif // LLVM_PASSANALYSISSUPPORT_H |
294 | |