[llvm] [Diagnostics] Return rvalue reference from temporary argument (PR #127400)
Jonas Hahnfeld via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 12 15:03:41 PDT 2025
https://github.com/hahnjo updated https://github.com/llvm/llvm-project/pull/127400
>From 3b0573bb84a604e1c65fd23f3f99d2f473d685ef Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <hahnjo at hahnjo.de>
Date: Sun, 16 Feb 2025 14:54:15 +0100
Subject: [PATCH 1/4] Return rvalue reference from temporary argument
This fixes compilation issues with GCC and C++23:
```
error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'
```
Closes #105778
---
.../llvm/Analysis/OptimizationRemarkEmitter.h | 5 ++++
llvm/include/llvm/IR/DiagnosticInfo.h | 24 ++++++++++++++-----
llvm/lib/Analysis/InlineAdvisor.cpp | 9 +++++--
3 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b14e55782adb..2640bb9194010 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -69,6 +69,11 @@ 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(static_cast<DiagnosticInfoOptimizationBase &>(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..1e26cfdd17b5f 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -30,6 +30,7 @@
#include <iterator>
#include <optional>
#include <string>
+#include <utility>
namespace llvm {
@@ -625,14 +626,14 @@ operator<<(RemarkT &R,
/// Also allow r-value for the remark to allow insertion into a
/// temporarily-constructed remark.
template <class RemarkT>
-RemarkT &
+RemarkT &&
operator<<(RemarkT &&R,
std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
StringRef>
S) {
R.insert(S);
- return R;
+ return std::move(R);
}
template <class RemarkT>
@@ -647,14 +648,14 @@ operator<<(RemarkT &R,
}
template <class RemarkT>
-RemarkT &
+RemarkT &&
operator<<(RemarkT &&R,
std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
DiagnosticInfoOptimizationBase::Argument>
A) {
R.insert(A);
- return R;
+ return std::move(R);
}
template <class RemarkT>
@@ -669,14 +670,14 @@ operator<<(RemarkT &R,
}
template <class RemarkT>
-RemarkT &
+RemarkT &&
operator<<(RemarkT &&R,
std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
DiagnosticInfoOptimizationBase::setIsVerbose>
V) {
R.insert(V);
- return R;
+ return std::move(R);
}
template <class RemarkT>
@@ -690,6 +691,17 @@ operator<<(RemarkT &R,
return R;
}
+template <class RemarkT>
+RemarkT &&
+operator<<(RemarkT &&R,
+ std::enable_if_t<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ DiagnosticInfoOptimizationBase::setExtraArgs>
+ EA) {
+ R.insert(EA);
+ return std::move(R);
+}
+
/// Common features for diagnostics dealing with optimization remarks
/// that are used by IR passes.
class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 12553dd446a61..6cf6f10f20392 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -337,8 +337,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
return R << Arg.Val;
}
-template <class RemarkT>
-RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
+template <class RemarkT> RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
using namespace ore;
if (IC.isAlways()) {
R << "(cost=always)";
@@ -352,6 +351,12 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
R << ": " << ore::NV("Reason", Reason);
return R;
}
+
+template <class RemarkT>
+RemarkT &&operator<<(RemarkT &&R, const InlineCost &IC) {
+ static_cast<RemarkT &>(R) << IC;
+ return std::move(R);
+}
} // namespace llvm
std::string llvm::inlineCostStr(const InlineCost &IC) {
>From 824936ca9f51b70fcfd61e443a441be082f144e2 Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <hahnjo at hahnjo.de>
Date: Tue, 11 Mar 2025 20:37:28 +0100
Subject: [PATCH 2/4] Remove unneeded cast
---
llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 2640bb9194010..64e6442bb92f8 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -71,9 +71,7 @@ class OptimizationRemarkEmitter {
void emit(DiagnosticInfoOptimizationBase &OptDiag);
/// Also allow r-value for OptDiag to allow emitting a temporarily-constructed
/// diagnostic.
- void emit(DiagnosticInfoOptimizationBase &&OptDiag) {
- emit(static_cast<DiagnosticInfoOptimizationBase &>(OptDiag));
- }
+ 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.
>From 0a8055149ed044e667530aaf6e35e593c44ca01c Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <hahnjo at hahnjo.de>
Date: Wed, 12 Mar 2025 19:36:08 +0100
Subject: [PATCH 3/4] Unify duplicated template functions
---
llvm/include/llvm/IR/DiagnosticInfo.h | 102 +++++++-------------------
llvm/lib/Analysis/InlineAdvisor.cpp | 11 +--
2 files changed, 31 insertions(+), 82 deletions(-)
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 1e26cfdd17b5f..0ab9f5a87e41b 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -613,93 +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 <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>
- S) {
+decltype(auto) operator<<(
+ RemarkT &&R,
+ std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>::value,
+ StringRef>
+ S) {
R.insert(S);
- return R;
+ return std::forward<RemarkT>(R);
}
-/// Also allow r-value for the remark to allow insertion into a
-/// temporarily-constructed remark.
template <class RemarkT>
-RemarkT &&
-operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>
- S) {
- R.insert(S);
- return std::move(R);
-}
-
-template <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>
- A) {
- R.insert(A);
- return R;
-}
-
-template <class RemarkT>
-RemarkT &&
-operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>
- A) {
+decltype(auto) operator<<(
+ RemarkT &&R,
+ std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>::value,
+ DiagnosticInfoOptimizationBase::Argument>
+ A) {
R.insert(A);
- return std::move(R);
+ return std::forward<RemarkT>(R);
}
template <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>
- V) {
+decltype(auto) operator<<(
+ RemarkT &&R,
+ std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>::value,
+ DiagnosticInfoOptimizationBase::setIsVerbose>
+ V) {
R.insert(V);
- return R;
-}
-
-template <class RemarkT>
-RemarkT &&
-operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>
- V) {
- R.insert(V);
- return std::move(R);
-}
-
-template <class RemarkT>
-RemarkT &
-operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setExtraArgs>
- EA) {
- R.insert(EA);
- return R;
+ return std::forward<RemarkT>(R);
}
template <class RemarkT>
-RemarkT &&
-operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setExtraArgs>
- EA) {
+decltype(auto) operator<<(
+ RemarkT &&R,
+ std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>::value,
+ DiagnosticInfoOptimizationBase::setExtraArgs>
+ EA) {
R.insert(EA);
- return std::move(R);
+ return std::forward<RemarkT>(R);
}
/// Common features for diagnostics dealing with optimization remarks
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 6cf6f10f20392..5b2f0479e2b41 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -337,7 +337,8 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
return R << Arg.Val;
}
-template <class RemarkT> RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
+template <class RemarkT>
+decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) {
using namespace ore;
if (IC.isAlways()) {
R << "(cost=always)";
@@ -349,13 +350,7 @@ template <class RemarkT> RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
}
if (const char *Reason = IC.getReason())
R << ": " << ore::NV("Reason", Reason);
- return R;
-}
-
-template <class RemarkT>
-RemarkT &&operator<<(RemarkT &&R, const InlineCost &IC) {
- static_cast<RemarkT &>(R) << IC;
- return std::move(R);
+ return std::forward<RemarkT>(R);
}
} // namespace llvm
>From 60c7cae624b4c5d6d87744fd8b6e9f4aabb459eb Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <hahnjo at hahnjo.de>
Date: Wed, 12 Mar 2025 23:03:18 +0100
Subject: [PATCH 4/4] Use is_base_of_v
---
llvm/include/llvm/IR/DiagnosticInfo.h | 48 +++++++++++++--------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 0ab9f5a87e41b..779c88993b71c 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -613,45 +613,45 @@ class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
/// common base class. This allows returning the result of the insertion
/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
template <class RemarkT>
-decltype(auto) operator<<(
- RemarkT &&R,
- std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
- std::remove_reference_t<RemarkT>>::value,
- StringRef>
- S) {
+decltype(auto)
+operator<<(RemarkT &&R,
+ std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>,
+ StringRef>
+ S) {
R.insert(S);
return std::forward<RemarkT>(R);
}
template <class RemarkT>
-decltype(auto) operator<<(
- RemarkT &&R,
- std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
- std::remove_reference_t<RemarkT>>::value,
- DiagnosticInfoOptimizationBase::Argument>
- A) {
+decltype(auto)
+operator<<(RemarkT &&R,
+ std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>,
+ DiagnosticInfoOptimizationBase::Argument>
+ A) {
R.insert(A);
return std::forward<RemarkT>(R);
}
template <class RemarkT>
-decltype(auto) operator<<(
- RemarkT &&R,
- std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
- std::remove_reference_t<RemarkT>>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>
- V) {
+decltype(auto)
+operator<<(RemarkT &&R,
+ std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>,
+ DiagnosticInfoOptimizationBase::setIsVerbose>
+ V) {
R.insert(V);
return std::forward<RemarkT>(R);
}
template <class RemarkT>
-decltype(auto) operator<<(
- RemarkT &&R,
- std::enable_if_t<std::is_base_of<DiagnosticInfoOptimizationBase,
- std::remove_reference_t<RemarkT>>::value,
- DiagnosticInfoOptimizationBase::setExtraArgs>
- EA) {
+decltype(auto)
+operator<<(RemarkT &&R,
+ std::enable_if_t<std::is_base_of_v<DiagnosticInfoOptimizationBase,
+ std::remove_reference_t<RemarkT>>,
+ DiagnosticInfoOptimizationBase::setExtraArgs>
+ EA) {
R.insert(EA);
return std::forward<RemarkT>(R);
}
More information about the llvm-commits
mailing list