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 | |
27 | bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { |
28 | S = nullptr; |
29 | |
30 | if (skipRegion(R&: *R)) |
31 | return false; |
32 | |
33 | if ((S = getAnalysis<ScopInfoRegionPass>().getScop())) |
34 | return runOnScop(S&: *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&: *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<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 &, |
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(IR&: S, AM, ExtraArgs&: AR, ExtraArgs&: U); |
83 | |
84 | AM.invalidate(IR&: S, PA: PassPA); |
85 | PA.intersect(Arg: 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 | |
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>(IR&: F, PA) || |
103 | Inv.invalidate<ScalarEvolutionAnalysis>(IR&: F, PA) || |
104 | Inv.invalidate<LoopAnalysis>(IR&: F, PA) || |
105 | Inv.invalidate<DominatorTreeAnalysis>(IR&: 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(IR&: *scop, Name: 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>(IR&: *scop)) { |
130 | for (const auto &InvPair : OuterProxy->getOuterInvalidations()) { |
131 | auto *OuterAnalysisID = InvPair.first; |
132 | const auto &InnerAnalysisIDs = InvPair.second; |
133 | |
134 | if (Inv.invalidate(ID: OuterAnalysisID, IR&: F, PA)) { |
135 | if (!InnerPA) |
136 | InnerPA = PA; |
137 | for (auto *InnerAnalysisID : InnerAnalysisIDs) |
138 | InnerPA->abandon(ID: InnerAnalysisID); |
139 | } |
140 | } |
141 | |
142 | if (InnerPA) { |
143 | InnerAM->invalidate(IR&: *scop, PA: *InnerPA); |
144 | continue; |
145 | } |
146 | } |
147 | |
148 | if (!allPreserved) |
149 | InnerAM->invalidate(IR&: *scop, PA); |
150 | } |
151 | |
152 | return false; // This proxy is still valid |
153 | } |
154 | |
155 | template <> |
156 | ScopAnalysisManagerFunctionProxy::Result |
157 | ScopAnalysisManagerFunctionProxy::run(Function &F, |
158 | FunctionAnalysisManager &FAM) { |
159 | return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(IR&: F)); |
160 | } |
161 | } // namespace llvm |
162 | |
163 | namespace polly { |
164 | template <> |
165 | OwningScopAnalysisManagerFunctionProxy::Result |
166 | OwningScopAnalysisManagerFunctionProxy::run(Function &F, |
167 | FunctionAnalysisManager &FAM) { |
168 | return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(IR&: F)); |
169 | } |
170 | } // namespace polly |
171 | |