summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/LoopAccessAnalysis.h8
-rw-r--r--llvm/include/llvm/IR/DiagnosticInfo.h29
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp62
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp9
4 files changed, 78 insertions, 30 deletions
diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 0aa09aa5d6d..81515337711 100644
--- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -22,6 +22,7 @@
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
@@ -595,7 +596,7 @@ public:
/// \brief The diagnostics report generated for the analysis. E.g. why we
/// couldn't analyze the loop.
- const Optional<LoopAccessReport> &getReport() const { return Report; }
+ const OptimizationRemarkAnalysis *getReport() const { return Report.get(); }
/// \brief the Memory Dependence Checker which can determine the
/// loop-independent and loop-carried dependences between memory accesses.
@@ -646,7 +647,8 @@ private:
/// LAA does not directly emits the remarks. Instead it stores it which the
/// client can retrieve and presents as its own analysis
/// (e.g. -Rpass-analysis=loop-vectorize).
- void recordAnalysis(LoopAccessReport &Message);
+ OptimizationRemarkAnalysis &recordAnalysis(StringRef RemarkName,
+ Instruction *Instr = nullptr);
/// \brief Collect memory access with loop invariant strides.
///
@@ -680,7 +682,7 @@ private:
/// \brief The diagnostics report generated for the analysis. E.g. why we
/// couldn't analyze the loop.
- Optional<LoopAccessReport> Report;
+ std::unique_ptr<OptimizationRemarkAnalysis> Report;
/// \brief If an access has a symbolic strides, this maps the pointer value to
/// the stride symbol.
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 015f3042a13..d8c73b5653a 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -409,6 +409,24 @@ public:
PassName(PassName), RemarkName(RemarkName), CodeRegion(CodeRegion),
IsVerbose(false) {}
+ /// \brief This is ctor variant allows a pass to build an optimization remark
+ /// from an existing remark.
+ ///
+ /// This is useful when a transformation pass (e.g LV) wants to emit a remark
+ /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
+ /// remark. The string \p Prepend will be emitted before the original
+ /// message.
+ DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend,
+ const DiagnosticInfoOptimizationBase &Orig)
+ : DiagnosticInfoWithDebugLocBase((DiagnosticKind)Orig.getKind(),
+ Orig.getSeverity(), Orig.getFunction(),
+ Orig.getDebugLoc()),
+ PassName(PassName), RemarkName(Orig.RemarkName),
+ CodeRegion(Orig.getCodeRegion()) {
+ *this << Prepend;
+ std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
+ }
+
/// Legacy interface.
/// \p PassName is the name of the pass emitting this diagnostic.
/// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
@@ -578,6 +596,17 @@ public:
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
const DebugLoc &DLoc, Value *CodeRegion);
+ /// \brief This is ctor variant allows a pass to build an optimization remark
+ /// from an existing remark.
+ ///
+ /// This is useful when a transformation pass (e.g LV) wants to emit a remark
+ /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
+ /// remark. The string \p Prepend will be emitted before the original
+ /// message.
+ OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
+ const OptimizationRemarkAnalysis &Orig)
+ : DiagnosticInfoOptimizationBase(PassName, Prepend, Orig) {}
+
/// \brief Same as above but \p Inst is used to derive code region and debug
/// location.
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index e17ff6f51cb..428d63960f0 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1482,23 +1482,23 @@ bool LoopAccessInfo::canAnalyzeLoop() {
// We can only analyze innermost loops.
if (!TheLoop->empty()) {
DEBUG(dbgs() << "LAA: loop is not the innermost loop\n");
- recordAnalysis(LoopAccessReport() << "loop is not the innermost loop");
+ recordAnalysis("NotInnerMostLoop") << "loop is not the innermost loop";
return false;
}
// We must have a single backedge.
if (TheLoop->getNumBackEdges() != 1) {
DEBUG(dbgs() << "LAA: loop control flow is not understood by analyzer\n");
- recordAnalysis(LoopAccessReport()
- << "loop control flow is not understood by analyzer");
+ recordAnalysis("CFGNotUnderstood")
+ << "loop control flow is not understood by analyzer";
return false;
}
// We must have a single exiting block.
if (!TheLoop->getExitingBlock()) {
DEBUG(dbgs() << "LAA: loop control flow is not understood by analyzer\n");
- recordAnalysis(LoopAccessReport()
- << "loop control flow is not understood by analyzer");
+ recordAnalysis("CFGNotUnderstood")
+ << "loop control flow is not understood by analyzer";
return false;
}
@@ -1507,16 +1507,16 @@ bool LoopAccessInfo::canAnalyzeLoop() {
// instructions in the loop are executed the same number of times.
if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
DEBUG(dbgs() << "LAA: loop control flow is not understood by analyzer\n");
- recordAnalysis(LoopAccessReport()
- << "loop control flow is not understood by analyzer");
+ recordAnalysis("CFGNotUnderstood")
+ << "loop control flow is not understood by analyzer";
return false;
}
// ScalarEvolution needs to be able to find the exit count.
const SCEV *ExitCount = PSE->getBackedgeTakenCount();
if (ExitCount == PSE->getSE()->getCouldNotCompute()) {
- recordAnalysis(LoopAccessReport()
- << "could not determine number of loop iterations");
+ recordAnalysis("CantComputeNumberOfIterations")
+ << "could not determine number of loop iterations";
DEBUG(dbgs() << "LAA: SCEV could not compute the loop exit count.\n");
return false;
}
@@ -1565,8 +1565,8 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
auto *Ld = dyn_cast<LoadInst>(&I);
if (!Ld || (!Ld->isSimple() && !IsAnnotatedParallel)) {
- recordAnalysis(LoopAccessReport(Ld)
- << "read with atomic ordering or volatile read");
+ recordAnalysis("NonSimpleLoad", Ld)
+ << "read with atomic ordering or volatile read";
DEBUG(dbgs() << "LAA: Found a non-simple load.\n");
CanVecMem = false;
return;
@@ -1583,14 +1583,14 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
if (I.mayWriteToMemory()) {
auto *St = dyn_cast<StoreInst>(&I);
if (!St) {
- recordAnalysis(LoopAccessReport(St)
- << "instruction cannot be vectorized");
+ recordAnalysis("CantVectorizeInstruction", St)
+ << "instruction cannot be vectorized";
CanVecMem = false;
return;
}
if (!St->isSimple() && !IsAnnotatedParallel) {
- recordAnalysis(LoopAccessReport(St)
- << "write with atomic ordering or volatile write");
+ recordAnalysis("NonSimpleStore", St)
+ << "write with atomic ordering or volatile write";
DEBUG(dbgs() << "LAA: Found a non-simple store.\n");
CanVecMem = false;
return;
@@ -1698,7 +1698,7 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
bool CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(*PtrRtChecking, PSE->getSE(),
TheLoop, SymbolicStrides);
if (!CanDoRTIfNeeded) {
- recordAnalysis(LoopAccessReport() << "cannot identify array bounds");
+ recordAnalysis("CantIdentifyArrayBounds") << "cannot identify array bounds";
DEBUG(dbgs() << "LAA: We can't vectorize because we can't find "
<< "the array bounds.\n");
CanVecMem = false;
@@ -1729,8 +1729,8 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
// Check that we found the bounds for the pointer.
if (!CanDoRTIfNeeded) {
- recordAnalysis(LoopAccessReport()
- << "cannot check memory dependencies at runtime");
+ recordAnalysis("CantCheckMemDepsAtRunTime")
+ << "cannot check memory dependencies at runtime";
DEBUG(dbgs() << "LAA: Can't vectorize with memory checks\n");
CanVecMem = false;
return;
@@ -1745,12 +1745,11 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
<< (PtrRtChecking->Need ? "" : " don't")
<< " need runtime memory checks.\n");
else {
- recordAnalysis(
- LoopAccessReport()
+ recordAnalysis("UnsafeMemDep")
<< "unsafe dependent memory operations in loop. Use "
"#pragma loop distribute(enable) to allow loop distribution "
"to attempt to isolate the offending operations into a separate "
- "loop");
+ "loop";
DEBUG(dbgs() << "LAA: unsafe dependent memory operations in loop\n");
}
}
@@ -1764,9 +1763,24 @@ bool LoopAccessInfo::blockNeedsPredication(BasicBlock *BB, Loop *TheLoop,
return !DT->dominates(BB, Latch);
}
-void LoopAccessInfo::recordAnalysis(LoopAccessReport &Message) {
+OptimizationRemarkAnalysis &LoopAccessInfo::recordAnalysis(StringRef RemarkName,
+ Instruction *I) {
assert(!Report && "Multiple reports generated");
- Report = Message;
+
+ Value *CodeRegion = TheLoop->getHeader();
+ DebugLoc DL = TheLoop->getStartLoc();
+
+ if (I) {
+ CodeRegion = I->getParent();
+ // If there is no debug location attached to the instruction, revert back to
+ // using the loop's.
+ if (I->getDebugLoc())
+ DL = I->getDebugLoc();
+ }
+
+ Report = make_unique<OptimizationRemarkAnalysis>(DEBUG_TYPE, RemarkName, DL,
+ CodeRegion);
+ return *Report;
}
bool LoopAccessInfo::isUniform(Value *V) const {
@@ -1974,7 +1988,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
}
if (Report)
- OS.indent(Depth) << "Report: " << Report->str() << "\n";
+ OS.indent(Depth) << "Report: " << Report->getMsg() << "\n";
if (auto *Dependences = DepChecker->getDependences()) {
OS.indent(Depth) << "Dependences:\n";
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index bc92441250f..fe37c19c230 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5505,9 +5505,12 @@ void LoopVectorizationLegality::collectLoopUniforms() {
bool LoopVectorizationLegality::canVectorizeMemory() {
LAI = &(*GetLAA)(*TheLoop);
InterleaveInfo.setLAI(LAI);
- auto &OptionalReport = LAI->getReport();
- if (OptionalReport)
- emitAnalysis(VectorizationReport(*OptionalReport));
+ const OptimizationRemarkAnalysis *LAR = LAI->getReport();
+ if (LAR) {
+ OptimizationRemarkAnalysis VR(Hints->vectorizeAnalysisPassName(),
+ "loop not vectorized: ", *LAR);
+ ORE->emit(VR);
+ }
if (!LAI->canVectorizeMemory())
return false;
OpenPOWER on IntegriCloud