Polly 20.0.0git
ScopPass.h
Go to the documentation of this file.
1//===--------- ScopPass.h - Pass for Static Control Parts --------*-C++ -*-===//
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 defines the ScopPass class. ScopPasses are just RegionPasses,
10// except they operate on Polly IR (Scop and ScopStmt) built by ScopInfo Pass.
11// Because they operate on Polly IR, not the LLVM IR, ScopPasses are not allowed
12// to modify the LLVM IR. Due to this limitation, the ScopPass class takes
13// care of declaring that no LLVM passes are invalidated.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef POLLY_SCOP_PASS_H
18#define POLLY_SCOP_PASS_H
19
20#include "polly/ScopInfo.h"
21#include "llvm/ADT/PriorityWorklist.h"
22#include "llvm/Analysis/RegionPass.h"
23#include "llvm/Analysis/TargetTransformInfo.h"
24#include "llvm/IR/PassManager.h"
25#include "llvm/IR/PassManagerImpl.h"
26
27namespace polly {
28using llvm::AllAnalysesOn;
29using llvm::AnalysisManager;
30using llvm::DominatorTreeAnalysis;
31using llvm::InnerAnalysisManagerProxy;
32using llvm::LoopAnalysis;
33using llvm::OuterAnalysisManagerProxy;
34using llvm::PassManager;
35using llvm::RegionInfoAnalysis;
36using llvm::ScalarEvolutionAnalysis;
37using llvm::SmallPriorityWorklist;
38using llvm::TargetIRAnalysis;
39using llvm::TargetTransformInfo;
40
41class Scop;
42class SPMUpdater;
44
46 AnalysisManager<Scop, ScopStandardAnalysisResults &>;
48 InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
50 OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
52} // namespace polly
53
54namespace llvm {
55using polly::Scop;
58using polly::ScopInfo;
61
62template <>
63class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result {
64public:
65 explicit Result(ScopAnalysisManager &InnerAM, ScopInfo &SI)
66 : InnerAM(&InnerAM), SI(&SI) {}
67 Result(Result &&R) : InnerAM(std::move(R.InnerAM)), SI(R.SI) {
68 R.InnerAM = nullptr;
69 }
71 InnerAM = RHS.InnerAM;
72 SI = RHS.SI;
73 RHS.InnerAM = nullptr;
74 return *this;
75 }
77 if (!InnerAM)
78 return;
79 InnerAM->clear();
80 }
81
82 ScopAnalysisManager &getManager() { return *InnerAM; }
83
84 bool invalidate(Function &F, const PreservedAnalyses &PA,
85 FunctionAnalysisManager::Invalidator &Inv);
86
87private:
88 ScopAnalysisManager *InnerAM;
90};
91
92// A partial specialization of the require analysis template pass to handle
93// extra parameters
94template <typename AnalysisT>
95struct RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
97 : PassInfoMixin<
98 RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
100 PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM,
102 (void)AM.template getResult<AnalysisT>(L, AR);
103 return PreservedAnalyses::all();
104 }
105};
106
107template <>
109InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
110 Function &F, FunctionAnalysisManager &FAM);
111
112template <>
113PreservedAnalyses
114PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
115 SPMUpdater &>::run(Scop &InitialS, ScopAnalysisManager &AM,
117extern template class PassManager<Scop, ScopAnalysisManager,
119extern template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
120extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
122} // namespace llvm
123
124namespace polly {
125
126template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
128 : public InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT> {
129public:
131 : InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>(InnerAM) {}
132 using Result = typename InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT,
133 ExtraArgTs...>::Result;
134 Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
135 ExtraArgTs...) {
136 return Result(InnerAM);
137 }
138
139 AnalysisManagerT &getManager() { return InnerAM; }
140
141private:
142 AnalysisManagerT InnerAM;
143};
144
145template <>
148 Function &F, FunctionAnalysisManager &FAM);
150 Function>;
151
156 SPMUpdater &>;
157
158/// ScopPass - This class adapts the RegionPass interface to allow convenient
159/// creation of passes that operate on the Polly IR. Instead of overriding
160/// runOnRegion, subclasses override runOnScop.
161class ScopPass : public RegionPass {
163
164protected:
165 explicit ScopPass(char &ID) : RegionPass(ID), S(nullptr) {}
166
167 /// runOnScop - This method must be overloaded to perform the
168 /// desired Polyhedral transformation or analysis.
169 ///
170 virtual bool runOnScop(Scop &S) = 0;
171
172 /// Print method for SCoPs.
173 virtual void printScop(raw_ostream &OS, Scop &S) const {}
174
175 /// getAnalysisUsage - Subclasses that override getAnalysisUsage
176 /// must call this.
177 ///
178 void getAnalysisUsage(AnalysisUsage &AU) const override;
179
180private:
181 bool runOnRegion(Region *R, RGPassManager &RGM) override;
182 void print(raw_ostream &OS, const Module *) const override;
183};
184
186 DominatorTree &DT;
188 ScalarEvolution &SE;
189 LoopInfo &LI;
190 RegionInfo &RI;
191 TargetTransformInfo &TTI;
192};
193
194class SPMUpdater final {
195public:
196 SPMUpdater(SmallPriorityWorklist<Region *, 4> &Worklist,
199
201
203 if (&S == CurrentScop)
205
206 Worklist.erase(&S.getRegion());
207 SAM.clear(S, S.getName());
208 }
209
210private:
213 SmallPriorityWorklist<Region *, 4> &Worklist;
215 template <typename ScopPassT> friend struct FunctionToScopPassAdaptor;
216};
217
218template <typename ScopPassT>
220 : PassInfoMixin<FunctionToScopPassAdaptor<ScopPassT>> {
221 explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {}
222
223 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
224 ScopDetection &SD = AM.getResult<ScopAnalysis>(F);
225 ScopInfo &SI = AM.getResult<ScopInfoAnalysis>(F);
226 if (SI.empty()) {
227 // With no scops having been detected, no IR changes have been made and
228 // therefore all analyses are preserved. However, we must still free the
229 // Scop analysis results which may hold AssertingVH that cause an error
230 // if its value is destroyed.
231 PreservedAnalyses PA = PreservedAnalyses::all();
232 PA.abandon<ScopInfoAnalysis>();
233 PA.abandon<ScopAnalysis>();
234 AM.invalidate(F, PA);
235 return PreservedAnalyses::all();
236 }
237
238 SmallPriorityWorklist<Region *, 4> Worklist;
239 for (auto &S : SI)
240 if (S.second)
241 Worklist.insert(S.first);
242
243 ScopStandardAnalysisResults AR = {AM.getResult<DominatorTreeAnalysis>(F),
244 AM.getResult<ScopInfoAnalysis>(F),
245 AM.getResult<ScalarEvolutionAnalysis>(F),
246 AM.getResult<LoopAnalysis>(F),
247 AM.getResult<RegionInfoAnalysis>(F),
248 AM.getResult<TargetIRAnalysis>(F)};
249
251 AM.getResult<ScopAnalysisManagerFunctionProxy>(F).getManager();
252
253 SPMUpdater Updater{Worklist, SAM};
254
255 while (!Worklist.empty()) {
256 Region *R = Worklist.pop_back_val();
257 if (!SD.isMaxRegionInScop(*R, /*Verify=*/false))
258 continue;
259 Scop *scop = SI.getScop(R);
260 if (!scop)
261 continue;
262 Updater.CurrentScop = scop;
263 Updater.InvalidateCurrentScop = false;
264 PreservedAnalyses PassPA = Pass.run(*scop, SAM, AR, Updater);
265
266 SAM.invalidate(*scop, PassPA);
267 if (Updater.invalidateCurrentScop())
268 SI.recompute();
269 };
270
271 // FIXME: For the same reason as we add a BarrierNoopPass in the legacy pass
272 // manager, do not preserve any analyses. While CodeGeneration may preserve
273 // IR analyses sufficiently to process another Scop in the same function (it
274 // has to, otherwise the ScopDetection result itself would need to be
275 // invalidated), it is not sufficient for other purposes. For instance,
276 // CodeGeneration does not inform LoopInfo about new loops in the
277 // Polly-generated IR.
278 return PreservedAnalyses::none();
279 }
280
281private:
282 ScopPassT Pass;
283};
284
285template <typename ScopPassT>
288 return FunctionToScopPassAdaptor<ScopPassT>(std::move(Pass));
289}
290} // namespace polly
291
292#endif
polly dump Polly Dump Function
polly scop functions based on how much of the function is a scop
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
ScopAnalysisManager * InnerAM
Definition: ScopPass.h:88
Result & operator=(Result &&RHS)
Definition: ScopPass.h:70
ScopAnalysisManager & getManager()
Definition: ScopPass.h:82
Result(ScopAnalysisManager &InnerAM, ScopInfo &SI)
Definition: ScopPass.h:65
typename InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Result Result
Definition: ScopPass.h:133
Result run(IRUnitT &IR, AnalysisManager< IRUnitT, ExtraArgTs... > &AM, ExtraArgTs...)
Definition: ScopPass.h:134
AnalysisManagerT & getManager()
Definition: ScopPass.h:139
ScopAnalysisManager & SAM
Definition: ScopPass.h:214
void invalidateScop(Scop &S)
Definition: ScopPass.h:202
bool InvalidateCurrentScop
Definition: ScopPass.h:212
bool invalidateCurrentScop() const
Definition: ScopPass.h:200
SPMUpdater(SmallPriorityWorklist< Region *, 4 > &Worklist, ScopAnalysisManager &SAM)
Definition: ScopPass.h:196
Scop * CurrentScop
Definition: ScopPass.h:211
SmallPriorityWorklist< Region *, 4 > & Worklist
Definition: ScopPass.h:213
Pass to detect the maximal static control parts (Scops) of a function.
bool isMaxRegionInScop(const Region &R, bool Verify=true)
Is the region is the maximum region of a Scop?
ScopPass - This class adapts the RegionPass interface to allow convenient creation of passes that ope...
Definition: ScopPass.h:161
ScopPass(char &ID)
Definition: ScopPass.h:165
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: ScopPass.cpp:44
void print(raw_ostream &OS, const Module *) const override
Definition: ScopPass.cpp:39
bool runOnRegion(Region *R, RGPassManager &RGM) override
Definition: ScopPass.cpp:27
virtual bool runOnScop(Scop &S)=0
runOnScop - This method must be overloaded to perform the desired Polyhedral transformation or analys...
virtual void printScop(raw_ostream &OS, Scop &S) const
Print method for SCoPs.
Definition: ScopPass.h:173
Static Control Part.
Definition: ScopInfo.h:1630
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
InnerAnalysisManagerProxy< ScopAnalysisManager, Function > ScopAnalysisManagerFunctionProxy
Definition: ScopPass.h:48
FunctionToScopPassAdaptor< ScopPassT > createFunctionToScopPassAdaptor(ScopPassT Pass)
Definition: ScopPass.h:287
PassManager< Scop, ScopAnalysisManager, ScopStandardAnalysisResults &, SPMUpdater & > ScopPassManager
Definition: ScopPass.h:156
AnalysisManager< Scop, ScopStandardAnalysisResults & > ScopAnalysisManager
Definition: ScopPass.h:46
OuterAnalysisManagerProxy< FunctionAnalysisManager, Scop, ScopStandardAnalysisResults & > FunctionAnalysisManagerScopProxy
Definition: ScopPass.h:51
PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM, ScopStandardAnalysisResults &AR, SPMUpdater &)
Definition: ScopPass.h:100
FunctionToScopPassAdaptor(ScopPassT Pass)
Definition: ScopPass.h:221
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: ScopPass.h:223
TargetTransformInfo & TTI
Definition: ScopPass.h:191