|
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