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