Castable: Optimize Switch() (part 2)
Use the TypeInfo already obtained from the object instead of calling As<T>() again, which would trigger another virtual call.
Bug: tint:1383
Change-Id: I0394ea049589b0f7f72c80509ac8e9536196f368
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79302
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/castable.h b/src/castable.h
index fb893cb..29784ee 100644
--- a/src/castable.h
+++ b/src/castable.h
@@ -130,14 +130,13 @@
return true;
}
- return type->Is(&Of<std::remove_const_t<TO>>());
+ return type->Is(&Of<std::remove_cv_t<TO>>());
}
/// @returns the static TypeInfo for the type T
template <typename T>
static const TypeInfo& Of() {
- using NO_CV = typename std::remove_cv<T>::type;
- return detail::TypeInfoOf<NO_CV>::info;
+ return detail::TypeInfoOf<std::remove_cv_t<T>>::info;
}
/// @returns a compile-time hashcode for the type `T`.
@@ -148,6 +147,9 @@
static constexpr HashCode HashCodeOf() {
static_assert(traits::IsTypeOrDerived<T, CastableBase>::value,
"T is not Castable");
+ static_assert(
+ std::is_same_v<T, std::remove_cv_t<T>>,
+ "Strip const / volatile decorations before calling HashCodeOf");
/// Use the compiler's "pretty" function name, which includes the template
/// type, to obtain a unique hash value.
#ifdef _MSC_VER
@@ -180,7 +182,7 @@
if constexpr (kCount == 0) {
return 0;
} else if constexpr (kCount == 1) {
- return HashCodeOf<std::tuple_element_t<0, TUPLE>>();
+ return HashCodeOf<std::remove_cv_t<std::tuple_element_t<0, TUPLE>>>();
} else {
constexpr auto kMid = kCount / 2;
return CombinedHashCodeOfTuple<traits::SliceTuple<0, kMid, TUPLE>>() |
@@ -472,8 +474,8 @@
/// @note does not handle the Default case
/// @see Switch().
template <typename FN>
-using SwitchCaseType = std::remove_const_t<std::remove_pointer_t<
- traits::ParameterType<std::remove_reference_t<FN>, 0>>>;
+using SwitchCaseType = std::remove_pointer_t<
+ traits::ParameterType<std::remove_reference_t<FN>, 0>>;
/// Evaluates to true if the function `FN` has the signature of a Default case
/// in a Switch().
@@ -530,7 +532,8 @@
// Attempt to dynamically cast the object to the handler type. If that
// succeeds, call the case handler with the cast object.
using CaseType = SwitchCaseType<CaseFunc>;
- if (auto* ptr = As<CaseType>(object)) {
+ if (type->Is(&TypeInfo::Of<CaseType>())) {
+ auto* ptr = static_cast<CaseType*>(object);
if constexpr (kHasReturnType) {
*result = std::get<0>(cases)(ptr);
} else {