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>
This commit is contained in:
Ben Clayton 2022-02-04 21:00:13 +00:00
parent 3fbe98e657
commit 3d5b38447a
1 changed files with 10 additions and 7 deletions

View File

@ -130,14 +130,13 @@ struct TypeInfo {
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 @@ struct TypeInfo {
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 @@ struct TypeInfo {
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 @@ namespace detail {
/// @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 @@ inline bool NonDefaultCases(T* object,
// 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 {