diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h | 16 | ||||
-rw-r--r-- | llvm/include/llvm/IR/DiagnosticHandler.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/IR/DiagnosticInfo.h | 83 |
3 files changed, 98 insertions, 6 deletions
diff --git a/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h b/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h index 4c3b0fb949b..aae1b2c1b0c 100644 --- a/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ b/llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -24,7 +24,6 @@ namespace llvm { class DebugLoc; -class LLVMContext; class Loop; class Pass; class Twine; @@ -71,6 +70,21 @@ public: /// optimization record file. void emit(DiagnosticInfoOptimizationBase &OptDiag); + /// \brief Take a lambda that returns a remark which will be emitted. Second + /// argument is only used to restrict this to functions. + template <typename T> + void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) { + // Avoid building the remark unless we know there are at least *some* + // remarks enabled. We can't currently check whether remarks are requested + // for the calling pass since that requires actually building the remark. + + if (F->getContext().getDiagnosticsOutputFile() || + F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) { + auto R = RemarkBuilder(); + emit(R); + } + } + /// \brief Whether we allow for extra compile-time budget to perform more /// analysis to produce fewer false positives. /// diff --git a/llvm/include/llvm/IR/DiagnosticHandler.h b/llvm/include/llvm/IR/DiagnosticHandler.h index c9a606f02f7..9256d4850df 100644 --- a/llvm/include/llvm/IR/DiagnosticHandler.h +++ b/llvm/include/llvm/IR/DiagnosticHandler.h @@ -60,12 +60,15 @@ struct DiagnosticHandler { /// to provide different implementation. virtual bool isPassedOptRemarkEnabled(StringRef PassName) const; - /// Return true if any type of remarks are enabled. + /// Return true if any type of remarks are enabled for this pass. bool isAnyRemarkEnabled(StringRef PassName) const { return (isMissedOptRemarkEnabled(PassName) || isPassedOptRemarkEnabled(PassName) || isAnalysisRemarkEnabled(PassName)); } + + /// Return true if any type of remarks are enabled for any pass. + virtual bool isAnyRemarkEnabled() const; }; } // namespace llvm diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h index a2023554a89..1e9bcb67e28 100644 --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -438,10 +438,10 @@ public: : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc), PassName(PassName), RemarkName(RemarkName) {} - DiagnosticInfoOptimizationBase &operator<<(StringRef S); - DiagnosticInfoOptimizationBase &operator<<(Argument A); - DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V); - DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA); + void insert(StringRef S); + void insert(Argument A); + void insert(setIsVerbose V); + void insert(setExtraArgs EA); /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -511,6 +511,81 @@ protected: friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>; }; +/// Allow the insertion operator to return the actual remark type rather than a +/// common base class. This allows returning the result of the insertion +/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". +template <class RemarkT> +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + StringRef>::type S) { + R.insert(S); + return R; +} + +/// Also allow r-value for the remark to allow insertion into a +/// temporarily-constructed remark. +template <class RemarkT> +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + StringRef>::type S) { + R.insert(S); + return R; +} + +template <class RemarkT> +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + DiagnosticInfoOptimizationBase::Argument>::type A) { + R.insert(A); + return R; +} + +template <class RemarkT> +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + DiagnosticInfoOptimizationBase::Argument>::type A) { + R.insert(A); + return R; +} + +template <class RemarkT> +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { + R.insert(V); + return R; +} + +template <class RemarkT> +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { + R.insert(V); + return R; +} + +template <class RemarkT> +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, + DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) { + R.insert(EA); + return R; +} + /// \brief Common features for diagnostics dealing with optimization remarks /// that are used by IR passes. class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { |