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
49#include
50
51namespace llvm {
52
53
56
57namespace {
58
59template
60using HasRunOnLoopT = decltype(std::declval().run(
61 std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
62 std::declval<LoopStandardAnalysisResults &>(),
63 std::declval<LPMUpdater &>()));
64
65}
66
67
68
69
70template <>
76public:
78
79
80
81
82
84 : IsLoopNestPass(std::move(Arg.IsLoopNestPass)),
85 LoopPasses(std::move(Arg.LoopPasses)),
86 LoopNestPasses(std::move(Arg.LoopNestPasses)) {}
87
89 IsLoopNestPass = std::move(RHS.IsLoopNestPass);
90 LoopPasses = std::move(RHS.LoopPasses);
91 LoopNestPasses = std::move(RHS.LoopNestPasses);
92 return *this;
93 }
94
98
102
103
104
105
106
107
110 using LoopPassModelT =
113 IsLoopNestPass.push_back(false);
114
115
116 LoopPasses.push_back(std::unique_ptr(
117 new LoopPassModelT(std::forward(Pass))));
118 } else {
119 using LoopNestPassModelT =
122 IsLoopNestPass.push_back(true);
123
124
125 LoopNestPasses.push_back(std::unique_ptr(
126 new LoopNestPassModelT(std::forward(Pass))));
127 }
128 }
129
130 bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
131
132 static bool isRequired() { return true; }
133
134 size_t getNumLoopPasses() const { return LoopPasses.size(); }
135 size_t getNumLoopNestPasses() const { return LoopNestPasses.size(); }
136
137protected:
138 using LoopPassConceptT =
141 using LoopNestPassConceptT =
144
145
146
148 std::vector<std::unique_ptr> LoopPasses;
149 std::vector<std::unique_ptr> LoopNestPasses;
150
151
152
153
154 template <typename IRUnitT, typename PassT>
155 std::optional
159
166
167private:
168 static const Loop &getLoopFromIR(Loop &L) { return L; }
169 static const Loop &getLoopFromIR(LoopNest &LN) {
171 }
172};
173
174
175
176
177
178
182
183
184
185
186template
194 (void)AM.template getResult(L, AR);
196 }
199 auto ClassName = AnalysisT::name();
200 auto PassName = MapClassName2PassName(ClassName);
201 OS << "require<" << PassName << '>';
202 }
203};
204
205
206template
210
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226class LPMUpdater {
227public:
228
229
230
231
232
233
235
236
237
238
239
240
241
242
243
244
245
247 LAM.clear(L, Name);
248 assert((&L == CurrentL || CurrentL->contains(&L)) &&
249 "Cannot delete a loop outside of the "
250 "subloop tree currently being processed.");
251 if (&L == CurrentL)
252 SkipCurrentLoop = true;
253 }
254
256#if LLVM_ENABLE_ABI_BREAKING_CHECKS
257 ParentL = L;
258#endif
259 }
260
261
262
263
264
265
266
268 assert(!LoopNestMode &&
269 "Child loops should not be pushed in loop-nest mode.");
270
271
272 Worklist.insert(CurrentL);
273
274#ifndef NDEBUG
275 for (Loop *NewL : NewChildLoops)
276 assert(NewL->getParentLoop() == CurrentL && "All of the new loops must "
277 "be immediate children of "
278 "the current loop!");
279#endif
280
282
283
284
285 SkipCurrentLoop = true;
286 }
287
288
289
290
291
292
293
295#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
296 for (Loop *NewL : NewSibLoops)
297 assert(NewL->getParentLoop() == ParentL &&
298 "All of the new loops must be siblings of the current loop!");
299#endif
300
301 if (LoopNestMode)
302 Worklist.insert(NewSibLoops);
303 else
305
306
307
308 }
309
310
311
312
313
314
316
317 SkipCurrentLoop = true;
318
319
320 Worklist.insert(CurrentL);
321 }
322
324 return LoopNestChanged;
325 }
326
327
328
330 LoopNestChanged = Changed;
331 }
332
333private:
335
336
338
339
341
342 Loop *CurrentL;
343 bool SkipCurrentLoop;
344 const bool LoopNestMode;
345 bool LoopNestChanged;
346
347#if LLVM_ENABLE_ABI_BREAKING_CHECKS
348
349
350 Loop *ParentL;
351#endif
352
355 bool LoopNestChanged = false)
356 : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode),
357 LoopNestChanged(LoopNestChanged) {}
358};
359
360template <typename IRUnitT, typename PassT>
361std::optional LoopPassManager::runSinglePass(
363 LoopStandardAnalysisResults &AR, LPMUpdater &U, PassInstrumentation &PI) {
364
365
366 const Loop &L = getLoopFromIR(IR);
367
368
369 if (!PI.runBeforePass(*Pass, L))
370 return std::nullopt;
371
372 PreservedAnalyses PA = Pass->run(IR, AM, AR, U);
373
374
375 if (U.skipCurrentLoop())
376 PI.runAfterPassInvalidated(*Pass, PA);
377 else
378 PI.runAfterPass(*Pass, L, PA);
379 return PA;
380}
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
399 : public PassInfoMixin {
400public:
404
406 bool UseMemorySSA = false,
407 bool LoopNestMode = false)
408 : Pass(std::move(Pass)), UseMemorySSA(UseMemorySSA),
409 LoopNestMode(LoopNestMode) {
411 LoopCanonicalizationFPM.addPass(LCSSAPass());
412 }
413
414
419
421
423
424private:
425 std::unique_ptr Pass;
426
428
429 bool UseMemorySSA = false;
430 const bool LoopNestMode;
431};
432
433
434
435
436
437
438
439
440template
441inline FunctionToLoopPassAdaptor
444 using PassModelT =
447
448
450 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
451 new PassModelT(std::forward(Pass))),
452 UseMemorySSA, false);
453 } else {
455 LPM.addPass(std::forward(Pass));
456 using PassModelT =
459
460
462 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
463 new PassModelT(std::move(LPM))),
464 UseMemorySSA, true);
465 }
466}
467
468
469
470template <>
473 bool UseMemorySSA) {
474
475
476 using PassModelT =
479 bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
480
481
483 std::unique_ptrFunctionToLoopPassAdaptor::PassConceptT(
484 new PassModelT(std::move(LPM))),
485 UseMemorySSA, LoopNestMode);
486}
487
488
491 std::string Banner;
492
493public:
496
499};
500}
501
502#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#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.
print mir2vec MIR2Vec Vocabulary Printer Pass
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
This file provides a priority worklist.
static const char PassName[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition LoopPassManager.h:399
static bool isRequired()
Definition LoopPassManager.h:420
FunctionToLoopPassAdaptor(std::unique_ptr< PassConceptT > Pass, bool UseMemorySSA=false, bool LoopNestMode=false)
Definition LoopPassManager.h:405
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
detail::PassConcept< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > PassConceptT
Definition LoopPassManager.h:401
bool isLoopNestMode() const
Definition LoopPassManager.h:422
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Runs the loop passes across every loop in the function.
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...
Definition LoopPassManager.h:226
void markLoopNestChanged(bool Changed)
Loopnest passes should use this method to indicate if the loopnest has been modified.
Definition LoopPassManager.h:329
void setParentLoop(Loop *L)
Definition LoopPassManager.h:255
bool isLoopNestChanged() const
Definition LoopPassManager.h:323
void revisitCurrentLoop()
Restart the current loop.
Definition LoopPassManager.h:315
bool skipCurrentLoop() const
This can be queried by loop passes which run other loop passes (like pass managers) to know whether t...
Definition LoopPassManager.h:234
void addChildLoops(ArrayRef< Loop * > NewChildLoops)
Loop passes should use this method to indicate they have added new child loops of the current loop.
Definition LoopPassManager.h:267
void markLoopAsDeleted(Loop &L, llvm::StringRef Name)
Loop passes should use this method to indicate they have deleted a loop from the nest.
Definition LoopPassManager.h:246
void addSiblingLoops(ArrayRef< Loop * > NewSibLoops)
Loop passes should use this method to indicate they have added new sibling loops to the current loop.
Definition LoopPassManager.h:294
const LoopT * getOutermostLoop() const
Get the outermost loop in which this loop is contained.
This class represents a loop nest and can be used to query its properties.
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...
Manages a sequence of passes over a particular unit of IR.
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.
LLVM_ABI 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.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
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.
Definition LoopPassManager.h:181
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
Definition LoopPassManager.h:442
LLVM_TEMPLATE_ABI void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor< LoopPassManager >(LoopPassManager &&LPM, bool UseMemorySSA)
If Pass is an instance of LoopPassManager, the returned adaptor will be in loop-nest mode if the pass...
Definition LoopPassManager.h:472
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
RequireAnalysisPass< AnalysisT, Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > RequireAnalysisLoopPass
An alias template to easily name a require analysis loop pass.
Definition LoopPassManager.h:207
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 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.