summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/Analysis/OptimizationDiagnosticInfo.h16
-rw-r--r--llvm/include/llvm/IR/DiagnosticHandler.h5
-rw-r--r--llvm/include/llvm/IR/DiagnosticInfo.h83
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 {
OpenPOWER on IntegriCloud