File indexing completed on 2026-05-10 08:48:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef POLLY_SCOP_PASS_H
0018 #define POLLY_SCOP_PASS_H
0019
0020 #include "polly/ScopInfo.h"
0021 #include "llvm/ADT/PriorityWorklist.h"
0022 #include "llvm/Analysis/RegionPass.h"
0023 #include "llvm/Analysis/TargetTransformInfo.h"
0024 #include "llvm/IR/PassManager.h"
0025 #include "llvm/IR/PassManagerImpl.h"
0026
0027 namespace polly {
0028 using llvm::AllAnalysesOn;
0029 using llvm::AnalysisManager;
0030 using llvm::DominatorTreeAnalysis;
0031 using llvm::InnerAnalysisManagerProxy;
0032 using llvm::LoopAnalysis;
0033 using llvm::OuterAnalysisManagerProxy;
0034 using llvm::PassManager;
0035 using llvm::RegionInfoAnalysis;
0036 using llvm::ScalarEvolutionAnalysis;
0037 using llvm::SmallPriorityWorklist;
0038 using llvm::TargetIRAnalysis;
0039 using llvm::TargetTransformInfo;
0040
0041 class Scop;
0042 class SPMUpdater;
0043 struct ScopStandardAnalysisResults;
0044
0045 using ScopAnalysisManager =
0046 AnalysisManager<Scop, ScopStandardAnalysisResults &>;
0047 using ScopAnalysisManagerFunctionProxy =
0048 InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
0049 using FunctionAnalysisManagerScopProxy =
0050 OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
0051 ScopStandardAnalysisResults &>;
0052 }
0053
0054 namespace llvm {
0055 using polly::Scop;
0056 using polly::ScopAnalysisManager;
0057 using polly::ScopAnalysisManagerFunctionProxy;
0058 using polly::ScopInfo;
0059 using polly::ScopStandardAnalysisResults;
0060 using polly::SPMUpdater;
0061
0062 template <>
0063 class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result {
0064 public:
0065 explicit Result(ScopAnalysisManager &InnerAM, ScopInfo &SI)
0066 : InnerAM(&InnerAM), SI(&SI) {}
0067 Result(Result &&R) : InnerAM(std::move(R.InnerAM)), SI(R.SI) {
0068 R.InnerAM = nullptr;
0069 }
0070 Result &operator=(Result &&RHS) {
0071 InnerAM = RHS.InnerAM;
0072 SI = RHS.SI;
0073 RHS.InnerAM = nullptr;
0074 return *this;
0075 }
0076 ~Result() {
0077 if (!InnerAM)
0078 return;
0079 InnerAM->clear();
0080 }
0081
0082 ScopAnalysisManager &getManager() { return *InnerAM; }
0083
0084 bool invalidate(Function &F, const PreservedAnalyses &PA,
0085 FunctionAnalysisManager::Invalidator &Inv);
0086
0087 private:
0088 ScopAnalysisManager *InnerAM;
0089 ScopInfo *SI;
0090 };
0091
0092
0093
0094 template <typename AnalysisT>
0095 struct RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
0096 ScopStandardAnalysisResults &, SPMUpdater &>
0097 : PassInfoMixin<
0098 RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
0099 ScopStandardAnalysisResults &, SPMUpdater &>> {
0100 PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM,
0101 ScopStandardAnalysisResults &AR, SPMUpdater &) {
0102 (void)AM.template getResult<AnalysisT>(L, AR);
0103 return PreservedAnalyses::all();
0104 }
0105 };
0106
0107 template <>
0108 InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
0109 InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
0110 Function &F, FunctionAnalysisManager &FAM);
0111
0112 template <>
0113 PreservedAnalyses
0114 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
0115 SPMUpdater &>::run(Scop &InitialS, ScopAnalysisManager &AM,
0116 ScopStandardAnalysisResults &, SPMUpdater &);
0117 extern template class PassManager<Scop, ScopAnalysisManager,
0118 ScopStandardAnalysisResults &, SPMUpdater &>;
0119 extern template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
0120 extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
0121 ScopStandardAnalysisResults &>;
0122 }
0123
0124 namespace polly {
0125
0126 template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
0127 class OwningInnerAnalysisManagerProxy final
0128 : public InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT> {
0129 public:
0130 OwningInnerAnalysisManagerProxy()
0131 : InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>(InnerAM) {}
0132 using Result = typename InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT,
0133 ExtraArgTs...>::Result;
0134 Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
0135 ExtraArgTs...) {
0136 return Result(InnerAM);
0137 }
0138
0139 AnalysisManagerT &getManager() { return InnerAM; }
0140
0141 private:
0142 AnalysisManagerT InnerAM;
0143 };
0144
0145 template <>
0146 OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
0147 OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
0148 Function &F, FunctionAnalysisManager &FAM);
0149 extern template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager,
0150 Function>;
0151
0152 using OwningScopAnalysisManagerFunctionProxy =
0153 OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
0154 using ScopPassManager =
0155 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
0156 SPMUpdater &>;
0157
0158
0159
0160
0161 class ScopPass : public RegionPass {
0162 Scop *S;
0163
0164 protected:
0165 explicit ScopPass(char &ID) : RegionPass(ID), S(nullptr) {}
0166
0167
0168
0169
0170 virtual bool runOnScop(Scop &S) = 0;
0171
0172
0173 virtual void printScop(raw_ostream &OS, Scop &S) const {}
0174
0175
0176
0177
0178 void getAnalysisUsage(AnalysisUsage &AU) const override;
0179
0180 private:
0181 bool runOnRegion(Region *R, RGPassManager &RGM) override;
0182 void print(raw_ostream &OS, const Module *) const override;
0183 };
0184
0185 struct ScopStandardAnalysisResults {
0186 DominatorTree &DT;
0187 ScopInfo &SI;
0188 ScalarEvolution &SE;
0189 LoopInfo &LI;
0190 RegionInfo &RI;
0191 TargetTransformInfo &TTI;
0192 };
0193
0194 class SPMUpdater final {
0195 public:
0196 SPMUpdater(SmallPriorityWorklist<Region *, 4> &Worklist,
0197 ScopAnalysisManager &SAM)
0198 : InvalidateCurrentScop(false), Worklist(Worklist), SAM(SAM) {}
0199
0200 bool invalidateCurrentScop() const { return InvalidateCurrentScop; }
0201
0202 void invalidateScop(Scop &S) {
0203 if (&S == CurrentScop)
0204 InvalidateCurrentScop = true;
0205
0206 Worklist.erase(&S.getRegion());
0207 SAM.clear(S, S.getName());
0208 }
0209
0210 private:
0211 Scop *CurrentScop;
0212 bool InvalidateCurrentScop;
0213 SmallPriorityWorklist<Region *, 4> &Worklist;
0214 ScopAnalysisManager &SAM;
0215 template <typename ScopPassT> friend struct FunctionToScopPassAdaptor;
0216 };
0217
0218 template <typename ScopPassT>
0219 struct FunctionToScopPassAdaptor final
0220 : PassInfoMixin<FunctionToScopPassAdaptor<ScopPassT>> {
0221 explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {}
0222
0223 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
0224 ScopDetection &SD = AM.getResult<ScopAnalysis>(F);
0225 ScopInfo &SI = AM.getResult<ScopInfoAnalysis>(F);
0226 if (SI.empty()) {
0227
0228
0229
0230
0231 PreservedAnalyses PA = PreservedAnalyses::all();
0232 PA.abandon<ScopInfoAnalysis>();
0233 PA.abandon<ScopAnalysis>();
0234 AM.invalidate(F, PA);
0235 return PreservedAnalyses::all();
0236 }
0237
0238 SmallPriorityWorklist<Region *, 4> Worklist;
0239 for (auto &S : SI)
0240 if (S.second)
0241 Worklist.insert(S.first);
0242
0243 ScopStandardAnalysisResults AR = {AM.getResult<DominatorTreeAnalysis>(F),
0244 AM.getResult<ScopInfoAnalysis>(F),
0245 AM.getResult<ScalarEvolutionAnalysis>(F),
0246 AM.getResult<LoopAnalysis>(F),
0247 AM.getResult<RegionInfoAnalysis>(F),
0248 AM.getResult<TargetIRAnalysis>(F)};
0249
0250 ScopAnalysisManager &SAM =
0251 AM.getResult<ScopAnalysisManagerFunctionProxy>(F).getManager();
0252
0253 SPMUpdater Updater{Worklist, SAM};
0254
0255 while (!Worklist.empty()) {
0256 Region *R = Worklist.pop_back_val();
0257 if (!SD.isMaxRegionInScop(*R, false))
0258 continue;
0259 Scop *scop = SI.getScop(R);
0260 if (!scop)
0261 continue;
0262 Updater.CurrentScop = scop;
0263 Updater.InvalidateCurrentScop = false;
0264 PreservedAnalyses PassPA = Pass.run(*scop, SAM, AR, Updater);
0265
0266 SAM.invalidate(*scop, PassPA);
0267 if (Updater.invalidateCurrentScop())
0268 SI.recompute();
0269 };
0270
0271
0272
0273
0274
0275
0276
0277
0278 return PreservedAnalyses::none();
0279 }
0280
0281 private:
0282 ScopPassT Pass;
0283 };
0284
0285 template <typename ScopPassT>
0286 FunctionToScopPassAdaptor<ScopPassT>
0287 createFunctionToScopPassAdaptor(ScopPassT Pass) {
0288 return FunctionToScopPassAdaptor<ScopPassT>(std::move(Pass));
0289 }
0290 }
0291
0292 #endif