36#ifndef LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
37#define LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
55class PassInstrumentation;
59template <
typename PassT>
60using HasRunOnLoopT =
decltype(std::declval<PassT>().run(
61 std::declval<Loop &>(), std::declval<LoopAnalysisManager &>(),
62 std::declval<LoopStandardAnalysisResults &>(),
63 std::declval<LPMUpdater &>()));
84 : IsLoopNestPass(
std::
move(Arg.IsLoopNestPass)),
85 LoopPasses(
std::
move(Arg.LoopPasses)),
86 LoopNestPasses(
std::
move(Arg.LoopNestPasses)) {}
89 IsLoopNestPass = std::move(
RHS.IsLoopNestPass);
90 LoopPasses = std::move(
RHS.LoopPasses);
91 LoopNestPasses = std::move(
RHS.LoopNestPasses);
110 using LoopPassModelT =
113 IsLoopNestPass.push_back(
false);
116 LoopPasses.push_back(std::unique_ptr<LoopPassConceptT>(
117 new LoopPassModelT(std::forward<PassT>(
Pass))));
119 using LoopNestPassModelT =
122 IsLoopNestPass.push_back(
true);
125 LoopNestPasses.push_back(std::unique_ptr<LoopNestPassConceptT>(
126 new LoopNestPassModelT(std::forward<PassT>(
Pass))));
130 bool isEmpty()
const {
return LoopPasses.empty() && LoopNestPasses.empty(); }
154 template <
typename IRUnitT,
typename PassT>
155 std::optional<PreservedAnalyses>
168 static const Loop &getLoopFromIR(
Loop &L) {
return L; }
186template <
typename AnalysisT>
194 (void)AM.template getResult<AnalysisT>(L, AR);
199 auto ClassName = AnalysisT::name();
200 auto PassName = MapClassName2PassName(ClassName);
206template <
typename AnalysisT>
249 "Cannot delete a loop outside of the "
250 "subloop tree currently being processed.");
252 SkipCurrentLoop =
true;
256#if LLVM_ENABLE_ABI_BREAKING_CHECKS
269 "Child loops should not be pushed in loop-nest mode.");
272 Worklist.insert(CurrentL);
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!");
285 SkipCurrentLoop =
true;
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!");
302 Worklist.insert(NewSibLoops);
317 SkipCurrentLoop =
true;
320 Worklist.insert(CurrentL);
324 return LoopNestChanged;
330 LoopNestChanged = Changed;
343 bool SkipCurrentLoop;
344 const bool LoopNestMode;
345 bool LoopNestChanged;
347#if LLVM_ENABLE_ABI_BREAKING_CHECKS
355 bool LoopNestChanged =
false)
356 : Worklist(Worklist),
LAM(
LAM), LoopNestMode(LoopNestMode),
357 LoopNestChanged(LoopNestChanged) {}
360template <
typename IRUnitT,
typename PassT>
366 const Loop &L = getLoopFromIR(
IR);
369 if (!PI.runBeforePass<
Loop>(*
Pass, L))
375 if (U.skipCurrentLoop())
376 PI.runAfterPassInvalidated<IRUnitT>(*
Pass, PA);
378 PI.runAfterPass<
Loop>(*
Pass, L, PA);
406 bool UseMemorySSA =
false,
407 bool UseBlockFrequencyInfo =
false,
408 bool UseBranchProbabilityInfo =
false,
409 bool LoopNestMode =
false)
411 UseBlockFrequencyInfo(UseBlockFrequencyInfo),
412 UseBranchProbabilityInfo(UseBranchProbabilityInfo),
413 LoopNestMode(LoopNestMode) {
429 std::unique_ptr<PassConceptT>
Pass;
433 bool UseMemorySSA =
false;
434 bool UseBlockFrequencyInfo =
false;
435 bool UseBranchProbabilityInfo =
false;
436 const bool LoopNestMode;
446template <
typename LoopPassT>
447inline FunctionToLoopPassAdaptor
449 bool UseBlockFrequencyInfo =
false,
450 bool UseBranchProbabilityInfo =
false) {
458 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
459 new PassModelT(std::forward<LoopPassT>(
Pass))),
460 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo,
false);
470 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
471 new PassModelT(std::move(LPM))),
472 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo,
true);
482 bool UseBranchProbabilityInfo) {
488 bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
492 std::unique_ptr<FunctionToLoopPassAdaptor::PassConceptT>(
493 new PassModelT(std::move(LPM))),
494 UseMemorySSA, UseBlockFrequencyInfo, UseBranchProbabilityInfo,
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.
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
This file provides a priority worklist.
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),...
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
bool isLoopNestMode() const
LLVM_ABI 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 void 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.
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.
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.
This is an optimization pass for GlobalISel generic memory operations.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
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...
LLVM_TEMPLATE_ABI 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.
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.