diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h index 7b14e55782adb..64e6442bb92f8 100644 --- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h +++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h @@ -69,6 +69,9 @@ class OptimizationRemarkEmitter { /// Output the remark via the diagnostic handler and to the /// optimization record file. void emit(DiagnosticInfoOptimizationBase &OptDiag); + /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed + /// diagnostic. + void emit(DiagnosticInfoOptimizationBase &&OptDiag) { emit(OptDiag); } /// Take a lambda that returns a remark which will be emitted. Second /// argument is only used to restrict this to functions. diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h index 694785317af04..779c88993b71c 100644 --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace llvm { @@ -612,82 +613,47 @@ class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase { /// common base class. This allows returning the result of the insertion /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". template -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of::value, - StringRef> - S) { - R.insert(S); - return R; -} - -/// Also allow r-value for the remark to allow insertion into a -/// temporarily-constructed remark. -template -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of::value, - StringRef> + std::enable_if_t>, + StringRef> S) { R.insert(S); - return R; -} - -template -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of::value, - DiagnosticInfoOptimizationBase::Argument> - A) { - R.insert(A); - return R; + return std::forward(R); } template -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of::value, - DiagnosticInfoOptimizationBase::Argument> + std::enable_if_t>, + DiagnosticInfoOptimizationBase::Argument> A) { R.insert(A); - return R; -} - -template -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of::value, - DiagnosticInfoOptimizationBase::setIsVerbose> - V) { - R.insert(V); - return R; + return std::forward(R); } template -RemarkT & +decltype(auto) operator<<(RemarkT &&R, - std::enable_if_t< - std::is_base_of::value, - DiagnosticInfoOptimizationBase::setIsVerbose> + std::enable_if_t>, + DiagnosticInfoOptimizationBase::setIsVerbose> V) { R.insert(V); - return R; + return std::forward(R); } template -RemarkT & -operator<<(RemarkT &R, - std::enable_if_t< - std::is_base_of::value, - DiagnosticInfoOptimizationBase::setExtraArgs> +decltype(auto) +operator<<(RemarkT &&R, + std::enable_if_t>, + DiagnosticInfoOptimizationBase::setExtraArgs> EA) { R.insert(EA); - return R; + return std::forward(R); } /// Common features for diagnostics dealing with optimization remarks diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp index 12553dd446a61..5b2f0479e2b41 100644 --- a/llvm/lib/Analysis/InlineAdvisor.cpp +++ b/llvm/lib/Analysis/InlineAdvisor.cpp @@ -338,7 +338,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) { } template -RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) { +decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) { using namespace ore; if (IC.isAlways()) { R << "(cost=always)"; @@ -350,7 +350,7 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) { } if (const char *Reason = IC.getReason()) R << ": " << ore::NV("Reason", Reason); - return R; + return std::forward(R); } } // namespace llvm