File indexing completed on 2026-05-10 08:43:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H
0015 #define LLVM_ANALYSIS_LOOPNESTANALYSIS_H
0016
0017 #include "llvm/ADT/STLExtras.h"
0018 #include "llvm/Analysis/LoopAnalysisManager.h"
0019 #include "llvm/Analysis/LoopInfo.h"
0020
0021 namespace llvm {
0022
0023 using LoopVectorTy = SmallVector<Loop *, 8>;
0024
0025 class LPMUpdater;
0026
0027
0028 class LLVM_ABI LoopNest {
0029 public:
0030 using InstrVectorTy = SmallVector<const Instruction *>;
0031
0032
0033 LoopNest(Loop &Root, ScalarEvolution &SE);
0034
0035 LoopNest() = delete;
0036
0037
0038 static std::unique_ptr<LoopNest> getLoopNest(Loop &Root, ScalarEvolution &SE);
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 static bool arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
0052 ScalarEvolution &SE);
0053
0054
0055
0056 static InstrVectorTy getInterveningInstructions(const Loop &OuterLoop,
0057 const Loop &InnerLoop,
0058 ScalarEvolution &SE);
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE);
0070
0071
0072
0073
0074
0075 static const BasicBlock &skipEmptyBlockUntil(const BasicBlock *From,
0076 const BasicBlock *End,
0077 bool CheckUniquePred = false);
0078
0079
0080 Loop &getOutermostLoop() const { return *Loops.front(); }
0081
0082
0083
0084
0085 Loop *getInnermostLoop() const {
0086 if (Loops.size() == 1)
0087 return Loops.back();
0088
0089
0090
0091
0092 Loop *LastLoop = Loops.back();
0093 auto SecondLastLoopIter = ++Loops.rbegin();
0094 return (LastLoop->getLoopDepth() == (*SecondLastLoopIter)->getLoopDepth())
0095 ? nullptr
0096 : LastLoop;
0097 }
0098
0099
0100 Loop *getLoop(unsigned Index) const {
0101 assert(Index < Loops.size() && "Index is out of bounds");
0102 return Loops[Index];
0103 }
0104
0105
0106 unsigned getLoopIndex(const Loop &L) const {
0107 for (unsigned I = 0; I < getNumLoops(); ++I)
0108 if (getLoop(I) == &L)
0109 return I;
0110 llvm_unreachable("Loop not in the loop nest");
0111 }
0112
0113
0114 size_t getNumLoops() const { return Loops.size(); }
0115
0116
0117 ArrayRef<Loop *> getLoops() const { return Loops; }
0118
0119
0120 LoopVectorTy getLoopsAtDepth(unsigned Depth) const {
0121 assert(Depth >= Loops.front()->getLoopDepth() &&
0122 Depth <= Loops.back()->getLoopDepth() && "Invalid depth");
0123 LoopVectorTy Result;
0124 for (unsigned I = 0; I < getNumLoops(); ++I) {
0125 Loop *L = getLoop(I);
0126 if (L->getLoopDepth() == Depth)
0127 Result.push_back(L);
0128 else if (L->getLoopDepth() > Depth)
0129 break;
0130 }
0131 return Result;
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 SmallVector<LoopVectorTy, 4> getPerfectLoops(ScalarEvolution &SE) const;
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 unsigned getNestDepth() const {
0156 int NestDepth =
0157 Loops.back()->getLoopDepth() - Loops.front()->getLoopDepth() + 1;
0158 assert(NestDepth > 0 && "Expecting NestDepth to be at least 1");
0159 return NestDepth;
0160 }
0161
0162
0163 unsigned getMaxPerfectDepth() const { return MaxPerfectDepth; }
0164
0165
0166 bool areAllLoopsSimplifyForm() const {
0167 return all_of(Loops, [](const Loop *L) { return L->isLoopSimplifyForm(); });
0168 }
0169
0170
0171 bool areAllLoopsRotatedForm() const {
0172 return all_of(Loops, [](const Loop *L) { return L->isRotatedForm(); });
0173 }
0174
0175
0176 Function *getParent() const {
0177 return Loops.front()->getHeader()->getParent();
0178 }
0179
0180 StringRef getName() const { return Loops.front()->getName(); }
0181
0182 protected:
0183 const unsigned MaxPerfectDepth;
0184 LoopVectorTy Loops;
0185
0186 private:
0187 enum LoopNestEnum {
0188 PerfectLoopNest,
0189 ImperfectLoopNest,
0190 InvalidLoopStructure,
0191 OuterLoopLowerBoundUnknown
0192 };
0193 static LoopNestEnum analyzeLoopNestForPerfectNest(const Loop &OuterLoop,
0194 const Loop &InnerLoop,
0195 ScalarEvolution &SE);
0196 };
0197
0198 raw_ostream &operator<<(raw_ostream &, const LoopNest &);
0199
0200
0201
0202 class LoopNestAnalysis : public AnalysisInfoMixin<LoopNestAnalysis> {
0203 friend AnalysisInfoMixin<LoopNestAnalysis>;
0204 static AnalysisKey Key;
0205
0206 public:
0207 using Result = LoopNest;
0208 Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR);
0209 };
0210
0211
0212 class LoopNestPrinterPass : public PassInfoMixin<LoopNestPrinterPass> {
0213 raw_ostream &OS;
0214
0215 public:
0216 explicit LoopNestPrinterPass(raw_ostream &OS) : OS(OS) {}
0217
0218 PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
0219 LoopStandardAnalysisResults &AR, LPMUpdater &U);
0220
0221 static bool isRequired() { return true; }
0222 };
0223
0224 }
0225
0226 #endif