1 //===--------- ScopPass.h - Pass for Static Control Parts --------*-C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ScopPass class. ScopPasses are just RegionPasses,
11 // except they operate on Polly IR (Scop and ScopStmt) built by ScopInfo Pass.
12 // Because they operate on Polly IR, not the LLVM IR, ScopPasses are not allowed
13 // to modify the LLVM IR. Due to this limitation, the ScopPass class takes
14 // care of declaring that no LLVM passes are invalidated.
16 //===----------------------------------------------------------------------===//
18 #ifndef POLLY_SCOP_PASS_H
19 #define POLLY_SCOP_PASS_H
21 #include "polly/ScopInfo.h"
22 #include "llvm/ADT/PriorityWorklist.h"
23 #include "llvm/Analysis/RegionPass.h"
24 #include "llvm/IR/PassManager.h"
31 struct ScopStandardAnalysisResults
;
33 using ScopAnalysisManager
=
34 AnalysisManager
<Scop
, ScopStandardAnalysisResults
&>;
35 using ScopAnalysisManagerFunctionProxy
=
36 InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
37 using FunctionAnalysisManagerScopProxy
=
38 OuterAnalysisManagerProxy
<FunctionAnalysisManager
, Scop
,
39 ScopStandardAnalysisResults
&>;
43 using polly::SPMUpdater
;
45 using polly::ScopAnalysisManager
;
46 using polly::ScopAnalysisManagerFunctionProxy
;
47 using polly::ScopInfo
;
48 using polly::ScopStandardAnalysisResults
;
51 class InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::Result
{
53 explicit Result(ScopAnalysisManager
&InnerAM
, ScopInfo
&SI
)
54 : InnerAM(&InnerAM
), SI(&SI
) {}
55 Result(Result
&&R
) : InnerAM(std::move(R
.InnerAM
)), SI(R
.SI
) {
58 Result
&operator=(Result
&&RHS
) {
59 InnerAM
= RHS
.InnerAM
;
61 RHS
.InnerAM
= nullptr;
70 ScopAnalysisManager
&getManager() { return *InnerAM
; }
72 bool invalidate(Function
&F
, const PreservedAnalyses
&PA
,
73 FunctionAnalysisManager::Invalidator
&Inv
);
76 ScopAnalysisManager
*InnerAM
;
80 // A partial specialization of the require analysis template pass to handle
82 template <typename AnalysisT
>
83 struct RequireAnalysisPass
<AnalysisT
, Scop
, ScopAnalysisManager
,
84 ScopStandardAnalysisResults
&, SPMUpdater
&>
86 RequireAnalysisPass
<AnalysisT
, Scop
, ScopAnalysisManager
,
87 ScopStandardAnalysisResults
&, SPMUpdater
&>> {
88 PreservedAnalyses
run(Scop
&L
, ScopAnalysisManager
&AM
,
89 ScopStandardAnalysisResults
&AR
, SPMUpdater
&) {
90 (void)AM
.template getResult
<AnalysisT
>(L
, AR
);
91 return PreservedAnalyses::all();
96 InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::Result
97 InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::run(
98 Function
&F
, FunctionAnalysisManager
&FAM
);
102 PassManager
<Scop
, ScopAnalysisManager
, ScopStandardAnalysisResults
&,
103 SPMUpdater
&>::run(Scop
&InitialS
, ScopAnalysisManager
&AM
,
104 ScopStandardAnalysisResults
&, SPMUpdater
&);
105 extern template class PassManager
<Scop
, ScopAnalysisManager
,
106 ScopStandardAnalysisResults
&, SPMUpdater
&>;
107 extern template class InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
108 extern template class OuterAnalysisManagerProxy
<FunctionAnalysisManager
, Scop
,
109 ScopStandardAnalysisResults
&>;
114 template <typename AnalysisManagerT
, typename IRUnitT
, typename
... ExtraArgTs
>
115 class OwningInnerAnalysisManagerProxy
116 : public InnerAnalysisManagerProxy
<AnalysisManagerT
, IRUnitT
> {
118 OwningInnerAnalysisManagerProxy()
119 : InnerAnalysisManagerProxy
<AnalysisManagerT
, IRUnitT
>(InnerAM
) {}
120 using Result
= typename InnerAnalysisManagerProxy
<AnalysisManagerT
, IRUnitT
,
121 ExtraArgTs
...>::Result
;
122 Result
run(IRUnitT
&IR
, AnalysisManager
<IRUnitT
, ExtraArgTs
...> &AM
,
124 return Result(InnerAM
);
127 AnalysisManagerT
&getManager() { return InnerAM
; }
130 AnalysisManagerT InnerAM
;
134 OwningInnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::Result
135 OwningInnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::run(
136 Function
&F
, FunctionAnalysisManager
&FAM
);
137 extern template class OwningInnerAnalysisManagerProxy
<ScopAnalysisManager
,
140 using OwningScopAnalysisManagerFunctionProxy
=
141 OwningInnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
142 using ScopPassManager
=
143 PassManager
<Scop
, ScopAnalysisManager
, ScopStandardAnalysisResults
&,
146 /// ScopPass - This class adapts the RegionPass interface to allow convenient
147 /// creation of passes that operate on the Polly IR. Instead of overriding
148 /// runOnRegion, subclasses override runOnScop.
149 class ScopPass
: public RegionPass
{
153 explicit ScopPass(char &ID
) : RegionPass(ID
), S(0) {}
155 /// runOnScop - This method must be overloaded to perform the
156 /// desired Polyhedral transformation or analysis.
158 virtual bool runOnScop(Scop
&S
) = 0;
160 /// Print method for SCoPs.
161 virtual void printScop(raw_ostream
&OS
, Scop
&S
) const {}
163 /// getAnalysisUsage - Subclasses that override getAnalysisUsage
166 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
169 bool runOnRegion(Region
*R
, RGPassManager
&RGM
) override
;
170 void print(raw_ostream
&OS
, const Module
*) const override
;
173 struct ScopStandardAnalysisResults
{
183 SPMUpdater(SmallPriorityWorklist
<Scop
*, 4> &Worklist
,
184 ScopAnalysisManager
&SAM
)
185 : Worklist(Worklist
), SAM(SAM
) {}
187 void SkipScop(Scop
&S
) {
188 if (Worklist
.erase(&S
))
193 SmallPriorityWorklist
<Scop
*, 4> &Worklist
;
194 ScopAnalysisManager
&SAM
;
197 template <typename ScopPassT
>
198 class FunctionToScopPassAdaptor
199 : public PassInfoMixin
<FunctionToScopPassAdaptor
<ScopPassT
>> {
201 explicit FunctionToScopPassAdaptor(ScopPassT Pass
) : Pass(std::move(Pass
)) {}
203 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&AM
) {
204 PreservedAnalyses PA
= PreservedAnalyses::all();
205 auto &Scops
= AM
.getResult
<ScopInfoAnalysis
>(F
);
209 ScopStandardAnalysisResults AR
= {AM
.getResult
<DominatorTreeAnalysis
>(F
),
210 AM
.getResult
<ScopInfoAnalysis
>(F
),
211 AM
.getResult
<ScalarEvolutionAnalysis
>(F
),
212 AM
.getResult
<LoopAnalysis
>(F
),
213 AM
.getResult
<RegionInfoAnalysis
>(F
)};
215 ScopAnalysisManager
&SAM
=
216 AM
.getResult
<ScopAnalysisManagerFunctionProxy
>(F
).getManager();
218 SmallPriorityWorklist
<Scop
*, 4> Worklist
;
219 SPMUpdater Updater
{Worklist
, SAM
};
221 for (auto &S
: Scops
)
222 if (auto *scop
= S
.second
.get())
223 Worklist
.insert(scop
);
225 while (!Worklist
.empty()) {
226 Scop
*scop
= Worklist
.pop_back_val();
227 PreservedAnalyses PassPA
= Pass
.run(*scop
, SAM
, AR
, Updater
);
229 SAM
.invalidate(*scop
, PassPA
);
230 PA
.intersect(std::move(PassPA
));
233 PA
.preserveSet
<AllAnalysesOn
<Scop
>>();
234 PA
.preserve
<ScopAnalysisManagerFunctionProxy
>();
235 PA
.preserve
<DominatorTreeAnalysis
>();
236 PA
.preserve
<ScopAnalysis
>();
237 PA
.preserve
<ScopInfoAnalysis
>();
238 PA
.preserve
<ScalarEvolutionAnalysis
>();
239 PA
.preserve
<LoopAnalysis
>();
240 PA
.preserve
<RegionInfoAnalysis
>();
246 }; // namespace polly
248 template <typename ScopPassT
>
249 FunctionToScopPassAdaptor
<ScopPassT
>
250 createFunctionToScopPassAdaptor(ScopPassT Pass
) {
251 return FunctionToScopPassAdaptor
<ScopPassT
>(std::move(Pass
));