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

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 16:46:52 PDT 2017


I think this may have broken the module build, could you please take a look?

http://green.lab.llvm.org/green/job/clang-stage2-configure-Rthinlto_build/5350/consoleFull#765228809a1ca8a51-895e-46c6-af87-ce24fa4cd561 <http://green.lab.llvm.org/green/job/clang-stage2-configure-Rthinlto_build/5350/consoleFull#765228809a1ca8a51-895e-46c6-af87-ce24fa4cd561>

-- adrian

> On Sep 15, 2017, at 12:30 PM, Vivek Pandya via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> Author: vivekvpandya
> Date: Fri Sep 15 12:30:59 2017
> New Revision: 313382
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=313382&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.
> 
> Added:
>    llvm/trunk/include/llvm/IR/DiagnosticHandler.h
>    llvm/trunk/lib/IR/DiagnosticHandler.cpp
> Modified:
>    llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h
>    llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
>    llvm/trunk/include/llvm/IR/DiagnosticInfo.h
>    llvm/trunk/include/llvm/IR/LLVMContext.h
>    llvm/trunk/include/llvm/LTO/Config.h
>    llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h
>    llvm/trunk/lib/IR/CMakeLists.txt
>    llvm/trunk/lib/IR/Core.cpp
>    llvm/trunk/lib/IR/DiagnosticInfo.cpp
>    llvm/trunk/lib/IR/LLVMContext.cpp
>    llvm/trunk/lib/IR/LLVMContextImpl.cpp
>    llvm/trunk/lib/IR/LLVMContextImpl.h
>    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
>    llvm/trunk/lib/Transforms/Scalar/GVN.cpp
>    llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>    llvm/trunk/test/Transforms/GVN/opt-remarks.ll
>    llvm/trunk/tools/llc/llc.cpp
>    llvm/trunk/tools/llvm-dis/llvm-dis.cpp
>    llvm/trunk/tools/llvm-link/llvm-link.cpp
>    llvm/trunk/tools/llvm-lto/llvm-lto.cpp
>    llvm/trunk/tools/lto/lto.cpp
> 
> Modified: llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h?rev=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h (original)
> +++ llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h Fri Sep 15 12:30:59 2017
> @@ -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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h Fri Sep 15 12:30:59 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=313382&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/DiagnosticHandler.h (added)
> +++ llvm/trunk/include/llvm/IR/DiagnosticHandler.h Fri Sep 15 12:30:59 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) {}
> +  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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/DiagnosticInfo.h (original)
> +++ llvm/trunk/include/llvm/IR/DiagnosticInfo.h Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
> +++ llvm/trunk/include/llvm/IR/LLVMContext.h Fri Sep 15 12:30:59 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
> +  /// 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;
> 
> +  /// 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();
> +
>   /// \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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LTO/Config.h (original)
> +++ llvm/trunk/include/llvm/LTO/Config.h Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h (original)
> +++ llvm/trunk/include/llvm/LTO/legacy/LTOCodeGenerator.h Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/CMakeLists.txt (original)
> +++ llvm/trunk/lib/IR/CMakeLists.txt Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/Core.cpp (original)
> +++ llvm/trunk/lib/IR/Core.cpp Fri Sep 15 12:30:59 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=313382&view=auto
> ==============================================================================
> --- llvm/trunk/lib/IR/DiagnosticHandler.cpp (added)
> +++ llvm/trunk/lib/IR/DiagnosticHandler.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/DiagnosticInfo.cpp (original)
> +++ llvm/trunk/lib/IR/DiagnosticInfo.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContext.cpp (original)
> +++ llvm/trunk/lib/IR/LLVMContext.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
> +++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
> +++ llvm/trunk/lib/IR/LLVMContextImpl.h Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
> +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/GVN/opt-remarks.ll (original)
> +++ llvm/trunk/test/Transforms/GVN/opt-remarks.ll Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llc/llc.cpp (original)
> +++ llvm/trunk/tools/llc/llc.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original)
> +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-link/llvm-link.cpp (original)
> +++ llvm/trunk/tools/llvm-link/llvm-link.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-lto/llvm-lto.cpp (original)
> +++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp Fri Sep 15 12:30:59 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=313382&r1=313381&r2=313382&view=diff
> ==============================================================================
> --- llvm/trunk/tools/lto/lto.cpp (original)
> +++ llvm/trunk/tools/lto/lto.cpp Fri Sep 15 12:30:59 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170915/d7063144/attachment.html>


More information about the llvm-commits mailing list