mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-27 15:57:30 +00:00
Extend late diagnostics to include late test for runtime pointer checks.
This patch moves checking the threshold of runtime pointer checks to the vectorization requirements (late diagnostics) and emits a diagnostic that infroms the user the loop would be vectorized if not for exceeding the pointer-check threshold. Clang will also append the options that can be used to allow vectorization. llvm-svn: 244523
This commit is contained in:
parent
5df3b56df8
commit
3f1d874bb9
@ -57,6 +57,7 @@ enum DiagnosticKind {
|
||||
DK_OptimizationRemarkMissed,
|
||||
DK_OptimizationRemarkAnalysis,
|
||||
DK_OptimizationRemarkAnalysisFPCommute,
|
||||
DK_OptimizationRemarkAnalysisAliasing,
|
||||
DK_OptimizationFailure,
|
||||
DK_MIRParser,
|
||||
DK_FirstPluginKind
|
||||
@ -421,6 +422,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Diagnostic information for optimization analysis remarks related to
|
||||
/// pointer aliasing.
|
||||
class DiagnosticInfoOptimizationRemarkAnalysisAliasing
|
||||
: public DiagnosticInfoOptimizationRemarkAnalysis {
|
||||
public:
|
||||
/// \p PassName is the name of the pass emitting this diagnostic. If
|
||||
/// this name matches the regular expression given in -Rpass-analysis=, then
|
||||
/// the diagnostic will be emitted. \p Fn is the function where the diagnostic
|
||||
/// is being emitted. \p DLoc is the location information to use in the
|
||||
/// diagnostic. If line table information is available, the diagnostic will
|
||||
/// include the source code location. \p Msg is the message to show. The
|
||||
/// front-end will append its own message related to options that address
|
||||
/// pointer aliasing legality. Note that this class does not copy this
|
||||
/// message, so this reference must be valid for the whole life time of the
|
||||
/// diagnostic.
|
||||
DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName,
|
||||
const Function &Fn,
|
||||
const DebugLoc &DLoc,
|
||||
const Twine &Msg)
|
||||
: DiagnosticInfoOptimizationRemarkAnalysis(
|
||||
DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {}
|
||||
|
||||
static bool classof(const DiagnosticInfo *DI) {
|
||||
return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
|
||||
}
|
||||
};
|
||||
|
||||
/// Diagnostic information for machine IR parser.
|
||||
class DiagnosticInfoMIRParser : public DiagnosticInfo {
|
||||
const SMDiagnostic &Diagnostic;
|
||||
@ -483,6 +511,18 @@ void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
|
||||
const DebugLoc &DLoc,
|
||||
const Twine &Msg);
|
||||
|
||||
/// Emit an optimization analysis remark related to messages about
|
||||
/// pointer aliasing. \p PassName is the name of the pass emitting the message.
|
||||
/// If -Rpass-analysis= is given and \p PassName matches the regular expression
|
||||
/// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
|
||||
/// the remark, \p DLoc is the debug location where the diagnostic is generated.
|
||||
/// \p Msg is the message string to use.
|
||||
void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
|
||||
const char *PassName,
|
||||
const Function &Fn,
|
||||
const DebugLoc &DLoc,
|
||||
const Twine &Msg);
|
||||
|
||||
/// Diagnostic information for optimization failures.
|
||||
class DiagnosticInfoOptimizationFailure
|
||||
: public DiagnosticInfoOptimizationBase {
|
||||
|
@ -205,6 +205,15 @@ void llvm::emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
|
||||
DLoc, Msg));
|
||||
}
|
||||
|
||||
void llvm::emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
|
||||
const char *PassName,
|
||||
const Function &Fn,
|
||||
const DebugLoc &DLoc,
|
||||
const Twine &Msg) {
|
||||
Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysisAliasing(PassName, Fn,
|
||||
DLoc, Msg));
|
||||
}
|
||||
|
||||
bool DiagnosticInfoOptimizationFailure::isEnabled() const {
|
||||
// Only print warnings.
|
||||
return getSeverity() == DS_Warning;
|
||||
|
@ -1435,7 +1435,8 @@ static void emitMissedWarning(Function *F, Loop *L,
|
||||
/// followed by a non-expert user.
|
||||
class LoopVectorizationRequirements {
|
||||
public:
|
||||
LoopVectorizationRequirements() : UnsafeAlgebraInst(nullptr) {}
|
||||
LoopVectorizationRequirements()
|
||||
: NumRuntimePointerChecks(0), UnsafeAlgebraInst(nullptr) {}
|
||||
|
||||
void addUnsafeAlgebraInst(Instruction *I) {
|
||||
// First unsafe algebra instruction.
|
||||
@ -1443,7 +1444,11 @@ public:
|
||||
UnsafeAlgebraInst = I;
|
||||
}
|
||||
|
||||
bool doesNotMeet(Function *F, const LoopVectorizeHints &Hints) {
|
||||
void addRuntimePointerChecks(unsigned Num) { NumRuntimePointerChecks = Num; }
|
||||
|
||||
bool doesNotMeet(Function *F, Loop *L, const LoopVectorizeHints &Hints) {
|
||||
bool failed = false;
|
||||
|
||||
if (UnsafeAlgebraInst &&
|
||||
Hints.getForce() == LoopVectorizeHints::FK_Undefined &&
|
||||
Hints.getWidth() == 0) {
|
||||
@ -1453,12 +1458,29 @@ public:
|
||||
"order of operations, however IEEE 754 "
|
||||
"floating-point operations are not "
|
||||
"commutative");
|
||||
return true;
|
||||
failed = true;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (NumRuntimePointerChecks >
|
||||
VectorizerParams::RuntimeMemoryCheckThreshold) {
|
||||
emitOptimizationRemarkAnalysisAliasing(
|
||||
F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
|
||||
VectorizationReport()
|
||||
<< "cannot prove pointers refer to independent arrays in memory. "
|
||||
"The loop requires "
|
||||
<< NumRuntimePointerChecks
|
||||
<< " runtime independence checks to vectorize the loop, but that "
|
||||
"would exceed the limit of "
|
||||
<< VectorizerParams::RuntimeMemoryCheckThreshold << " checks");
|
||||
DEBUG(dbgs() << "LV: Too many memory checks needed.\n");
|
||||
failed = true;
|
||||
}
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned NumRuntimePointerChecks;
|
||||
Instruction *UnsafeAlgebraInst;
|
||||
};
|
||||
|
||||
@ -1714,7 +1736,7 @@ struct LoopVectorize : public FunctionPass {
|
||||
std::string VecDiagMsg, IntDiagMsg;
|
||||
bool VectorizeLoop = true, InterleaveLoop = true;
|
||||
|
||||
if (Requirements.doesNotMeet(F, Hints)) {
|
||||
if (Requirements.doesNotMeet(F, L, Hints)) {
|
||||
DEBUG(dbgs() << "LV: Not vectorizing: loop did not meet vectorization "
|
||||
"requirements.\n");
|
||||
emitMissedWarning(F, L, Hints);
|
||||
@ -4297,15 +4319,8 @@ bool LoopVectorizationLegality::canVectorizeMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LAI->getNumRuntimePointerChecks() >
|
||||
VectorizerParams::RuntimeMemoryCheckThreshold) {
|
||||
emitAnalysis(VectorizationReport()
|
||||
<< LAI->getNumRuntimePointerChecks() << " exceeds limit of "
|
||||
<< VectorizerParams::RuntimeMemoryCheckThreshold
|
||||
<< " dependent memory operations checked at runtime");
|
||||
DEBUG(dbgs() << "LV: Too many memory checks needed.\n");
|
||||
return false;
|
||||
}
|
||||
Requirements->addRuntimePointerChecks(LAI->getNumRuntimePointerChecks());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,13 @@
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -S | FileCheck %s
|
||||
; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -pass-remarks=loop-vectorize -pass-remarks-missed=loop-vectorize -S 2>&1 | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.8.0"
|
||||
|
||||
; First loop produced diagnostic pass remark.
|
||||
;CHECK: remark: {{.*}}:0:0: vectorized loop (vectorization width: 4, interleaved count: 1)
|
||||
; Second loop produces diagnostic analysis remark.
|
||||
;CHECK: remark: {{.*}}:0:0: loop not vectorized: cannot prove pointers refer to independent arrays in memory. The loop requires 11 runtime independence checks to vectorize the loop, but that would exceed the limit of 8 checks
|
||||
|
||||
; We are vectorizing with 6 runtime checks.
|
||||
;CHECK-LABEL: func1x6(
|
||||
;CHECK: <4 x i32>
|
||||
|
Loading…
x
Reference in New Issue
Block a user