[PATCH] Add warning capabilities in LLVM (backend part)
Quentin Colombet
qcolombet at apple.com
Fri Nov 15 10:34:30 PST 2013
On Nov 15, 2013, at 10:28 AM, Tom Stellard <tom at stellard.net> wrote:
> On Fri, Nov 15, 2013 at 10:17:11AM -0800, Quentin Colombet wrote:
>> Hi dblaikie, echristo, rengolin, chandlerc,
>>
>> Hi,
>>
>> This patch implements the proposal discussed a few months ago (http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/063845.html) regarding adding warning capabilities in LLVM.
>>
>> //// Overview ////
>>
>> The patch adds a new LLVMContext::report that can be used to communicate to the front-end, if any, that something of interest happened.
>> The report contains the following information:
>> - The kind of the report: What this is this about.
>> - The severity of the report: How bad this is.
>> - The default message to print: What should be reported.
>> - A data field: Some meta information.
>>
>> The data field should be used to communicate all sort of data to the front-end. Ultimately, this field should provide enough information to the front-end so that it could build its own diagnostic if it does not want to print the default message.
>> This means that both the back-end and the front-end should agree on the structure of this field based on the pair kind/severity.
>> This feature is not stressed by this patch.
>>
>> This patch introduces a new ReportHandlerTy and a new ReportContext that should be set by the front-end to be able to map these reports in its own diagnostics system.
>
> I like this feature, thanks for working on it. Could it be used as
> a replacement for report_fatal_error() ?
Thanks for asking, this is a great point.
I thought about that and I believe it can, but not everywhere.
Indeed, report_fatal_error does not require a LLVMContext, whereas this approaches does.
Moreover, report_fatal_error does not return, whereas LLVMContext::report may return based on the ferror-limit set in the front-end.
Therefore, we should look into each case to see if it is suitable to switch to this report.
-Quentin
>
> -Tom
>
>>
>> //// Next Steps ////
>>
>> - Send the patch for clang (I have it on hold).
>> - Switch to this reporting for all warnings printing happening in the backend.
>> - Switch the InlineAsmDiagHandler to the new reporting mechanism. This involves a bit of work, especially regarding the meta data.
>>
>> Thanks for your reviews.
>>
>> Cheers,
>> Quentin
>>
>> PS: Sorry for the delay, it took my ages to get to this point in my todolist.
>>
>> http://llvm-reviews.chandlerc.com/D2190
>>
>> Files:
>> include/llvm/IR/LLVMContext.h
>> lib/CodeGen/PrologEpilogInserter.cpp
>> lib/IR/LLVMContext.cpp
>> lib/IR/LLVMContextImpl.cpp
>> lib/IR/LLVMContextImpl.h
>
>> Index: include/llvm/IR/LLVMContext.h
>> ===================================================================
>> --- include/llvm/IR/LLVMContext.h
>> +++ include/llvm/IR/LLVMContext.h
>> @@ -52,6 +52,22 @@
>> MD_invariant_load = 6 // "invariant.load"
>> };
>>
>> + /// Defines the different supported kind of report.
>> + /// \see LLVMContext::report.
>> + enum ReportKind {
>> + RK_InlineAsm,
>> + RK_StackSize,
>> + RK_Other
>> + };
>> +
>> + /// Defines the different supported severity of a report.
>> + /// \see LLVMContext::report.
>> + enum ReportSeverity {
>> + RS_Error,
>> + RS_Warning,
>> + RS_Note
>> + };
>> +
>> /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
>> /// This ID is uniqued across modules in the current LLVMContext.
>> unsigned getMDKindID(StringRef Name) const;
>> @@ -64,6 +80,14 @@
>> typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
>> unsigned LocCookie);
>>
>> + /// Defines the type of a report handler.
>> + /// \see LLVMContext::setReportHandler.
>> + /// \see LLVMContext::report.
>> + typedef void (*ReportHandlerTy)(void *Context, ReportKind Kind,
>> + StringRef StringData,
>> + ReportSeverity Severity,
>> + StringRef Message);
>> +
>> /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
>> /// when problems with inline asm are detected by the backend. The first
>> /// argument is a function pointer and the second is a context pointer that
>> @@ -82,6 +106,40 @@
>> /// setInlineAsmDiagnosticHandler.
>> void *getInlineAsmDiagnosticContext() const;
>>
>> + /// setReportHandler - 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 ReportHandler.
>> + ///
>> + /// LLVMContext doesn't take ownership or interpret either of these
>> + /// pointers.
>> + void setReportHandler(ReportHandlerTy ReportHandler, void *ReportContext = 0);
>> +
>> + /// getReportHandler - Return the diagnostic handler set by
>> + /// setReportHandler.
>> + ReportHandlerTy getReportHandler() const;
>> +
>> + /// getReportContext - Return the diagnostic context set by
>> + /// setReportContext.
>> + void *getReportContext() const;
>> +
>> + /// report - Report a message to the currently installed report handler.
>> + /// This function returns, in particular in the case of error reporting
>> + /// (Severity == RS_Error), so code should be prepared to drop the
>> + /// erroneous construct on the floor and "not crash".
>> + /// The generated code need not be correct.
>> + /// \p Kind is used to precise the kind of report this is about.
>> + /// \p StringData can be used to pass specific information to the report
>> + /// handler, so that it can create its own specific message.
>> + /// \p Severity gives the severity of the report.
>> + /// \p Message is the default message to be printed. It is used when the
>> + /// report handler is not capable to take advantages of \p StringData.
>> + /// The reported message will be implicitly prefixed with the severity
>> + /// keyword, i.e., "error: " for RS_Error, "warning: " for RS_Warning,
>> + /// and "note: " for RS_Note.
>> + /// The message should not end with a ".".
>> + void report(ReportKind Kind, StringRef StringData,
>> + ReportSeverity Severity, StringRef Message);
>>
>> /// emitError - Emit an error message to the currently installed error handler
>> /// with optional location information. This function returns, so code should
>> Index: lib/CodeGen/PrologEpilogInserter.cpp
>> ===================================================================
>> --- lib/CodeGen/PrologEpilogInserter.cpp
>> +++ lib/CodeGen/PrologEpilogInserter.cpp
>> @@ -30,6 +30,7 @@
>> #include "llvm/CodeGen/MachineRegisterInfo.h"
>> #include "llvm/CodeGen/RegisterScavenging.h"
>> #include "llvm/IR/InlineAsm.h"
>> +#include "llvm/IR/LLVMContext.h"
>> #include "llvm/Support/CommandLine.h"
>> #include "llvm/Support/Compiler.h"
>> #include "llvm/Support/Debug.h"
>> @@ -160,10 +161,19 @@
>>
>> // Warn on stack size when we exceeds the given limit.
>> MachineFrameInfo *MFI = Fn.getFrameInfo();
>> + uint64_t StackSize = MFI->getStackSize();
>> if (WarnStackSize.getNumOccurrences() > 0 &&
>> - WarnStackSize < MFI->getStackSize())
>> - errs() << "warning: Stack size limit exceeded (" << MFI->getStackSize()
>> - << ") in " << Fn.getName() << ".\n";
>> + WarnStackSize < StackSize) {
>> + std::string DataStorage;
>> + raw_string_ostream Data(DataStorage);
>> + Data << StackSize;
>> +
>> + std::string MsgStorage("Stack size limit exceeded (");
>> + raw_string_ostream Msg(MsgStorage);
>> + Msg << StackSize << ") in " << Fn.getName();
>> + F->getContext().report(LLVMContext::RK_StackSize, Data.str(),
>> + LLVMContext::RS_Warning, Msg.str());
>> + }
>>
>> delete RS;
>> ReturnBlocks.clear();
>> Index: lib/IR/LLVMContext.cpp
>> ===================================================================
>> --- lib/IR/LLVMContext.cpp
>> +++ lib/IR/LLVMContext.cpp
>> @@ -98,6 +98,22 @@
>> return pImpl->InlineAsmDiagContext;
>> }
>>
>> +void LLVMContext::setReportHandler(ReportHandlerTy ReportHandler,
>> + void *ReportContext) {
>> + pImpl->ReportHandler = ReportHandler;
>> + pImpl->ReportContext = ReportContext;
>> +}
>> +
>> +/// getReportHandler - Return the diagnostic handler set by
>> +/// setReportHandler.
>> +LLVMContext::ReportHandlerTy LLVMContext::getReportHandler() const {
>> + return pImpl->ReportHandler;
>> +}
>> +
>> +/// getReportContext - Return the diagnostic context set by
>> +/// setReportContext.
>> +void *LLVMContext::getReportContext() const { return pImpl->ReportContext; }
>> +
>> void LLVMContext::emitError(const Twine &ErrorStr) {
>> emitError(0U, ErrorStr);
>> }
>> @@ -112,6 +128,29 @@
>> return emitError(LocCookie, ErrorStr);
>> }
>>
>> +void LLVMContext::report(ReportKind Kind, StringRef StringData,
>> + ReportSeverity Severity,
>> + StringRef Message) {
>> + // If there is a report handler, use it.
>> + if (pImpl->ReportHandler != 0) {
>> + pImpl->ReportHandler(pImpl->ReportContext, Kind, StringData, Severity,
>> + Message);
>> + return;
>> + }
>> + // Otherwise, print the message with a prefix based on the severity.
>> + switch (Severity) {
>> + case RS_Error:
>> + errs() << "error: " << Message << "\n";
>> + exit(1);
>> + case RS_Warning:
>> + errs() << "warning: " << Message << "\n";
>> + break;
>> + case RS_Note:
>> + errs() << "note: " << Message << "\n";
>> + break;
>> + }
>> +}
>> +
>> void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
>> // If there is no error handler installed, just print the error and exit.
>> if (pImpl->InlineAsmDiagHandler == 0) {
>> Index: lib/IR/LLVMContextImpl.cpp
>> ===================================================================
>> --- lib/IR/LLVMContextImpl.cpp
>> +++ lib/IR/LLVMContextImpl.cpp
>> @@ -37,6 +37,8 @@
>> Int64Ty(C, 64) {
>> InlineAsmDiagHandler = 0;
>> InlineAsmDiagContext = 0;
>> + ReportHandler = 0;
>> + ReportContext = 0;
>> NamedStructTypesUniqueID = 0;
>> }
>>
>> Index: lib/IR/LLVMContextImpl.h
>> ===================================================================
>> --- lib/IR/LLVMContextImpl.h
>> +++ lib/IR/LLVMContextImpl.h
>> @@ -238,8 +238,11 @@
>>
>> LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler;
>> void *InlineAsmDiagContext;
>> -
>> - typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
>> +
>> + LLVMContext::ReportHandlerTy ReportHandler;
>> + void *ReportContext;
>> +
>> + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *,
>> DenseMapAPIntKeyInfo> IntMapTy;
>> IntMapTy IntConstants;
>>
>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131115/716c93d3/attachment.html>
More information about the llvm-commits
mailing list