LLVM 20.0.0git
LoopPassManager.h
Go to the documentation of this file.
1//===- LoopPassManager.h - Loop pass management -----------------*- 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/// \file
9///
10/// This header provides classes for managing a pipeline of passes over loops
11/// in LLVM IR.
12///
13/// The primary loop pass pipeline is managed in a very particular way to
14/// provide a set of core guarantees:
15/// 1) Loops are, where possible, in simplified form.
16/// 2) Loops are *always* in LCSSA form.
17/// 3) A collection of Loop-specific analysis results are available:
18/// - LoopInfo
19/// - DominatorTree
20/// - ScalarEvolution
21/// - AAManager
22/// 4) All loop passes preserve #1 (where possible), #2, and #3.
23/// 5) Loop passes run over each loop in the loop nest from the innermost to
24/// the outermost. Specifically, all inner loops are processed before
25/// passes run over outer loops. When running the pipeline across an inner
26/// loop creates new inner loops, those are added and processed in this
27/// order as well.
28///
29/// This process is designed to facilitate transformations which simplify,
30/// reduce, and remove loops. For passes which are more oriented towards
31/// optimizing loops, especially optimizing loop *nests* instead of single
32/// loops in isolation, this framework is less interesting.
33///
34//===----------------------------------------------------------------------===//
35
36#ifndef LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
37#define LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
38
43#include "llvm/IR/PassManager.h"
48#include <memory>
49
50namespace llvm {
51
52// Forward declarations of an update tracking API used in the pass manager.
53class LPMUpdater;
54class PassInstrumentation;
55
56namespace {
57
58template <typename PassT>
59using HasRunOnLoopT = decltype(std::declval<PassT>().run(
60 std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
61 std::declval<LoopStandardAnalysisResults &>(),
62 std::declval<LPMUpdater &>()));
63
64} // namespace
65
66// Explicit specialization and instantiation declarations for the pass manager.
67// See the comments on the definition of the specialization for details on how
68// it differs from the primary template.
69template <>
71 LPMUpdater &>
72 : public PassInfoMixin<
74 LPMUpdater &>> {
75public:
76 explicit PassManager() = default;
77
78 // FIXME: These are equivalent to the default move constructor/move
79 // assignment. However, using = default triggers linker errors due to the
80 // explicit instantiations below. Find a way to use the default and remove the
81 // duplicated code here.
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
97 void printPipeline(raw_ostream &OS,
98 function_ref<StringRef(StringRef)> MapClassName2PassName);
99 /// Add either a loop pass or a loop-nest pass to the pass manager. Append \p
100 /// Pass to the list of loop passes if it has a dedicated \fn run() method for
101 /// loops and to the list of loop-nest passes if the \fn run() method is for
102 /// loop-nests instead. Also append whether \p Pass is loop-nest pass or not
103 /// to the end of \var IsLoopNestPass so we can easily identify the types of
104 /// passes in the pass manager later.
105 template <typename PassT>
107 std::enable_if_t<is_detected<HasRunOnLoopT, PassT>::value>
108 addPass(PassT &&Pass) {
109 using LoopPassModelT =
112 IsLoopNestPass.push_back(false);
113 // Do not use make_unique or emplace_back, they cause too many template
114 // instantiations, causing terrible compile times.
115 LoopPasses.push_back(std::unique_ptr<LoopPassConceptT>(
116 new LoopPassModelT(std::forward<PassT>(Pass))));
117 }
118
119 template <typename PassT>
121 std::enable_if_t<!is_detected<HasRunOnLoopT, PassT>::value>
122 addPass(PassT &&Pass) {
123 using LoopNestPassModelT =
126 IsLoopNestPass.push_back(true);
127 // Do not use make_unique or emplace_back, they cause too many template
128 // instantiations, causing terrible compile times.
129 LoopNestPasses.push_back(std::unique_ptr<LoopNestPassConceptT>(
130 new LoopNestPassModelT(std::forward<PassT>(Pass))));
131 }
132
133 bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
134
135 static bool isRequired() { return true; }
136
137 size_t getNumLoopPasses() const { return LoopPasses.size(); }
138 size_t getNumLoopNestPasses() const { return LoopNestPasses.size(); }
139
140protected:
147
148 // BitVector that identifies whether the passes are loop passes or loop-nest
149 // passes (true for loop-nest passes).
151 std::vector<std::unique_ptr<LoopPassConceptT>> LoopPasses;
152 std::vector<std::unique_ptr<LoopNestPassConceptT>> LoopNestPasses;
153
154 /// Run either a loop pass or a loop-nest pass. Returns `std::nullopt` if
155 /// PassInstrumentation's BeforePass returns false. Otherwise, returns the
156 /// preserved analyses of the pass.
157 template <typename IRUnitT, typename PassT>
158 std::optional<PreservedAnalyses>
159 runSinglePass(IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
162
163 PreservedAnalyses runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
165 LPMUpdater &U);
166 PreservedAnalyses runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
168 LPMUpdater &U);
169
170private:
171 static const Loop &getLoopFromIR(Loop &L) { return L; }
172 static const Loop &getLoopFromIR(LoopNest &LN) {
173 return LN.getOutermostLoop();
174 }
175};
176
177/// The Loop pass manager.
178///
179/// See the documentation for the PassManager template for details. It runs
180/// a sequence of Loop passes over each Loop that the manager is run over. This
181/// typedef serves as a convenient way to refer to this construct.
182typedef PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
183 LPMUpdater &>
185
186/// A partial specialization of the require analysis template pass to forward
187/// the extra parameters from a transformation's run method to the
188/// AnalysisManager's getResult.
189template <typename AnalysisT>
197 (void)AM.template getResult<AnalysisT>(L, AR);
198 return PreservedAnalyses::all();
199 }
201 function_ref<StringRef(StringRef)> MapClassName2PassName) {
202 auto ClassName = AnalysisT::name();
203 auto PassName = MapClassName2PassName(ClassName);
204 OS << "require<" << PassName << '>';
205 }
206};
207
208/// An alias template to easily name a require analysis loop pass.
209template <typename AnalysisT>
213
215
216/// This class provides an interface for updating the loop pass manager based
217/// on mutations to the loop nest.
218///
219/// A reference to an instance of this class is passed as an argument to each
220/// Loop pass, and Loop passes should use it to update LPM infrastructure if
221/// they modify the loop nest structure.
222///
223/// \c LPMUpdater comes with two modes: the loop mode and the loop-nest mode. In
224/// loop mode, all the loops in the function will be pushed into the worklist
225/// and when new loops are added to the pipeline, their subloops are also
226/// inserted recursively. On the other hand, in loop-nest mode, only top-level
227/// loops are contained in the worklist and the addition of new (top-level)
228/// loops will not trigger the addition of their subloops.
230public:
231 /// This can be queried by loop passes which run other loop passes (like pass
232 /// managers) to know whether the loop needs to be skipped due to updates to
233 /// the loop nest.
234 ///
235 /// If this returns true, the loop object may have been deleted, so passes
236 /// should take care not to touch the object.
237 bool skipCurrentLoop() const { return SkipCurrentLoop; }
238
239 /// Loop passes should use this method to indicate they have deleted a loop
240 /// from the nest.
241 ///
242 /// Note that this loop must either be the current loop or a subloop of the
243 /// current loop. This routine must be called prior to removing the loop from
244 /// the loop nest.
245 ///
246 /// If this is called for the current loop, in addition to clearing any
247 /// state, this routine will mark that the current loop should be skipped by
248 /// the rest of the pass management infrastructure.
250 LAM.clear(L, Name);
251 assert((&L == CurrentL || CurrentL->contains(&L)) &&
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 /// Loop passes should use this method to indicate they have added new child
265 /// loops of the current loop.
266 ///
267 /// \p NewChildLoops must contain only the immediate children. Any nested
268 /// loops within them will be visited in postorder as usual for the loop pass
269 /// manager.
270 void addChildLoops(ArrayRef<Loop *> NewChildLoops) {
271 assert(!LoopNestMode &&
272 "Child loops should not be pushed in loop-nest mode.");
273 // Insert ourselves back into the worklist first, as this loop should be
274 // revisited after all the children have been processed.
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
284 appendLoopsToWorklist(NewChildLoops, Worklist);
285
286 // Also skip further processing of the current loop--it will be revisited
287 // after all of its newly added children are accounted for.
288 SkipCurrentLoop = true;
289 }
290
291 /// Loop passes should use this method to indicate they have added new
292 /// sibling loops to the current loop.
293 ///
294 /// \p NewSibLoops must only contain the immediate sibling loops. Any nested
295 /// loops within them will be visited in postorder as usual for the loop pass
296 /// manager.
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
307 appendLoopsToWorklist(NewSibLoops, Worklist);
308
309 // No need to skip the current loop or revisit it, as sibling loops
310 // shouldn't impact anything.
311 }
312
313 /// Restart the current loop.
314 ///
315 /// Loop passes should call this method to indicate the current loop has been
316 /// sufficiently changed that it should be re-visited from the begining of
317 /// the loop pass pipeline rather than continuing.
319 // Tell the currently in-flight pipeline to stop running.
320 SkipCurrentLoop = true;
321
322 // And insert ourselves back into the worklist.
323 Worklist.insert(CurrentL);
324 }
325
326 bool isLoopNestChanged() const {
327 return LoopNestChanged;
328 }
329
330 /// Loopnest passes should use this method to indicate if the
331 /// loopnest has been modified.
332 void markLoopNestChanged(bool Changed) {
333 LoopNestChanged = Changed;
334 }
335
336private:
338
339 /// The \c FunctionToLoopPassAdaptor's worklist of loops to process.
341
342 /// The analysis manager for use in the current loop nest.
344
345 Loop *CurrentL;
346 bool SkipCurrentLoop;
347 const bool LoopNestMode;
348 bool LoopNestChanged;
349
350#if LLVM_ENABLE_ABI_BREAKING_CHECKS
351 // In debug builds we also track the parent loop to implement asserts even in
352 // the face of loop deletion.
353 Loop *ParentL;
354#endif
355
357 LoopAnalysisManager &LAM, bool LoopNestMode = false,
358 bool LoopNestChanged = false)
359 : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode),
360 LoopNestChanged(LoopNestChanged) {}
361};
362
363template <typename IRUnitT, typename PassT>
364std::optional<PreservedAnalyses> LoopPassManager::runSinglePass(
365 IRUnitT &IR, PassT &Pass, LoopAnalysisManager &AM,
367 // Get the loop in case of Loop pass and outermost loop in case of LoopNest
368 // pass which is to be passed to BeforePass and AfterPass call backs.
369 const Loop &L = getLoopFromIR(IR);
370 // Check the PassInstrumentation's BeforePass callbacks before running the
371 // pass, skip its execution completely if asked to (callback returns false).
372 if (!PI.runBeforePass<Loop>(*Pass, L))
373 return std::nullopt;
374
375 PreservedAnalyses PA = Pass->run(IR, AM, AR, U);
376
377 // do not pass deleted Loop into the instrumentation
378 if (U.skipCurrentLoop())
379 PI.runAfterPassInvalidated<IRUnitT>(*Pass, PA);
380 else
381 PI.runAfterPass<Loop>(*Pass, L, PA);
382 return PA;
383}
384
385/// Adaptor that maps from a function to its loops.
386///
387/// Designed to allow composition of a LoopPass(Manager) and a
388/// FunctionPassManager. Note that if this pass is constructed with a \c
389/// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
390/// analysis prior to running the loop passes over the function to enable a \c
391/// LoopAnalysisManager to be used within this run safely.
392///
393/// The adaptor comes with two modes: the loop mode and the loop-nest mode, and
394/// the worklist updater lived inside will be in the same mode as the adaptor
395/// (refer to the documentation of \c LPMUpdater for more detailed explanation).
396/// Specifically, in loop mode, all loops in the function will be pushed into
397/// the worklist and processed by \p Pass, while only top-level loops are
398/// processed in loop-nest mode. Please refer to the various specializations of
399/// \fn createLoopFunctionToLoopPassAdaptor to see when loop mode and loop-nest
400/// mode are used.
402 : public PassInfoMixin<FunctionToLoopPassAdaptor> {
403public:
407
408 explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass,
409 bool UseMemorySSA = false,
410 bool UseBlockFrequencyInfo = false,
411 bool UseBranchProbabilityInfo = false,
412 bool LoopNestMode = false)
413 : Pass(std::move(Pass)), UseMemorySSA(UseMemorySSA),
414 UseBlockFrequencyInfo(UseBlockFrequencyInfo),
415 UseBranchProbabilityInfo(UseBranchProbabilityInfo),
416 LoopNestMode(LoopNestMode) {
417 LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
418 LoopCanonicalizationFPM.addPass(LCSSAPass());
419 }
420
421 /// Runs the loop passes across every loop in the function.
424 function_ref<StringRef(StringRef)> MapClassName2PassName);
425
426 static bool isRequired() { return true; }
427
428 bool isLoopNestMode() const { return LoopNestMode; }
429
430private:
431 std::unique_ptr<PassConceptT> Pass;
432
433 FunctionPassManager LoopCanonicalizationFPM;
434
435 bool UseMemorySSA = false;
436 bool UseBlockFrequencyInfo = false;
437 bool UseBranchProbabilityInfo = false;
438 const bool LoopNestMode;
439};
440
441/// A function to deduce a loop pass type and wrap it in the templated
442/// adaptor.
443///
444/// If \p Pass is a loop pass, the returned adaptor will be in loop mode.
445template <typename LoopPassT>
446inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value,
447 FunctionToLoopPassAdaptor>
448createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA = false,
449 bool UseBlockFrequencyInfo = false,
450 bool UseBranchProbabilityInfo = false) {
451 using PassModelT =
454 // Do not use make_unique, it causes too many template instantiations,
455 // causing terrible compile times.
457 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
458 new PassModelT(std::forward<LoopPassT>(Pass))),
459 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, false);
460}
461
462/// If \p Pass is a loop-nest pass, \p Pass will first be wrapped into a
463/// \c LoopPassManager and the returned adaptor will be in loop-nest mode.
464template <typename LoopNestPassT>
465inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value,
466 FunctionToLoopPassAdaptor>
467createFunctionToLoopPassAdaptor(LoopNestPassT &&Pass, bool UseMemorySSA = false,
468 bool UseBlockFrequencyInfo = false,
469 bool UseBranchProbabilityInfo = false) {
470 LoopPassManager LPM;
471 LPM.addPass(std::forward<LoopNestPassT>(Pass));
472 using PassModelT =
475 // Do not use make_unique, it causes too many template instantiations,
476 // causing terrible compile times.
478 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
479 new PassModelT(std::move(LPM))),
480 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo, true);
481}
482
483/// If \p Pass is an instance of \c LoopPassManager, the returned adaptor will
484/// be in loop-nest mode if the pass manager contains only loop-nest passes.
485template <>
488 LoopPassManager &&LPM, bool UseMemorySSA, bool UseBlockFrequencyInfo,
489 bool UseBranchProbabilityInfo) {
490 // Check if LPM contains any loop pass and if it does not, returns an adaptor
491 // in loop-nest mode.
492 using PassModelT =
495 bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
496 // Do not use make_unique, it causes too many template instantiations,
497 // causing terrible compile times.
499 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
500 new PassModelT(std::move(LPM))),
501 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo,
502 LoopNestMode);
503}
504
505/// Pass for printing a loop's contents as textual IR.
506class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
508 std::string Banner;
509
510public:
512 PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
513
516};
517}
518
519#endif // LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
aarch64 AArch64 CCMP Pass
#define LLVM_ATTRIBUTE_MINSIZE
Definition: Compiler.h:312
std::string Name
This header defines various interfaces for pass management in LLVM.
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:80
This header provides classes for managing per-loop analyses.
This file defines the interface for the loop nest analysis.
#define F(x, y, z)
Definition: MD5.cpp:55
LoopAnalysisManager LAM
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())
raw_pwrite_stream & OS
static const char PassName[]
Value * RHS
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
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),...
Definition: ArrayRef.h:41
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
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.
Definition: LCSSA.h:37
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.
Definition: LoopSimplify.h:53
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:39
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
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)
Manages a sequence of passes over a particular unit of IR.
Definition: PassManager.h:162
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Definition: PassManager.h:195
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
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.
Definition: StringRef.h:51
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.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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.
Definition: LoopUtils.cpp:1814
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
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.
Definition: BitVector.h:858
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.
Definition: PassManager.h:69
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.
Definition: PassManager.h:878
Template for the abstract base class used to dispatch polymorphically over pass objects.
A template wrapper used to implement the polymorphic API.