diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 9af3bf07065..93ee959bfa7 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -16,6 +16,7 @@ #define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H #include "llvm/ADT/EquivalenceClasses.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" @@ -129,11 +130,11 @@ public: SmallVector AliasSetId; }; - LoopAccessInfo(Function *F, Loop *L, ScalarEvolution *SE, - const DataLayout *DL, const TargetLibraryInfo *TLI, - AliasAnalysis *AA, DominatorTree *DT) : - TheFunction(F), TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT), - NumLoads(0), NumStores(0), MaxSafeDepDistBytes(-1U) {} + LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout *DL, + const TargetLibraryInfo *TLI, AliasAnalysis *AA, + DominatorTree *DT) : + TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT), NumLoads(0), + NumStores(0), MaxSafeDepDistBytes(-1U) {} /// Return true we can analyze the memory accesses in the loop and there are /// no memory dependence cycles. Replaces symbolic strides using Strides. @@ -159,13 +160,16 @@ public: /// second value is the final comparator value or NULL if no check is needed. std::pair addRuntimeCheck(Instruction *Loc); + /// \brief The diagnostics report generated for the analysis. E.g. why we + /// couldn't analyze the loop. + Optional &getReport() { return Report; } + private: void emitAnalysis(VectorizationReport &Message); /// We need to check that all of the pointers in this list are disjoint /// at runtime. RuntimePointerCheck PtrRtCheck; - Function *TheFunction; Loop *TheLoop; ScalarEvolution *SE; const DataLayout *DL; @@ -177,6 +181,10 @@ private: unsigned NumStores; unsigned MaxSafeDepDistBytes; + + /// \brief The diagnostics report generated for the analysis. E.g. why we + /// couldn't analyze the loop. + Optional Report; }; Value *stripIntegerCast(Value *V); diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp index 9ac27ddb46f..927ae494548 100644 --- a/lib/Analysis/LoopAccessAnalysis.cpp +++ b/lib/Analysis/LoopAccessAnalysis.cpp @@ -1077,7 +1077,8 @@ bool LoopAccessInfo::blockNeedsPredication(BasicBlock *BB) { } void LoopAccessInfo::emitAnalysis(VectorizationReport &Message) { - VectorizationReport::emitAnalysis(Message, TheFunction, TheLoop); + assert(!Report && "Multiple report generated"); + Report = Message; } bool LoopAccessInfo::isUniform(Value *V) { diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 3f6660203c0..abb38d19ea1 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -556,7 +556,7 @@ public: : NumPredStores(0), TheLoop(L), SE(SE), DL(DL), TLI(TLI), TheFunction(F), TTI(TTI), Induction(nullptr), WidestIndTy(nullptr), - LAI(F, L, SE, DL, TLI, AA, DT), + LAI(L, SE, DL, TLI, AA, DT), HasFunNoNaNAttr(false) {} /// This enum represents the kinds of reductions that we support. @@ -3825,7 +3825,11 @@ void LoopVectorizationLegality::collectLoopUniforms() { } bool LoopVectorizationLegality::canVectorizeMemory() { - return LAI.canVectorizeMemory(Strides); + bool Success = LAI.canVectorizeMemory(Strides); + auto &OptionalReport = LAI.getReport(); + if (OptionalReport) + emitAnalysis(*OptionalReport); + return Success; } static bool hasMultipleUsesOf(Instruction *I,