File indexing completed on 2026-05-10 08:44:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef LLVM_IR_PASSMANAGER_H
0038 #define LLVM_IR_PASSMANAGER_H
0039
0040 #include "llvm/ADT/DenseMap.h"
0041 #include "llvm/ADT/STLExtras.h"
0042 #include "llvm/ADT/StringRef.h"
0043 #include "llvm/ADT/TinyPtrVector.h"
0044 #include "llvm/IR/Analysis.h"
0045 #include "llvm/IR/PassManagerInternal.h"
0046 #include "llvm/Support/TypeName.h"
0047 #include <cassert>
0048 #include <cstring>
0049 #include <iterator>
0050 #include <list>
0051 #include <memory>
0052 #include <tuple>
0053 #include <type_traits>
0054 #include <utility>
0055 #include <vector>
0056
0057 namespace llvm {
0058
0059 class Function;
0060 class Module;
0061
0062
0063 template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
0064
0065
0066
0067
0068
0069 template <typename DerivedT> struct PassInfoMixin {
0070
0071 static StringRef name() {
0072 static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
0073 "Must pass the derived type as the template argument!");
0074 StringRef Name = getTypeName<DerivedT>();
0075 Name.consume_front("llvm::");
0076 return Name;
0077 }
0078
0079 void printPipeline(raw_ostream &OS,
0080 function_ref<StringRef(StringRef)> MapClassName2PassName) {
0081 StringRef ClassName = DerivedT::name();
0082 auto PassName = MapClassName2PassName(ClassName);
0083 OS << PassName;
0084 }
0085 };
0086
0087
0088
0089
0090
0091 template <typename DerivedT>
0092 struct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 static AnalysisKey *ID() {
0109 static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
0110 "Must pass the derived type as the template argument!");
0111 return &DerivedT::Key;
0112 }
0113 };
0114
0115 namespace detail {
0116
0117
0118
0119 template <typename PassT, typename IRUnitT, typename AnalysisManagerT,
0120 typename... ArgTs, size_t... Ns>
0121 typename PassT::Result
0122 getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
0123 std::tuple<ArgTs...> Args,
0124 std::index_sequence<Ns...>) {
0125 (void)Args;
0126 return AM.template getResult<PassT>(IR, std::get<Ns>(Args)...);
0127 }
0128
0129
0130
0131
0132
0133
0134 template <typename PassT, typename IRUnitT, typename... AnalysisArgTs,
0135 typename... MainArgTs>
0136 typename PassT::Result
0137 getAnalysisResult(AnalysisManager<IRUnitT, AnalysisArgTs...> &AM, IRUnitT &IR,
0138 std::tuple<MainArgTs...> Args) {
0139 return (getAnalysisResultUnpackTuple<
0140 PassT, IRUnitT>)(AM, IR, Args,
0141 std::index_sequence_for<AnalysisArgTs...>{});
0142 }
0143
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 template <typename IRUnitT,
0159 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
0160 typename... ExtraArgTs>
0161 class PassManager : public PassInfoMixin<
0162 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
0163 public:
0164
0165 explicit PassManager() = default;
0166
0167
0168
0169
0170
0171 PassManager(PassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
0172
0173 PassManager &operator=(PassManager &&RHS) {
0174 Passes = std::move(RHS.Passes);
0175 return *this;
0176 }
0177
0178 void printPipeline(raw_ostream &OS,
0179 function_ref<StringRef(StringRef)> MapClassName2PassName) {
0180 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
0181 auto *P = Passes[Idx].get();
0182 P->printPipeline(OS, MapClassName2PassName);
0183 if (Idx + 1 < Size)
0184 OS << ',';
0185 }
0186 }
0187
0188
0189
0190 PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM,
0191 ExtraArgTs... ExtraArgs);
0192
0193 template <typename PassT>
0194 LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v<PassT, PassManager>>
0195 addPass(PassT &&Pass) {
0196 using PassModelT =
0197 detail::PassModel<IRUnitT, PassT, AnalysisManagerT, ExtraArgTs...>;
0198
0199
0200 Passes.push_back(std::unique_ptr<PassConceptT>(
0201 new PassModelT(std::forward<PassT>(Pass))));
0202 }
0203
0204
0205
0206
0207
0208
0209 template <typename PassT>
0210 LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<std::is_same_v<PassT, PassManager>>
0211 addPass(PassT &&Pass) {
0212 for (auto &P : Pass.Passes)
0213 Passes.push_back(std::move(P));
0214 }
0215
0216
0217 bool isEmpty() const { return Passes.empty(); }
0218
0219 static bool isRequired() { return true; }
0220
0221 protected:
0222 using PassConceptT =
0223 detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
0224
0225 std::vector<std::unique_ptr<PassConceptT>> Passes;
0226 };
0227
0228 template <typename IRUnitT>
0229 void printIRUnitNameForStackTrace(raw_ostream &OS, const IRUnitT &IR);
0230
0231 template <>
0232 void printIRUnitNameForStackTrace<Module>(raw_ostream &OS, const Module &IR);
0233
0234 extern template class PassManager<Module>;
0235
0236
0237 using ModulePassManager = PassManager<Module>;
0238
0239 template <>
0240 void printIRUnitNameForStackTrace<Function>(raw_ostream &OS,
0241 const Function &IR);
0242
0243 extern template class PassManager<Function>;
0244
0245
0246 using FunctionPassManager = PassManager<Function>;
0247
0248
0249
0250
0251
0252
0253 template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager {
0254 public:
0255 class Invalidator;
0256
0257 private:
0258
0259 using ResultConceptT = detail::AnalysisResultConcept<IRUnitT, Invalidator>;
0260 using PassConceptT =
0261 detail::AnalysisPassConcept<IRUnitT, Invalidator, ExtraArgTs...>;
0262
0263
0264
0265
0266
0267
0268
0269 using AnalysisResultListT =
0270 std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
0271
0272
0273 using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>;
0274
0275
0276
0277
0278 using AnalysisResultMapT =
0279 DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
0280 typename AnalysisResultListT::iterator>;
0281
0282 public:
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 class Invalidator {
0293 public:
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 template <typename PassT>
0310 bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
0311 using ResultModelT =
0312 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
0313 Invalidator>;
0314
0315 return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA);
0316 }
0317
0318
0319
0320
0321
0322
0323
0324 bool invalidate(AnalysisKey *ID, IRUnitT &IR, const PreservedAnalyses &PA) {
0325 return invalidateImpl<>(ID, IR, PA);
0326 }
0327
0328 private:
0329 friend class AnalysisManager;
0330
0331 template <typename ResultT = ResultConceptT>
0332 bool invalidateImpl(AnalysisKey *ID, IRUnitT &IR,
0333 const PreservedAnalyses &PA) {
0334
0335
0336 auto IMapI = IsResultInvalidated.find(ID);
0337 if (IMapI != IsResultInvalidated.end())
0338 return IMapI->second;
0339
0340
0341 auto RI = Results.find({ID, &IR});
0342 assert(RI != Results.end() &&
0343 "Trying to invalidate a dependent result that isn't in the "
0344 "manager's cache is always an error, likely due to a stale result "
0345 "handle!");
0346
0347 auto &Result = static_cast<ResultT &>(*RI->second->second);
0348
0349
0350
0351
0352
0353 bool Inserted;
0354 std::tie(IMapI, Inserted) =
0355 IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, *this)});
0356 (void)Inserted;
0357 assert(Inserted && "Should not have already inserted this ID, likely "
0358 "indicates a dependency cycle!");
0359 return IMapI->second;
0360 }
0361
0362 Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
0363 const AnalysisResultMapT &Results)
0364 : IsResultInvalidated(IsResultInvalidated), Results(Results) {}
0365
0366 SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
0367 const AnalysisResultMapT &Results;
0368 };
0369
0370
0371 AnalysisManager();
0372 AnalysisManager(AnalysisManager &&);
0373 AnalysisManager &operator=(AnalysisManager &&);
0374
0375
0376 bool empty() const {
0377 assert(AnalysisResults.empty() == AnalysisResultLists.empty() &&
0378 "The storage and index of analysis results disagree on how many "
0379 "there are!");
0380 return AnalysisResults.empty();
0381 }
0382
0383
0384
0385
0386
0387
0388 void clear(IRUnitT &IR, llvm::StringRef Name);
0389
0390
0391
0392
0393
0394
0395
0396 void clear() {
0397 AnalysisResults.clear();
0398 AnalysisResultLists.clear();
0399 }
0400
0401
0402 template <typename PassT> bool isPassRegistered() const {
0403 return AnalysisPasses.count(PassT::ID());
0404 }
0405
0406
0407
0408
0409 template <typename PassT>
0410 typename PassT::Result &getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs) {
0411 assert(AnalysisPasses.count(PassT::ID()) &&
0412 "This analysis pass was not registered prior to being queried");
0413 ResultConceptT &ResultConcept =
0414 getResultImpl(PassT::ID(), IR, ExtraArgs...);
0415
0416 using ResultModelT =
0417 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
0418 Invalidator>;
0419
0420 return static_cast<ResultModelT &>(ResultConcept).Result;
0421 }
0422
0423
0424
0425
0426
0427
0428 template <typename PassT>
0429 typename PassT::Result *getCachedResult(IRUnitT &IR) const {
0430 assert(AnalysisPasses.count(PassT::ID()) &&
0431 "This analysis pass was not registered prior to being queried");
0432
0433 ResultConceptT *ResultConcept = getCachedResultImpl(PassT::ID(), IR);
0434 if (!ResultConcept)
0435 return nullptr;
0436
0437 using ResultModelT =
0438 detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
0439 Invalidator>;
0440
0441 return &static_cast<ResultModelT *>(ResultConcept)->Result;
0442 }
0443
0444
0445 template <typename PassT>
0446 void verifyNotInvalidated(IRUnitT &IR, typename PassT::Result *Result) const {
0447 PreservedAnalyses PA = PreservedAnalyses::none();
0448 SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
0449 Invalidator Inv(IsResultInvalidated, AnalysisResults);
0450 assert(!Result->invalidate(IR, PA, Inv) &&
0451 "Cached result cannot be invalidated");
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 template <typename PassBuilderT>
0471 bool registerPass(PassBuilderT &&PassBuilder) {
0472 using PassT = decltype(PassBuilder());
0473 using PassModelT =
0474 detail::AnalysisPassModel<IRUnitT, PassT, Invalidator, ExtraArgTs...>;
0475
0476 auto &PassPtr = AnalysisPasses[PassT::ID()];
0477 if (PassPtr)
0478
0479 return false;
0480
0481
0482 PassPtr.reset(new PassModelT(PassBuilder()));
0483 return true;
0484 }
0485
0486
0487
0488
0489
0490 void invalidate(IRUnitT &IR, const PreservedAnalyses &PA);
0491
0492 private:
0493
0494 PassConceptT &lookUpPass(AnalysisKey *ID) {
0495 typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(ID);
0496 assert(PI != AnalysisPasses.end() &&
0497 "Analysis passes must be registered prior to being queried!");
0498 return *PI->second;
0499 }
0500
0501
0502 const PassConceptT &lookUpPass(AnalysisKey *ID) const {
0503 typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(ID);
0504 assert(PI != AnalysisPasses.end() &&
0505 "Analysis passes must be registered prior to being queried!");
0506 return *PI->second;
0507 }
0508
0509
0510 ResultConceptT &getResultImpl(AnalysisKey *ID, IRUnitT &IR,
0511 ExtraArgTs... ExtraArgs);
0512
0513
0514 ResultConceptT *getCachedResultImpl(AnalysisKey *ID, IRUnitT &IR) const {
0515 typename AnalysisResultMapT::const_iterator RI =
0516 AnalysisResults.find({ID, &IR});
0517 return RI == AnalysisResults.end() ? nullptr : &*RI->second->second;
0518 }
0519
0520
0521 using AnalysisPassMapT =
0522 DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
0523
0524
0525 AnalysisPassMapT AnalysisPasses;
0526
0527
0528
0529
0530
0531 AnalysisResultListMapT AnalysisResultLists;
0532
0533
0534
0535 AnalysisResultMapT AnalysisResults;
0536 };
0537
0538 extern template class AnalysisManager<Module>;
0539
0540
0541 using ModuleAnalysisManager = AnalysisManager<Module>;
0542
0543 extern template class AnalysisManager<Function>;
0544
0545
0546 using FunctionAnalysisManager = AnalysisManager<Function>;
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
0565 class InnerAnalysisManagerProxy
0566 : public AnalysisInfoMixin<
0567 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
0568 public:
0569 class Result {
0570 public:
0571 explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
0572
0573 Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) {
0574
0575
0576
0577 Arg.InnerAM = nullptr;
0578 }
0579
0580 ~Result() {
0581
0582 if (!InnerAM)
0583 return;
0584
0585
0586
0587 InnerAM->clear();
0588 }
0589
0590 Result &operator=(Result &&RHS) {
0591 InnerAM = RHS.InnerAM;
0592
0593
0594
0595 RHS.InnerAM = nullptr;
0596 return *this;
0597 }
0598
0599
0600 AnalysisManagerT &getManager() { return *InnerAM; }
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612 bool invalidate(
0613 IRUnitT &IR, const PreservedAnalyses &PA,
0614 typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &Inv);
0615
0616 private:
0617 AnalysisManagerT *InnerAM;
0618 };
0619
0620 explicit InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM)
0621 : InnerAM(&InnerAM) {}
0622
0623
0624
0625
0626
0627
0628 Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
0629 ExtraArgTs...) {
0630 return Result(*InnerAM);
0631 }
0632
0633 private:
0634 friend AnalysisInfoMixin<
0635 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
0636
0637 static AnalysisKey Key;
0638
0639 AnalysisManagerT *InnerAM;
0640 };
0641
0642 template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
0643 AnalysisKey
0644 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
0645
0646
0647 using FunctionAnalysisManagerModuleProxy =
0648 InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
0649
0650
0651
0652 template <>
0653 bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
0654 Module &M, const PreservedAnalyses &PA,
0655 ModuleAnalysisManager::Invalidator &Inv);
0656
0657
0658
0659 extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
0660 Module>;
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689 template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
0690 class OuterAnalysisManagerProxy
0691 : public AnalysisInfoMixin<
0692 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
0693 public:
0694
0695 class Result {
0696 public:
0697 explicit Result(const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
0698
0699
0700
0701 template <typename PassT, typename IRUnitTParam>
0702 typename PassT::Result *getCachedResult(IRUnitTParam &IR) const {
0703 typename PassT::Result *Res =
0704 OuterAM->template getCachedResult<PassT>(IR);
0705 if (Res)
0706 OuterAM->template verifyNotInvalidated<PassT>(IR, Res);
0707 return Res;
0708 }
0709
0710
0711 template <typename PassT, typename IRUnitTParam>
0712 bool cachedResultExists(IRUnitTParam &IR) const {
0713 typename PassT::Result *Res =
0714 OuterAM->template getCachedResult<PassT>(IR);
0715 return Res != nullptr;
0716 }
0717
0718
0719 bool invalidate(
0720 IRUnitT &IRUnit, const PreservedAnalyses &PA,
0721 typename AnalysisManager<IRUnitT, ExtraArgTs...>::Invalidator &Inv) {
0722
0723
0724 SmallVector<AnalysisKey *, 4> DeadKeys;
0725 for (auto &KeyValuePair : OuterAnalysisInvalidationMap) {
0726 AnalysisKey *OuterID = KeyValuePair.first;
0727 auto &InnerIDs = KeyValuePair.second;
0728 llvm::erase_if(InnerIDs, [&](AnalysisKey *InnerID) {
0729 return Inv.invalidate(InnerID, IRUnit, PA);
0730 });
0731 if (InnerIDs.empty())
0732 DeadKeys.push_back(OuterID);
0733 }
0734
0735 for (auto *OuterID : DeadKeys)
0736 OuterAnalysisInvalidationMap.erase(OuterID);
0737
0738
0739 return false;
0740 }
0741
0742
0743
0744 template <typename OuterAnalysisT, typename InvalidatedAnalysisT>
0745 void registerOuterAnalysisInvalidation() {
0746 AnalysisKey *OuterID = OuterAnalysisT::ID();
0747 AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
0748
0749 auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
0750
0751
0752
0753
0754 if (!llvm::is_contained(InvalidatedIDList, InvalidatedID))
0755 InvalidatedIDList.push_back(InvalidatedID);
0756 }
0757
0758
0759
0760 const SmallDenseMap<AnalysisKey *, TinyPtrVector<AnalysisKey *>, 2> &
0761 getOuterInvalidations() const {
0762 return OuterAnalysisInvalidationMap;
0763 }
0764
0765 private:
0766 const AnalysisManagerT *OuterAM;
0767
0768
0769
0770 SmallDenseMap<AnalysisKey *, TinyPtrVector<AnalysisKey *>, 2>
0771 OuterAnalysisInvalidationMap;
0772 };
0773
0774 OuterAnalysisManagerProxy(const AnalysisManagerT &OuterAM)
0775 : OuterAM(&OuterAM) {}
0776
0777
0778
0779
0780 Result run(IRUnitT &, AnalysisManager<IRUnitT, ExtraArgTs...> &,
0781 ExtraArgTs...) {
0782 return Result(*OuterAM);
0783 }
0784
0785 private:
0786 friend AnalysisInfoMixin<
0787 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>;
0788
0789 static AnalysisKey Key;
0790
0791 const AnalysisManagerT *OuterAM;
0792 };
0793
0794 template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
0795 AnalysisKey
0796 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
0797
0798 extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
0799 Function>;
0800
0801 using ModuleAnalysisManagerFunctionProxy =
0802 OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 class ModuleToFunctionPassAdaptor
0828 : public PassInfoMixin<ModuleToFunctionPassAdaptor> {
0829 public:
0830 using PassConceptT = detail::PassConcept<Function, FunctionAnalysisManager>;
0831
0832 explicit ModuleToFunctionPassAdaptor(std::unique_ptr<PassConceptT> Pass,
0833 bool EagerlyInvalidate)
0834 : Pass(std::move(Pass)), EagerlyInvalidate(EagerlyInvalidate) {}
0835
0836
0837 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0838 void printPipeline(raw_ostream &OS,
0839 function_ref<StringRef(StringRef)> MapClassName2PassName);
0840
0841 static bool isRequired() { return true; }
0842
0843 private:
0844 std::unique_ptr<PassConceptT> Pass;
0845 bool EagerlyInvalidate;
0846 };
0847
0848
0849
0850 template <typename FunctionPassT>
0851 ModuleToFunctionPassAdaptor
0852 createModuleToFunctionPassAdaptor(FunctionPassT &&Pass,
0853 bool EagerlyInvalidate = false) {
0854 using PassModelT =
0855 detail::PassModel<Function, FunctionPassT, FunctionAnalysisManager>;
0856
0857
0858 return ModuleToFunctionPassAdaptor(
0859 std::unique_ptr<ModuleToFunctionPassAdaptor::PassConceptT>(
0860 new PassModelT(std::forward<FunctionPassT>(Pass))),
0861 EagerlyInvalidate);
0862 }
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873 template <typename AnalysisT, typename IRUnitT,
0874 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
0875 typename... ExtraArgTs>
0876 struct RequireAnalysisPass
0877 : PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
0878 ExtraArgTs...>> {
0879
0880
0881
0882
0883
0884
0885 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM,
0886 ExtraArgTs &&... Args) {
0887 (void)AM.template getResult<AnalysisT>(Arg,
0888 std::forward<ExtraArgTs>(Args)...);
0889
0890 return PreservedAnalyses::all();
0891 }
0892 void printPipeline(raw_ostream &OS,
0893 function_ref<StringRef(StringRef)> MapClassName2PassName) {
0894 auto ClassName = AnalysisT::name();
0895 auto PassName = MapClassName2PassName(ClassName);
0896 OS << "require<" << PassName << '>';
0897 }
0898 static bool isRequired() { return true; }
0899 };
0900
0901
0902
0903 template <typename AnalysisT>
0904 struct InvalidateAnalysisPass
0905 : PassInfoMixin<InvalidateAnalysisPass<AnalysisT>> {
0906
0907
0908
0909
0910
0911
0912 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
0913 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...) {
0914 auto PA = PreservedAnalyses::all();
0915 PA.abandon<AnalysisT>();
0916 return PA;
0917 }
0918 void printPipeline(raw_ostream &OS,
0919 function_ref<StringRef(StringRef)> MapClassName2PassName) {
0920 auto ClassName = AnalysisT::name();
0921 auto PassName = MapClassName2PassName(ClassName);
0922 OS << "invalidate<" << PassName << '>';
0923 }
0924 };
0925
0926
0927
0928
0929
0930 struct InvalidateAllAnalysesPass : PassInfoMixin<InvalidateAllAnalysesPass> {
0931
0932 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
0933 PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
0934 return PreservedAnalyses::none();
0935 }
0936 };
0937
0938 }
0939
0940 #endif