1 //===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the definitions of the ScopPass members.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "polly/ScopPass.h"
15 #include "polly/ScopInfo.h"
16 
17 #include "llvm/Analysis/AssumptionCache.h"
18 #include "llvm/Analysis/BasicAliasAnalysis.h"
19 #include "llvm/Analysis/GlobalsModRef.h"
20 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
21 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 
24 using namespace llvm;
25 using namespace polly;
26 
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 
39 void ScopPass::print(raw_ostream &OS, const Module *M) const {
40   if (S)
41     printScop(OS, *S);
42 }
43 
44 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<RegionInfoPass>();
57   AU.addPreserved<ScopInfoRegionPass>();
58   AU.addPreserved<TargetTransformInfoWrapperPass>();
59 }
60 
61 namespace polly {
62 template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
63 }
64 
65 namespace llvm {
66 
67 template class PassManager<Scop, ScopAnalysisManager,
68                            ScopStandardAnalysisResults &, SPMUpdater &>;
69 template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
70 template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
71                                          ScopStandardAnalysisResults &>;
72 
73 template <>
74 PreservedAnalyses
75 PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
76             SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM,
77                                ScopStandardAnalysisResults &AR, SPMUpdater &U) {
78   auto PA = PreservedAnalyses::all();
79   for (auto &Pass : Passes) {
80     auto PassPA = Pass->run(S, AM, AR, U);
81 
82     AM.invalidate(S, PassPA);
83     PA.intersect(std::move(PassPA));
84   }
85 
86   // All analyses for 'this' Scop have been invalidated above.
87   // If ScopPasses affect break other scops they have to propagate this
88   // information through the updater
89   PA.preserveSet<AllAnalysesOn<Scop>>();
90   return PA;
91 }
92 
93 bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
94     Function &F, const PreservedAnalyses &PA,
95     FunctionAnalysisManager::Invalidator &Inv) {
96 
97   // First, check whether our ScopInfo is about to be invalidated
98   auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>();
99   if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
100       Inv.invalidate<ScopInfoAnalysis>(F, PA) ||
101       Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
102       Inv.invalidate<LoopAnalysis>(F, PA) ||
103       Inv.invalidate<DominatorTreeAnalysis>(F, PA)) {
104 
105     // As everything depends on ScopInfo, we must drop all existing results
106     for (auto &S : *SI)
107       if (auto *scop = S.second.get())
108         if (InnerAM)
109           InnerAM->clear(*scop, scop->getName());
110 
111     InnerAM = nullptr;
112     return true; // Invalidate the proxy result as well.
113   }
114 
115   bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>();
116 
117   // Invalidate all non-preserved analyses
118   // Even if all analyses were preserved, we still need to run deferred
119   // invalidation
120   for (auto &S : *SI) {
121     Optional<PreservedAnalyses> InnerPA;
122     auto *scop = S.second.get();
123     if (!scop)
124       continue;
125 
126     if (auto *OuterProxy =
127             InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) {
128       for (const auto &InvPair : OuterProxy->getOuterInvalidations()) {
129         auto *OuterAnalysisID = InvPair.first;
130         const auto &InnerAnalysisIDs = InvPair.second;
131 
132         if (Inv.invalidate(OuterAnalysisID, F, PA)) {
133           if (!InnerPA)
134             InnerPA = PA;
135           for (auto *InnerAnalysisID : InnerAnalysisIDs)
136             InnerPA->abandon(InnerAnalysisID);
137         }
138       }
139 
140       if (InnerPA) {
141         InnerAM->invalidate(*scop, *InnerPA);
142         continue;
143       }
144     }
145 
146     if (!allPreserved)
147       InnerAM->invalidate(*scop, PA);
148   }
149 
150   return false; // This proxy is still valid
151 }
152 
153 template <>
154 ScopAnalysisManagerFunctionProxy::Result
155 ScopAnalysisManagerFunctionProxy::run(Function &F,
156                                       FunctionAnalysisManager &FAM) {
157   return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
158 }
159 } // namespace llvm
160 
161 namespace polly {
162 template <>
163 OwningScopAnalysisManagerFunctionProxy::Result
164 OwningScopAnalysisManagerFunctionProxy::run(Function &F,
165                                             FunctionAnalysisManager &FAM) {
166   return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
167 }
168 } // namespace polly
169