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