tint: Replace type::UniqueNode::Hash() virtual with field

Virtual methods are expensive to call, and hashes are frequently tested.
The hash must be immutable, so just calculate it once in the constructor and store it as an immutable field.

Change-Id: I9d29fb3fc074e57e7af91367768a47193baa40f1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114780
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-12-19 17:07:29 +00:00 committed by Dawn LUCI CQ
parent ada5e7b0f9
commit ce93a6b224
75 changed files with 169 additions and 397 deletions

View File

@ -57,11 +57,10 @@ constexpr static const size_t kNumFixedCandidates = 8;
/// A special type that matches all TypeMatchers
class Any final : public Castable<Any, type::Type> {
public:
Any() : Base(type::Flags{}) {}
Any() : Base(0u, type::Flags{}) {}
~Any() override = default;
// Stub implementations for type::Type conformance.
size_t Hash() const override { return 0; }
bool Equals(const type::UniqueNode&) const override { return false; }
std::string FriendlyName(const SymbolTable&) const override { return "<any>"; }
};

View File

@ -20,13 +20,10 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::UnnamedOverrideArrayCount);
namespace tint::sem {
NamedOverrideArrayCount::NamedOverrideArrayCount(const GlobalVariable* var)
: Base(), variable(var) {}
: Base(static_cast<size_t>(TypeInfo::Of<NamedOverrideArrayCount>().full_hashcode)),
variable(var) {}
NamedOverrideArrayCount::~NamedOverrideArrayCount() = default;
size_t NamedOverrideArrayCount::Hash() const {
return static_cast<size_t>(TypeInfo::Of<NamedOverrideArrayCount>().full_hashcode);
}
bool NamedOverrideArrayCount::Equals(const UniqueNode& other) const {
if (auto* v = other.As<NamedOverrideArrayCount>()) {
return variable == v->variable;
@ -38,13 +35,10 @@ std::string NamedOverrideArrayCount::FriendlyName(const SymbolTable& symbols) co
return symbols.NameFor(variable->Declaration()->symbol);
}
UnnamedOverrideArrayCount::UnnamedOverrideArrayCount(const Expression* e) : Base(), expr(e) {}
UnnamedOverrideArrayCount::UnnamedOverrideArrayCount(const Expression* e)
: Base(static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode)), expr(e) {}
UnnamedOverrideArrayCount::~UnnamedOverrideArrayCount() = default;
size_t UnnamedOverrideArrayCount::Hash() const {
return static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode);
}
bool UnnamedOverrideArrayCount::Equals(const UniqueNode& other) const {
if (auto* v = other.As<UnnamedOverrideArrayCount>()) {
return expr == v->expr;

View File

@ -36,9 +36,6 @@ class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, t
explicit NamedOverrideArrayCount(const GlobalVariable* var);
~NamedOverrideArrayCount() override;
/// @returns a hash of the array count.
size_t Hash() const override;
/// @param other the other node
/// @returns true if this array count is equal @p other
bool Equals(const type::UniqueNode& other) const override;
@ -65,9 +62,6 @@ class UnnamedOverrideArrayCount final
explicit UnnamedOverrideArrayCount(const Expression* e);
~UnnamedOverrideArrayCount() override;
/// @returns a hash of the array count.
size_t Hash() const override;
/// @param other the other node
/// @returns true if this array count is equal @p other
bool Equals(const type::UniqueNode& other) const override;

View File

@ -21,14 +21,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::AbstractFloat);
namespace tint::type {
AbstractFloat::AbstractFloat() = default;
AbstractFloat::AbstractFloat(AbstractFloat&&) = default;
AbstractFloat::AbstractFloat() : Base(utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode)) {}
AbstractFloat::~AbstractFloat() = default;
size_t AbstractFloat::Hash() const {
return utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode);
}
bool AbstractFloat::Equals(const UniqueNode& other) const {
return other.Is<AbstractFloat>();
}

View File

@ -28,13 +28,9 @@ class AbstractFloat final : public Castable<AbstractFloat, AbstractNumeric> {
/// Constructor
AbstractFloat();
/// Move constructor
AbstractFloat(AbstractFloat&&);
/// Destructor
~AbstractFloat() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other type to compare against
/// @returns true if this type is equal to the given type
bool Equals(const UniqueNode& other) const override;

View File

@ -21,13 +21,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::AbstractInt);
namespace tint::type {
AbstractInt::AbstractInt() = default;
AbstractInt::AbstractInt(AbstractInt&&) = default;
AbstractInt::~AbstractInt() = default;
AbstractInt::AbstractInt() : Base(utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode)) {}
size_t AbstractInt::Hash() const {
return utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode);
}
AbstractInt::~AbstractInt() = default;
bool AbstractInt::Equals(const UniqueNode& other) const {
return other.Is<AbstractInt>();

View File

@ -28,13 +28,9 @@ class AbstractInt final : public Castable<AbstractInt, AbstractNumeric> {
/// Constructor
AbstractInt();
/// Move constructor
AbstractInt(AbstractInt&&);
/// Destructor
~AbstractInt() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -18,13 +18,13 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::AbstractNumeric);
namespace tint::type {
AbstractNumeric::AbstractNumeric()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
AbstractNumeric::AbstractNumeric(AbstractNumeric&&) = default;
AbstractNumeric::AbstractNumeric(size_t hash)
: Base(hash,
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
AbstractNumeric::~AbstractNumeric() = default;
uint32_t AbstractNumeric::Size() const {

View File

@ -26,10 +26,10 @@ namespace tint::type {
class AbstractNumeric : public Castable<AbstractNumeric, Type> {
public:
/// Constructor
AbstractNumeric();
/// @param hash the unique hash of the node
explicit AbstractNumeric(size_t hash);
/// Move constructor
AbstractNumeric(AbstractNumeric&&);
/// Destructor
~AbstractNumeric() override;
/// @returns 0, as the type is abstract.

View File

@ -58,7 +58,8 @@ Array::Array(const Type* element,
uint32_t size,
uint32_t stride,
uint32_t implicit_stride)
: Base(FlagsFrom(element, count)),
: Base(utils::Hash(TypeInfo::Of<Array>().full_hashcode, count, align, size, stride),
FlagsFrom(element, count)),
element_(element),
count_(count),
align_(align),
@ -68,10 +69,6 @@ Array::Array(const Type* element,
TINT_ASSERT(Type, element_);
}
size_t Array::Hash() const {
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_, stride_);
}
bool Array::Equals(const UniqueNode& other) const {
if (auto* o = other.As<Array>()) {
// Note: implicit_stride is not part of the type_name string as this is

View File

@ -52,9 +52,6 @@ class Array final : public Castable<Array, Type> {
uint32_t stride,
uint32_t implicit_stride);
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -20,16 +20,13 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::RuntimeArrayCount);
namespace tint::type {
ArrayCount::ArrayCount() : Base() {}
ArrayCount::ArrayCount(size_t hash) : Base(hash) {}
ArrayCount::~ArrayCount() = default;
ConstantArrayCount::ConstantArrayCount(uint32_t val) : Base(), value(val) {}
ConstantArrayCount::ConstantArrayCount(uint32_t val)
: Base(static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode)), value(val) {}
ConstantArrayCount::~ConstantArrayCount() = default;
size_t ConstantArrayCount::Hash() const {
return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
}
bool ConstantArrayCount::Equals(const UniqueNode& other) const {
if (auto* v = other.As<ConstantArrayCount>()) {
return value == v->value;
@ -41,13 +38,10 @@ std::string ConstantArrayCount::FriendlyName(const SymbolTable&) const {
return std::to_string(value);
}
RuntimeArrayCount::RuntimeArrayCount() : Base() {}
RuntimeArrayCount::RuntimeArrayCount()
: Base(static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode)) {}
RuntimeArrayCount::~RuntimeArrayCount() = default;
size_t RuntimeArrayCount::Hash() const {
return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
}
bool RuntimeArrayCount::Equals(const UniqueNode& other) const {
return other.Is<RuntimeArrayCount>();
}

View File

@ -33,7 +33,9 @@ class ArrayCount : public Castable<ArrayCount, UniqueNode> {
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
protected:
ArrayCount();
/// Constructor
/// @param hash the unique hash of the node
explicit ArrayCount(size_t hash);
};
/// The variant of an ArrayCount when the array is a const-expression.
@ -49,9 +51,6 @@ class ConstantArrayCount final : public Castable<ConstantArrayCount, ArrayCount>
explicit ConstantArrayCount(uint32_t val);
~ConstantArrayCount() override;
/// @returns a hash of the array count.
size_t Hash() const override;
/// @param other the other object
/// @returns true if this array count is equal to other
bool Equals(const UniqueNode& other) const override;
@ -75,9 +74,6 @@ class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
RuntimeArrayCount();
~RuntimeArrayCount() override;
/// @returns a hash of the array count.
size_t Hash() const override;
/// @param other the other object
/// @returns true if this array count is equal to other
bool Equals(const UniqueNode& other) const override;
@ -89,27 +85,4 @@ class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
} // namespace tint::type
namespace std {
/// std::hash specialization for tint::type::ArrayCount
template <>
struct hash<tint::type::ArrayCount> {
/// @param a the array count to obtain a hash from
/// @returns the hash of the array count
size_t operator()(const tint::type::ArrayCount& a) const { return a.Hash(); }
};
/// std::equal_to specialization for tint::type::ArrayCount
template <>
struct equal_to<tint::type::ArrayCount> {
/// @param a the first array count to compare
/// @param b the second array count to compare
/// @returns true if the two array counts are equal
bool operator()(const tint::type::ArrayCount& a, const tint::type::ArrayCount& b) const {
return a.Equals(b);
}
};
} // namespace std
#endif // SRC_TINT_TYPE_ARRAY_COUNT_H_

View File

@ -75,7 +75,7 @@ TEST_F(ArrayTest, Hash) {
auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(ArrayTest, Equals) {

View File

@ -23,18 +23,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Atomic);
namespace tint::type {
Atomic::Atomic(const type::Type* subtype)
: Base(type::Flags{
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
: Base(utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype),
type::Flags{
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
subtype_(subtype) {
TINT_ASSERT(AST, !subtype->Is<Reference>());
}
size_t Atomic::Hash() const {
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
}
bool Atomic::Equals(const type::UniqueNode& other) const {
if (auto* o = other.As<Atomic>()) {
return o->subtype_ == subtype_;
@ -56,8 +53,6 @@ uint32_t Atomic::Align() const {
return subtype_->Align();
}
Atomic::Atomic(Atomic&&) = default;
Atomic::~Atomic() = default;
} // namespace tint::type

View File

@ -28,13 +28,9 @@ class Atomic final : public Castable<Atomic, Type> {
/// @param subtype the atomic type
explicit Atomic(const type::Type* subtype);
/// Move constructor
Atomic(Atomic&&);
/// Destructor
~Atomic() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const type::UniqueNode& other) const override;

View File

@ -33,7 +33,7 @@ TEST_F(AtomicTest, Creation) {
TEST_F(AtomicTest, Hash) {
auto* a = create<Atomic>(create<I32>());
auto* b = create<Atomic>(create<I32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(AtomicTest, Equals) {

View File

@ -21,20 +21,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Bool);
namespace tint::type {
Bool::Bool()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
Bool::Bool(Bool&&) = default;
: Base(static_cast<size_t>(TypeInfo::Of<Bool>().full_hashcode),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
Bool::~Bool() = default;
size_t Bool::Hash() const {
return static_cast<size_t>(TypeInfo::Of<Bool>().full_hashcode);
}
bool Bool::Equals(const UniqueNode& other) const {
return other.Is<Bool>();
}

View File

@ -32,12 +32,9 @@ class Bool final : public Castable<Bool, Type> {
public:
/// Constructor
Bool();
/// Move constructor
Bool(Bool&&);
~Bool() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~Bool() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -29,7 +29,7 @@ TEST_F(BoolTest, Creation) {
TEST_F(BoolTest, Hash) {
auto* a = create<Bool>();
auto* b = create<Bool>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(BoolTest, Equals) {

View File

@ -28,18 +28,13 @@ bool IsValidDepthDimension(ast::TextureDimension dim) {
} // namespace
DepthMultisampledTexture::DepthMultisampledTexture(ast::TextureDimension dim) : Base(dim) {
DepthMultisampledTexture::DepthMultisampledTexture(ast::TextureDimension dim)
: Base(utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim), dim) {
TINT_ASSERT(Type, IsValidDepthDimension(dim));
}
DepthMultisampledTexture::DepthMultisampledTexture(DepthMultisampledTexture&&) = default;
DepthMultisampledTexture::~DepthMultisampledTexture() = default;
size_t DepthMultisampledTexture::Hash() const {
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim());
}
bool DepthMultisampledTexture::Equals(const UniqueNode& other) const {
if (auto* o = other.As<DepthMultisampledTexture>()) {
return o->dim() == dim();

View File

@ -27,12 +27,9 @@ class DepthMultisampledTexture final : public Castable<DepthMultisampledTexture,
/// Constructor
/// @param dim the dimensionality of the texture
explicit DepthMultisampledTexture(ast::TextureDimension dim);
/// Move constructor
DepthMultisampledTexture(DepthMultisampledTexture&&);
~DepthMultisampledTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~DepthMultisampledTexture() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -35,7 +35,7 @@ TEST_F(DepthMultisampledTextureTest, Hash) {
auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(DepthMultisampledTextureTest, Equals) {

View File

@ -29,18 +29,13 @@ bool IsValidDepthDimension(ast::TextureDimension dim) {
} // namespace
DepthTexture::DepthTexture(ast::TextureDimension dim) : Base(dim) {
DepthTexture::DepthTexture(ast::TextureDimension dim)
: Base(utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim), dim) {
TINT_ASSERT(Type, IsValidDepthDimension(dim));
}
DepthTexture::DepthTexture(DepthTexture&&) = default;
DepthTexture::~DepthTexture() = default;
size_t DepthTexture::Hash() const {
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
}
bool DepthTexture::Equals(const UniqueNode& other) const {
if (auto* o = other.As<DepthTexture>()) {
return o->dim() == dim();

View File

@ -27,12 +27,9 @@ class DepthTexture final : public Castable<DepthTexture, Texture> {
/// Constructor
/// @param dim the dimensionality of the texture
explicit DepthTexture(ast::TextureDimension dim);
/// Move constructor
DepthTexture(DepthTexture&&);
~DepthTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~DepthTexture() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -37,7 +37,7 @@ TEST_F(DepthTextureTest, Hash) {
auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(DepthTextureTest, Equals) {

View File

@ -20,16 +20,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::ExternalTexture);
namespace tint::type {
ExternalTexture::ExternalTexture() : Base(ast::TextureDimension::k2d) {}
ExternalTexture::ExternalTexture(ExternalTexture&&) = default;
ExternalTexture::ExternalTexture()
: Base(static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode),
ast::TextureDimension::k2d) {}
ExternalTexture::~ExternalTexture() = default;
size_t ExternalTexture::Hash() const {
return static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode);
}
bool ExternalTexture::Equals(const UniqueNode& other) const {
return other.Is<ExternalTexture>();
}

View File

@ -27,13 +27,9 @@ class ExternalTexture final : public Castable<ExternalTexture, Texture> {
/// Constructor
ExternalTexture();
/// Move constructor
ExternalTexture(ExternalTexture&&);
/// Destructor
~ExternalTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -34,7 +34,7 @@ TEST_F(ExternalTextureTest, Creation) {
TEST_F(ExternalTextureTest, Hash) {
auto* a = create<ExternalTexture>();
auto* b = create<ExternalTexture>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(ExternalTextureTest, Equals) {

View File

@ -21,20 +21,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::F16);
namespace tint::type {
F16::F16()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
F16::F16(F16&&) = default;
: Base(static_cast<size_t>(TypeInfo::Of<F16>().full_hashcode),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
F16::~F16() = default;
size_t F16::Hash() const {
return static_cast<size_t>(TypeInfo::Of<F16>().full_hashcode);
}
bool F16::Equals(const UniqueNode& other) const {
return other.Is<F16>();
}

View File

@ -26,12 +26,9 @@ class F16 final : public Castable<F16, Type> {
public:
/// Constructor
F16();
/// Move constructor
F16(F16&&);
~F16() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~F16() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -29,7 +29,7 @@ TEST_F(F16Test, Creation) {
TEST_F(F16Test, Hash) {
auto* a = create<F16>();
auto* b = create<F16>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(F16Test, Equals) {

View File

@ -21,20 +21,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::F32);
namespace tint::type {
F32::F32()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
F32::F32(F32&&) = default;
: Base(static_cast<size_t>(TypeInfo::Of<F32>().full_hashcode),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
F32::~F32() = default;
size_t F32::Hash() const {
return static_cast<size_t>(TypeInfo::Of<F32>().full_hashcode);
}
bool F32::Equals(const UniqueNode& other) const {
return other.Is<F32>();
}

View File

@ -26,12 +26,9 @@ class F32 final : public Castable<F32, Type> {
public:
/// Constructor
F32();
/// Move constructor
F32(F32&&);
~F32() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~F32() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -29,7 +29,7 @@ TEST_F(F32Test, Creation) {
TEST_F(F32Test, Hash) {
auto* a = create<F32>();
auto* b = create<F32>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(F32Test, Equals) {

View File

@ -21,20 +21,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::I32);
namespace tint::type {
I32::I32()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
I32::I32(I32&&) = default;
: Base(static_cast<size_t>(TypeInfo::Of<I32>().full_hashcode),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
I32::~I32() = default;
size_t I32::Hash() const {
return static_cast<size_t>(TypeInfo::Of<I32>().full_hashcode);
}
bool I32::Equals(const UniqueNode& other) const {
return other.Is<I32>();
}

View File

@ -26,12 +26,9 @@ class I32 final : public Castable<I32, Type> {
public:
/// Constructor
I32();
/// Move constructor
I32(I32&&);
~I32() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~I32() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -29,7 +29,7 @@ TEST_F(I32Test, Creation) {
TEST_F(I32Test, Hash) {
auto* a = create<I32>();
auto* b = create<I32>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(I32Test, Equals) {

View File

@ -23,11 +23,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Matrix);
namespace tint::type {
Matrix::Matrix(const Vector* column_type, uint32_t columns)
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
: Base(utils::Hash(TypeInfo::Of<Vector>().full_hashcode, columns, column_type),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
subtype_(column_type->type()),
column_type_(column_type),
rows_(column_type->Width()),
@ -38,14 +39,8 @@ Matrix::Matrix(const Vector* column_type, uint32_t columns)
TINT_ASSERT(AST, columns_ < 5);
}
Matrix::Matrix(Matrix&&) = default;
Matrix::~Matrix() = default;
size_t Matrix::Hash() const {
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, rows_, columns_, column_type_);
}
bool Matrix::Equals(const UniqueNode& other) const {
if (auto* v = other.As<Matrix>()) {
return v->rows_ == rows_ && v->columns_ == columns_ && v->column_type_ == column_type_;

View File

@ -33,12 +33,9 @@ class Matrix final : public Castable<Matrix, Type> {
/// @param column_type the type of a column of the matrix
/// @param columns the number of columns in the matrix
Matrix(const Vector* column_type, uint32_t columns);
/// Move constructor
Matrix(Matrix&&);
~Matrix() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~Matrix() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -41,7 +41,7 @@ TEST_F(MatrixTest, Hash) {
auto* a = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
auto* b = create<Matrix>(create<Vector>(create<I32>(), 3u), 4u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(MatrixTest, Equals) {

View File

@ -22,18 +22,13 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::MultisampledTexture);
namespace tint::type {
MultisampledTexture::MultisampledTexture(ast::TextureDimension dim, const Type* type)
: Base(dim), type_(type) {
: Base(utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim, type), dim),
type_(type) {
TINT_ASSERT(Type, type_);
}
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
MultisampledTexture::~MultisampledTexture() = default;
size_t MultisampledTexture::Hash() const {
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(), type_);
}
bool MultisampledTexture::Equals(const UniqueNode& other) const {
if (auto* o = other.As<MultisampledTexture>()) {
return o->dim() == dim() && o->type_ == type_;

View File

@ -28,12 +28,9 @@ class MultisampledTexture final : public Castable<MultisampledTexture, Texture>
/// @param dim the dimensionality of the texture
/// @param type the data type of the multisampled texture
MultisampledTexture(ast::TextureDimension dim, const Type* type);
/// Move constructor
MultisampledTexture(MultisampledTexture&&);
~MultisampledTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~MultisampledTexture() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -38,7 +38,7 @@ TEST_F(MultisampledTextureTest, Creation) {
TEST_F(MultisampledTextureTest, Hash) {
auto* a = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
auto* b = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(MultisampledTextureTest, Equals) {

View File

@ -23,15 +23,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Pointer);
namespace tint::type {
Pointer::Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
: Base(type::Flags{}), subtype_(subtype), address_space_(address_space), access_(access) {
: Base(utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space, subtype, access),
type::Flags{}),
subtype_(subtype),
address_space_(address_space),
access_(access) {
TINT_ASSERT(Type, !subtype->Is<Reference>());
TINT_ASSERT(Type, access != ast::Access::kUndefined);
}
size_t Pointer::Hash() const {
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
}
bool Pointer::Equals(const UniqueNode& other) const {
if (auto* o = other.As<Pointer>()) {
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
@ -51,8 +51,6 @@ std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
return out.str();
}
Pointer::Pointer(Pointer&&) = default;
Pointer::~Pointer() = default;
} // namespace tint::type

View File

@ -32,13 +32,9 @@ class Pointer final : public Castable<Pointer, Type> {
/// @param access the resolved access control of the reference
Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
/// Move constructor
Pointer(Pointer&&);
/// Destructor
~Pointer() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -41,7 +41,7 @@ TEST_F(PointerTest, Hash) {
auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(PointerTest, Equals) {

View File

@ -22,15 +22,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Reference);
namespace tint::type {
Reference::Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
: Base(type::Flags{}), subtype_(subtype), address_space_(address_space), access_(access) {
: Base(utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space, subtype, access),
type::Flags{}),
subtype_(subtype),
address_space_(address_space),
access_(access) {
TINT_ASSERT(Type, !subtype->Is<Reference>());
TINT_ASSERT(Type, access != ast::Access::kUndefined);
}
size_t Reference::Hash() const {
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
}
bool Reference::Equals(const UniqueNode& other) const {
if (auto* o = other.As<Reference>()) {
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
@ -50,8 +50,6 @@ std::string Reference::FriendlyName(const SymbolTable& symbols) const {
return out.str();
}
Reference::Reference(Reference&&) = default;
Reference::~Reference() = default;
} // namespace tint::type

View File

@ -32,13 +32,9 @@ class Reference final : public Castable<Reference, Type> {
/// @param access the resolved access control of the reference
Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
/// Move constructor
Reference(Reference&&);
/// Destructor
~Reference() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -47,7 +47,7 @@ TEST_F(ReferenceTest, Hash) {
auto* b =
create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(ReferenceTest, Equals) {

View File

@ -22,18 +22,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::SampledTexture);
namespace tint::type {
SampledTexture::SampledTexture(ast::TextureDimension dim, const Type* type)
: Base(dim), type_(type) {
: Base(utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim, type), dim), type_(type) {
TINT_ASSERT(Type, type_);
}
SampledTexture::SampledTexture(SampledTexture&&) = default;
SampledTexture::~SampledTexture() = default;
size_t SampledTexture::Hash() const {
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(), type_);
}
bool SampledTexture::Equals(const UniqueNode& other) const {
if (auto* o = other.As<SampledTexture>()) {
return o->dim() == dim() && o->type_ == type_;

View File

@ -28,12 +28,9 @@ class SampledTexture final : public Castable<SampledTexture, Texture> {
/// @param dim the dimensionality of the texture
/// @param type the data type of the sampled texture
SampledTexture(ast::TextureDimension dim, const Type* type);
/// Move constructor
SampledTexture(SampledTexture&&);
~SampledTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~SampledTexture() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -42,7 +42,7 @@ TEST_F(SampledTextureTest, Hash) {
auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(SampledTextureTest, Equals) {

View File

@ -21,16 +21,11 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Sampler);
namespace tint::type {
Sampler::Sampler(ast::SamplerKind kind) : Base(type::Flags{}), kind_(kind) {}
Sampler::Sampler(Sampler&&) = default;
Sampler::Sampler(ast::SamplerKind kind)
: Base(utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind), type::Flags{}), kind_(kind) {}
Sampler::~Sampler() = default;
size_t Sampler::Hash() const {
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
}
bool Sampler::Equals(const UniqueNode& other) const {
if (auto* o = other.As<Sampler>()) {
return o->kind_ == kind_;

View File

@ -28,12 +28,9 @@ class Sampler final : public Castable<Sampler, Type> {
/// Constructor
/// @param kind the kind of sampler
explicit Sampler(ast::SamplerKind kind);
/// Move constructor
Sampler(Sampler&&);
~Sampler() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~Sampler() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -40,7 +40,7 @@ TEST_F(SamplerTest, Hash) {
auto* a = create<Sampler>(ast::SamplerKind::kSampler);
auto* b = create<Sampler>(ast::SamplerKind::kSampler);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(SamplerTest, Equals) {

View File

@ -25,16 +25,13 @@ StorageTexture::StorageTexture(ast::TextureDimension dim,
ast::TexelFormat format,
ast::Access access,
Type* subtype)
: Base(dim), texel_format_(format), access_(access), subtype_(subtype) {}
StorageTexture::StorageTexture(StorageTexture&&) = default;
: Base(utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim, format, access), dim),
texel_format_(format),
access_(access),
subtype_(subtype) {}
StorageTexture::~StorageTexture() = default;
size_t StorageTexture::Hash() const {
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(), texel_format_, access_);
}
bool StorageTexture::Equals(const UniqueNode& other) const {
if (auto* o = other.As<StorageTexture>()) {
return o->dim() == dim() && o->texel_format_ == texel_format_ && o->access_ == access_;

View File

@ -41,13 +41,9 @@ class StorageTexture final : public Castable<StorageTexture, Texture> {
ast::Access access,
Type* subtype);
/// Move constructor
StorageTexture(StorageTexture&&);
/// Destructor
~StorageTexture() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -56,7 +56,7 @@ TEST_F(StorageTextureTest, Hash) {
auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
ast::Access::kReadWrite);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(StorageTextureTest, Equals) {

View File

@ -56,7 +56,7 @@ Struct::Struct(tint::Source source,
uint32_t align,
uint32_t size,
uint32_t size_no_padding)
: Base(FlagsFrom(members)),
: Base(utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name), FlagsFrom(members)),
source_(source),
name_(name),
members_(std::move(members)),
@ -66,10 +66,6 @@ Struct::Struct(tint::Source source,
Struct::~Struct() = default;
size_t Struct::Hash() const {
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
}
bool Struct::Equals(const UniqueNode& other) const {
if (auto* o = other.As<Struct>()) {
return o->name_ == name_;

View File

@ -65,9 +65,6 @@ class Struct : public Castable<Struct, Type> {
/// Destructor
~Struct() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other
bool Equals(const UniqueNode& other) const override;

View File

@ -18,9 +18,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Texture);
namespace tint::type {
Texture::Texture(ast::TextureDimension dim) : Base(type::Flags{}), dim_(dim) {}
Texture::Texture(Texture&&) = default;
Texture::Texture(size_t hash, ast::TextureDimension dim) : Base(hash, type::Flags{}), dim_(dim) {}
Texture::~Texture() = default;

View File

@ -24,10 +24,10 @@ namespace tint::type {
class Texture : public Castable<Texture, Type> {
public:
/// Constructor
/// @param hash the unique hash of the node
/// @param dim the dimensionality of the texture
explicit Texture(ast::TextureDimension dim);
/// Move constructor
Texture(Texture&&);
Texture(size_t hash, ast::TextureDimension dim);
/// Destructor
~Texture() override;
/// @returns the texture dimension

View File

@ -34,14 +34,12 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Type);
namespace tint::type {
Type::Type(type::Flags flags) : flags_(flags) {
Type::Type(size_t hash, type::Flags flags) : Base(hash), flags_(flags) {
if (IsConstructible()) {
TINT_ASSERT(Type, HasCreationFixedFootprint());
}
}
Type::Type(Type&&) = default;
Type::~Type() = default;
const Type* Type::UnwrapPtr() const {

View File

@ -48,8 +48,7 @@ using Flags = utils::EnumSet<Flag>;
/// Base class for a type in the system
class Type : public Castable<Type, UniqueNode> {
public:
/// Move constructor
Type(Type&&);
/// Destructor
~Type() override;
/// @param symbols the program's symbol table
@ -187,8 +186,9 @@ class Type : public Castable<Type, UniqueNode> {
protected:
/// Constructor
/// @param hash the immutable hash for the node
/// @param flags the flags of this type
explicit Type(type::Flags flags);
Type(size_t hash, type::Flags flags);
/// The flags of this type.
const type::Flags flags_;
@ -203,7 +203,7 @@ template <>
struct hash<tint::type::Type> {
/// @param type the type to obtain a hash from
/// @returns the hash of the type
size_t operator()(const tint::type::Type& type) const { return type.Hash(); }
size_t operator()(const tint::type::Type& type) const { return type.unique_hash; }
};
/// std::equal_to specialization for tint::type::Type

View File

@ -21,20 +21,15 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::U32);
namespace tint::type {
U32::U32()
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
: Base(static_cast<size_t>(TypeInfo::Of<U32>().full_hashcode),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}) {}
U32::~U32() = default;
U32::U32(U32&&) = default;
size_t U32::Hash() const {
return static_cast<size_t>(TypeInfo::Of<U32>().full_hashcode);
}
bool U32::Equals(const UniqueNode& other) const {
return other.Is<U32>();
}

View File

@ -26,12 +26,9 @@ class U32 final : public Castable<U32, Type> {
public:
/// Constructor
U32();
/// Move constructor
U32(U32&&);
~U32() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~U32() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -29,7 +29,7 @@ TEST_F(U32Test, Creation) {
TEST_F(U32Test, Hash) {
auto* a = create<U32>();
auto* b = create<U32>();
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(U32Test, Equals) {

View File

@ -18,10 +18,6 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::UniqueNode);
namespace tint::type {
UniqueNode::UniqueNode() = default;
UniqueNode::UniqueNode(const UniqueNode&) = default;
UniqueNode::~UniqueNode() = default;
} // namespace tint::type

View File

@ -28,20 +28,18 @@ namespace tint::type {
class UniqueNode : public Castable<UniqueNode, Node> {
public:
/// Constructor
UniqueNode();
/// Copy constructor
UniqueNode(const UniqueNode&);
/// @param hash the immutable hash for the node
inline explicit UniqueNode(size_t hash) : unique_hash(hash) {}
/// Destructor
~UniqueNode() override;
/// @returns a hash of the node.
virtual size_t Hash() const = 0;
/// @param other the other node to compare this node against
/// @returns true if the this node is equal to @p other
virtual bool Equals(const UniqueNode& other) const = 0;
/// the immutable hash for the node
const size_t unique_hash;
};
} // namespace tint::type
@ -53,7 +51,7 @@ template <>
struct hash<tint::type::UniqueNode> {
/// @param node the unique node to obtain a hash from
/// @returns the hash of the node
size_t operator()(const tint::type::UniqueNode& node) const { return node.Hash(); }
size_t operator()(const tint::type::UniqueNode& node) const { return node.unique_hash; }
};
/// std::equal_to specialization for tint::type::UniqueNode

View File

@ -22,25 +22,20 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Vector);
namespace tint::type {
Vector::Vector(Type const* subtype, uint32_t width)
: Base(type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
: Base(utils::Hash(TypeInfo::Of<Vector>().full_hashcode, width, subtype),
type::Flags{
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
}),
subtype_(subtype),
width_(width) {
TINT_ASSERT(Type, width_ > 1);
TINT_ASSERT(Type, width_ < 5);
}
Vector::Vector(Vector&&) = default;
Vector::~Vector() = default;
size_t Vector::Hash() const {
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, width_, subtype_);
}
bool Vector::Equals(const UniqueNode& other) const {
if (auto* v = other.As<Vector>()) {
return v->width_ == width_ && v->subtype_ == subtype_;

View File

@ -28,12 +28,9 @@ class Vector final : public Castable<Vector, Type> {
/// @param subtype the vector element type
/// @param size the number of elements in the vector
Vector(Type const* subtype, uint32_t size);
/// Move constructor
Vector(Vector&&);
~Vector() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~Vector() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other

View File

@ -38,7 +38,7 @@ TEST_F(VectorTest, Hash) {
auto* a = create<Vector>(create<I32>(), 2u);
auto* b = create<Vector>(create<I32>(), 2u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_EQ(a->unique_hash, b->unique_hash);
}
TEST_F(VectorTest, Equals) {

View File

@ -20,16 +20,10 @@ TINT_INSTANTIATE_TYPEINFO(tint::type::Void);
namespace tint::type {
Void::Void() : Base(type::Flags{}) {}
Void::Void(Void&&) = default;
Void::Void() : Base(static_cast<size_t>(TypeInfo::Of<Void>().full_hashcode), type::Flags{}) {}
Void::~Void() = default;
size_t Void::Hash() const {
return static_cast<size_t>(TypeInfo::Of<Void>().full_hashcode);
}
bool Void::Equals(const UniqueNode& other) const {
return other.Is<Void>();
}

View File

@ -26,12 +26,9 @@ class Void final : public Castable<Void, Type> {
public:
/// Constructor
Void();
/// Move constructor
Void(Void&&);
~Void() override;
/// @returns a hash of the type.
size_t Hash() const override;
/// Destructor
~Void() override;
/// @param other the other node to compare against
/// @returns true if the this type is equal to @p other