xref: /aosp_15_r20/external/llvm/include/llvm/Analysis/LoopPassManager.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- LoopPassManager.h - Loop pass management -----------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker /// \file
10*9880d681SAndroid Build Coastguard Worker ///
11*9880d681SAndroid Build Coastguard Worker /// This header provides classes for managing passes over loops in LLVM IR.
12*9880d681SAndroid Build Coastguard Worker ///
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_ANALYSIS_LOOPPASSMANAGER_H
16*9880d681SAndroid Build Coastguard Worker #define LLVM_ANALYSIS_LOOPPASSMANAGER_H
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h"
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker namespace llvm {
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker extern template class PassManager<Loop>;
25*9880d681SAndroid Build Coastguard Worker /// \brief The loop pass manager.
26*9880d681SAndroid Build Coastguard Worker ///
27*9880d681SAndroid Build Coastguard Worker /// See the documentation for the PassManager template for details. It runs a
28*9880d681SAndroid Build Coastguard Worker /// sequency of loop passes over each loop that the manager is run over. This
29*9880d681SAndroid Build Coastguard Worker /// typedef serves as a convenient way to refer to this construct.
30*9880d681SAndroid Build Coastguard Worker typedef PassManager<Loop> LoopPassManager;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker extern template class AnalysisManager<Loop>;
33*9880d681SAndroid Build Coastguard Worker /// \brief The loop analysis manager.
34*9880d681SAndroid Build Coastguard Worker ///
35*9880d681SAndroid Build Coastguard Worker /// See the documentation for the AnalysisManager template for detail
36*9880d681SAndroid Build Coastguard Worker /// documentation. This typedef serves as a convenient way to refer to this
37*9880d681SAndroid Build Coastguard Worker /// construct in the adaptors and proxies used to integrate this into the larger
38*9880d681SAndroid Build Coastguard Worker /// pass manager infrastructure.
39*9880d681SAndroid Build Coastguard Worker typedef AnalysisManager<Loop> LoopAnalysisManager;
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
42*9880d681SAndroid Build Coastguard Worker /// A proxy from a \c LoopAnalysisManager to a \c Function.
43*9880d681SAndroid Build Coastguard Worker typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
44*9880d681SAndroid Build Coastguard Worker     LoopAnalysisManagerFunctionProxy;
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
47*9880d681SAndroid Build Coastguard Worker /// A proxy from a \c FunctionAnalysisManager to a \c Loop.
48*9880d681SAndroid Build Coastguard Worker typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
49*9880d681SAndroid Build Coastguard Worker     FunctionAnalysisManagerLoopProxy;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker /// Returns the minimum set of Analyses that all loop passes must preserve.
52*9880d681SAndroid Build Coastguard Worker PreservedAnalyses getLoopPassPreservedAnalyses();
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker /// \brief Adaptor that maps from a function to its loops.
55*9880d681SAndroid Build Coastguard Worker ///
56*9880d681SAndroid Build Coastguard Worker /// Designed to allow composition of a LoopPass(Manager) and a
57*9880d681SAndroid Build Coastguard Worker /// FunctionPassManager. Note that if this pass is constructed with a \c
58*9880d681SAndroid Build Coastguard Worker /// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
59*9880d681SAndroid Build Coastguard Worker /// analysis prior to running the loop passes over the function to enable a \c
60*9880d681SAndroid Build Coastguard Worker /// LoopAnalysisManager to be used within this run safely.
61*9880d681SAndroid Build Coastguard Worker template <typename LoopPassT>
62*9880d681SAndroid Build Coastguard Worker class FunctionToLoopPassAdaptor
63*9880d681SAndroid Build Coastguard Worker     : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
64*9880d681SAndroid Build Coastguard Worker public:
FunctionToLoopPassAdaptor(LoopPassT Pass)65*9880d681SAndroid Build Coastguard Worker   explicit FunctionToLoopPassAdaptor(LoopPassT Pass)
66*9880d681SAndroid Build Coastguard Worker       : Pass(std::move(Pass)) {}
67*9880d681SAndroid Build Coastguard Worker   // We have to explicitly define all the special member functions because MSVC
68*9880d681SAndroid Build Coastguard Worker   // refuses to generate them.
FunctionToLoopPassAdaptor(const FunctionToLoopPassAdaptor & Arg)69*9880d681SAndroid Build Coastguard Worker   FunctionToLoopPassAdaptor(const FunctionToLoopPassAdaptor &Arg)
70*9880d681SAndroid Build Coastguard Worker       : Pass(Arg.Pass) {}
FunctionToLoopPassAdaptor(FunctionToLoopPassAdaptor && Arg)71*9880d681SAndroid Build Coastguard Worker   FunctionToLoopPassAdaptor(FunctionToLoopPassAdaptor &&Arg)
72*9880d681SAndroid Build Coastguard Worker       : Pass(std::move(Arg.Pass)) {}
swap(FunctionToLoopPassAdaptor & LHS,FunctionToLoopPassAdaptor & RHS)73*9880d681SAndroid Build Coastguard Worker   friend void swap(FunctionToLoopPassAdaptor &LHS,
74*9880d681SAndroid Build Coastguard Worker                    FunctionToLoopPassAdaptor &RHS) {
75*9880d681SAndroid Build Coastguard Worker     using std::swap;
76*9880d681SAndroid Build Coastguard Worker     swap(LHS.Pass, RHS.Pass);
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker   FunctionToLoopPassAdaptor &operator=(FunctionToLoopPassAdaptor RHS) {
79*9880d681SAndroid Build Coastguard Worker     swap(*this, RHS);
80*9880d681SAndroid Build Coastguard Worker     return *this;
81*9880d681SAndroid Build Coastguard Worker   }
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   /// \brief Runs the loop passes across every loop in the function.
run(Function & F,FunctionAnalysisManager & AM)84*9880d681SAndroid Build Coastguard Worker   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
85*9880d681SAndroid Build Coastguard Worker     // Setup the loop analysis manager from its proxy.
86*9880d681SAndroid Build Coastguard Worker     LoopAnalysisManager &LAM =
87*9880d681SAndroid Build Coastguard Worker         AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
88*9880d681SAndroid Build Coastguard Worker     // Get the loop structure for this function
89*9880d681SAndroid Build Coastguard Worker     LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker     PreservedAnalyses PA = PreservedAnalyses::all();
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker     // We want to visit the loops in reverse post-order. We'll build the stack
94*9880d681SAndroid Build Coastguard Worker     // of loops to visit in Loops by first walking the loops in pre-order.
95*9880d681SAndroid Build Coastguard Worker     SmallVector<Loop *, 2> Loops;
96*9880d681SAndroid Build Coastguard Worker     SmallVector<Loop *, 2> WorkList(LI.begin(), LI.end());
97*9880d681SAndroid Build Coastguard Worker     while (!WorkList.empty()) {
98*9880d681SAndroid Build Coastguard Worker       Loop *L = WorkList.pop_back_val();
99*9880d681SAndroid Build Coastguard Worker       WorkList.insert(WorkList.end(), L->begin(), L->end());
100*9880d681SAndroid Build Coastguard Worker       Loops.push_back(L);
101*9880d681SAndroid Build Coastguard Worker     }
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker     // Now pop each element off of the stack to visit the loops in reverse
104*9880d681SAndroid Build Coastguard Worker     // post-order.
105*9880d681SAndroid Build Coastguard Worker     for (auto *L : reverse(Loops)) {
106*9880d681SAndroid Build Coastguard Worker       PreservedAnalyses PassPA = Pass.run(*L, LAM);
107*9880d681SAndroid Build Coastguard Worker       assert(PassPA.preserved(getLoopPassPreservedAnalyses()) &&
108*9880d681SAndroid Build Coastguard Worker              "Loop passes must preserve all relevant analyses");
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker       // We know that the loop pass couldn't have invalidated any other loop's
111*9880d681SAndroid Build Coastguard Worker       // analyses (that's the contract of a loop pass), so directly handle the
112*9880d681SAndroid Build Coastguard Worker       // loop analysis manager's invalidation here.  Also, update the
113*9880d681SAndroid Build Coastguard Worker       // preserved analyses to reflect that once invalidated these can again
114*9880d681SAndroid Build Coastguard Worker       // be preserved.
115*9880d681SAndroid Build Coastguard Worker       PassPA = LAM.invalidate(*L, std::move(PassPA));
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker       // Then intersect the preserved set so that invalidation of module
118*9880d681SAndroid Build Coastguard Worker       // analyses will eventually occur when the module pass completes.
119*9880d681SAndroid Build Coastguard Worker       PA.intersect(std::move(PassPA));
120*9880d681SAndroid Build Coastguard Worker     }
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker     // By definition we preserve the proxy. This precludes *any* invalidation of
123*9880d681SAndroid Build Coastguard Worker     // loop analyses by the proxy, but that's OK because we've taken care to
124*9880d681SAndroid Build Coastguard Worker     // invalidate analyses in the loop analysis manager incrementally above.
125*9880d681SAndroid Build Coastguard Worker     PA.preserve<LoopAnalysisManagerFunctionProxy>();
126*9880d681SAndroid Build Coastguard Worker     return PA;
127*9880d681SAndroid Build Coastguard Worker   }
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker private:
130*9880d681SAndroid Build Coastguard Worker   LoopPassT Pass;
131*9880d681SAndroid Build Coastguard Worker };
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker /// \brief A function to deduce a loop pass type and wrap it in the templated
134*9880d681SAndroid Build Coastguard Worker /// adaptor.
135*9880d681SAndroid Build Coastguard Worker template <typename LoopPassT>
136*9880d681SAndroid Build Coastguard Worker FunctionToLoopPassAdaptor<LoopPassT>
createFunctionToLoopPassAdaptor(LoopPassT Pass)137*9880d681SAndroid Build Coastguard Worker createFunctionToLoopPassAdaptor(LoopPassT Pass) {
138*9880d681SAndroid Build Coastguard Worker   return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass));
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker #endif // LLVM_ANALYSIS_LOOPPASSMANAGER_H
143