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