Skip to content
Snippets Groups Projects
Commit f123d908 authored by Tyler Nowicki's avatar Tyler Nowicki
Browse files

Recommit: Handle diagnostic warnings in Frontend diagnostic handler.

Clang uses a diagnostic handler to grab diagnostic messages so it can print them
with the line of source code they refer to. This patch extends this to handle
optimization failures that were added to llvm to produce a warning when
loop vectorization is explicitly specified (using a pragma clang loop directive)
but fails.

Update renames warning flag name to avoid indicating the flag's severity and
adds a test.

Reviewed by Alp Toker



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213400 91177308-0d34-0410-b5e6-96231b3b80d8
parent a627c561
No related branches found
No related tags found
No related merge requests found
...@@ -41,6 +41,8 @@ def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo, ...@@ -41,6 +41,8 @@ def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
InGroup<BackendOptimizationRemarkMissed>, DefaultRemark; InGroup<BackendOptimizationRemarkMissed>, DefaultRemark;
def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo, def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo,
InGroup<BackendOptimizationRemarkAnalysis>, DefaultRemark; InGroup<BackendOptimizationRemarkAnalysis>, DefaultRemark;
def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
InGroup<BackendOptimizationFailure>, DefaultWarn;
def note_fe_backend_optimization_remark_invalid_loc : Note<"could " def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
"not determine the original source location for %0:%1:%2">; "not determine the original source location for %0:%1:%2">;
......
...@@ -704,6 +704,7 @@ def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">; ...@@ -704,6 +704,7 @@ def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
def BackendOptimizationRemark : DiagGroup<"pass">; def BackendOptimizationRemark : DiagGroup<"pass">;
def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">; def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">; def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
def BackendOptimizationFailure : DiagGroup<"pass-failed">;
// Instrumentation based profiling warnings. // Instrumentation based profiling warnings.
def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">; def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
......
...@@ -238,15 +238,16 @@ namespace clang { ...@@ -238,15 +238,16 @@ namespace clang {
/// \brief Specialized handlers for optimization remarks. /// \brief Specialized handlers for optimization remarks.
/// Note that these handlers only accept remarks and they always handle /// Note that these handlers only accept remarks and they always handle
/// them. /// them.
void void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
EmitOptimizationRemark(const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID);
unsigned DiagID);
void void
OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D);
void OptimizationRemarkHandler( void OptimizationRemarkHandler(
const llvm::DiagnosticInfoOptimizationRemarkMissed &D); const llvm::DiagnosticInfoOptimizationRemarkMissed &D);
void OptimizationRemarkHandler( void OptimizationRemarkHandler(
const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D); const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D);
void OptimizationFailureHandler(
const llvm::DiagnosticInfoOptimizationFailure &D);
}; };
void BackendConsumer::anchor() {} void BackendConsumer::anchor() {}
...@@ -416,10 +417,11 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { ...@@ -416,10 +417,11 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
return false; return false;
} }
void BackendConsumer::EmitOptimizationRemark( void BackendConsumer::EmitOptimizationMessage(
const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
// We only support remarks. // We only support warnings and remarks.
assert(D.getSeverity() == llvm::DS_Remark); assert(D.getSeverity() == llvm::DS_Remark ||
D.getSeverity() == llvm::DS_Warning);
SourceManager &SourceMgr = Context->getSourceManager(); SourceManager &SourceMgr = Context->getSourceManager();
FileManager &FileMgr = SourceMgr.getFileManager(); FileManager &FileMgr = SourceMgr.getFileManager();
...@@ -442,8 +444,9 @@ void BackendConsumer::EmitOptimizationRemark( ...@@ -442,8 +444,9 @@ void BackendConsumer::EmitOptimizationRemark(
if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace()); Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());
Diags.Report(Loc, DiagID) << AddFlagValue(D.getPassName()) Diags.Report(Loc, DiagID)
<< D.getMsg().str(); << AddFlagValue(D.getPassName() ? D.getPassName() : "")
<< D.getMsg().str();
if (DILoc.isInvalid()) if (DILoc.isInvalid())
// If we were not able to translate the file:line:col information // If we were not able to translate the file:line:col information
...@@ -460,7 +463,7 @@ void BackendConsumer::OptimizationRemarkHandler( ...@@ -460,7 +463,7 @@ void BackendConsumer::OptimizationRemarkHandler(
// expression that matches the name of the pass name in \p D. // expression that matches the name of the pass name in \p D.
if (CodeGenOpts.OptimizationRemarkPattern && if (CodeGenOpts.OptimizationRemarkPattern &&
CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
EmitOptimizationRemark(D, diag::remark_fe_backend_optimization_remark); EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
} }
void BackendConsumer::OptimizationRemarkHandler( void BackendConsumer::OptimizationRemarkHandler(
...@@ -470,8 +473,8 @@ void BackendConsumer::OptimizationRemarkHandler( ...@@ -470,8 +473,8 @@ void BackendConsumer::OptimizationRemarkHandler(
// name in \p D. // name in \p D.
if (CodeGenOpts.OptimizationRemarkMissedPattern && if (CodeGenOpts.OptimizationRemarkMissedPattern &&
CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName())) CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
EmitOptimizationRemark(D, EmitOptimizationMessage(D,
diag::remark_fe_backend_optimization_remark_missed); diag::remark_fe_backend_optimization_remark_missed);
} }
void BackendConsumer::OptimizationRemarkHandler( void BackendConsumer::OptimizationRemarkHandler(
...@@ -481,10 +484,15 @@ void BackendConsumer::OptimizationRemarkHandler( ...@@ -481,10 +484,15 @@ void BackendConsumer::OptimizationRemarkHandler(
// name in \p D. // name in \p D.
if (CodeGenOpts.OptimizationRemarkAnalysisPattern && if (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())) CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))
EmitOptimizationRemark( EmitOptimizationMessage(
D, diag::remark_fe_backend_optimization_remark_analysis); D, diag::remark_fe_backend_optimization_remark_analysis);
} }
void BackendConsumer::OptimizationFailureHandler(
const llvm::DiagnosticInfoOptimizationFailure &D) {
EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
}
/// \brief This function is invoked when the backend needs /// \brief This function is invoked when the backend needs
/// to report something to the user. /// to report something to the user.
void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
...@@ -518,6 +526,11 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { ...@@ -518,6 +526,11 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
OptimizationRemarkHandler( OptimizationRemarkHandler(
cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI));
return; return;
case llvm::DK_OptimizationFailure:
// Optimization failures are always handled completely by this
// handler.
OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
return;
default: default:
// Plugin IDs are not bound to any value as they are set dynamically. // Plugin IDs are not bound to any value as they are set dynamically.
ComputeDiagRemarkID(Severity, backend_plugin, DiagID); ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
......
// RUN: %clang_cc1 %s -O3 -emit-llvm -gline-tables-only -S -verify -o /dev/null
// Test verifies optimization failures generated by the backend are handled
// correctly by clang. LLVM tests verify all of the failure conditions.
void test_switch(int *A, int *B, int Length) {
#pragma clang loop vectorize(enable) unroll(disable)
for (int i = 0; i < Length; i++) {
/* expected-warning {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) {
case 0:
B[i] = 1;
break;
case 1:
B[i] = 2;
break;
default:
B[i] = 3;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment