[llvm] r313390 - This patch fixes https://bugs.llvm.org/show_bug.cgi?id=32352

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 16:47:56 PST 2017


Vivek Pandya via llvm-commits <llvm-commits at lists.llvm.org> writes:
> Author: vivekvpandya
> Date: Fri Sep 15 13:10:09 2017
> New Revision: 313390
>
> URL: http://llvm.org/viewvc/llvm-project?rev=313390&view=rev
> Log:
> This patch fixes https://bugs.llvm.org/show_bug.cgi?id=32352 
> It enables OptimizationRemarkEmitter::allowExtraAnalysis and
> MachineOptimizationRemarkEmitter::allowExtraAnalysis to return true
> not only for -fsave-optimization-record but when specific remarks are
> requested with
> command line options.
> The diagnostic handler used to be callback now this patch adds a class
> DiagnosticHandler. It has virtual method to provide custom diagnostic handler
> and methods to control which particular remarks are enabled. 
> However LLVM-C API users can still provide callback function for
> diagnostic handler.

Sorry to reply to this so late - I hadn't seen it earlier.

> Modified: llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
>
> --- llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h (original)
> +++ llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h Fri Sep 15 13:10:09 2017
> @@ -67,8 +67,8 @@ public:
>    bool invalidate(Function &F, const PreservedAnalyses &PA,
>                    FunctionAnalysisManager::Invalidator &Inv);
>  
> -  /// \brief Output the remark to the optimization record file.  Also send it to
> -  /// the diagnostic handler if remarks are requested for the pass.
> +  /// \brief Output the remark via the diagnostic handler and to the
> +  /// optimization record file.
>    void emit(DiagnosticInfoOptimizationBase &OptDiag);
>  
>    /// \brief Whether we allow for extra compile-time budget to perform more
> @@ -78,10 +78,9 @@ public:
>    /// use the extra analysis (1) to filter trivial false positives or (2) to
>    /// provide more context so that non-trivial false positives can be quickly
>    /// detected by the user.
> -  bool allowExtraAnalysis() const {
> -    // For now, only allow this with -fsave-optimization-record since the -Rpass
> -    // options are handled in the front-end.
> -    return F->getContext().getDiagnosticsOutputFile();
> +  bool allowExtraAnalysis(StringRef PassName) const {
> +    return (F->getContext().getDiagnosticsOutputFile() ||
> +            F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
>    }
>  
>  private:
>
> Modified: llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h Fri Sep 15 13:10:09 2017
> @@ -73,7 +73,9 @@ public:
>  
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
>    bool isEnabled() const override {
> -    return OptimizationRemark::isEnabled(getPassName());
> +    const Function &Fn = getFunction();
> +    LLVMContext &Ctx = Fn.getContext();
> +    return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
>    }
>  };
>  
> @@ -97,7 +99,9 @@ public:
>  
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
>    bool isEnabled() const override {
> -    return OptimizationRemarkMissed::isEnabled(getPassName());
> +    const Function &Fn = getFunction();
> +    LLVMContext &Ctx = Fn.getContext();
> +    return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
>    }
>  };
>  
> @@ -121,7 +125,9 @@ public:
>  
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
>    bool isEnabled() const override {
> -    return OptimizationRemarkAnalysis::isEnabled(getPassName());
> +    const Function &Fn = getFunction();
> +    LLVMContext &Ctx = Fn.getContext();
> +    return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
>    }
>  };
>  
> @@ -152,10 +158,10 @@ public:
>    /// that are normally too noisy.  In this mode, we can use the extra analysis
>    /// (1) to filter trivial false positives or (2) to provide more context so
>    /// that non-trivial false positives can be quickly detected by the user.
> -  bool allowExtraAnalysis() const {
> -    // For now, only allow this with -fsave-optimization-record since the -Rpass
> -    // options are handled in the front-end.
> -    return MF.getFunction()->getContext().getDiagnosticsOutputFile();
> +  bool allowExtraAnalysis(StringRef PassName) const {
> +    return (MF.getFunction()->getContext().getDiagnosticsOutputFile() ||
> +            MF.getFunction()->getContext()
> +            .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
>    }
>  
>  private:
>
> Added: llvm/trunk/include/llvm/IR/DiagnosticHandler.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DiagnosticHandler.h?rev=313390&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/DiagnosticHandler.h (added)
> +++ llvm/trunk/include/llvm/IR/DiagnosticHandler.h Fri Sep 15 13:10:09 2017
> @@ -0,0 +1,67 @@
> +//===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -*- C++ ---*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +// Base DiagnosticHandler class declaration. Derive from this class to provide
> +// custom diagnostic reporting.
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/ADT/StringRef.h"
> +
> +namespace llvm {
> +class DiagnosticInfo;
> +
> +/// \brief This is the base class for diagnostic handling in LLVM.
> +/// The handleDiagnostics method must be overriden by the subclasses to handle
> +/// diagnostic. The *RemarkEnabled methods can be overriden to control
> +/// which remarks are enabled.
> +struct DiagnosticHandler {
> +  void *DiagnosticContext = nullptr;
> +  DiagnosticHandler(void *DiagContext = nullptr)
> +      : DiagnosticContext(DiagContext) {}

It seems unfortunate that we're imposing an extra pointer of storage on
every subclass here for the DiagnosticContext, which is only ever used
by the C API / generic callback user. Wouldn't it be better to have a
subclass specifically for setDiagnosticHandlerCallBack that does this?

> +  virtual ~DiagnosticHandler() = default;
> +
> +  using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
> +
> +  /// DiagHandlerCallback is settable from the C API and base implementation
> +  /// of DiagnosticHandler will call it from handleDiagnostics(). Any derived
> +  /// class of DiagnosticHandler should not use callback but
> +  /// implement handleDiagnostics().
> +  DiagnosticHandlerTy DiagHandlerCallback = nullptr;
> +
> +  /// Override handleDiagnostics to provide custom implementation.
> +  /// Return true if it handles diagnostics reporting properly otherwise
> +  /// return false to make LLVMContext::diagnose() to print the message
> +  /// with a prefix based on the severity.
> +  virtual bool handleDiagnostics(const DiagnosticInfo &DI) {
> +    if (DiagHandlerCallback) {
> +      DiagHandlerCallback(DI, DiagnosticContext);
> +      return true;
> +    }
> +    return false;
> +  }
> +
> +  /// Return true if analysis remarks are enabled, override
> +  /// to provide different implementation.
> +  virtual bool isAnalysisRemarkEnabled(StringRef PassName) const;
> +
> +  /// Return true if missed optimization remarks are enabled, override
> +  /// to provide different implementation.
> +  virtual bool isMissedOptRemarkEnabled(StringRef PassName) const;
> +
> +  /// Return true if passed optimization remarks are enabled, override
> +  /// to provide different implementation.
> +  virtual bool isPassedOptRemarkEnabled(StringRef PassName) const;
> +
> +  /// Return true if any type of remarks are enabled.
> +  bool isAnyRemarkEnabled(StringRef PassName) const {
> +    return (isMissedOptRemarkEnabled(PassName) ||
> +            isPassedOptRemarkEnabled(PassName) ||
> +            isAnalysisRemarkEnabled(PassName));
> +  }
> +};
> +}
>
> Modified: llvm/trunk/include/llvm/IR/DiagnosticInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DiagnosticInfo.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/DiagnosticInfo.h (original)
> +++ llvm/trunk/include/llvm/IR/DiagnosticInfo.h Fri Sep 15 13:10:09 2017
> @@ -604,10 +604,8 @@ public:
>      return DI->getKind() == DK_OptimizationRemark;
>    }
>  
> -  static bool isEnabled(StringRef PassName);
> -
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
> -  bool isEnabled() const override { return isEnabled(getPassName()); }
> +  bool isEnabled() const override;
>  
>  private:
>    /// This is deprecated now and only used by the function API below.
> @@ -647,10 +645,8 @@ public:
>      return DI->getKind() == DK_OptimizationRemarkMissed;
>    }
>  
> -  static bool isEnabled(StringRef PassName);
> -
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
> -  bool isEnabled() const override { return isEnabled(getPassName()); }
> +  bool isEnabled() const override;
>  
>  private:
>    /// This is deprecated now and only used by the function API below.
> @@ -701,12 +697,8 @@ public:
>      return DI->getKind() == DK_OptimizationRemarkAnalysis;
>    }
>  
> -  static bool isEnabled(StringRef PassName);
> -
>    /// \see DiagnosticInfoOptimizationBase::isEnabled.
> -  bool isEnabled() const override {
> -    return shouldAlwaysPrint() || isEnabled(getPassName());
> -  }
> +  bool isEnabled() const override;
>  
>    static const char *AlwaysPrint;
>  
>
> Modified: llvm/trunk/include/llvm/IR/LLVMContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
> +++ llvm/trunk/include/llvm/IR/LLVMContext.h Fri Sep 15 13:10:09 2017
> @@ -16,6 +16,7 @@
>  #define LLVM_IR_LLVMCONTEXT_H
>  
>  #include "llvm-c/Types.h"
> +#include "llvm/IR/DiagnosticHandler.h"
>  #include "llvm/Support/CBindingWrapping.h"
>  #include "llvm/Support/Options.h"
>  #include <cstdint>
> @@ -167,11 +168,6 @@ public:
>    using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context,
>                                            unsigned LocCookie);
>  
> -  /// Defines the type of a diagnostic handler.
> -  /// \see LLVMContext::setDiagnosticHandler.
> -  /// \see LLVMContext::diagnose.
> -  using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
> -
>    /// Defines the type of a yield callback.
>    /// \see LLVMContext::setYieldCallback.
>    using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
> @@ -194,26 +190,43 @@ public:
>    /// setInlineAsmDiagnosticHandler.
>    void *getInlineAsmDiagnosticContext() const;
>  
> -  /// 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.  The third argument should be set to
> +  /// setDiagnosticHandlerCallBack - This method sets a handler call back
> +  /// 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.  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 setDiagnosticHandlerCallBack(
> +      DiagnosticHandler::DiagnosticHandlerTy DiagHandler,
> +      void *DiagContext = nullptr, bool RespectFilters = false);
> +
> +  /// setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler
> +  /// to provide custom diagnostic handling. The first argument is unique_ptr of object
> +  /// of type DiagnosticHandler or a derived of that.   The third argument should be

There are a number of long lines in this file, mostly in doc comments.
Please stick to 80 columns.

> +  /// set to true if the handler only expects enabled diagnostics.
> +  ///
> +  /// Ownership of this pointer is moved to LLVMContextImpl.
> +  void setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
>                              bool RespectFilters = false);
>  
> -  /// getDiagnosticHandler - Return the diagnostic handler set by
> -  /// setDiagnosticHandler.
> -  DiagnosticHandlerTy getDiagnosticHandler() const;
> +  /// getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by
> +  /// setDiagnosticHandlerCallBack.
> +  DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const;
>  
>    /// getDiagnosticContext - Return the diagnostic context set by
>    /// setDiagnosticContext.
>    void *getDiagnosticContext() const;

This API should be removed. It only makes sense to use in the generic
callback case, and even then you probably don't need it because
handleDiagnostics marshals it to the function for you.

>  
> +  /// getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by
> +  /// setDiagnosticHandler.
> +  const DiagnosticHandler *getDiagHandlerPtr() const;
> +
> +  /// getDiagnosticHandler - transfers owenership of DiagnosticHandler unique_ptr
> +  /// to caller.
> +  std::unique_ptr<DiagnosticHandler> getDiagnosticHandler();

This change is unnecessarily hostile to users of the API, for two
reasons:

1. You've made a dangerous semantic change to a function without
   changing its name. Consider some code that did something like this:

     if (Ctx.getDiagnosticHandler()) {
       // do something here
     }

   or even just:

     auto DH = Ctx.getDiagnosticHandler()

   These would previously get an unowned pointer, but now take
   ownership. In the first case, this will almost certainly lead to
   use-after-free bugs.

2. It's surprising for a function called "get" to transfer ownership. It
   should probably be called takeDiagnosticHandler, or something like
   that.

If nothing else, we should definitely rename this function to avoid
breaking existing code in confusing and hard to debug ways.

> +
>    /// \brief Return if a code hotness metric should be included in optimization
>    /// diagnostics.
>    bool getDiagnosticsHotnessRequested() const;
>
> Modified: llvm/trunk/include/llvm/LTO/Config.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/Config.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LTO/Config.h (original)
> +++ llvm/trunk/include/llvm/LTO/Config.h Fri Sep 15 13:10:09 2017
> @@ -171,20 +171,27 @@ struct Config {
>                       bool UseInputModulePath = false);
>  };
>  
> +struct LTOLLVMDiagnosticHandler : public DiagnosticHandler {
> +  DiagnosticHandlerFunction *Fn;
> +  LTOLLVMDiagnosticHandler(DiagnosticHandlerFunction *DiagHandlerFn)
> +      : Fn(DiagHandlerFn) {}
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    (*Fn)(DI);
> +    return true;
> +  }
> +};
>  /// A derived class of LLVMContext that initializes itself according to a given
>  /// Config object. The purpose of this class is to tie ownership of the
>  /// diagnostic handler to the context, as opposed to the Config object (which
>  /// may be ephemeral).
> +// FIXME: This should not be required as diagnostic handler is not callback.
>  struct LTOLLVMContext : LLVMContext {
> -  static void funcDiagHandler(const DiagnosticInfo &DI, void *Context) {
> -    auto *Fn = static_cast<DiagnosticHandlerFunction *>(Context);
> -    (*Fn)(DI);
> -  }
>  
>    LTOLLVMContext(const Config &C) : DiagHandler(C.DiagHandler) {
>      setDiscardValueNames(C.ShouldDiscardValueNames);
>      enableDebugTypeODRUniquing();
> -    setDiagnosticHandler(funcDiagHandler, &DiagHandler, true);
> +    setDiagnosticHandler(
> +        llvm::make_unique<LTOLLVMDiagnosticHandler>(&DiagHandler), true);
>    }
>    DiagnosticHandlerFunction DiagHandler;
>  };
>
> Modified: llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h (original)
> +++ llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h Fri Sep 15 13:10:09 2017
> @@ -184,6 +184,7 @@ struct LTOCodeGenerator {
>    LLVMContext &getContext() { return Context; }
>  
>    void resetMergedModule() { MergedModule.reset(); }
> +  void DiagnosticHandler(const DiagnosticInfo &DI);
>  
>  private:
>    void initializeLTOPasses();
> @@ -204,10 +205,6 @@ private:
>    bool determineTarget();
>    std::unique_ptr<TargetMachine> createTargetMachine();
>  
> -  static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);
> -
> -  void DiagnosticHandler2(const DiagnosticInfo &DI);
> -
>    void emitError(const std::string &ErrMsg);
>    void emitWarning(const std::string &ErrMsg);
>  
>
> Modified: llvm/trunk/lib/IR/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/CMakeLists.txt?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/CMakeLists.txt (original)
> +++ llvm/trunk/lib/IR/CMakeLists.txt Fri Sep 15 13:10:09 2017
> @@ -17,6 +17,7 @@ add_llvm_library(LLVMCore
>    DebugInfo.cpp
>    DebugInfoMetadata.cpp
>    DebugLoc.cpp
> +  DiagnosticHandler.cpp
>    DiagnosticInfo.cpp
>    DiagnosticPrinter.cpp
>    Dominators.cpp
>
> Modified: llvm/trunk/lib/IR/Core.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/Core.cpp (original)
> +++ llvm/trunk/lib/IR/Core.cpp Fri Sep 15 13:10:09 2017
> @@ -85,15 +85,15 @@ LLVMContextRef LLVMGetGlobalContext() {
>  void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
>                                       LLVMDiagnosticHandler Handler,
>                                       void *DiagnosticContext) {
> -  unwrap(C)->setDiagnosticHandler(
> -      LLVM_EXTENSION reinterpret_cast<LLVMContext::DiagnosticHandlerTy>(
> +  unwrap(C)->setDiagnosticHandlerCallBack(
> +      LLVM_EXTENSION reinterpret_cast<DiagnosticHandler::DiagnosticHandlerTy>(
>            Handler),
>        DiagnosticContext);
>  }
>  
>  LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C) {
>    return LLVM_EXTENSION reinterpret_cast<LLVMDiagnosticHandler>(
> -      unwrap(C)->getDiagnosticHandler());
> +      unwrap(C)->getDiagnosticHandlerCallBack());
>  }
>  
>  void *LLVMContextGetDiagnosticContext(LLVMContextRef C) {
>
> Added: llvm/trunk/lib/IR/DiagnosticHandler.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DiagnosticHandler.cpp?rev=313390&view=auto
> ==============================================================================
> --- llvm/trunk/lib/IR/DiagnosticHandler.cpp (added)
> +++ llvm/trunk/lib/IR/DiagnosticHandler.cpp Fri Sep 15 13:10:09 2017
> @@ -0,0 +1,86 @@
> +//===- DiagnosticHandler.h - DiagnosticHandler class for LLVM -------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +//
> +//===----------------------------------------------------------------------===//
> +#include "llvm/IR/DiagnosticHandler.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/Regex.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +
> +/// \brief Regular expression corresponding to the value given in one of the
> +/// -pass-remarks* command line flags. Passes whose name matches this regexp
> +/// will emit a diagnostic when calling the associated diagnostic function
> +/// (emitOptimizationRemark, emitOptimizationRemarkMissed or
> +/// emitOptimizationRemarkAnalysis).
> +struct PassRemarksOpt {
> +  std::shared_ptr<Regex> Pattern;
> +
> +  void operator=(const std::string &Val) {
> +    // Create a regexp object to match pass names for emitOptimizationRemark.
> +    if (!Val.empty()) {
> +      Pattern = std::make_shared<Regex>(Val);
> +      std::string RegexError;
> +      if (!Pattern->isValid(RegexError))
> +        report_fatal_error("Invalid regular expression '" + Val +
> +                               "' in -pass-remarks: " + RegexError,
> +                           false);
> +    }
> +  }
> +};
> +
> +static PassRemarksOpt PassRemarksPassedOptLoc;
> +static PassRemarksOpt PassRemarksMissedOptLoc;
> +static PassRemarksOpt PassRemarksAnalysisOptLoc;
> +
> +// -pass-remarks
> +//    Command line flag to enable emitOptimizationRemark()
> +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarks(
> +    "pass-remarks", cl::value_desc("pattern"),
> +    cl::desc("Enable optimization remarks from passes whose name match "
> +             "the given regular expression"),
> +    cl::Hidden, cl::location(PassRemarksPassedOptLoc), cl::ValueRequired,
> +    cl::ZeroOrMore);
> +
> +// -pass-remarks-missed
> +//    Command line flag to enable emitOptimizationRemarkMissed()
> +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
> +    "pass-remarks-missed", cl::value_desc("pattern"),
> +    cl::desc("Enable missed optimization remarks from passes whose name match "
> +             "the given regular expression"),
> +    cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
> +    cl::ZeroOrMore);
> +
> +// -pass-remarks-analysis
> +//    Command line flag to enable emitOptimizationRemarkAnalysis()
> +static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
> +    PassRemarksAnalysis(
> +        "pass-remarks-analysis", cl::value_desc("pattern"),
> +        cl::desc(
> +            "Enable optimization analysis remarks from passes whose name match "
> +            "the given regular expression"),
> +        cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
> +        cl::ZeroOrMore);
> +}
> +
> +bool DiagnosticHandler::isAnalysisRemarkEnabled(StringRef PassName) const {
> +  return (PassRemarksAnalysisOptLoc.Pattern &&
> +          PassRemarksAnalysisOptLoc.Pattern->match(PassName));
> +}
> +bool DiagnosticHandler::isMissedOptRemarkEnabled(StringRef PassName) const {
> +  return (PassRemarksMissedOptLoc.Pattern &&
> +          PassRemarksMissedOptLoc.Pattern->match(PassName));
> +}
> +bool DiagnosticHandler::isPassedOptRemarkEnabled(StringRef PassName) const {
> +  return (PassRemarksPassedOptLoc.Pattern &&
> +          PassRemarksPassedOptLoc.Pattern->match(PassName));
> +}
>
> Modified: llvm/trunk/lib/IR/DiagnosticInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DiagnosticInfo.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/DiagnosticInfo.cpp (original)
> +++ llvm/trunk/lib/IR/DiagnosticInfo.cpp Fri Sep 15 13:10:09 2017
> @@ -13,6 +13,7 @@
>  //===----------------------------------------------------------------------===//
>  
>  #include "llvm/IR/DiagnosticInfo.h"
> +#include "LLVMContextImpl.h"
>  #include "llvm/ADT/StringExtras.h"
>  #include "llvm/ADT/Twine.h"
>  #include "llvm/ADT/iterator_range.h"
> @@ -41,61 +42,6 @@
>  
>  using namespace llvm;
>  
> -namespace {
> -
> -/// \brief Regular expression corresponding to the value given in one of the
> -/// -pass-remarks* command line flags. Passes whose name matches this regexp
> -/// will emit a diagnostic via ORE->emit(...);
> -struct PassRemarksOpt {
> -  std::shared_ptr<Regex> Pattern;
> -
> -  void operator=(const std::string &Val) {
> -    if (!Val.empty()) {
> -      Pattern = std::make_shared<Regex>(Val);
> -      std::string RegexError;
> -      if (!Pattern->isValid(RegexError))
> -        report_fatal_error("Invalid regular expression '" + Val +
> -                               "' in -pass-remarks: " + RegexError,
> -                           false);
> -    }
> -  }
> -};
> -
> -} // end anonymous namespace
> -
> -static PassRemarksOpt PassRemarksOptLoc;
> -static PassRemarksOpt PassRemarksMissedOptLoc;
> -static PassRemarksOpt PassRemarksAnalysisOptLoc;
> -
> -// -pass-remarks
> -//    Command line flag to enable optimization remarks
> -static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
> -PassRemarks("pass-remarks", cl::value_desc("pattern"),
> -            cl::desc("Enable optimization remarks from passes whose name match "
> -                     "the given regular expression"),
> -            cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
> -            cl::ZeroOrMore);
> -
> -// -pass-remarks-missed
> -//    Command line flag to enable missed optimization remarks
> -static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
> -    "pass-remarks-missed", cl::value_desc("pattern"),
> -    cl::desc("Enable missed optimization remarks from passes whose name match "
> -             "the given regular expression"),
> -    cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
> -    cl::ZeroOrMore);
> -
> -// -pass-remarks-analysis
> -//    Command line flag to enable optimization analysis remarks
> -static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
> -PassRemarksAnalysis(
> -    "pass-remarks-analysis", cl::value_desc("pattern"),
> -    cl::desc(
> -        "Enable optimization analysis remarks from passes whose name match "
> -        "the given regular expression"),
> -    cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
> -    cl::ZeroOrMore);
> -
>  int llvm::getNextAvailablePluginDiagnosticKind() {
>    static std::atomic<int> PluginKindID(DK_FirstPluginKind);
>    return ++PluginKindID;
> @@ -283,9 +229,10 @@ OptimizationRemark::OptimizationRemark(c
>                                     RemarkName, *Func, Func->getSubprogram(),
>                                     &getFirstFunctionBlock(Func)) {}
>  
> -bool OptimizationRemark::isEnabled(StringRef PassName) {
> -  return PassRemarksOptLoc.Pattern &&
> -         PassRemarksOptLoc.Pattern->match(PassName);
> +bool OptimizationRemark::isEnabled() const {
> +  const Function &Fn = getFunction();
> +  LLVMContext &Ctx = Fn.getContext();
> +  return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
>  }
>  
>  OptimizationRemarkMissed::OptimizationRemarkMissed(
> @@ -303,9 +250,10 @@ OptimizationRemarkMissed::OptimizationRe
>                                     *Inst->getParent()->getParent(),
>                                     Inst->getDebugLoc(), Inst->getParent()) {}
>  
> -bool OptimizationRemarkMissed::isEnabled(StringRef PassName) {
> -  return PassRemarksMissedOptLoc.Pattern &&
> -         PassRemarksMissedOptLoc.Pattern->match(PassName);
> +bool OptimizationRemarkMissed::isEnabled() const {
> +  const Function &Fn = getFunction();
> +  LLVMContext &Ctx = Fn.getContext();
> +  return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
>  }
>  
>  OptimizationRemarkAnalysis::OptimizationRemarkAnalysis(
> @@ -330,9 +278,11 @@ OptimizationRemarkAnalysis::Optimization
>                                     *cast<BasicBlock>(CodeRegion)->getParent(),
>                                     Loc, CodeRegion) {}
>  
> -bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) {
> -  return PassRemarksAnalysisOptLoc.Pattern &&
> -         PassRemarksAnalysisOptLoc.Pattern->match(PassName);
> +bool OptimizationRemarkAnalysis::isEnabled() const {
> +  const Function &Fn = getFunction();
> +  LLVMContext &Ctx = Fn.getContext();
> +  return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName()) ||
> +         shouldAlwaysPrint();
>  }
>  
>  void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
>
> Modified: llvm/trunk/lib/IR/LLVMContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContext.cpp (original)
> +++ llvm/trunk/lib/IR/LLVMContext.cpp Fri Sep 15 13:10:09 2017
> @@ -129,11 +129,17 @@ void *LLVMContext::getInlineAsmDiagnosti
>    return pImpl->InlineAsmDiagContext;
>  }
>  
> -void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
> -                                       void *DiagnosticContext,
> -                                       bool RespectFilters) {
> -  pImpl->DiagnosticHandler = DiagnosticHandler;
> -  pImpl->DiagnosticContext = DiagnosticContext;
> +void LLVMContext::setDiagnosticHandlerCallBack(
> +    DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
> +    void *DiagnosticContext, bool RespectFilters) {
> +  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
> +  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
> +  pImpl->RespectDiagnosticFilters = RespectFilters;
> +}
> +
> +void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
> +                                      bool RespectFilters) {
> +  pImpl->DiagHandler = std::move(DH);
>    pImpl->RespectDiagnosticFilters = RespectFilters;
>  }
>  
> @@ -159,12 +165,13 @@ void LLVMContext::setDiagnosticsOutputFi
>    pImpl->DiagnosticsOutputFile = std::move(F);
>  }
>  
> -LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
> -  return pImpl->DiagnosticHandler;
> +DiagnosticHandler::DiagnosticHandlerTy
> +LLVMContext::getDiagnosticHandlerCallBack() const {
> +  return pImpl->DiagHandler->DiagHandlerCallback;
>  }
>  
>  void *LLVMContext::getDiagnosticContext() const {
> -  return pImpl->DiagnosticContext;
> +  return pImpl->DiagHandler->DiagnosticContext;
>  }
>  
>  void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
> @@ -215,11 +222,10 @@ LLVMContext::getDiagnosticMessagePrefix(
>  
>  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);
> +  if (pImpl->DiagHandler &&
> +      (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
> +      pImpl->DiagHandler->handleDiagnostics(DI))
>      return;
> -  }
>  
>    if (!isDiagnosticEnabled(DI))
>      return;
> @@ -315,3 +321,11 @@ void LLVMContext::setDiscardValueNames(b
>  OptBisect &LLVMContext::getOptBisect() {
>    return pImpl->getOptBisect();
>  }
> +
> +const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
> +  return pImpl->DiagHandler.get();
> +}
> +
> +std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
> +  return std::move(pImpl->DiagHandler);
> +}
>
> Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
> +++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Fri Sep 15 13:10:09 2017
> @@ -22,7 +22,8 @@
>  using namespace llvm;
>  
>  LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
> -  : VoidTy(C, Type::VoidTyID),
> +  : DiagHandler(llvm::make_unique<DiagnosticHandler>()),
> +    VoidTy(C, Type::VoidTyID),
>      LabelTy(C, Type::LabelTyID),
>      HalfTy(C, Type::HalfTyID),
>      FloatTy(C, Type::FloatTyID),
>
> Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
> +++ llvm/trunk/lib/IR/LLVMContextImpl.h Fri Sep 15 13:10:09 2017
> @@ -1168,8 +1168,7 @@ public:
>    LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr;
>    void *InlineAsmDiagContext = nullptr;
>  
> -  LLVMContext::DiagnosticHandlerTy DiagnosticHandler = nullptr;
> -  void *DiagnosticContext = nullptr;
> +  std::unique_ptr<DiagnosticHandler> DiagHandler;
>    bool RespectDiagnosticFilters = false;
>    bool DiagnosticsHotnessRequested = false;
>    uint64_t DiagnosticsHotnessThreshold = 0;
>
> Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
> +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Fri Sep 15 13:10:09 2017
> @@ -622,12 +622,8 @@ void LTOCodeGenerator::parseCodeGenDebug
>    }
>  }
>  
> -void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
> -                                         void *Context) {
> -  ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
> -}
>  
> -void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
> +void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
>    // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
>    lto_codegen_diagnostic_severity_t Severity;
>    switch (DI.getSeverity()) {
> @@ -657,17 +653,29 @@ void LTOCodeGenerator::DiagnosticHandler
>    (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
>  }
>  
> +namespace {
> +struct LTODiagnosticHandler : public DiagnosticHandler {
> +  LTOCodeGenerator *CodeGenerator;
> +  LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
> +      : CodeGenerator(CodeGenPtr) {}
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    CodeGenerator->DiagnosticHandler(DI);
> +    return true;
> +  }
> +};
> +}
> +
>  void
>  LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
>                                         void *Ctxt) {
>    this->DiagHandler = DiagHandler;
>    this->DiagContext = Ctxt;
>    if (!DiagHandler)
> -    return Context.setDiagnosticHandler(nullptr, nullptr);
> +    return Context.setDiagnosticHandler(nullptr);
>    // Register the LTOCodeGenerator stub in the LLVMContext to forward the
>    // diagnostic to the external DiagHandler.
> -  Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this,
> -                               /* RespectFilters */ true);
> +  Context.setDiagnosticHandler(llvm::make_unique<LTODiagnosticHandler>(this),
> +                               true);
>  }
>  
>  namespace {
>
> Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Sep 15 13:10:09 2017
> @@ -920,8 +920,7 @@ bool GVN::AnalyzeLoadAvailability(LoadIn
>        Instruction *I = DepInfo.getInst();
>        dbgs() << " is clobbered by " << *I << '\n';
>      );
> -
> -    if (ORE->allowExtraAnalysis())
> +    if (ORE->allowExtraAnalysis(DEBUG_TYPE))
>        reportMayClobberedLoad(LI, DepInfo, DT, ORE);
>  
>      return false;
>
> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Fri Sep 15 13:10:09 2017
> @@ -4957,12 +4957,15 @@ bool LoopVectorizationLegality::canVecto
>    // Store the result and return it at the end instead of exiting early, in case
>    // allowExtraAnalysis is used to report multiple reasons for not vectorizing.
>    bool Result = true;
> +  
> +  bool DoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
> +  if (DoExtraAnalysis)
>    // We must have a loop in canonical form. Loops with indirectbr in them cannot
>    // be canonicalized.
>    if (!TheLoop->getLoopPreheader()) {
>      ORE->emit(createMissedAnalysis("CFGNotUnderstood")
>                << "loop control flow is not understood by vectorizer");
> -    if (ORE->allowExtraAnalysis())
> +  if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -4975,7 +4978,7 @@ bool LoopVectorizationLegality::canVecto
>    if (!TheLoop->empty()) {
>      ORE->emit(createMissedAnalysis("NotInnermostLoop")
>                << "loop is not the innermost loop");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -4985,7 +4988,7 @@ bool LoopVectorizationLegality::canVecto
>    if (TheLoop->getNumBackEdges() != 1) {
>      ORE->emit(createMissedAnalysis("CFGNotUnderstood")
>                << "loop control flow is not understood by vectorizer");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -4995,7 +4998,7 @@ bool LoopVectorizationLegality::canVecto
>    if (!TheLoop->getExitingBlock()) {
>      ORE->emit(createMissedAnalysis("CFGNotUnderstood")
>                << "loop control flow is not understood by vectorizer");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -5007,7 +5010,7 @@ bool LoopVectorizationLegality::canVecto
>    if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
>      ORE->emit(createMissedAnalysis("CFGNotUnderstood")
>                << "loop control flow is not understood by vectorizer");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -5021,7 +5024,7 @@ bool LoopVectorizationLegality::canVecto
>    unsigned NumBlocks = TheLoop->getNumBlocks();
>    if (NumBlocks != 1 && !canVectorizeWithIfConvert()) {
>      DEBUG(dbgs() << "LV: Can't if-convert the loop.\n");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -5030,7 +5033,7 @@ bool LoopVectorizationLegality::canVecto
>    // Check if we can vectorize the instructions and CFG in this loop.
>    if (!canVectorizeInstrs()) {
>      DEBUG(dbgs() << "LV: Can't vectorize the instructions or CFG\n");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -5039,7 +5042,7 @@ bool LoopVectorizationLegality::canVecto
>    // Go over each instruction and look at memory deps.
>    if (!canVectorizeMemory()) {
>      DEBUG(dbgs() << "LV: Can't vectorize due to memory conflicts\n");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
> @@ -5070,7 +5073,7 @@ bool LoopVectorizationLegality::canVecto
>                << "Too many SCEV assumptions need to be made and checked "
>                << "at runtime");
>      DEBUG(dbgs() << "LV: Too many SCEV checks needed.\n");
> -    if (ORE->allowExtraAnalysis())
> +    if (DoExtraAnalysis)
>        Result = false;
>      else
>        return false;
>
> Modified: llvm/trunk/test/Transforms/GVN/opt-remarks.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/opt-remarks.ll?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/GVN/opt-remarks.ll (original)
> +++ llvm/trunk/test/Transforms/GVN/opt-remarks.ll Fri Sep 15 13:10:09 2017
> @@ -11,7 +11,7 @@
>  ; CHECK:      remark: <unknown>:0:0: load of type i32 eliminated{{$}}
>  ; CHECK-NEXT: remark: <unknown>:0:0: load of type i32 eliminated{{$}}
>  ; CHECK-NEXT: remark: <unknown>:0:0: load of type i32 eliminated{{$}}
> -; CHECK-NOT:  remark:
> +; CHECK-NEXT: remark: /tmp/s.c:3:3: load of type i32 not eliminated
>  
>  ; YAML:      --- !Passed
>  ; YAML-NEXT: Pass:            gvn
>
> Modified: llvm/trunk/tools/llc/llc.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llc/llc.cpp (original)
> +++ llvm/trunk/tools/llc/llc.cpp Fri Sep 15 13:10:09 2017
> @@ -235,20 +235,24 @@ GetOutputStream(const char *TargetName,
>    return FDOut;
>  }
>  
> -static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
> -  bool *HasError = static_cast<bool *>(Context);
> -  if (DI.getSeverity() == DS_Error)
> -    *HasError = true;
> -
> -  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
> -    if (!Remark->isEnabled())
> -      return;
> -
> -  DiagnosticPrinterRawOStream DP(errs());
> -  errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
> -  DI.print(DP);
> -  errs() << "\n";
> -}
> +struct LLCDiagnosticHandler : public DiagnosticHandler {
> +  bool *HasError;
> +  LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    if (DI.getSeverity() == DS_Error)
> +      *HasError = true;
> +
> +    if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
> +      if (!Remark->isEnabled())
> +        return true;
> +
> +    DiagnosticPrinterRawOStream DP(errs());
> +    errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
> +    DI.print(DP);
> +    errs() << "\n";
> +    return true;
> +  }
> +};
>  
>  static void InlineAsmDiagHandler(const SMDiagnostic &SMD, void *Context,
>                                   unsigned LocCookie) {
> @@ -308,7 +312,8 @@ int main(int argc, char **argv) {
>  
>    // Set a diagnostic handler that doesn't exit on the first error
>    bool HasError = false;
> -  Context.setDiagnosticHandler(DiagnosticHandler, &HasError);
> +  Context.setDiagnosticHandler(
> +      llvm::make_unique<LLCDiagnosticHandler>(&HasError));
>    Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
>  
>    if (PassRemarksWithHotness)
> @@ -564,8 +569,9 @@ static int compileModule(char **argv, LL
>  
>      PM.run(*M);
>  
> -    auto HasError = *static_cast<bool *>(Context.getDiagnosticContext());
> -    if (HasError)
> +    auto HasError =
> +        ((const LLCDiagnosticHandler *)(Context.getDiagHandlerPtr()))->HasError;
> +    if (*HasError)
>        return 1;
>  
>      // Compare the two outputs and make sure they're the same
>
> Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original)
> +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Fri Sep 15 13:10:09 2017
> @@ -122,25 +122,29 @@ public:
>    }
>  };
>  
> -} // end anon namespace
> -
> -static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
> -  raw_ostream &OS = errs();
> -  OS << (char *)Context << ": ";
> -  switch (DI.getSeverity()) {
> -  case DS_Error: OS << "error: "; break;
> -  case DS_Warning: OS << "warning: "; break;
> -  case DS_Remark: OS << "remark: "; break;
> -  case DS_Note: OS << "note: "; break;
> +struct LLVMDisDiagnosticHandler : public DiagnosticHandler {
> +  char *Prefix;
> +  LLVMDisDiagnosticHandler(char *PrefixPtr) : Prefix(PrefixPtr) {}
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    raw_ostream &OS = errs();
> +    OS << Prefix << ": ";
> +    switch (DI.getSeverity()) {
> +      case DS_Error: OS << "error: "; break;
> +      case DS_Warning: OS << "warning: "; break;
> +      case DS_Remark: OS << "remark: "; break;
> +      case DS_Note: OS << "note: "; break;
> +    }
> +
> +    DiagnosticPrinterRawOStream DP(OS);
> +    DI.print(DP);
> +    OS << '\n';
> +
> +    if (DI.getSeverity() == DS_Error)
> +      exit(1);
> +    return true;
>    }
> -
> -  DiagnosticPrinterRawOStream DP(OS);
> -  DI.print(DP);
> -  OS << '\n';
> -
> -  if (DI.getSeverity() == DS_Error)
> -    exit(1);
> -}
> +};
> +} // end anon namespace
>  
>  static ExitOnError ExitOnErr;
>  
> @@ -166,9 +170,8 @@ int main(int argc, char **argv) {
>  
>    LLVMContext Context;
>    llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
> -
> -  Context.setDiagnosticHandler(diagnosticHandler, argv[0]);
> -
> +  Context.setDiagnosticHandler(
> +      llvm::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
>    cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
>  
>    std::unique_ptr<Module> M = openInputFile(Context);
>
> Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-link/llvm-link.cpp (original)
> +++ llvm/trunk/tools/llvm-link/llvm-link.cpp Fri Sep 15 13:10:09 2017
> @@ -182,25 +182,30 @@ Module &ModuleLazyLoaderCache::operator(
>  }
>  } // anonymous namespace
>  
> -static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
> -  unsigned Severity = DI.getSeverity();
> -  switch (Severity) {
> -  case DS_Error:
> -    errs() << "ERROR: ";
> -    break;
> -  case DS_Warning:
> -    if (SuppressWarnings)
> -      return;
> -    errs() << "WARNING: ";
> -    break;
> -  case DS_Remark:
> -  case DS_Note:
> -    llvm_unreachable("Only expecting warnings and errors");
> -  }
> +namespace {
> +struct LLVMLinkDiagnosticHandler : public DiagnosticHandler {
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    unsigned Severity = DI.getSeverity();
> +    switch (Severity) {
> +    case DS_Error:
> +      errs() << "ERROR: ";
> +      break;
> +    case DS_Warning:
> +      if (SuppressWarnings)
> +        return true;
> +      errs() << "WARNING: ";
> +      break;
> +    case DS_Remark:
> +    case DS_Note:
> +      llvm_unreachable("Only expecting warnings and errors");
> +    }
>  
> -  DiagnosticPrinterRawOStream DP(errs());
> -  DI.print(DP);
> -  errs() << '\n';
> +    DiagnosticPrinterRawOStream DP(errs());
> +    DI.print(DP);
> +    errs() << '\n';
> +    return true;
> +  }
> +};
>  }
>  
>  /// Import any functions requested via the -import option.
> @@ -347,8 +352,8 @@ int main(int argc, char **argv) {
>    ExitOnErr.setBanner(std::string(argv[0]) + ": ");
>  
>    LLVMContext Context;
> -  Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);
> -
> +  Context.setDiagnosticHandler(
> +    llvm::make_unique<LLVMLinkDiagnosticHandler>(), true);
>    llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
>    cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
>  
>
> Modified: llvm/trunk/tools/llvm-lto/llvm-lto.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-lto/llvm-lto.cpp (original)
> +++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp Fri Sep 15 13:10:09 2017
> @@ -235,34 +235,40 @@ static void handleDiagnostics(lto_codege
>  }
>  
>  static std::string CurrentActivity;
> -static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
> -  raw_ostream &OS = errs();
> -  OS << "llvm-lto: ";
> -  switch (DI.getSeverity()) {
> -  case DS_Error:
> -    OS << "error";
> -    break;
> -  case DS_Warning:
> -    OS << "warning";
> -    break;
> -  case DS_Remark:
> -    OS << "remark";
> -    break;
> -  case DS_Note:
> -    OS << "note";
> -    break;
> -  }
> -  if (!CurrentActivity.empty())
> -    OS << ' ' << CurrentActivity;
> -  OS << ": ";
> -
> -  DiagnosticPrinterRawOStream DP(OS);
> -  DI.print(DP);
> -  OS << '\n';
>  
> -  if (DI.getSeverity() == DS_Error)
> -    exit(1);
> -}
> +namespace {
> +  struct LLVMLTODiagnosticHandler : public DiagnosticHandler {
> +    bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +      raw_ostream &OS = errs();
> +      OS << "llvm-lto: ";
> +      switch (DI.getSeverity()) {
> +      case DS_Error:
> +        OS << "error";
> +        break;
> +      case DS_Warning:
> +        OS << "warning";
> +        break;
> +      case DS_Remark:
> +        OS << "remark";
> +        break;
> +      case DS_Note:
> +        OS << "note";
> +        break;
> +      }
> +      if (!CurrentActivity.empty())
> +        OS << ' ' << CurrentActivity;
> +      OS << ": ";
> +  
> +      DiagnosticPrinterRawOStream DP(OS);
> +      DI.print(DP);
> +      OS << '\n';
> +  
> +      if (DI.getSeverity() == DS_Error)
> +        exit(1);
> +      return true;
> +    }
> +  };
> +  }
>  
>  static void error(const Twine &Msg) {
>    errs() << "llvm-lto: " << Msg << '\n';
> @@ -293,7 +299,8 @@ getLocalLTOModule(StringRef Path, std::u
>    Buffer = std::move(BufferOrErr.get());
>    CurrentActivity = ("loading file '" + Path + "'").str();
>    std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
> -  Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
> +  Context->setDiagnosticHandler(llvm::make_unique<LLVMLTODiagnosticHandler>(),
> +                                true);
>    ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext(
>        std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(),
>        Options, Path);
> @@ -837,7 +844,8 @@ int main(int argc, char **argv) {
>    unsigned BaseArg = 0;
>  
>    LLVMContext Context;
> -  Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);
> +  Context.setDiagnosticHandler(llvm::make_unique<LLVMLTODiagnosticHandler>(),
> +                               true);
>  
>    LTOCodeGenerator CodeGen(Context);
>  
>
> Modified: llvm/trunk/tools/lto/lto.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=313390&r1=313389&r2=313390&view=diff
> ==============================================================================
> --- llvm/trunk/tools/lto/lto.cpp (original)
> +++ llvm/trunk/tools/lto/lto.cpp Fri Sep 15 13:10:09 2017
> @@ -75,20 +75,23 @@ static bool parsedOptions = false;
>  
>  static LLVMContext *LTOContext = nullptr;
>  
> -static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
> -  if (DI.getSeverity() != DS_Error) {
> -    DiagnosticPrinterRawOStream DP(errs());
> -    DI.print(DP);
> -    errs() << '\n';
> -    return;
> -  }
> -  sLastErrorString = "";
> -  {
> -    raw_string_ostream Stream(sLastErrorString);
> -    DiagnosticPrinterRawOStream DP(Stream);
> -    DI.print(DP);
> +struct LTOToolDiagnosticHandler : public DiagnosticHandler {
> +  bool handleDiagnostics(const DiagnosticInfo &DI) override {
> +    if (DI.getSeverity() != DS_Error) {
> +      DiagnosticPrinterRawOStream DP(errs());
> +      DI.print(DP);
> +      errs() << '\n';
> +      return true;
> +    }
> +    sLastErrorString = "";
> +    {
> +      raw_string_ostream Stream(sLastErrorString);
> +      DiagnosticPrinterRawOStream DP(Stream);
> +      DI.print(DP);
> +    }
> +    return true;
>    }
> -}
> +};
>  
>  // Initialize the configured targets if they have not been initialized.
>  static void lto_initialize() {
> @@ -108,7 +111,8 @@ static void lto_initialize() {
>  
>      static LLVMContext Context;
>      LTOContext = &Context;
> -    LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true);
> +    LTOContext->setDiagnosticHandler(
> +        llvm::make_unique<LTOToolDiagnosticHandler>(), true);
>      initialized = true;
>    }
>  }
> @@ -274,7 +278,8 @@ lto_module_t lto_module_create_in_local_
>  
>    // Create a local context. Ownership will be transferred to LTOModule.
>    std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
> -  Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
> +  Context->setDiagnosticHandler(llvm::make_unique<LTOToolDiagnosticHandler>(),
> +                                true);
>  
>    ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInLocalContext(
>        std::move(Context), mem, length, Options, StringRef(path));
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list