Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- llvm/Analysis/LoopNestAnalysis.h -------------------------*- 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 | /// |
||
9 | /// \file |
||
10 | /// This file defines the interface for the loop nest analysis. |
||
11 | /// |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H |
||
15 | #define LLVM_ANALYSIS_LOOPNESTANALYSIS_H |
||
16 | |||
17 | #include "llvm/ADT/STLExtras.h" |
||
18 | #include "llvm/Analysis/LoopAnalysisManager.h" |
||
19 | #include "llvm/Analysis/LoopInfo.h" |
||
20 | |||
21 | namespace llvm { |
||
22 | |||
23 | using LoopVectorTy = SmallVector<Loop *, 8>; |
||
24 | |||
25 | class LPMUpdater; |
||
26 | |||
27 | /// This class represents a loop nest and can be used to query its properties. |
||
28 | class LLVM_EXTERNAL_VISIBILITY LoopNest { |
||
29 | public: |
||
30 | using InstrVectorTy = SmallVector<const Instruction *>; |
||
31 | |||
32 | /// Construct a loop nest rooted by loop \p Root. |
||
33 | LoopNest(Loop &Root, ScalarEvolution &SE); |
||
34 | |||
35 | LoopNest() = delete; |
||
36 | |||
37 | /// Construct a LoopNest object. |
||
38 | static std::unique_ptr<LoopNest> getLoopNest(Loop &Root, ScalarEvolution &SE); |
||
39 | |||
40 | /// Return true if the given loops \p OuterLoop and \p InnerLoop are |
||
41 | /// perfectly nested with respect to each other, and false otherwise. |
||
42 | /// Example: |
||
43 | /// \code |
||
44 | /// for(i) |
||
45 | /// for(j) |
||
46 | /// for(k) |
||
47 | /// \endcode |
||
48 | /// arePerfectlyNested(loop_i, loop_j, SE) would return true. |
||
49 | /// arePerfectlyNested(loop_j, loop_k, SE) would return true. |
||
50 | /// arePerfectlyNested(loop_i, loop_k, SE) would return false. |
||
51 | static bool arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop, |
||
52 | ScalarEvolution &SE); |
||
53 | |||
54 | /// Return a vector of instructions that prevent the LoopNest given |
||
55 | /// by loops \p OuterLoop and \p InnerLoop from being perfect. |
||
56 | static InstrVectorTy getInterveningInstructions(const Loop &OuterLoop, |
||
57 | const Loop &InnerLoop, |
||
58 | ScalarEvolution &SE); |
||
59 | |||
60 | /// Return the maximum nesting depth of the loop nest rooted by loop \p Root. |
||
61 | /// For example given the loop nest: |
||
62 | /// \code |
||
63 | /// for(i) // loop at level 1 and Root of the nest |
||
64 | /// for(j) // loop at level 2 |
||
65 | /// <code> |
||
66 | /// for(k) // loop at level 3 |
||
67 | /// \endcode |
||
68 | /// getMaxPerfectDepth(Loop_i) would return 2. |
||
69 | static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE); |
||
70 | |||
71 | /// Recursivelly traverse all empty 'single successor' basic blocks of \p From |
||
72 | /// (if there are any). When \p CheckUniquePred is set to true, check if |
||
73 | /// each of the empty single successors has a unique predecessor. Return |
||
74 | /// the last basic block found or \p End if it was reached during the search. |
||
75 | static const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From, |
||
76 | const BasicBlock *End, |
||
77 | bool CheckUniquePred = false); |
||
78 | |||
79 | /// Return the outermost loop in the loop nest. |
||
80 | Loop &getOutermostLoop() const { return *Loops.front(); } |
||
81 | |||
82 | /// Return the innermost loop in the loop nest if the nest has only one |
||
83 | /// innermost loop, and a nullptr otherwise. |
||
84 | /// Note: the innermost loop returned is not necessarily perfectly nested. |
||
85 | Loop *getInnermostLoop() const { |
||
86 | if (Loops.size() == 1) |
||
87 | return Loops.back(); |
||
88 | |||
89 | // The loops in the 'Loops' vector have been collected in breadth first |
||
90 | // order, therefore if the last 2 loops in it have the same nesting depth |
||
91 | // there isn't a unique innermost loop in the nest. |
||
92 | Loop *LastLoop = Loops.back(); |
||
93 | auto SecondLastLoopIter = ++Loops.rbegin(); |
||
94 | return (LastLoop->getLoopDepth() == (*SecondLastLoopIter)->getLoopDepth()) |
||
95 | ? nullptr |
||
96 | : LastLoop; |
||
97 | } |
||
98 | |||
99 | /// Return the loop at the given \p Index. |
||
100 | Loop *getLoop(unsigned Index) const { |
||
101 | assert(Index < Loops.size() && "Index is out of bounds"); |
||
102 | return Loops[Index]; |
||
103 | } |
||
104 | |||
105 | /// Get the loop index of the given loop \p L. |
||
106 | unsigned getLoopIndex(const Loop &L) const { |
||
107 | for (unsigned I = 0; I < getNumLoops(); ++I) |
||
108 | if (getLoop(I) == &L) |
||
109 | return I; |
||
110 | llvm_unreachable("Loop not in the loop nest"); |
||
111 | } |
||
112 | |||
113 | /// Return the number of loops in the nest. |
||
114 | size_t getNumLoops() const { return Loops.size(); } |
||
115 | |||
116 | /// Get the loops in the nest. |
||
117 | ArrayRef<Loop *> getLoops() const { return Loops; } |
||
118 | |||
119 | /// Get the loops in the nest at the given \p Depth. |
||
120 | LoopVectorTy getLoopsAtDepth(unsigned Depth) const { |
||
121 | assert(Depth >= Loops.front()->getLoopDepth() && |
||
122 | Depth <= Loops.back()->getLoopDepth() && "Invalid depth"); |
||
123 | LoopVectorTy Result; |
||
124 | for (unsigned I = 0; I < getNumLoops(); ++I) { |
||
125 | Loop *L = getLoop(I); |
||
126 | if (L->getLoopDepth() == Depth) |
||
127 | Result.push_back(L); |
||
128 | else if (L->getLoopDepth() > Depth) |
||
129 | break; |
||
130 | } |
||
131 | return Result; |
||
132 | } |
||
133 | |||
134 | /// Retrieve a vector of perfect loop nests contained in the current loop |
||
135 | /// nest. For example, given the following nest containing 4 loops, this |
||
136 | /// member function would return {{L1,L2},{L3,L4}}. |
||
137 | /// \code |
||
138 | /// for(i) // L1 |
||
139 | /// for(j) // L2 |
||
140 | /// <code> |
||
141 | /// for(k) // L3 |
||
142 | /// for(l) // L4 |
||
143 | /// \endcode |
||
144 | SmallVector<LoopVectorTy, 4> getPerfectLoops(ScalarEvolution &SE) const; |
||
145 | |||
146 | /// Return the loop nest depth (i.e. the loop depth of the 'deepest' loop) |
||
147 | /// For example given the loop nest: |
||
148 | /// \code |
||
149 | /// for(i) // loop at level 1 and Root of the nest |
||
150 | /// for(j1) // loop at level 2 |
||
151 | /// for(k) // loop at level 3 |
||
152 | /// for(j2) // loop at level 2 |
||
153 | /// \endcode |
||
154 | /// getNestDepth() would return 3. |
||
155 | unsigned getNestDepth() const { |
||
156 | int NestDepth = |
||
157 | Loops.back()->getLoopDepth() - Loops.front()->getLoopDepth() + 1; |
||
158 | assert(NestDepth > 0 && "Expecting NestDepth to be at least 1"); |
||
159 | return NestDepth; |
||
160 | } |
||
161 | |||
162 | /// Return the maximum perfect nesting depth. |
||
163 | unsigned getMaxPerfectDepth() const { return MaxPerfectDepth; } |
||
164 | |||
165 | /// Return true if all loops in the loop nest are in simplify form. |
||
166 | bool areAllLoopsSimplifyForm() const { |
||
167 | return all_of(Loops, [](const Loop *L) { return L->isLoopSimplifyForm(); }); |
||
168 | } |
||
169 | |||
170 | /// Return true if all loops in the loop nest are in rotated form. |
||
171 | bool areAllLoopsRotatedForm() const { |
||
172 | return all_of(Loops, [](const Loop *L) { return L->isRotatedForm(); }); |
||
173 | } |
||
174 | |||
175 | /// Return the function to which the loop-nest belongs. |
||
176 | Function *getParent() const { |
||
177 | return Loops.front()->getHeader()->getParent(); |
||
178 | } |
||
179 | |||
180 | StringRef getName() const { return Loops.front()->getName(); } |
||
181 | |||
182 | protected: |
||
183 | const unsigned MaxPerfectDepth; // maximum perfect nesting depth level. |
||
184 | LoopVectorTy Loops; // the loops in the nest (in breadth first order). |
||
185 | |||
186 | private: |
||
187 | enum LoopNestEnum { |
||
188 | PerfectLoopNest, |
||
189 | ImperfectLoopNest, |
||
190 | InvalidLoopStructure, |
||
191 | OuterLoopLowerBoundUnknown |
||
192 | }; |
||
193 | static LoopNestEnum analyzeLoopNestForPerfectNest(const Loop &OuterLoop, |
||
194 | const Loop &InnerLoop, |
||
195 | ScalarEvolution &SE); |
||
196 | }; |
||
197 | |||
198 | raw_ostream &operator<<(raw_ostream &, const LoopNest &); |
||
199 | |||
200 | /// This analysis provides information for a loop nest. The analysis runs on |
||
201 | /// demand and can be initiated via AM.getResult<LoopNestAnalysis>. |
||
202 | class LoopNestAnalysis : public AnalysisInfoMixin<LoopNestAnalysis> { |
||
203 | friend AnalysisInfoMixin<LoopNestAnalysis>; |
||
204 | static AnalysisKey Key; |
||
205 | |||
206 | public: |
||
207 | using Result = LoopNest; |
||
208 | Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR); |
||
209 | }; |
||
210 | |||
211 | /// Printer pass for the \c LoopNest results. |
||
212 | class LoopNestPrinterPass : public PassInfoMixin<LoopNestPrinterPass> { |
||
213 | raw_ostream &OS; |
||
214 | |||
215 | public: |
||
216 | explicit LoopNestPrinterPass(raw_ostream &OS) : OS(OS) {} |
||
217 | |||
218 | PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, |
||
219 | LoopStandardAnalysisResults &AR, LPMUpdater &U); |
||
220 | }; |
||
221 | |||
222 | } // namespace llvm |
||
223 | |||
224 | #endif // LLVM_ANALYSIS_LOOPNESTANALYSIS_H |