File indexing completed on 2026-05-10 08:44:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H)
0019 #error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead"
0020 #endif
0021
0022 #ifndef LLVM_PASSANALYSISSUPPORT_H
0023 #define LLVM_PASSANALYSISSUPPORT_H
0024
0025 #include "llvm/ADT/STLExtras.h"
0026 #include "llvm/ADT/SmallVector.h"
0027 #include <cassert>
0028 #include <tuple>
0029 #include <utility>
0030 #include <vector>
0031
0032 namespace llvm {
0033
0034 class Function;
0035 class Pass;
0036 class PMDataManager;
0037 class StringRef;
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 class AnalysisUsage {
0048 public:
0049 using VectorType = SmallVectorImpl<AnalysisID>;
0050
0051 private:
0052
0053
0054
0055
0056 SmallVector<AnalysisID, 8> Required;
0057 SmallVector<AnalysisID, 2> RequiredTransitive;
0058 SmallVector<AnalysisID, 2> Preserved;
0059 SmallVector<AnalysisID, 0> Used;
0060 bool PreservesAll = false;
0061
0062 void pushUnique(VectorType &Set, AnalysisID ID) {
0063 if (!llvm::is_contained(Set, ID))
0064 Set.push_back(ID);
0065 }
0066
0067 public:
0068 AnalysisUsage() = default;
0069
0070
0071
0072 AnalysisUsage &addRequiredID(const void *ID);
0073 AnalysisUsage &addRequiredID(char &ID);
0074 template<class PassClass>
0075 AnalysisUsage &addRequired() {
0076 return addRequiredID(PassClass::ID);
0077 }
0078
0079 AnalysisUsage &addRequiredTransitiveID(char &ID);
0080 template<class PassClass>
0081 AnalysisUsage &addRequiredTransitive() {
0082 return addRequiredTransitiveID(PassClass::ID);
0083 }
0084
0085
0086
0087
0088 AnalysisUsage &addPreservedID(const void *ID) {
0089 pushUnique(Preserved, ID);
0090 return *this;
0091 }
0092 AnalysisUsage &addPreservedID(char &ID) {
0093 pushUnique(Preserved, &ID);
0094 return *this;
0095 }
0096
0097 template<class PassClass>
0098 AnalysisUsage &addPreserved() {
0099 pushUnique(Preserved, &PassClass::ID);
0100 return *this;
0101 }
0102
0103
0104
0105
0106
0107 AnalysisUsage &addUsedIfAvailableID(const void *ID) {
0108 pushUnique(Used, ID);
0109 return *this;
0110 }
0111 AnalysisUsage &addUsedIfAvailableID(char &ID) {
0112 pushUnique(Used, &ID);
0113 return *this;
0114 }
0115
0116 template<class PassClass>
0117 AnalysisUsage &addUsedIfAvailable() {
0118 pushUnique(Used, &PassClass::ID);
0119 return *this;
0120 }
0121
0122
0123
0124
0125
0126
0127 AnalysisUsage &addPreserved(StringRef Arg);
0128
0129
0130 void setPreservesAll() { PreservesAll = true; }
0131
0132
0133 bool getPreservesAll() const { return PreservesAll; }
0134
0135
0136
0137
0138
0139
0140
0141
0142 void setPreservesCFG();
0143
0144 const VectorType &getRequiredSet() const { return Required; }
0145 const VectorType &getRequiredTransitiveSet() const {
0146 return RequiredTransitive;
0147 }
0148 const VectorType &getPreservedSet() const { return Preserved; }
0149 const VectorType &getUsedSet() const { return Used; }
0150 };
0151
0152
0153
0154
0155
0156
0157 class AnalysisResolver {
0158 public:
0159 AnalysisResolver() = delete;
0160 explicit AnalysisResolver(PMDataManager &P) : PM(P) {}
0161
0162 PMDataManager &getPMDataManager() { return PM; }
0163
0164
0165 Pass *findImplPass(AnalysisID PI) {
0166 Pass *ResultPass = nullptr;
0167 for (const auto &AnalysisImpl : AnalysisImpls) {
0168 if (AnalysisImpl.first == PI) {
0169 ResultPass = AnalysisImpl.second;
0170 break;
0171 }
0172 }
0173 return ResultPass;
0174 }
0175
0176
0177 std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F);
0178
0179 void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
0180 if (findImplPass(PI) == P)
0181 return;
0182 std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
0183 AnalysisImpls.push_back(pir);
0184 }
0185
0186
0187 void clearAnalysisImpls() {
0188 AnalysisImpls.clear();
0189 }
0190
0191
0192 Pass *getAnalysisIfAvailable(AnalysisID ID) const;
0193
0194 private:
0195
0196
0197 std::vector<std::pair<AnalysisID, Pass *>> AnalysisImpls;
0198
0199
0200 PMDataManager &PM;
0201 };
0202
0203
0204
0205
0206
0207
0208
0209
0210 template<typename AnalysisType>
0211 AnalysisType *Pass::getAnalysisIfAvailable() const {
0212 assert(Resolver && "Pass not resident in a PassManager object!");
0213
0214 const void *PI = &AnalysisType::ID;
0215
0216 Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI);
0217 if (!ResultPass) return nullptr;
0218
0219
0220
0221
0222
0223 return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0224 }
0225
0226
0227
0228
0229 template<typename AnalysisType>
0230 AnalysisType &Pass::getAnalysis() const {
0231 assert(Resolver && "Pass has not been inserted into a PassManager object!");
0232 return getAnalysisID<AnalysisType>(&AnalysisType::ID);
0233 }
0234
0235 template<typename AnalysisType>
0236 AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
0237 assert(PI && "getAnalysis for unregistered pass!");
0238 assert(Resolver&&"Pass has not been inserted into a PassManager object!");
0239
0240
0241
0242 Pass *ResultPass = Resolver->findImplPass(PI);
0243 assert(ResultPass &&
0244 "getAnalysis*() called on an analysis that was not "
0245 "'required' by pass!");
0246
0247
0248
0249
0250
0251 return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0252 }
0253
0254
0255
0256
0257
0258
0259 template <typename AnalysisType>
0260 AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) {
0261 assert(Resolver &&"Pass has not been inserted into a PassManager object!");
0262
0263 return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed);
0264 }
0265
0266 template <typename AnalysisType>
0267 AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) {
0268 assert(PI && "getAnalysis for unregistered pass!");
0269 assert(Resolver && "Pass has not been inserted into a PassManager object!");
0270
0271
0272
0273 Pass *ResultPass;
0274 bool LocalChanged;
0275 std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F);
0276
0277 assert(ResultPass && "Unable to find requested analysis info");
0278 if (Changed)
0279 *Changed |= LocalChanged;
0280 else
0281 assert(!LocalChanged &&
0282 "A pass trigged a code update but the update status is lost");
0283
0284
0285
0286
0287
0288 return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
0289 }
0290
0291 }
0292
0293 #endif