1 //===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the definitions of the ScopPass members.
11 //===----------------------------------------------------------------------===//
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"
25 using namespace polly
;
27 bool ScopPass::runOnRegion(Region
*R
, RGPassManager
&RGM
) {
33 if ((S
= getAnalysis
<ScopInfoRegionPass
>().getScop()))
39 void ScopPass::print(raw_ostream
&OS
, const Module
*M
) const {
44 void ScopPass::getAnalysisUsage(AnalysisUsage
&AU
) const {
45 AU
.addRequired
<ScopInfoRegionPass
>();
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
>();
64 template class OwningInnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
69 template class PassManager
<Scop
, ScopAnalysisManager
,
70 ScopStandardAnalysisResults
&, SPMUpdater
&>;
71 template class InnerAnalysisManagerProxy
<ScopAnalysisManager
, Function
>;
72 template class OuterAnalysisManagerProxy
<FunctionAnalysisManager
, Scop
,
73 ScopStandardAnalysisResults
&>;
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(S
, AM
, AR
, U
);
84 AM
.invalidate(S
, PassPA
);
85 PA
.intersect(std::move(PassPA
));
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
>>();
95 bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
96 Function
&F
, const PreservedAnalyses
&PA
,
97 FunctionAnalysisManager::Invalidator
&Inv
) {
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
>(F
, PA
) ||
103 Inv
.invalidate
<ScalarEvolutionAnalysis
>(F
, PA
) ||
104 Inv
.invalidate
<LoopAnalysis
>(F
, PA
) ||
105 Inv
.invalidate
<DominatorTreeAnalysis
>(F
, PA
)) {
107 // As everything depends on ScopInfo, we must drop all existing results
109 if (auto *scop
= S
.second
.get())
111 InnerAM
->clear(*scop
, scop
->getName());
114 return true; // Invalidate the proxy result as well.
117 bool allPreserved
= PA
.allAnalysesInSetPreserved
<AllAnalysesOn
<Scop
>>();
119 // Invalidate all non-preserved analyses
120 // Even if all analyses were preserved, we still need to run deferred
122 for (auto &S
: *SI
) {
123 std::optional
<PreservedAnalyses
> InnerPA
;
124 auto *scop
= S
.second
.get();
128 if (auto *OuterProxy
=
129 InnerAM
->getCachedResult
<FunctionAnalysisManagerScopProxy
>(*scop
)) {
130 for (const auto &InvPair
: OuterProxy
->getOuterInvalidations()) {
131 auto *OuterAnalysisID
= InvPair
.first
;
132 const auto &InnerAnalysisIDs
= InvPair
.second
;
134 if (Inv
.invalidate(OuterAnalysisID
, F
, PA
)) {
137 for (auto *InnerAnalysisID
: InnerAnalysisIDs
)
138 InnerPA
->abandon(InnerAnalysisID
);
143 InnerAM
->invalidate(*scop
, *InnerPA
);
149 InnerAM
->invalidate(*scop
, PA
);
152 return false; // This proxy is still valid
156 ScopAnalysisManagerFunctionProxy::Result
157 ScopAnalysisManagerFunctionProxy::run(Function
&F
,
158 FunctionAnalysisManager
&FAM
) {
159 return Result(*InnerAM
, FAM
.getResult
<ScopInfoAnalysis
>(F
));
165 OwningScopAnalysisManagerFunctionProxy::Result
166 OwningScopAnalysisManagerFunctionProxy::run(Function
&F
,
167 FunctionAnalysisManager
&FAM
) {
168 return Result(InnerAM
, FAM
.getResult
<ScopInfoAnalysis
>(F
));