Index: include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h =================================================================== --- include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h +++ include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h @@ -73,7 +73,12 @@ /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override { - return OptimizationRemark::isEnabled(getPassName()); + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::OptRemarkEnable) + return true; + return false; } }; @@ -97,7 +102,12 @@ /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override { - return OptimizationRemarkMissed::isEnabled(getPassName()); + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::MissedOptRemarkEnable) + return true; + return false; } }; @@ -121,7 +131,12 @@ /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override { - return OptimizationRemarkAnalysis::isEnabled(getPassName()); + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::AnalysisRemarkEnable) + return true; + return false; } }; Index: include/llvm/IR/DiagnosticHandler.h =================================================================== --- /dev/null +++ include/llvm/IR/DiagnosticHandler.h @@ -0,0 +1,32 @@ +//===- DiagnosticHandler.cpp - 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. +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Regex.h" + +namespace llvm { +enum class RemarkInfo { + RemarkNotEnabled, + AnalysisRemarkEnable, + MissedOptRemarkEnable, + OptRemarkEnable +}; +class DiagnosticInfo; +class DiagnosticHandler { +public: + using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context); + DiagnosticHandlerTy DiagnosticHandler; + RemarkInfo isRemarkEnable(const std::string &PassName); + std::shared_ptr PassRemarkAnalysisClang; + std::shared_ptr PassRemarkOptClang; + std::shared_ptr PassRemarkMissedOptClang; +}; +} Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -21,7 +21,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Function.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/YAMLTraits.h" #include "llvm-c/Types.h" #include @@ -34,7 +36,6 @@ // Forward declarations. class DiagnosticPrinter; -class Function; class Instruction; class LLVMContext; class Module; @@ -605,10 +606,17 @@ return DI->getKind() == DK_OptimizationRemark; } - static bool isEnabled(StringRef PassName); + //static bool isEnabled(StringRef PassName); /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override { return isEnabled(getPassName()); } + bool isEnabled() const override { + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::OptRemarkEnable) + return true; + return false; +} private: /// This is deprecated now and only used by the function API below. @@ -653,10 +661,17 @@ return DI->getKind() == DK_OptimizationRemarkMissed; } - static bool isEnabled(StringRef PassName); + //static bool isEnabled(StringRef PassName); /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override { return isEnabled(getPassName()); } + bool isEnabled() const override { + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::MissedOptRemarkEnable) + return true; + return false; + } private: /// This is deprecated now and only used by the function API below. @@ -713,11 +728,16 @@ return DI->getKind() == DK_OptimizationRemarkAnalysis; } - static bool isEnabled(StringRef PassName); + //static bool isEnabled(StringRef PassName); /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override { - return shouldAlwaysPrint() || isEnabled(getPassName()); + const Function &Fn = getFunction(); + LLVMContext &Ctx = Fn.getContext(); + RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(getPassName().str()); + if (RemarkInfoVal == RemarkInfo::AnalysisRemarkEnable || shouldAlwaysPrint()) + return true; + return false; } static const char *AlwaysPrint; Index: include/llvm/IR/LLVMContext.h =================================================================== --- include/llvm/IR/LLVMContext.h +++ include/llvm/IR/LLVMContext.h @@ -15,6 +15,7 @@ #ifndef LLVM_IR_LLVMCONTEXT_H #define LLVM_IR_LLVMCONTEXT_H +#include "DiagnosticHandler.h" #include "llvm-c/Types.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Options.h" @@ -139,11 +140,6 @@ 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); @@ -174,18 +170,20 @@ /// /// LLVMContext doesn't take ownership or interpret either of these /// pointers. - void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler, + void setDiagnosticHandler(DiagnosticHandler::DiagnosticHandlerTy DiagHandler, void *DiagContext = nullptr, bool RespectFilters = false); /// getDiagnosticHandler - Return the diagnostic handler set by /// setDiagnosticHandler. - DiagnosticHandlerTy getDiagnosticHandler() const; + DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandler() const; /// getDiagnosticContext - Return the diagnostic context set by /// setDiagnosticContext. void *getDiagnosticContext() const; + DiagnosticHandler getDiagHandler() const; + /// \brief Return if a code hotness metric should be included in optimization /// diagnostics. bool getDiagnosticHotnessRequested() const; Index: lib/Analysis/OptimizationDiagnosticInfo.cpp =================================================================== --- lib/Analysis/OptimizationDiagnosticInfo.cpp +++ lib/Analysis/OptimizationDiagnosticInfo.cpp @@ -155,7 +155,6 @@ DiagnosticInfoOptimizationBase &OptDiagBase) { auto &OptDiag = cast(OptDiagBase); computeHotness(OptDiag); - yaml::Output *Out = F->getContext().getDiagnosticsOutputFile(); if (Out) { auto *P = const_cast(&OptDiagBase); Index: lib/IR/CMakeLists.txt =================================================================== --- lib/IR/CMakeLists.txt +++ lib/IR/CMakeLists.txt @@ -17,6 +17,7 @@ DebugInfo.cpp DebugInfoMetadata.cpp DebugLoc.cpp + DiagnosticHandler.cpp DiagnosticInfo.cpp DiagnosticPrinter.cpp Dominators.cpp Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -86,7 +86,7 @@ LLVMDiagnosticHandler Handler, void *DiagnosticContext) { unwrap(C)->setDiagnosticHandler( - LLVM_EXTENSION reinterpret_cast( + LLVM_EXTENSION reinterpret_cast( Handler), DiagnosticContext); } Index: lib/IR/DiagnosticHandler.cpp =================================================================== --- /dev/null +++ lib/IR/DiagnosticHandler.cpp @@ -0,0 +1,88 @@ +//===- 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 +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 Pattern; + + void operator=(const std::string &Val) { + // Create a regexp object to match pass names for emitOptimizationRemark. + if (!Val.empty()) { + Pattern = std::make_shared(Val); + std::string RegexError; + if (!Pattern->isValid(RegexError)) + report_fatal_error("Invalid regular expression '" + Val + + "' in -pass-remarks: " + RegexError, + false); + } + } +}; + +static PassRemarksOpt PassRemarksOptLoc; +static PassRemarksOpt PassRemarksMissedOptLoc; +static PassRemarksOpt PassRemarksAnalysisOptLoc; + +// -pass-remarks +// Command line flag to enable emitOptimizationRemark() +static cl::opt> +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 emitOptimizationRemarkMissed() +static cl::opt> 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> +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); +} + +RemarkInfo DiagnosticHandler::isRemarkEnable(const std::string &PassName) { + if ((PassRemarksMissedOptLoc.Pattern && PassRemarksMissedOptLoc.Pattern->match(PassName)) + || (PassRemarkMissedOptClang && PassRemarkMissedOptClang->match(PassName))) + return RemarkInfo::MissedOptRemarkEnable; + + if ((PassRemarksOptLoc.Pattern && PassRemarksOptLoc.Pattern->match(PassName)) + || (PassRemarkOptClang && PassRemarkOptClang->match(PassName))) + return RemarkInfo::OptRemarkEnable; + + if ((PassRemarksAnalysisOptLoc.Pattern && PassRemarksAnalysisOptLoc.Pattern->match(PassName)) + || (PassRemarkAnalysisClang && PassRemarkAnalysisClang->match(PassName))) + return RemarkInfo::AnalysisRemarkEnable; + + return RemarkInfo::RemarkNotEnabled; +} Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -30,63 +30,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 when calling the associated diagnostic function -/// (emitOptimizationRemark, emitOptimizationRemarkMissed or -/// emitOptimizationRemarkAnalysis). -struct PassRemarksOpt { - std::shared_ptr Pattern; - - void operator=(const std::string &Val) { - // Create a regexp object to match pass names for emitOptimizationRemark. - if (!Val.empty()) { - Pattern = std::make_shared(Val); - std::string RegexError; - if (!Pattern->isValid(RegexError)) - report_fatal_error("Invalid regular expression '" + Val + - "' in -pass-remarks: " + RegexError, - false); - } - } -}; - -static PassRemarksOpt PassRemarksOptLoc; -static PassRemarksOpt PassRemarksMissedOptLoc; -static PassRemarksOpt PassRemarksAnalysisOptLoc; - -// -pass-remarks -// Command line flag to enable emitOptimizationRemark() -static cl::opt> -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 emitOptimizationRemarkMissed() -static cl::opt> 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> -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 PluginKindID(DK_FirstPluginKind); return ++PluginKindID; @@ -248,10 +191,14 @@ RemarkName, *Func, Func->getSubprogram(), &getFirstFunctionBlock(Func)) {} -bool OptimizationRemark::isEnabled(StringRef PassName) { - return PassRemarksOptLoc.Pattern && - PassRemarksOptLoc.Pattern->match(PassName); -} +// bool OptimizationRemark::isEnabled(StringRef PassName) { +// //const Function &Fn = getFunction(); +// LLVMContext &Ctx = Fn.getContext(); +// RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(PassName.str()); +// if (RemarkInfoVal == RemarkInfo::OptRemarkEnable) +// return true; +// return false; +// } OptimizationRemarkMissed::OptimizationRemarkMissed( const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, @@ -268,10 +215,14 @@ *Inst->getParent()->getParent(), Inst->getDebugLoc(), Inst->getParent()) {} -bool OptimizationRemarkMissed::isEnabled(StringRef PassName) { - return PassRemarksMissedOptLoc.Pattern && - PassRemarksMissedOptLoc.Pattern->match(PassName); -} +// bool OptimizationRemarkMissed::isEnabled(StringRef PassName) { +// const Function &Fn = getFunction(); +// LLVMContext &Ctx = Fn.getContext(); +// RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(PassName.str()); +// if (RemarkInfoVal == RemarkInfo::MissedOptRemarkEnable) +// return true; +// return false; +// } OptimizationRemarkAnalysis::OptimizationRemarkAnalysis( const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc, @@ -295,10 +246,14 @@ *cast(CodeRegion)->getParent(), Loc, CodeRegion) {} -bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) { - return PassRemarksAnalysisOptLoc.Pattern && - PassRemarksAnalysisOptLoc.Pattern->match(PassName); -} +// bool OptimizationRemarkAnalysis::isEnabled(StringRef PassName) { +// const Function &Fn = getFunction(); +// LLVMContext &Ctx = Fn.getContext(); +// RemarkInfo RemarkInfoVal = Ctx.getDiagHandler().isRemarkEnable(PassName.str()); +// if (RemarkInfoVal == RemarkInfo::AnalysisRemarkEnable) +// return true; +// return false; +// } void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const { DP << Diagnostic; Index: lib/IR/LLVMContext.cpp =================================================================== --- lib/IR/LLVMContext.cpp +++ lib/IR/LLVMContext.cpp @@ -117,10 +117,10 @@ return pImpl->InlineAsmDiagContext; } -void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler, +void LLVMContext::setDiagnosticHandler(DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, void *DiagnosticContext, bool RespectFilters) { - pImpl->DiagnosticHandler = DiagnosticHandler; + pImpl->DiagHandler.DiagnosticHandler = DiagnosticHandler; pImpl->DiagnosticContext = DiagnosticContext; pImpl->RespectDiagnosticFilters = RespectFilters; } @@ -140,8 +140,8 @@ pImpl->DiagnosticsOutputFile = std::move(F); } -LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { - return pImpl->DiagnosticHandler; +DiagnosticHandler::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const { + return pImpl->DiagHandler.DiagnosticHandler; } void *LLVMContext::getDiagnosticContext() const { @@ -196,9 +196,9 @@ void LLVMContext::diagnose(const DiagnosticInfo &DI) { // If there is a report handler, use it. - if (pImpl->DiagnosticHandler) { + if (pImpl->DiagHandler.DiagnosticHandler) { if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) - pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext); + pImpl->DiagHandler.DiagnosticHandler(DI, pImpl->DiagnosticContext); return; } @@ -288,3 +288,7 @@ OptBisect &LLVMContext::getOptBisect() { return pImpl->getOptBisect(); } + +DiagnosticHandler LLVMContext::getDiagHandler() const { + return pImpl->DiagHandler; +} Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -1100,7 +1100,7 @@ LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; void *InlineAsmDiagContext; - LLVMContext::DiagnosticHandlerTy DiagnosticHandler; + DiagnosticHandler DiagHandler; void *DiagnosticContext; bool RespectDiagnosticFilters; bool DiagnosticHotnessRequested; Index: lib/IR/LLVMContextImpl.cpp =================================================================== --- lib/IR/LLVMContextImpl.cpp +++ lib/IR/LLVMContextImpl.cpp @@ -42,7 +42,7 @@ Int128Ty(C, 128) { InlineAsmDiagHandler = nullptr; InlineAsmDiagContext = nullptr; - DiagnosticHandler = nullptr; + DiagHandler = DiagnosticHandler(); DiagnosticContext = nullptr; RespectDiagnosticFilters = false; DiagnosticHotnessRequested = false; Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -243,7 +243,7 @@ return FDOut; } -static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) { +static void DiagnosticHandlerImpl(const DiagnosticInfo &DI, void *Context) { bool *HasError = static_cast(Context); if (DI.getSeverity() == DS_Error) *HasError = true; @@ -313,7 +313,7 @@ // Set a diagnostic handler that doesn't exit on the first error bool HasError = false; - Context.setDiagnosticHandler(DiagnosticHandler, &HasError); + Context.setDiagnosticHandler(DiagnosticHandlerImpl, &HasError); Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError); if (PassRemarksWithHotness)