diff options
| -rw-r--r-- | llvm/include/llvm/IR/LLVMContext.h | 6 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContext.cpp | 31 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 1 | ||||
| -rw-r--r-- | llvm/lib/LTO/LTOCodeGenerator.cpp | 2 | ||||
| -rw-r--r-- | llvm/test/LTO/diagnostic-handler-remarks.ll | 38 | ||||
| -rw-r--r-- | llvm/tools/llvm-lto/llvm-lto.cpp | 26 |
7 files changed, 91 insertions, 14 deletions
diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h index 2914caaf51c..cdd2150153f 100644 --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -99,12 +99,14 @@ public: /// setDiagnosticHandler - This method sets a handler that is invoked /// when the backend needs to report anything to the user. The first /// argument is a function pointer and the second is a context pointer that - /// gets passed into the DiagHandler. + /// gets passed into the DiagHandler. The third argument should be set to + /// true if the handler only expects enabled diagnostics. /// /// LLVMContext doesn't take ownership or interpret either of these /// pointers. void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler, - void *DiagContext = nullptr); + void *DiagContext = nullptr, + bool RespectFilters = false); /// getDiagnosticHandler - Return the diagnostic handler set by /// setDiagnosticHandler. diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp index d4ba83dfa62..73ddc8cbe20 100644 --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -112,9 +112,11 @@ void *LLVMContext::getInlineAsmDiagnosticContext() const { } void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, - void *DiagnosticContext) { + void *DiagnosticContext, + bool RespectFilters) { pImpl->DiagnosticHandler = DiagnosticHandler; pImpl->DiagnosticContext = DiagnosticContext; + pImpl->RespectDiagnosticFilters = RespectFilters; } LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { @@ -145,13 +147,7 @@ void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); } -void LLVMContext::diagnose(const DiagnosticInfo &DI) { - // If there is a report handler, use it. - if (pImpl->DiagnosticHandler) { - pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); - return; - } - +static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { // Optimization remarks are selective. They need to check whether the regexp // pattern, passed via one of the -pass-remarks* flags, matches the name of // the pass that is emitting the diagnostic. If there is no match, ignore the @@ -159,19 +155,32 @@ void LLVMContext::diagnose(const DiagnosticInfo &DI) { switch (DI.getKind()) { case llvm::DK_OptimizationRemark: if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled()) - return; + return false; break; case llvm::DK_OptimizationRemarkMissed: if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled()) - return; + return false; break; case llvm::DK_OptimizationRemarkAnalysis: if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled()) - return; + return false; break; default: break; } + return true; +} + +void LLVMContext::diagnose(const DiagnosticInfo &DI) { + // If there is a report handler, use it. + if (pImpl->DiagnosticHandler) { + if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) + pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); + return; + } + + if (!isDiagnosticEnabled(DI)) + return; // Otherwise, print the message with a prefix based on the severity. std::string MsgStorage; diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index 6513965ae7a..09bf6b123a9 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -40,6 +40,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) InlineAsmDiagContext = nullptr; DiagnosticHandler = nullptr; DiagnosticContext = nullptr; + RespectDiagnosticFilters = false; YieldCallback = nullptr; YieldOpaqueHandle = nullptr; NamedStructTypesUniqueID = 0; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index b376064d2ed..bd0097c31ba 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -244,6 +244,7 @@ public: LLVMContext::DiagnosticHandlerTy DiagnosticHandler; void *DiagnosticContext; + bool RespectDiagnosticFilters; LLVMContext::YieldCallbackTy YieldCallback; void *YieldOpaqueHandle; diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 1b6f905f0ac..75ca56fbbe7 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -558,5 +558,5 @@ LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, return Context.setDiagnosticHandler(nullptr, nullptr); // Register the LTOCodeGenerator stub in the LLVMContext to forward the // diagnostic to the external DiagHandler. - Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this); + Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this, true); } diff --git a/llvm/test/LTO/diagnostic-handler-remarks.ll b/llvm/test/LTO/diagnostic-handler-remarks.ll new file mode 100644 index 00000000000..bc3ce2541e1 --- /dev/null +++ b/llvm/test/LTO/diagnostic-handler-remarks.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s >%t.bc +; PR21108: Diagnostic handlers get pass remarks, even if they're not enabled. + +; Confirm that there are -pass-remarks. +; RUN: llvm-lto -pass-remarks=inline \ +; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty -check-prefix=REMARKS +; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM + +; RUN: llvm-lto -pass-remarks=inline -use-diagnostic-handler \ +; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty -check-prefix=REMARKS +; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM + +; Confirm that -pass-remarks are not printed by default. +; RUN: llvm-lto \ +; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM + +; RUN: llvm-lto -use-diagnostic-handler \ +; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; RUN: llvm-nm %t.o | FileCheck %s -check-prefix NM + +; REMARKS: remark: +; CHECK-NOT: remark: +; NM-NOT: foo +; NM: main + +define i32 @foo() { + ret i32 7 +} + +define i32 @main() { + %i = call i32 @foo() + ret i32 %i +} diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp index 2f19090dfc9..2bfd9594555 100644 --- a/llvm/tools/llvm-lto/llvm-lto.cpp +++ b/llvm/tools/llvm-lto/llvm-lto.cpp @@ -38,6 +38,10 @@ static cl::opt<bool> DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), cl::desc("Do not run the GVN load PRE pass")); +static cl::opt<bool> +UseDiagnosticHandler("use-diagnostic-handler", cl::init(false), + cl::desc("Use a diagnostic handler to test the handler interface")); + static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, cl::desc("<input bitcode files>")); @@ -63,6 +67,25 @@ struct ModuleInfo { }; } +void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity, + const char *Msg, void *) { + switch (Severity) { + case LTO_DS_NOTE: + errs() << "note: "; + break; + case LTO_DS_REMARK: + errs() << "remark: "; + break; + case LTO_DS_ERROR: + errs() << "error: "; + break; + case LTO_DS_WARNING: + errs() << "warning: "; + break; + } + errs() << Msg << "\n"; +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -84,6 +107,9 @@ int main(int argc, char **argv) { LTOCodeGenerator CodeGen; + if (UseDiagnosticHandler) + CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); + switch (RelocModel) { case Reloc::Static: CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_STATIC); |

