- //===--------- ScopPass.h - Pass for Static Control Parts --------*-C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file defines the ScopPass class.  ScopPasses are just RegionPasses, 
- // except they operate on Polly IR (Scop and ScopStmt) built by ScopInfo Pass. 
- // Because they operate on Polly IR, not the LLVM IR, ScopPasses are not allowed 
- // to modify the LLVM IR. Due to this limitation, the ScopPass class takes 
- // care of declaring that no LLVM passes are invalidated. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef POLLY_SCOP_PASS_H 
- #define POLLY_SCOP_PASS_H 
-   
- #include "polly/ScopInfo.h" 
- #include "llvm/ADT/PriorityWorklist.h" 
- #include "llvm/Analysis/RegionPass.h" 
- #include "llvm/Analysis/TargetTransformInfo.h" 
- #include "llvm/IR/PassManager.h" 
- #include "llvm/IR/PassManagerImpl.h" 
-   
- namespace polly { 
- using llvm::AllAnalysesOn; 
- using llvm::AnalysisManager; 
- using llvm::DominatorTreeAnalysis; 
- using llvm::InnerAnalysisManagerProxy; 
- using llvm::LoopAnalysis; 
- using llvm::OuterAnalysisManagerProxy; 
- using llvm::PassManager; 
- using llvm::RegionInfoAnalysis; 
- using llvm::ScalarEvolutionAnalysis; 
- using llvm::SmallPriorityWorklist; 
- using llvm::TargetIRAnalysis; 
- using llvm::TargetTransformInfo; 
-   
- class Scop; 
- class SPMUpdater; 
- struct ScopStandardAnalysisResults; 
-   
- using ScopAnalysisManager = 
-     AnalysisManager<Scop, ScopStandardAnalysisResults &>; 
- using ScopAnalysisManagerFunctionProxy = 
-     InnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 
- using FunctionAnalysisManagerScopProxy = 
-     OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop, 
-                               ScopStandardAnalysisResults &>; 
- } // namespace polly 
-   
- namespace llvm { 
- using polly::Scop; 
- using polly::ScopAnalysisManager; 
- using polly::ScopAnalysisManagerFunctionProxy; 
- using polly::ScopInfo; 
- using polly::ScopStandardAnalysisResults; 
- using polly::SPMUpdater; 
-   
- template <> 
- class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result { 
- public: 
-   explicit Result(ScopAnalysisManager &InnerAM, ScopInfo &SI) 
-       : InnerAM(&InnerAM), SI(&SI) {} 
-   Result(Result &&R) : InnerAM(std::move(R.InnerAM)), SI(R.SI) { 
-     R.InnerAM = nullptr; 
-   } 
-   Result &operator=(Result &&RHS) { 
-     InnerAM = RHS.InnerAM; 
-     SI = RHS.SI; 
-     RHS.InnerAM = nullptr; 
-     return *this; 
-   } 
-   ~Result() { 
-     if (!InnerAM) 
-       return; 
-     InnerAM->clear(); 
-   } 
-   
-   ScopAnalysisManager &getManager() { return *InnerAM; } 
-   
-   bool invalidate(Function &F, const PreservedAnalyses &PA, 
-                   FunctionAnalysisManager::Invalidator &Inv); 
-   
- private: 
-   ScopAnalysisManager *InnerAM; 
-   ScopInfo *SI; 
- }; 
-   
- // A partial specialization of the require analysis template pass to handle 
- // extra parameters 
- template <typename AnalysisT> 
- struct RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager, 
-                            ScopStandardAnalysisResults &, SPMUpdater &> 
-     : PassInfoMixin< 
-           RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager, 
-                               ScopStandardAnalysisResults &, SPMUpdater &>> { 
-   PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM, 
-                         ScopStandardAnalysisResults &AR, SPMUpdater &) { 
-     (void)AM.template getResult<AnalysisT>(L, AR); 
-     return PreservedAnalyses::all(); 
-   } 
- }; 
-   
- template <> 
- InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result 
- InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run( 
-     Function &F, FunctionAnalysisManager &FAM); 
-   
- template <> 
- PreservedAnalyses 
- PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &, 
-             SPMUpdater &>::run(Scop &InitialS, ScopAnalysisManager &AM, 
-                                ScopStandardAnalysisResults &, SPMUpdater &); 
- extern template class PassManager<Scop, ScopAnalysisManager, 
-                                   ScopStandardAnalysisResults &, SPMUpdater &>; 
- extern template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 
- extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop, 
-                                                 ScopStandardAnalysisResults &>; 
- } // namespace llvm 
-   
- namespace polly { 
-   
- template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs> 
- class OwningInnerAnalysisManagerProxy final 
-     : public InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT> { 
- public: 
-   OwningInnerAnalysisManagerProxy() 
-       : InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>(InnerAM) {} 
-   using Result = typename InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, 
-                                                     ExtraArgTs...>::Result; 
-   Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM, 
-              ExtraArgTs...) { 
-     return Result(InnerAM); 
-   } 
-   
-   AnalysisManagerT &getManager() { return InnerAM; } 
-   
- private: 
-   AnalysisManagerT InnerAM; 
- }; 
-   
- template <> 
- OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result 
- OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run( 
-     Function &F, FunctionAnalysisManager &FAM); 
- extern template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, 
-                                                       Function>; 
-   
- using OwningScopAnalysisManagerFunctionProxy = 
-     OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>; 
- using ScopPassManager = 
-     PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &, 
-                 SPMUpdater &>; 
-   
- /// ScopPass - This class adapts the RegionPass interface to allow convenient 
- /// creation of passes that operate on the Polly IR. Instead of overriding 
- /// runOnRegion, subclasses override runOnScop. 
- class ScopPass : public RegionPass { 
-   Scop *S; 
-   
- protected: 
-   explicit ScopPass(char &ID) : RegionPass(ID), S(nullptr) {} 
-   
-   /// runOnScop - This method must be overloaded to perform the 
-   /// desired Polyhedral transformation or analysis. 
-   /// 
-   virtual bool runOnScop(Scop &S) = 0; 
-   
-   /// Print method for SCoPs. 
-   virtual void printScop(raw_ostream &OS, Scop &S) const {} 
-   
-   /// getAnalysisUsage - Subclasses that override getAnalysisUsage 
-   /// must call this. 
-   /// 
-   void getAnalysisUsage(AnalysisUsage &AU) const override; 
-   
- private: 
-   bool runOnRegion(Region *R, RGPassManager &RGM) override; 
-   void print(raw_ostream &OS, const Module *) const override; 
- }; 
-   
- struct ScopStandardAnalysisResults { 
-   DominatorTree &DT; 
-   ScopInfo &SI; 
-   ScalarEvolution &SE; 
-   LoopInfo &LI; 
-   RegionInfo &RI; 
-   TargetTransformInfo &TTI; 
- }; 
-   
- class SPMUpdater final { 
- public: 
-   SPMUpdater(SmallPriorityWorklist<Region *, 4> &Worklist, 
-              ScopAnalysisManager &SAM) 
-       : InvalidateCurrentScop(false), Worklist(Worklist), SAM(SAM) {} 
-   
-   bool invalidateCurrentScop() const { return InvalidateCurrentScop; } 
-   
-   void invalidateScop(Scop &S) { 
-     if (&S == CurrentScop) 
-       InvalidateCurrentScop = true; 
-   
-     Worklist.erase(&S.getRegion()); 
-     SAM.clear(S, S.getName()); 
-   } 
-   
- private: 
-   Scop *CurrentScop; 
-   bool InvalidateCurrentScop; 
-   SmallPriorityWorklist<Region *, 4> &Worklist; 
-   ScopAnalysisManager &SAM; 
-   template <typename ScopPassT> friend struct FunctionToScopPassAdaptor; 
- }; 
-   
- template <typename ScopPassT> 
- struct FunctionToScopPassAdaptor final 
-     : PassInfoMixin<FunctionToScopPassAdaptor<ScopPassT>> { 
-   explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {} 
-   
-   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { 
-     ScopDetection &SD = AM.getResult<ScopAnalysis>(F); 
-     ScopInfo &SI = AM.getResult<ScopInfoAnalysis>(F); 
-     if (SI.empty()) { 
-       // With no scops having been detected, no IR changes have been made and 
-       // therefore all analyses are preserved. However, we must still free the 
-       // Scop analysis results which may hold AssertingVH that cause an error 
-       // if its value is destroyed. 
-       PreservedAnalyses PA = PreservedAnalyses::all(); 
-       PA.abandon<ScopInfoAnalysis>(); 
-       PA.abandon<ScopAnalysis>(); 
-       AM.invalidate(F, PA); 
-       return PreservedAnalyses::all(); 
-     } 
-   
-     SmallPriorityWorklist<Region *, 4> Worklist; 
-     for (auto &S : SI) 
-       if (S.second) 
-         Worklist.insert(S.first); 
-   
-     ScopStandardAnalysisResults AR = {AM.getResult<DominatorTreeAnalysis>(F), 
-                                       AM.getResult<ScopInfoAnalysis>(F), 
-                                       AM.getResult<ScalarEvolutionAnalysis>(F), 
-                                       AM.getResult<LoopAnalysis>(F), 
-                                       AM.getResult<RegionInfoAnalysis>(F), 
-                                       AM.getResult<TargetIRAnalysis>(F)}; 
-   
-     ScopAnalysisManager &SAM = 
-         AM.getResult<ScopAnalysisManagerFunctionProxy>(F).getManager(); 
-   
-     SPMUpdater Updater{Worklist, SAM}; 
-   
-     while (!Worklist.empty()) { 
-       Region *R = Worklist.pop_back_val(); 
-       if (!SD.isMaxRegionInScop(*R, /*Verify=*/false)) 
-         continue; 
-       Scop *scop = SI.getScop(R); 
-       if (!scop) 
-         continue; 
-       Updater.CurrentScop = scop; 
-       Updater.InvalidateCurrentScop = false; 
-       PreservedAnalyses PassPA = Pass.run(*scop, SAM, AR, Updater); 
-   
-       SAM.invalidate(*scop, PassPA); 
-       if (Updater.invalidateCurrentScop()) 
-         SI.recompute(); 
-     }; 
-   
-     // FIXME: For the same reason as we add a BarrierNoopPass in the legacy pass 
-     // manager, do not preserve any analyses. While CodeGeneration may preserve 
-     // IR analyses sufficiently to process another Scop in the same function (it 
-     // has to, otherwise the ScopDetection result itself would need to be 
-     // invalidated), it is not sufficient for other purposes. For instance, 
-     // CodeGeneration does not inform LoopInfo about new loops in the 
-     // Polly-generated IR. 
-     return PreservedAnalyses::none(); 
-   } 
-   
- private: 
-   ScopPassT Pass; 
- }; 
-   
- template <typename ScopPassT> 
- FunctionToScopPassAdaptor<ScopPassT> 
- createFunctionToScopPassAdaptor(ScopPassT Pass) { 
-   return FunctionToScopPassAdaptor<ScopPassT>(std::move(Pass)); 
- } 
- } // namespace polly 
-   
- #endif 
-