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
;
81 InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::Result
82 InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>::run(
83 Function
&F
, FunctionAnalysisManager
&FAM
);
87 PassManager
<Scop
, ScopAnalysisManager
, ScopStandardAnalysisResults
&,
88 SPMUpdater
&>::run(Scop
&InitialS
, ScopAnalysisManager
&AM
,
89 ScopStandardAnalysisResults
&, SPMUpdater
&);
90 extern template class PassManager
<Scop
, ScopAnalysisManager
,
91 ScopStandardAnalysisResults
&, SPMUpdater
&>;
92 extern template class InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
93 extern template class OuterAnalysisManagerProxy
<FunctionAnalysisManager
, Scop
,
94 ScopStandardAnalysisResults
&>;
98 using ScopPassManager
=
99 PassManager
<Scop
, ScopAnalysisManager
, ScopStandardAnalysisResults
&,
102 /// ScopPass - This class adapts the RegionPass interface to allow convenient
103 /// creation of passes that operate on the Polly IR. Instead of overriding
104 /// runOnRegion, subclasses override runOnScop.
105 class ScopPass
: public RegionPass
{
109 explicit ScopPass(char &ID
) : RegionPass(ID
), S(0) {}
111 /// runOnScop - This method must be overloaded to perform the
112 /// desired Polyhedral transformation or analysis.
114 virtual bool runOnScop(Scop
&S
) = 0;
116 /// Print method for SCoPs.
117 virtual void printScop(raw_ostream
&OS
, Scop
&S
) const {}
119 /// getAnalysisUsage - Subclasses that override getAnalysisUsage
122 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
125 bool runOnRegion(Region
*R
, RGPassManager
&RGM
) override
;
126 void print(raw_ostream
&OS
, const Module
*) const override
;
129 struct ScopStandardAnalysisResults
{
138 SPMUpdater(SmallPriorityWorklist
<Scop
*, 4> &Worklist
,
139 ScopAnalysisManager
&SAM
)
140 : Worklist(Worklist
), SAM(SAM
) {}
142 void SkipScop(Scop
&S
) {
143 if (Worklist
.erase(&S
))
148 SmallPriorityWorklist
<Scop
*, 4> &Worklist
;
149 ScopAnalysisManager
&SAM
;
152 template <typename ScopPassT
>
153 class FunctionToScopPassAdaptor
154 : public PassInfoMixin
<FunctionToScopPassAdaptor
<ScopPassT
>> {
156 explicit FunctionToScopPassAdaptor(ScopPassT Pass
) : Pass(std::move(Pass
)) {}
158 PreservedAnalyses
run(Function
&F
, FunctionAnalysisManager
&AM
) {
159 PreservedAnalyses PA
= PreservedAnalyses::all();
160 auto &Scops
= AM
.getResult
<ScopInfoAnalysis
>(F
);
164 ScopAnalysisManager
&SAM
=
165 AM
.getResult
<ScopAnalysisManagerFunctionProxy
>(F
).getManager();
167 ScopStandardAnalysisResults AR
= {AM
.getResult
<DominatorTreeAnalysis
>(F
),
168 AM
.getResult
<ScalarEvolutionAnalysis
>(F
),
169 AM
.getResult
<LoopAnalysis
>(F
),
170 AM
.getResult
<RegionInfoAnalysis
>(F
)};
172 SmallPriorityWorklist
<Scop
*, 4> Worklist
;
173 SPMUpdater Updater
{Worklist
, SAM
};
175 for (auto &S
: Scops
)
176 if (auto *scop
= S
.second
.get())
177 Worklist
.insert(scop
);
179 while (!Worklist
.empty()) {
180 Scop
*scop
= Worklist
.pop_back_val();
181 PreservedAnalyses PassPA
= Pass
.run(*scop
, SAM
, AR
, Updater
);
183 SAM
.invalidate(*scop
, PassPA
);
184 PA
.intersect(std::move(PassPA
));
187 PA
.preserveSet
<AllAnalysesOn
<Scop
>>();
188 PA
.preserve
<ScopAnalysisManagerFunctionProxy
>();
194 }; // namespace polly
196 template <typename ScopPassT
>
197 FunctionToScopPassAdaptor
<ScopPassT
>
198 createFunctionToScopPassAdaptor(ScopPassT Pass
) {
199 return FunctionToScopPassAdaptor
<ScopPassT
>(std::move(Pass
));