LLVM  14.0.0git
PassAnalysisSupport.h
Go to the documentation of this file.
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 ///
48 public:
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.
57  SmallVector<AnalysisID, 2> RequiredTransitive;
60  bool PreservesAll = false;
61 
62  void pushUnique(VectorType &Set, AnalysisID ID) {
63  if (!llvm::is_contained(Set, ID))
64  Set.push_back(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);
74  template<class PassClass>
77  }
78 
80  template<class PassClass>
83  }
84  ///@}
85 
86  ///@{
87  /// Add the specified ID to the set of analyses preserved by this pass.
89  pushUnique(Preserved, ID);
90  return *this;
91  }
93  pushUnique(Preserved, &ID);
94  return *this;
95  }
96  /// Add the specified Pass class to the set of analyses preserved by this pass.
97  template<class PassClass>
99  pushUnique(Preserved, &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..
108  pushUnique(Used, ID);
109  return *this;
110  }
112  pushUnique(Used, &ID);
113  return *this;
114  }
115  /// Add the specified Pass class to the set of analyses used by this pass.
116  template<class PassClass>
118  pushUnique(Used, &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!
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; }
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 ///
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.
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 
180  if (findImplPass(PI) == P)
181  return;
182  std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
183  AnalysisImpls.push_back(pir);
184  }
185 
186  /// Clear cache that is used to connect a pass to the analysis (PassInfo).
188  AnalysisImpls.clear();
189  }
190 
191  /// Return analysis result or null if it doesn't exist.
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(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(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(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(ResultPass, LocalChanged) = Resolver->findImplPass(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(PI);
289 }
290 
291 } // end namespace llvm
292 
293 #endif // LLVM_PASSANALYSISSUPPORT_H
llvm::AnalysisUsage::getRequiredTransitiveSet
const VectorType & getRequiredTransitiveSet() const
Definition: PassAnalysisSupport.h:145
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::Pass::getAnalysis
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
Definition: PassAnalysisSupport.h:230
Pass
print lazy value Lazy Value Info Printer Pass
Definition: LazyValueInfo.cpp:1965
llvm::Function
Definition: Function.h:62
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::SmallVector< AnalysisID, 8 >
llvm::AnalysisID
const void * AnalysisID
Definition: Pass.h:47
STLExtras.h
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::Pass::getAdjustedAnalysisPointer
virtual void * getAdjustedAnalysisPointer(AnalysisID ID)
getAdjustedAnalysisPointer - This method is used when a pass implements an analysis interface through...
Definition: Pass.cpp:105
llvm::Resolver
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:2000
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
llvm::PMDataManager
PMDataManager provides the common place to manage the analysis data used by pass managers.
Definition: LegacyPassManagers.h:296
llvm::AnalysisUsage::getPreservesAll
bool getPreservesAll() const
Determine whether a pass said it does not transform its input at all.
Definition: PassAnalysisSupport.h:133
llvm::AnalysisUsage::addRequiredTransitiveID
AnalysisUsage & addRequiredTransitiveID(char &ID)
Definition: Pass.cpp:277
llvm::Pass::getAnalysisIfAvailable
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
Definition: PassAnalysisSupport.h:211
llvm::AnalysisUsage::getUsedSet
const VectorType & getUsedSet() const
Definition: PassAnalysisSupport.h:149
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::AnalysisResolver
AnalysisResolver - Simple interface used by Pass objects to pull all analysis information out of pass...
Definition: PassAnalysisSupport.h:157
llvm::AnalysisUsage::addUsedIfAvailableID
AnalysisUsage & addUsedIfAvailableID(const void *ID)
Definition: PassAnalysisSupport.h:107
llvm::AnalysisResolver::AnalysisResolver
AnalysisResolver()=delete
llvm::AnalysisResolver::getAnalysisIfAvailable
Pass * getAnalysisIfAvailable(AnalysisID ID) const
Return analysis result or null if it doesn't exist.
Definition: LegacyPassManager.cpp:1315
llvm::AnalysisUsage::getRequiredSet
const VectorType & getRequiredSet() const
Definition: PassAnalysisSupport.h:144
llvm::AnalysisResolver::clearAnalysisImpls
void clearAnalysisImpls()
Clear cache that is used to connect a pass to the analysis (PassInfo).
Definition: PassAnalysisSupport.h:187
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1616
llvm::AnalysisResolver::findImplPass
Pass * findImplPass(AnalysisID PI)
Find pass that is implementing PI.
Definition: PassAnalysisSupport.h:165
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AnalysisResolver::AnalysisResolver
AnalysisResolver(PMDataManager &P)
Definition: PassAnalysisSupport.h:160
llvm::ReplayInlineScope::Function
@ Function
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::AnalysisUsage::addPreservedID
AnalysisUsage & addPreservedID(const void *ID)
Definition: PassAnalysisSupport.h:88
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::AnalysisResolver::addAnalysisImplsPair
void addAnalysisImplsPair(AnalysisID PI, Pass *P)
Definition: PassAnalysisSupport.h:179
llvm::AnalysisUsage::AnalysisUsage
AnalysisUsage()=default
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
SmallVector.h
llvm::AnalysisResolver::getPMDataManager
PMDataManager & getPMDataManager()
Definition: PassAnalysisSupport.h:162
llvm::AnalysisUsage::getPreservedSet
const VectorType & getPreservedSet() const
Definition: PassAnalysisSupport.h:148
llvm::SmallVectorImpl< AnalysisID >
llvm::Pass::getAnalysisID
AnalysisType & getAnalysisID(AnalysisID PI) const
Definition: PassAnalysisSupport.h:236
llvm::AnalysisUsage::addRequiredTransitive
AnalysisUsage & addRequiredTransitive()
Definition: PassAnalysisSupport.h:81
llvm::AnalysisUsage::addUsedIfAvailable
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
Definition: PassAnalysisSupport.h:117
llvm::AnalysisUsage::addRequiredID
AnalysisUsage & addRequiredID(const void *ID)
Definition: Pass.cpp:267
llvm::AnalysisUsage::addUsedIfAvailableID
AnalysisUsage & addUsedIfAvailableID(char &ID)
Definition: PassAnalysisSupport.h:111
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::AnalysisUsage::addPreservedID
AnalysisUsage & addPreservedID(char &ID)
Definition: PassAnalysisSupport.h:92
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37