[PATCH] Add warning capabilities in LLVM (backend part)

Tom Stellard tom at stellard.net
Fri Nov 15 10:28:03 PST 2013


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() ?

-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




More information about the llvm-commits mailing list