|
16 | 16 | #include "llvm/Analysis/IVDescriptors.h" |
17 | 17 | #include "llvm/Analysis/LoopInfo.h" |
18 | 18 | #include "llvm/Analysis/LoopPass.h" |
| 19 | +#include "llvm/Analysis/OptimizationRemarkEmitter.h" |
19 | 20 | #include "llvm/Analysis/ScalarEvolution.h" |
20 | 21 | #include "llvm/Analysis/ScalarEvolutionExpressions.h" |
21 | 22 | #include "llvm/Analysis/ValueTracking.h" |
@@ -43,19 +44,19 @@ static cl::opt<bool> EnableEVLIndVarSimplify( |
43 | 44 | namespace { |
44 | 45 | struct EVLIndVarSimplifyImpl { |
45 | 46 | ScalarEvolution &SE; |
| 47 | + OptimizationRemarkEmitter *ORE = nullptr; |
46 | 48 |
|
47 | | - explicit EVLIndVarSimplifyImpl(LoopStandardAnalysisResults &LAR) |
48 | | - : SE(LAR.SE) {} |
49 | | - |
50 | | - explicit EVLIndVarSimplifyImpl(ScalarEvolution &SE) : SE(SE) {} |
| 49 | + EVLIndVarSimplifyImpl(LoopStandardAnalysisResults &LAR, |
| 50 | + OptimizationRemarkEmitter *ORE) |
| 51 | + : SE(LAR.SE), ORE(ORE) {} |
51 | 52 |
|
52 | 53 | // Returns true if modify the loop. |
53 | 54 | bool run(Loop &L); |
54 | 55 | }; |
55 | 56 | } // anonymous namespace |
56 | 57 |
|
57 | | -// Returns the constant part of vectorization factor from the induction |
58 | | -// variable's step value SCEV expression. |
| 58 | +/// Returns the constant part of vectorization factor from the induction |
| 59 | +/// variable's step value SCEV expression. |
59 | 60 | static uint32_t getVFFromIndVar(const SCEV *Step, const Function &F) { |
60 | 61 | if (!Step) |
61 | 62 | return 0U; |
@@ -113,8 +114,17 @@ bool EVLIndVarSimplifyImpl::run(Loop &L) { |
113 | 114 | InductionDescriptor IVD; |
114 | 115 | PHINode *IndVar = L.getInductionVariable(SE); |
115 | 116 | if (!IndVar || !L.getInductionDescriptor(SE, IVD)) { |
| 117 | + const char *Reason = (IndVar ? "induction descriptor is not available" |
| 118 | + : "cannot recognize induction variable"); |
116 | 119 | LLVM_DEBUG(dbgs() << "Cannot retrieve IV from loop " << L.getName() |
117 | | - << "\n"); |
| 120 | + << " because" << Reason << "\n"); |
| 121 | + if (ORE) { |
| 122 | + ORE->emit([&]() { |
| 123 | + return OptimizationRemarkMissed(DEBUG_TYPE, "MissingIndVar", |
| 124 | + L.getStartLoc(), L.getHeader()) |
| 125 | + << "Cannot retrieve IV because " << ore::NV("Reason", Reason); |
| 126 | + }); |
| 127 | + } |
118 | 128 | return false; |
119 | 129 | } |
120 | 130 |
|
@@ -205,6 +215,22 @@ bool EVLIndVarSimplifyImpl::run(Loop &L) { |
205 | 215 | return false; |
206 | 216 |
|
207 | 217 | LLVM_DEBUG(dbgs() << "Using " << *EVLIndVar << " for EVL-based IndVar\n"); |
| 218 | + if (ORE) { |
| 219 | + ORE->emit([&]() { |
| 220 | + DebugLoc DL; |
| 221 | + BasicBlock *Region = nullptr; |
| 222 | + if (auto *I = dyn_cast<Instruction>(EVLIndVar)) { |
| 223 | + DL = I->getDebugLoc(); |
| 224 | + Region = I->getParent(); |
| 225 | + } else { |
| 226 | + DL = L.getStartLoc(); |
| 227 | + Region = L.getHeader(); |
| 228 | + } |
| 229 | + return OptimizationRemark(DEBUG_TYPE, "UseEVLIndVar", DL, Region) |
| 230 | + << "Using " << ore::NV("EVLIndVar", EVLIndVar) |
| 231 | + << " for EVL-based IndVar"; |
| 232 | + }); |
| 233 | + } |
208 | 234 |
|
209 | 235 | // Create an EVL-based comparison and replace the branch to use it as |
210 | 236 | // predicate. |
@@ -240,7 +266,12 @@ bool EVLIndVarSimplifyImpl::run(Loop &L) { |
240 | 266 | PreservedAnalyses EVLIndVarSimplifyPass::run(Loop &L, LoopAnalysisManager &LAM, |
241 | 267 | LoopStandardAnalysisResults &AR, |
242 | 268 | LPMUpdater &U) { |
243 | | - if (EVLIndVarSimplifyImpl(AR).run(L)) |
| 269 | + Function &F = *L.getHeader()->getParent(); |
| 270 | + auto &FAMProxy = LAM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR); |
| 271 | + OptimizationRemarkEmitter *ORE = |
| 272 | + FAMProxy.getCachedResult<OptimizationRemarkEmitterAnalysis>(F); |
| 273 | + |
| 274 | + if (EVLIndVarSimplifyImpl(AR, ORE).run(L)) |
244 | 275 | return PreservedAnalyses::allInSet<CFGAnalyses>(); |
245 | 276 | return PreservedAnalyses::all(); |
246 | 277 | } |
0 commit comments