Gabe Black has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/49130 )
Change subject: cpu: Switch std::variant out for std::any in IntResult.
......................................................................
cpu: Switch std::variant out for std::any in IntResult.
This avoids having to explicitly list the types that the result can
hold, avoiding having to specify what the vector types are. Also, the
variant type always has enough space for the result no matter what type
it is. For the "any" type, implementations are encouraged to not
dynamically allocate storage for small values (and RegVal == uint64_t
probably qualifies). This means that for the common case, RegVal, the
amount of storage will be smaller, and only when we actually need space
to store a VecRegContainer, etc, will that actually be allocated.
Change-Id: I43bf8d1866b1538db7d91cd9f1e635df642dd2c9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49130
Maintainer: Gabe Black <[email protected]>
Reviewed-by: Yu-hsin Wang <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/cpu/inst_res.hh
1 file changed, 60 insertions(+), 21 deletions(-)
Approvals:
Yu-hsin Wang: Looks good to me, approved
Gabe Black: Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/cpu/inst_res.hh b/src/cpu/inst_res.hh
index 19ce640..c9507ba 100644
--- a/src/cpu/inst_res.hh
+++ b/src/cpu/inst_res.hh
@@ -38,10 +38,11 @@
#ifndef __CPU_INST_RES_HH__
#define __CPU_INST_RES_HH__
+#include <any>
#include <type_traits>
-#include <variant>
#include "arch/vecregs.hh"
+#include "base/logging.hh"
#include "base/types.hh"
namespace gem5
@@ -50,25 +51,61 @@
class InstResult
{
private:
- std::variant<RegVal, TheISA::VecRegContainer,
- TheISA::VecPredRegContainer> result;
+ std::any result;
+ std::function<bool(const std::any &a, const std::any &b)> equals;
public:
/** Default constructor creates an invalid result. */
- InstResult() = default;
+ InstResult() :
+ // This InstResult is empty, and will only equal other InstResults
+ // which are also empty.
+ equals([](const std::any &a, const std::any &b) -> bool {
+ gem5_assert(!a.has_value());
+ return !b.has_value();
+ })
+ {}
InstResult(const InstResult &) = default;
template <typename T>
- explicit InstResult(T val) : result(val) {}
+ explicit InstResult(T val) : result(val),
- template <typename T, typename enable=
- std::enable_if_t<std::is_floating_point_v<T>>>
- explicit InstResult(T val) : result(floatToBits(val)) {}
+ // Set equals so it knows how to compare results of type T.
+ equals([](const std::any &a, const std::any &b) -> bool {
+ // If one has a value but the other doesn't, not equal.
+ if (a.has_value() != b.has_value())
+ return false;
+ // If they are both empty, equal.
+ if (!a.has_value())
+ return true;
+ // At least the local object should be of the right type.
+ gem5_assert(a.type() == typeid(T));
+ // If these aren't the same type, not equal.
+ if (a.type() != b.type())
+ return false;
+ // We now know these both hold a result of the right type.
+ return std::any_cast<const T&>(a) == std::any_cast<const
T&>(b);
+ })
+ {
+ static_assert(!std::is_pointer_v<T>,
+ "InstResult shouldn't point to external data.");
+ }
+
+ // Convert floating point values to integers.
+ template <typename T,
+ std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
+ explicit InstResult(T val) : InstResult(floatToBits(val)) {}
+
+ // Convert all integer types to RegVal.
+ template <typename T,
+ std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T,
RegVal>,
+ int> = 0>
+ explicit InstResult(T val) : InstResult(static_cast<RegVal>(val)) {}
InstResult &
operator=(const InstResult& that)
{
result = that.result;
+ equals = that.equals;
return *this;
}
@@ -79,7 +116,7 @@
bool
operator==(const InstResult& that) const
{
- return result == that.result;
+ return equals(result, that.result);
}
bool
@@ -94,23 +131,23 @@
bool
isScalar() const
{
- return std::holds_alternative<RegVal>(result);
+ return result.type() == typeid(RegVal);
}
/** Is this a vector result?. */
bool
isVector() const
{
- return std::holds_alternative<TheISA::VecRegContainer>(result);
+ return result.type() == typeid(TheISA::VecRegContainer);
}
/** Is this a predicate result?. */
bool
isPred() const
{
- return std::holds_alternative<TheISA::VecPredRegContainer>(result);
+ return result.type() == typeid(TheISA::VecPredRegContainer);
}
/** Is this a valid result?. */
- bool isValid() const { return result.index() != 0; }
+ bool isValid() const { return result.has_value(); }
/** @} */
/** Explicit cast-like operations. */
@@ -118,8 +155,8 @@
RegVal
asInteger() const
{
- assert(isScalar());
- return std::get<RegVal>(result);
+ panic_if(!isScalar(), "Converting non-scalar to scalar!!");
+ return std::any_cast<RegVal>(result);
}
/** Cast to integer without checking type.
@@ -129,21 +166,23 @@
RegVal
asIntegerNoAssert() const
{
- const RegVal *ptr = std::get_if<RegVal>(&result);
- return ptr ? *ptr : 0;
+ if (!isScalar())
+ return 0;
+ return std::any_cast<RegVal>(result);
}
- const TheISA::VecRegContainer&
+
+ TheISA::VecRegContainer
asVector() const
{
panic_if(!isVector(), "Converting scalar (or invalid) to
vector!!");
- return std::get<TheISA::VecRegContainer>(result);
+ return std::any_cast<TheISA::VecRegContainer>(result);
}
- const TheISA::VecPredRegContainer&
+ TheISA::VecPredRegContainer
asPred() const
{
panic_if(!isPred(), "Converting scalar (or invalid) to
predicate!!");
- return std::get<TheISA::VecPredRegContainer>(result);
+ return std::any_cast<TheISA::VecPredRegContainer>(result);
}
/** @} */
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/49130
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I43bf8d1866b1538db7d91cd9f1e635df642dd2c9
Gerrit-Change-Number: 49130
Gerrit-PatchSet: 10
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Bobby R. Bruce <[email protected]>
Gerrit-Reviewer: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: Jui-min Lee <[email protected]>
Gerrit-Reviewer: Yu-hsin Wang <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s