mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-24 05:09:34 +00:00
Print vectorization analysis when loop hint is specified.
This patch and a relatec clang patch solve the problem of having to explicitly enable analysis when specifying a loop hint pragma to get the diagnostics. Passing AlwasyPrint as the pass name (see below) causes the front-end to print the diagnostic if the user has specified '-Rpass-analysis' without an '=<target-pass>’. Users of loop hints can pass that compiler option without having to specify the pass and they will get diagnostics for only those loops with loop hints. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244555 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ad12f71abc
commit
f175a4758b
@ -101,6 +101,8 @@ public:
|
||||
/// The printed message must not end with '.' nor start with a severity
|
||||
/// keyword.
|
||||
virtual void print(DiagnosticPrinter &DP) const = 0;
|
||||
|
||||
static const char *AlwaysPrint;
|
||||
};
|
||||
|
||||
typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
|
||||
|
@ -91,6 +91,8 @@ int llvm::getNextAvailablePluginDiagnosticKind() {
|
||||
return ++PluginKindID;
|
||||
}
|
||||
|
||||
const char *DiagnosticInfo::AlwaysPrint = "";
|
||||
|
||||
DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
|
||||
const Twine &MsgStr,
|
||||
DiagnosticSeverity Severity)
|
||||
@ -166,8 +168,9 @@ bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
|
||||
}
|
||||
|
||||
bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
|
||||
return PassRemarksAnalysisOptLoc.Pattern &&
|
||||
PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
|
||||
return getPassName() == DiagnosticInfo::AlwaysPrint ||
|
||||
(PassRemarksAnalysisOptLoc.Pattern &&
|
||||
PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
|
||||
}
|
||||
|
||||
void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
|
||||
|
@ -914,6 +914,10 @@ public:
|
||||
unsigned getWidth() const { return Width.Value; }
|
||||
unsigned getInterleave() const { return Interleave.Value; }
|
||||
enum ForceKind getForce() const { return (ForceKind)Force.Value; }
|
||||
bool isForced() const {
|
||||
return getForce() == LoopVectorizeHints::FK_Enabled || getWidth() > 1 ||
|
||||
getInterleave() > 1;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Find hints specified in the loop metadata and update local values.
|
||||
@ -1031,6 +1035,14 @@ private:
|
||||
const Loop *TheLoop;
|
||||
};
|
||||
|
||||
static void emitAnalysisDiag(const Function *TheFunction, const Loop *TheLoop,
|
||||
const LoopVectorizeHints &Hints,
|
||||
const LoopAccessReport &Message) {
|
||||
// If a loop hint is provided the diagnostic is always produced.
|
||||
const char *Name = Hints.isForced() ? DiagnosticInfo::AlwaysPrint : LV_NAME;
|
||||
LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, Name);
|
||||
}
|
||||
|
||||
static void emitMissedWarning(Function *F, Loop *L,
|
||||
const LoopVectorizeHints &LH) {
|
||||
emitOptimizationRemarkMissed(F->getContext(), DEBUG_TYPE, *F,
|
||||
@ -1067,11 +1079,12 @@ public:
|
||||
TargetLibraryInfo *TLI, AliasAnalysis *AA,
|
||||
Function *F, const TargetTransformInfo *TTI,
|
||||
LoopAccessAnalysis *LAA,
|
||||
LoopVectorizationRequirements *R)
|
||||
LoopVectorizationRequirements *R,
|
||||
const LoopVectorizeHints *H)
|
||||
: NumPredStores(0), TheLoop(L), SE(SE), TLI(TLI), TheFunction(F),
|
||||
TTI(TTI), DT(DT), LAA(LAA), LAI(nullptr), InterleaveInfo(SE, L, DT),
|
||||
Induction(nullptr), WidestIndTy(nullptr), HasFunNoNaNAttr(false),
|
||||
Requirements(R) {}
|
||||
Requirements(R), Hints(H) {}
|
||||
|
||||
/// This enum represents the kinds of inductions that we support.
|
||||
enum InductionKind {
|
||||
@ -1285,8 +1298,8 @@ private:
|
||||
/// not vectorized. These are handled as LoopAccessReport rather than
|
||||
/// VectorizationReport because the << operator of VectorizationReport returns
|
||||
/// LoopAccessReport.
|
||||
void emitAnalysis(const LoopAccessReport &Message) {
|
||||
LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
|
||||
void emitAnalysis(const LoopAccessReport &Message) const {
|
||||
emitAnalysisDiag(TheFunction, TheLoop, *Hints, Message);
|
||||
}
|
||||
|
||||
unsigned NumPredStores;
|
||||
@ -1340,6 +1353,9 @@ private:
|
||||
/// Vectorization requirements that will go through late-evaluation.
|
||||
LoopVectorizationRequirements *Requirements;
|
||||
|
||||
/// Used to emit an analysis of any legality issues.
|
||||
const LoopVectorizeHints *Hints;
|
||||
|
||||
ValueToValueMap Strides;
|
||||
SmallPtrSet<Value *, 8> StrideSet;
|
||||
|
||||
@ -1430,8 +1446,8 @@ private:
|
||||
/// not vectorized. These are handled as LoopAccessReport rather than
|
||||
/// VectorizationReport because the << operator of VectorizationReport returns
|
||||
/// LoopAccessReport.
|
||||
void emitAnalysis(const LoopAccessReport &Message) {
|
||||
LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
|
||||
void emitAnalysis(const LoopAccessReport &Message) const {
|
||||
emitAnalysisDiag(TheFunction, TheLoop, *Hints, Message);
|
||||
}
|
||||
|
||||
/// Values used only by @llvm.assume calls.
|
||||
@ -1480,13 +1496,14 @@ public:
|
||||
void addRuntimePointerChecks(unsigned Num) { NumRuntimePointerChecks = Num; }
|
||||
|
||||
bool doesNotMeet(Function *F, Loop *L, const LoopVectorizeHints &Hints) {
|
||||
// If a loop hint is provided the diagnostic is always produced.
|
||||
const char *Name = Hints.isForced() ? DiagnosticInfo::AlwaysPrint : LV_NAME;
|
||||
bool failed = false;
|
||||
|
||||
if (UnsafeAlgebraInst &&
|
||||
Hints.getForce() == LoopVectorizeHints::FK_Undefined &&
|
||||
Hints.getWidth() == 0) {
|
||||
emitOptimizationRemarkAnalysisFPCommute(
|
||||
F->getContext(), DEBUG_TYPE, *F, UnsafeAlgebraInst->getDebugLoc(),
|
||||
F->getContext(), Name, *F, UnsafeAlgebraInst->getDebugLoc(),
|
||||
VectorizationReport() << "vectorization requires changes in the "
|
||||
"order of operations, however IEEE 754 "
|
||||
"floating-point operations are not "
|
||||
@ -1497,7 +1514,7 @@ public:
|
||||
if (NumRuntimePointerChecks >
|
||||
VectorizerParams::RuntimeMemoryCheckThreshold) {
|
||||
emitOptimizationRemarkAnalysisAliasing(
|
||||
F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
|
||||
F->getContext(), Name, *F, L->getStartLoc(),
|
||||
VectorizationReport()
|
||||
<< "cannot prove pointers refer to independent arrays in memory. "
|
||||
"The loop requires "
|
||||
@ -1679,9 +1696,9 @@ struct LoopVectorize : public FunctionPass {
|
||||
DEBUG(dbgs() << " But vectorizing was explicitly forced.\n");
|
||||
else {
|
||||
DEBUG(dbgs() << "\n");
|
||||
emitOptimizationRemarkAnalysis(
|
||||
F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
|
||||
"vectorization is not beneficial and is not explicitly forced");
|
||||
emitAnalysisDiag(F, L, Hints, VectorizationReport()
|
||||
<< "vectorization is not beneficial "
|
||||
"and is not explicitly forced");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1689,7 +1706,7 @@ struct LoopVectorize : public FunctionPass {
|
||||
// Check if it is legal to vectorize the loop.
|
||||
LoopVectorizationRequirements Requirements;
|
||||
LoopVectorizationLegality LVL(L, SE, DT, TLI, AA, F, TTI, LAA,
|
||||
&Requirements);
|
||||
&Requirements, &Hints);
|
||||
if (!LVL.canVectorize()) {
|
||||
DEBUG(dbgs() << "LV: Not vectorizing: Cannot prove legality.\n");
|
||||
emitMissedWarning(F, L, Hints);
|
||||
@ -1724,9 +1741,10 @@ struct LoopVectorize : public FunctionPass {
|
||||
if (F->hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
DEBUG(dbgs() << "LV: Can't vectorize when the NoImplicitFloat"
|
||||
"attribute is used.\n");
|
||||
emitOptimizationRemarkAnalysis(
|
||||
F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
|
||||
"loop not vectorized due to NoImplicitFloat attribute");
|
||||
emitAnalysisDiag(
|
||||
F, L, Hints,
|
||||
VectorizationReport()
|
||||
<< "loop not vectorized due to NoImplicitFloat attribute");
|
||||
emitMissedWarning(F, L, Hints);
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' -pass-remarks-analysis='loop-vectorize' 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' 2>&1 | FileCheck %s
|
||||
|
||||
; C/C++ code for control flow test
|
||||
; int test(int *A, int Length) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt -S -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -pass-remarks-analysis=loop-vectorize < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 < %s 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: remark: {{.*}}: loop not vectorized: value could not be identified as an induction or reduction variable
|
||||
; CHECK: remark: {{.*}}: loop not vectorized: use of induction value outside of the loop is not handled by vectorizer
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' -pass-remarks-analysis='loop-vectorize' 2>&1 | FileCheck %s
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement
|
||||
; CHECK: remark: source.cpp:4:5: loop not vectorized: use -Rpass-analysis=loop-vectorize for more info (Force=true, Vector Width=4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user