LLVM: include/llvm/Transforms/Scalar/LoopPassManager.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#ifndef LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
37#define LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
38
48#include
49
50namespace llvm {
51
52
53class LPMUpdater;
54class PassInstrumentation;
55
56namespace {
57
58template
59using HasRunOnLoopT = decltype(std::declval().run(
60 std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
61 std::declval<LoopStandardAnalysisResults &>(),
62 std::declval<LPMUpdater &>()));
63
64}
65
66
67
68
69template <>
75public:
77
78
79
80
81
83 : IsLoopNestPass(std::move(Arg.IsLoopNestPass)),
84 LoopPasses(std::move(Arg.LoopPasses)),
85 LoopNestPasses(std::move(Arg.LoopNestPasses)) {}
86
88 IsLoopNestPass = std::move(RHS.IsLoopNestPass);
89 LoopPasses = std::move(RHS.LoopPasses);
90 LoopNestPasses = std::move(RHS.LoopNestPasses);
91 return *this;
92 }
93
96
99
100
101
102
103
104
105 template
107 std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
109 using LoopPassModelT =
112 IsLoopNestPass.push_back(false);
113
114
115 LoopPasses.push_back(std::unique_ptr(
116 new LoopPassModelT(std::forward(Pass))));
117 }
118
119 template
121 std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
123 using LoopNestPassModelT =
126 IsLoopNestPass.push_back(true);
127
128
129 LoopNestPasses.push_back(std::unique_ptr(
130 new LoopNestPassModelT(std::forward(Pass))));
131 }
132
133 bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
134
136
139
140protected:
147
148
149
151 std::vector<std::unique_ptr> LoopPasses;
152 std::vector<std::unique_ptr> LoopNestPasses;
153
154
155
156
157 template <typename IRUnitT, typename PassT>
158 std::optional
162
169
170private:
171 static const Loop &getLoopFromIR(Loop &L) { return L; }
172 static const Loop &getLoopFromIR(LoopNest &LN) {
174 }
175};
176
177
178
179
180
181
182typedef PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
183 LPMUpdater &>
185
186
187
188
189template
197 (void)AM.template getResult(L, AR);
199 }
202 auto ClassName = AnalysisT::name();
203 auto PassName = MapClassName2PassName(ClassName);
205 }
206};
207
208
209template
213
215
216
217
218
219
220
221
222
223
224
225
226
227
228
230public:
231
232
233
234
235
236
238
239
240
241
242
243
244
245
246
247
248
252 "Cannot delete a loop outside of the "
253 "subloop tree currently being processed.");
254 if (&L == CurrentL)
255 SkipCurrentLoop = true;
256 }
257
259#if LLVM_ENABLE_ABI_BREAKING_CHECKS
260 ParentL = L;
261#endif
262 }
263
264
265
266
267
268
269
271 assert(!LoopNestMode &&
272 "Child loops should not be pushed in loop-nest mode.");
273
274
275 Worklist.insert(CurrentL);
276
277#ifndef NDEBUG
278 for (Loop *NewL : NewChildLoops)
279 assert(NewL->getParentLoop() == CurrentL && "All of the new loops must "
280 "be immediate children of "
281 "the current loop!");
282#endif
283
285
286
287
288 SkipCurrentLoop = true;
289 }
290
291
292
293
294
295
296
298#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
299 for (Loop *NewL : NewSibLoops)
300 assert(NewL->getParentLoop() == ParentL &&
301 "All of the new loops must be siblings of the current loop!");
302#endif
303
304 if (LoopNestMode)
305 Worklist.insert(NewSibLoops);
306 else
308
309
310
311 }
312
313
314
315
316
317
319
320 SkipCurrentLoop = true;
321
322
323 Worklist.insert(CurrentL);
324 }
325
327 return LoopNestChanged;
328 }
329
330
331
333 LoopNestChanged = Changed;
334 }
335
336private:
338
339
341
342
344
345 Loop *CurrentL;
346 bool SkipCurrentLoop;
347 const bool LoopNestMode;
348 bool LoopNestChanged;
349
350#if LLVM_ENABLE_ABI_BREAKING_CHECKS
351
352
353 Loop *ParentL;
354#endif
355
358 bool LoopNestChanged = false)
359 : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode),
360 LoopNestChanged(LoopNestChanged) {}
361};
362
363template <typename IRUnitT, typename PassT>
367
368
369 const Loop &L = getLoopFromIR(IR);
370
371
372 if (!PI.runBeforePass<Loop>(*Pass, L))
373 return std::nullopt;
374
376
377
378 if (U.skipCurrentLoop())
379 PI.runAfterPassInvalidated(*Pass, PA);
380 else
381 PI.runAfterPass<Loop>(*Pass, L, PA);
382 return PA;
383}
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
402 : public PassInfoMixin {
403public:
407
409 bool UseMemorySSA = false,
410 bool UseBlockFrequencyInfo = false,
411 bool UseBranchProbabilityInfo = false,
412 bool LoopNestMode = false)
414 UseBlockFrequencyInfo(UseBlockFrequencyInfo),
415 UseBranchProbabilityInfo(UseBranchProbabilityInfo),
416 LoopNestMode(LoopNestMode) {
419 }
420
421
425
427
429
430private:
431 std::unique_ptr Pass;
432
434
435 bool UseMemorySSA = false;
436 bool UseBlockFrequencyInfo = false;
437 bool UseBranchProbabilityInfo = false;
438 const bool LoopNestMode;
439};
440
441
442
443
444
445template
446inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value,
447 FunctionToLoopPassAdaptor>
449 bool UseBlockFrequencyInfo = false,
450 bool UseBranchProbabilityInfo = false) {
451 using PassModelT =
454
455
457 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
458 new PassModelT(std::forward(Pass))),
459 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, false);
460}
461
462
463
464template
465inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value,
466 FunctionToLoopPassAdaptor>
468 bool UseBlockFrequencyInfo = false,
469 bool UseBranchProbabilityInfo = false) {
471 LPM.addPass(std::forward(Pass));
472 using PassModelT =
475
476
478 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
479 new PassModelT(std::move(LPM))),
480 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, true);
481}
482
483
484
485template <>
488 LoopPassManager &&LPM, bool UseMemorySSA, bool UseBlockFrequencyInfo,
489 bool UseBranchProbabilityInfo) {
490
491
492 using PassModelT =
495 bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
496
497
499 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
500 new PassModelT(std::move(LPM))),
501 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo,
502 LoopNestMode);
503}
504
505
508 std::string Banner;
509
510public:
513
516};
517}
518
519#endif
aarch64 AArch64 CCMP Pass
#define LLVM_ATTRIBUTE_MINSIZE
This header defines various interfaces for pass management in LLVM.
Legalize the Machine IR a function s Machine IR
This header provides classes for managing per-loop analyses.
This file defines the interface for the loop nest analysis.
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
This file provides a priority worklist.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char PassName[]
A container for analyses that lazily runs them and caches their results.
void clear(IRUnitT &IR, llvm::StringRef Name)
Clear any cached analysis results for a single unit of IR.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
bool isLoopNestMode() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Runs the loop passes across every loop in the function.
FunctionToLoopPassAdaptor(std::unique_ptr< PassConceptT > Pass, bool UseMemorySSA=false, bool UseBlockFrequencyInfo=false, bool UseBranchProbabilityInfo=false, bool LoopNestMode=false)
Converts loops into loop-closed SSA form.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
void markLoopNestChanged(bool Changed)
Loopnest passes should use this method to indicate if the loopnest has been modified.
void setParentLoop(Loop *L)
bool isLoopNestChanged() const
void revisitCurrentLoop()
Restart the current loop.
bool skipCurrentLoop() const
This can be queried by loop passes which run other loop passes (like pass managers) to know whether t...
void addChildLoops(ArrayRef< Loop * > NewChildLoops)
Loop passes should use this method to indicate they have added new child loops of the current loop.
void markLoopAsDeleted(Loop &L, llvm::StringRef Name)
Loop passes should use this method to indicate they have deleted a loop from the nest.
void addSiblingLoops(ArrayRef< Loop * > NewSibLoops)
Loop passes should use this method to indicate they have added new sibling loops to the current loop.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
This class represents a loop nest and can be used to query its properties.
Loop & getOutermostLoop() const
Return the outermost loop in the loop nest.
This pass is responsible for loop canonicalization.
Represents a single loop in the control flow graph.
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
size_t getNumLoopPasses() const
PassManager(PassManager &&Arg)
size_t getNumLoopNestPasses() const
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
std::vector< std::unique_ptr< LoopNestPassConceptT > > LoopNestPasses
std::optional< PreservedAnalyses > runSinglePass(IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U, PassInstrumentation &PI)
Run either a loop pass or a loop-nest pass.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
std::vector< std::unique_ptr< LoopPassConceptT > > LoopPasses
PassManager & operator=(PassManager &&RHS)
Manages a sequence of passes over a particular unit of IR.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Pass interface - Implemented by all 'passes'.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Pass for printing a loop's contents as textual IR.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &, LoopStandardAnalysisResults &, LPMUpdater &)
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
StringRef - Represent a constant reference to a string, i.e.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor< LoopPassManager >(LoopPassManager &&LPM, bool UseMemorySSA, bool UseBlockFrequencyInfo, bool UseBranchProbabilityInfo)
If Pass is an instance of LoopPassManager, the returned adaptor will be in loop-nest mode if the pass...
void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
std::enable_if_t< is_detected< HasRunOnLoopT, LoopPassT >::value, FunctionToLoopPassAdaptor > createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false, bool UseBlockFrequencyInfo=false, bool UseBranchProbabilityInfo=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
Implement std::hash so that hash_code can be used in STL containers.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
A CRTP mix-in to automatically provide informational APIs needed for passes.
A partial specialization of the require analysis template pass to forward the extra parameters from a...
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
A utility pass template to force an analysis result to be available.
Template for the abstract base class used to dispatch polymorphically over pass objects.
A template wrapper used to implement the polymorphic API.