1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02: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:
Tyler Nowicki 2015-08-10 23:01:55 +00:00
parent 5df3b56df8
commit 3f1d874bb9
4 changed files with 84 additions and 15 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}

View File

@ -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>