xref: /llvm-project/polly/lib/Analysis/ScopPass.cpp (revision ccdc271a0899c2225a9cd2db1af61c1d5cf8fcad)
1 //===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
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 contains the definitions of the ScopPass members.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "polly/ScopPass.h"
14 #include "polly/ScopInfo.h"
15 #include "llvm/Analysis/BasicAliasAnalysis.h"
16 #include "llvm/Analysis/GlobalsModRef.h"
17 #include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18 #include "llvm/Analysis/LazyBranchProbabilityInfo.h"
19 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
20 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
21 #include "llvm/Analysis/TargetTransformInfo.h"
22 #include <optional>
23 
24 using namespace llvm;
25 using namespace polly;
26 
runOnRegion(Region * R,RGPassManager & RGM)27 bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
28   S = nullptr;
29 
30   if (skipRegion(*R))
31     return false;
32 
33   if ((S = getAnalysis<ScopInfoRegionPass>().getScop()))
34     return runOnScop(*S);
35 
36   return false;
37 }
38 
print(raw_ostream & OS,const Module * M) const39 void ScopPass::print(raw_ostream &OS, const Module *M) const {
40   if (S)
41     printScop(OS, *S);
42 }
43 
getAnalysisUsage(AnalysisUsage & AU) const44 void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
45   AU.addRequired<ScopInfoRegionPass>();
46 
47   AU.addPreserved<AAResultsWrapperPass>();
48   AU.addPreserved<BasicAAWrapperPass>();
49   AU.addPreserved<LoopInfoWrapperPass>();
50   AU.addPreserved<DominatorTreeWrapperPass>();
51   AU.addPreserved<GlobalsAAWrapperPass>();
52   AU.addPreserved<ScopDetectionWrapperPass>();
53   AU.addPreserved<ScalarEvolutionWrapperPass>();
54   AU.addPreserved<SCEVAAWrapperPass>();
55   AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
56   AU.addPreserved<LazyBlockFrequencyInfoPass>();
57   AU.addPreserved<LazyBranchProbabilityInfoPass>();
58   AU.addPreserved<RegionInfoPass>();
59   AU.addPreserved<ScopInfoRegionPass>();
60   AU.addPreserved<TargetTransformInfoWrapperPass>();
61 }
62 
63 namespace polly {
64 template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
65 }
66 
67 namespace llvm {
68 
69 template class PassManager<Scop, ScopAnalysisManager,
70                            ScopStandardAnalysisResults &, SPMUpdater &>;
71 template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
72 template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
73                                          ScopStandardAnalysisResults &>;
74 
75 template <>
76 PreservedAnalyses
77 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
run(Scop & S,ScopAnalysisManager & AM,ScopStandardAnalysisResults & AR,SPMUpdater & U)78             SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM,
79                                ScopStandardAnalysisResults &AR, SPMUpdater &U) {
80   auto PA = PreservedAnalyses::all();
81   for (auto &Pass : Passes) {
82     auto PassPA = Pass->run(S, AM, AR, U);
83 
84     AM.invalidate(S, PassPA);
85     PA.intersect(std::move(PassPA));
86   }
87 
88   // All analyses for 'this' Scop have been invalidated above.
89   // If ScopPasses affect break other scops they have to propagate this
90   // information through the updater
91   PA.preserveSet<AllAnalysesOn<Scop>>();
92   return PA;
93 }
94 
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator & Inv)95 bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
96     Function &F, const PreservedAnalyses &PA,
97     FunctionAnalysisManager::Invalidator &Inv) {
98 
99   // First, check whether our ScopInfo is about to be invalidated
100   auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>();
101   if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
102       Inv.invalidate<ScopInfoAnalysis>(F, PA) ||
103       Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
104       Inv.invalidate<LoopAnalysis>(F, PA) ||
105       Inv.invalidate<DominatorTreeAnalysis>(F, PA)) {
106 
107     // As everything depends on ScopInfo, we must drop all existing results
108     for (auto &S : *SI)
109       if (auto *scop = S.second.get())
110         if (InnerAM)
111           InnerAM->clear(*scop, scop->getName());
112 
113     InnerAM = nullptr;
114     return true; // Invalidate the proxy result as well.
115   }
116 
117   bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>();
118 
119   // Invalidate all non-preserved analyses
120   // Even if all analyses were preserved, we still need to run deferred
121   // invalidation
122   for (auto &S : *SI) {
123     std::optional<PreservedAnalyses> InnerPA;
124     auto *scop = S.second.get();
125     if (!scop)
126       continue;
127 
128     if (auto *OuterProxy =
129             InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) {
130       for (const auto &InvPair : OuterProxy->getOuterInvalidations()) {
131         auto *OuterAnalysisID = InvPair.first;
132         const auto &InnerAnalysisIDs = InvPair.second;
133 
134         if (Inv.invalidate(OuterAnalysisID, F, PA)) {
135           if (!InnerPA)
136             InnerPA = PA;
137           for (auto *InnerAnalysisID : InnerAnalysisIDs)
138             InnerPA->abandon(InnerAnalysisID);
139         }
140       }
141 
142       if (InnerPA) {
143         InnerAM->invalidate(*scop, *InnerPA);
144         continue;
145       }
146     }
147 
148     if (!allPreserved)
149       InnerAM->invalidate(*scop, PA);
150   }
151 
152   return false; // This proxy is still valid
153 }
154 
155 template <>
156 ScopAnalysisManagerFunctionProxy::Result
run(Function & F,FunctionAnalysisManager & FAM)157 ScopAnalysisManagerFunctionProxy::run(Function &F,
158                                       FunctionAnalysisManager &FAM) {
159   return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
160 }
161 } // namespace llvm
162 
163 namespace polly {
164 template <>
165 OwningScopAnalysisManagerFunctionProxy::Result
run(Function & F,FunctionAnalysisManager & FAM)166 OwningScopAnalysisManagerFunctionProxy::run(Function &F,
167                                             FunctionAnalysisManager &FAM) {
168   return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
169 }
170 } // namespace polly
171