Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/include/polly/ScopPass.h
Line
Count
Source (jump to first uncovered line)
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/IR/PassManager.h"
24
25
using namespace llvm;
26
27
namespace polly {
28
class Scop;
29
class SPMUpdater;
30
struct ScopStandardAnalysisResults;
31
32
using ScopAnalysisManager =
33
    AnalysisManager<Scop, ScopStandardAnalysisResults &>;
34
using ScopAnalysisManagerFunctionProxy =
35
    InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
36
using FunctionAnalysisManagerScopProxy =
37
    OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
38
                              ScopStandardAnalysisResults &>;
39
} // namespace polly
40
41
namespace llvm {
42
using polly::Scop;
43
using polly::ScopAnalysisManager;
44
using polly::ScopAnalysisManagerFunctionProxy;
45
using polly::ScopInfo;
46
using polly::ScopStandardAnalysisResults;
47
using polly::SPMUpdater;
48
49
template <>
50
class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result {
51
public:
52
  explicit Result(ScopAnalysisManager &InnerAM, ScopInfo &SI)
53
0
      : InnerAM(&InnerAM), SI(&SI) {}
54
0
  Result(Result &&R) : InnerAM(std::move(R.InnerAM)), SI(R.SI) {
55
0
    R.InnerAM = nullptr;
56
0
  }
57
0
  Result &operator=(Result &&RHS) {
58
0
    InnerAM = RHS.InnerAM;
59
0
    SI = RHS.SI;
60
0
    RHS.InnerAM = nullptr;
61
0
    return *this;
62
0
  }
63
0
  ~Result() {
64
0
    if (!InnerAM)
65
0
      return;
66
0
    InnerAM->clear();
67
0
  }
68
69
0
  ScopAnalysisManager &getManager() { return *InnerAM; }
70
71
  bool invalidate(Function &F, const PreservedAnalyses &PA,
72
                  FunctionAnalysisManager::Invalidator &Inv);
73
74
private:
75
  ScopAnalysisManager *InnerAM;
76
  ScopInfo *SI;
77
};
78
79
// A partial specialization of the require analysis template pass to handle
80
// extra parameters
81
template <typename AnalysisT>
82
struct RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
83
                           ScopStandardAnalysisResults &, SPMUpdater &>
84
    : PassInfoMixin<
85
          RequireAnalysisPass<AnalysisT, Scop, ScopAnalysisManager,
86
                              ScopStandardAnalysisResults &, SPMUpdater &>> {
87
  PreservedAnalyses run(Scop &L, ScopAnalysisManager &AM,
88
0
                        ScopStandardAnalysisResults &AR, SPMUpdater &) {
89
0
    (void)AM.template getResult<AnalysisT>(L, AR);
90
0
    return PreservedAnalyses::all();
91
0
  }
Unexecuted instantiation: llvm::RequireAnalysisPass<polly::IslAstAnalysis, polly::Scop, llvm::AnalysisManager<polly::Scop, polly::ScopStandardAnalysisResults&>, polly::ScopStandardAnalysisResults&, polly::SPMUpdater&>::run(polly::Scop&, llvm::AnalysisManager<polly::Scop, polly::ScopStandardAnalysisResults&>&, polly::ScopStandardAnalysisResults&, polly::SPMUpdater&)
Unexecuted instantiation: llvm::RequireAnalysisPass<polly::DependenceAnalysis, polly::Scop, llvm::AnalysisManager<polly::Scop, polly::ScopStandardAnalysisResults&>, polly::ScopStandardAnalysisResults&, polly::SPMUpdater&>::run(polly::Scop&, llvm::AnalysisManager<polly::Scop, polly::ScopStandardAnalysisResults&>&, polly::ScopStandardAnalysisResults&, polly::SPMUpdater&)
92
};
93
94
template <>
95
InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
96
InnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
97
    Function &F, FunctionAnalysisManager &FAM);
98
99
template <>
100
PreservedAnalyses
101
PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
102
            SPMUpdater &>::run(Scop &InitialS, ScopAnalysisManager &AM,
103
                               ScopStandardAnalysisResults &, SPMUpdater &);
104
extern template class PassManager<Scop, ScopAnalysisManager,
105
                                  ScopStandardAnalysisResults &, SPMUpdater &>;
106
extern template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
107
extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
108
                                                ScopStandardAnalysisResults &>;
109
} // namespace llvm
110
111
namespace polly {
112
113
template <typename AnalysisManagerT, typename IRUnitT, typename... ExtraArgTs>
114
class OwningInnerAnalysisManagerProxy
115
    : public InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT> {
116
public:
117
  OwningInnerAnalysisManagerProxy()
118
1.24k
      : InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>(InnerAM) {}
119
  using Result = typename InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT,
120
                                                    ExtraArgTs...>::Result;
121
  Result run(IRUnitT &IR, AnalysisManager<IRUnitT, ExtraArgTs...> &AM,
122
             ExtraArgTs...) {
123
    return Result(InnerAM);
124
  }
125
126
3.74k
  AnalysisManagerT &getManager() { return InnerAM; }
127
128
private:
129
  AnalysisManagerT InnerAM;
130
};
131
132
template <>
133
OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::Result
134
OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>::run(
135
    Function &F, FunctionAnalysisManager &FAM);
136
extern template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager,
137
                                                      Function>;
138
139
using OwningScopAnalysisManagerFunctionProxy =
140
    OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
141
using ScopPassManager =
142
    PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
143
                SPMUpdater &>;
144
145
/// ScopPass - This class adapts the RegionPass interface to allow convenient
146
/// creation of passes that operate on the Polly IR. Instead of overriding
147
/// runOnRegion, subclasses override runOnScop.
148
class ScopPass : public RegionPass {
149
  Scop *S;
150
151
protected:
152
1.73k
  explicit ScopPass(char &ID) : RegionPass(ID), S(0) {}
153
154
  /// runOnScop - This method must be overloaded to perform the
155
  /// desired Polyhedral transformation or analysis.
156
  ///
157
  virtual bool runOnScop(Scop &S) = 0;
158
159
  /// Print method for SCoPs.
160
27
  virtual void printScop(raw_ostream &OS, Scop &S) const {}
161
162
  /// getAnalysisUsage - Subclasses that override getAnalysisUsage
163
  /// must call this.
164
  ///
165
  virtual void getAnalysisUsage(AnalysisUsage &AU) const override;
166
167
private:
168
  bool runOnRegion(Region *R, RGPassManager &RGM) override;
169
  void print(raw_ostream &OS, const Module *) const override;
170
};
171
172
struct ScopStandardAnalysisResults {
173
  DominatorTree &DT;
174
  ScopInfo &SI;
175
  ScalarEvolution &SE;
176
  LoopInfo &LI;
177
  RegionInfo &RI;
178
};
179
180
class SPMUpdater {
181
public:
182
  SPMUpdater(SmallPriorityWorklist<Region *, 4> &Worklist,
183
             ScopAnalysisManager &SAM)
184
0
      : InvalidateCurrentScop(false), Worklist(Worklist), SAM(SAM) {}
185
186
0
  bool invalidateCurrentScop() const { return InvalidateCurrentScop; }
187
188
0
  void invalidateScop(Scop &S) {
189
0
    if (&S == CurrentScop)
190
0
      InvalidateCurrentScop = true;
191
0
192
0
    Worklist.erase(&S.getRegion());
193
0
    SAM.clear(S, S.getName());
194
0
  }
195
196
private:
197
  Scop *CurrentScop;
198
  bool InvalidateCurrentScop;
199
  SmallPriorityWorklist<Region *, 4> &Worklist;
200
  ScopAnalysisManager &SAM;
201
  template <typename ScopPassT> friend class FunctionToScopPassAdaptor;
202
};
203
204
template <typename ScopPassT>
205
class FunctionToScopPassAdaptor
206
    : public PassInfoMixin<FunctionToScopPassAdaptor<ScopPassT>> {
207
public:
208
2
  explicit FunctionToScopPassAdaptor(ScopPassT Pass) : Pass(std::move(Pass)) {}
209
210
1
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
211
1
    PreservedAnalyses PA = PreservedAnalyses::all();
212
1
    auto &SD = AM.getResult<ScopAnalysis>(F);
213
1
    auto &SI = AM.getResult<ScopInfoAnalysis>(F);
214
1
    if (SI.empty())
215
1
      return PA;
216
0
217
0
    SmallPriorityWorklist<Region *, 4> Worklist;
218
0
    for (auto &S : SI)
219
0
      if (S.second)
220
0
        Worklist.insert(S.first);
221
0
222
0
    ScopStandardAnalysisResults AR = {AM.getResult<DominatorTreeAnalysis>(F),
223
0
                                      AM.getResult<ScopInfoAnalysis>(F),
224
0
                                      AM.getResult<ScalarEvolutionAnalysis>(F),
225
0
                                      AM.getResult<LoopAnalysis>(F),
226
0
                                      AM.getResult<RegionInfoAnalysis>(F)};
227
0
228
0
    ScopAnalysisManager &SAM =
229
0
        AM.getResult<ScopAnalysisManagerFunctionProxy>(F).getManager();
230
0
231
0
    SPMUpdater Updater{Worklist, SAM};
232
0
233
0
    while (!Worklist.empty()) {
234
0
      Region *R = Worklist.pop_back_val();
235
0
      if (!SD.isMaxRegionInScop(*R))
236
0
        continue;
237
0
      Scop *scop = SI.getScop(R);
238
0
      if (!scop)
239
0
        continue;
240
0
      Updater.CurrentScop = scop;
241
0
      Updater.InvalidateCurrentScop = false;
242
0
      PreservedAnalyses PassPA = Pass.run(*scop, SAM, AR, Updater);
243
0
244
0
      SAM.invalidate(*scop, PassPA);
245
0
      PA.intersect(std::move(PassPA));
246
0
      if (Updater.invalidateCurrentScop())
247
0
        SI.recompute();
248
0
    };
249
0
250
0
    PA.preserveSet<AllAnalysesOn<Scop>>();
251
0
    PA.preserve<ScopAnalysisManagerFunctionProxy>();
252
0
    PA.preserve<DominatorTreeAnalysis>();
253
0
    PA.preserve<ScopAnalysis>();
254
0
    PA.preserve<ScopInfoAnalysis>();
255
0
    PA.preserve<ScalarEvolutionAnalysis>();
256
0
    PA.preserve<LoopAnalysis>();
257
0
    PA.preserve<RegionInfoAnalysis>();
258
0
    return PA;
259
0
  }
260
261
private:
262
  ScopPassT Pass;
263
};
264
265
template <typename ScopPassT>
266
FunctionToScopPassAdaptor<ScopPassT>
267
2
createFunctionToScopPassAdaptor(ScopPassT Pass) {
268
2
  return FunctionToScopPassAdaptor<ScopPassT>(std::move(Pass));
269
2
}
270
} // namespace polly
271
272
#endif