tint: Rework tint::Manager
Don't use dynamic casting in hashing and equality. These should be fast, and dynamic casting is expensive. Add type::UniqueNode for things that need de-duplicating and bin the types on construction. Replace some use of SFINAE with constexpr. Also fixes a build failure for x86. Bug: oss-fuzz:54184 Change-Id: Ic1b0708394f9f5703fc179a2c31ce18bd07e196c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114760 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
1438e82354
commit
7c3e9a6dd2
|
@ -583,6 +583,7 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"type/texture.h",
|
"type/texture.h",
|
||||||
"type/type.h",
|
"type/type.h",
|
||||||
"type/u32.h",
|
"type/u32.h",
|
||||||
|
"type/unique_node.h",
|
||||||
"type/vector.h",
|
"type/vector.h",
|
||||||
"type/void.h",
|
"type/void.h",
|
||||||
"utils/bitcast.h",
|
"utils/bitcast.h",
|
||||||
|
@ -754,6 +755,8 @@ libtint_source_set("libtint_type_src") {
|
||||||
"type/type.h",
|
"type/type.h",
|
||||||
"type/u32.cc",
|
"type/u32.cc",
|
||||||
"type/u32.h",
|
"type/u32.h",
|
||||||
|
"type/unique_node.cc",
|
||||||
|
"type/unique_node.h",
|
||||||
"type/vector.cc",
|
"type/vector.cc",
|
||||||
"type/vector.h",
|
"type/vector.h",
|
||||||
"type/void.cc",
|
"type/void.cc",
|
||||||
|
|
|
@ -514,6 +514,8 @@ list(APPEND TINT_LIB_SRCS
|
||||||
type/type.h
|
type/type.h
|
||||||
type/u32.cc
|
type/u32.cc
|
||||||
type/u32.h
|
type/u32.h
|
||||||
|
type/unique_node.cc
|
||||||
|
type/unique_node.h
|
||||||
type/vector.cc
|
type/vector.cc
|
||||||
type/vector.h
|
type/vector.h
|
||||||
type/void.cc
|
type/void.cc
|
||||||
|
|
|
@ -539,35 +539,18 @@ class ProgramBuilder {
|
||||||
return constant_nodes_.Create<constant::Splat>(type, element, n);
|
return constant_nodes_.Create<constant::Splat>(type, element, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new type::Type owned by the ProgramBuilder.
|
/// Creates a new type::Node owned by the ProgramBuilder.
|
||||||
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the returned node will also
|
||||||
/// returned `Type` will also be destructed.
|
/// be destructed. If T derives from type::UniqueNode, then the calling create() for the same
|
||||||
/// Types are unique (de-aliased), and so calling create() for the same `T`
|
/// `T` and arguments will return the same pointer.
|
||||||
/// and arguments will return the same pointer.
|
/// @param args the arguments to pass to the constructor
|
||||||
/// @param args the arguments to pass to the type constructor
|
/// @returns the new, or existing node
|
||||||
/// @returns the de-aliased type pointer
|
|
||||||
template <typename T, typename... ARGS>
|
template <typename T, typename... ARGS>
|
||||||
traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
|
traits::EnableIfIsType<T, type::Node>* create(ARGS&&... args) {
|
||||||
AssertNotMoved();
|
AssertNotMoved();
|
||||||
return types_.Get<T>(std::forward<ARGS>(args)...);
|
return types_.Get<T>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new type::ArrayCount owned by the ProgramBuilder.
|
|
||||||
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
|
|
||||||
/// returned `ArrayCount` will also be destructed.
|
|
||||||
/// ArrayCounts are unique (de-aliased), and so calling create() for the same `T`
|
|
||||||
/// and arguments will return the same pointer.
|
|
||||||
/// @param args the arguments to pass to the array count constructor
|
|
||||||
/// @returns the de-aliased array count pointer
|
|
||||||
template <typename T, typename... ARGS>
|
|
||||||
traits::EnableIf<traits::IsTypeOrDerived<T, type::ArrayCount> ||
|
|
||||||
traits::IsTypeOrDerived<T, type::StructMember>,
|
|
||||||
T>*
|
|
||||||
create(ARGS&&... args) {
|
|
||||||
AssertNotMoved();
|
|
||||||
return types_.GetNode<T>(std::forward<ARGS>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Marks this builder as moved, preventing any further use of the builder.
|
/// Marks this builder as moved, preventing any further use of the builder.
|
||||||
void MarkAsMoved();
|
void MarkAsMoved();
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Any final : public Castable<Any, type::Type> {
|
||||||
|
|
||||||
// Stub implementations for type::Type conformance.
|
// Stub implementations for type::Type conformance.
|
||||||
size_t Hash() const override { return 0; }
|
size_t Hash() const override { return 0; }
|
||||||
bool Equals(const type::Type&) const override { return false; }
|
bool Equals(const type::UniqueNode&) const override { return false; }
|
||||||
std::string FriendlyName(const SymbolTable&) const override { return "<any>"; }
|
std::string FriendlyName(const SymbolTable&) const override { return "<any>"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ size_t NamedOverrideArrayCount::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<NamedOverrideArrayCount>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<NamedOverrideArrayCount>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NamedOverrideArrayCount::Equals(const ArrayCount& other) const {
|
bool NamedOverrideArrayCount::Equals(const UniqueNode& other) const {
|
||||||
if (auto* v = other.As<NamedOverrideArrayCount>()) {
|
if (auto* v = other.As<NamedOverrideArrayCount>()) {
|
||||||
return variable == v->variable;
|
return variable == v->variable;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ size_t UnnamedOverrideArrayCount::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnnamedOverrideArrayCount::Equals(const ArrayCount& other) const {
|
bool UnnamedOverrideArrayCount::Equals(const UniqueNode& other) const {
|
||||||
if (auto* v = other.As<UnnamedOverrideArrayCount>()) {
|
if (auto* v = other.As<UnnamedOverrideArrayCount>()) {
|
||||||
return expr == v->expr;
|
return expr == v->expr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, t
|
||||||
/// @returns a hash of the array count.
|
/// @returns a hash of the array count.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param other the other node
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal @p other
|
||||||
bool Equals(const type::ArrayCount& t) const override;
|
bool Equals(const type::UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the symbol table
|
/// @param symbols the symbol table
|
||||||
/// @returns the friendly name for this array count
|
/// @returns the friendly name for this array count
|
||||||
|
@ -68,9 +68,9 @@ class UnnamedOverrideArrayCount final
|
||||||
/// @returns a hash of the array count.
|
/// @returns a hash of the array count.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param other the other node
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal @p other
|
||||||
bool Equals(const type::ArrayCount& t) const override;
|
bool Equals(const type::UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the symbol table
|
/// @param symbols the symbol table
|
||||||
/// @returns the friendly name for this array count
|
/// @returns the friendly name for this array count
|
||||||
|
|
|
@ -29,7 +29,7 @@ size_t AbstractFloat::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode);
|
return utils::Hash(TypeInfo::Of<AbstractFloat>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractFloat::Equals(const Type& other) const {
|
bool AbstractFloat::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<AbstractFloat>();
|
return other.Is<AbstractFloat>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class AbstractFloat final : public Castable<AbstractFloat, AbstractNumeric> {
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other type to compare against
|
||||||
/// @returns true if this type is equal to the given type
|
/// @returns true if this type is equal to the given type
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type when printed in diagnostics.
|
/// @returns the name for this type when printed in diagnostics.
|
||||||
|
|
|
@ -29,7 +29,7 @@ size_t AbstractInt::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode);
|
return utils::Hash(TypeInfo::Of<AbstractInt>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractInt::Equals(const Type& other) const {
|
bool AbstractInt::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<AbstractInt>();
|
return other.Is<AbstractInt>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,9 @@ class AbstractInt final : public Castable<AbstractInt, AbstractNumeric> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type when printed in diagnostics.
|
/// @returns the name for this type when printed in diagnostics.
|
||||||
|
|
|
@ -72,7 +72,7 @@ size_t Array::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_, stride_);
|
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_, stride_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Array::Equals(const Type& other) const {
|
bool Array::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Array>()) {
|
if (auto* o = other.As<Array>()) {
|
||||||
// Note: implicit_stride is not part of the type_name string as this is
|
// Note: implicit_stride is not part of the type_name string as this is
|
||||||
// derived from the element type
|
// derived from the element type
|
||||||
|
|
|
@ -55,9 +55,9 @@ class Array final : public Castable<Array, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @return the array element type
|
/// @return the array element type
|
||||||
Type const* ElemType() const { return element_; }
|
Type const* ElemType() const { return element_; }
|
||||||
|
|
|
@ -30,7 +30,7 @@ size_t ConstantArrayCount::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConstantArrayCount::Equals(const ArrayCount& other) const {
|
bool ConstantArrayCount::Equals(const UniqueNode& other) const {
|
||||||
if (auto* v = other.As<ConstantArrayCount>()) {
|
if (auto* v = other.As<ConstantArrayCount>()) {
|
||||||
return value == v->value;
|
return value == v->value;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ size_t RuntimeArrayCount::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RuntimeArrayCount::Equals(const ArrayCount& other) const {
|
bool RuntimeArrayCount::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<RuntimeArrayCount>();
|
return other.Is<RuntimeArrayCount>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,22 +19,15 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/symbol_table.h"
|
#include "src/tint/symbol_table.h"
|
||||||
#include "src/tint/type/node.h"
|
#include "src/tint/type/unique_node.h"
|
||||||
|
|
||||||
namespace tint::type {
|
namespace tint::type {
|
||||||
|
|
||||||
/// An array count
|
/// An array count
|
||||||
class ArrayCount : public Castable<ArrayCount, Node> {
|
class ArrayCount : public Castable<ArrayCount, UniqueNode> {
|
||||||
public:
|
public:
|
||||||
~ArrayCount() override;
|
~ArrayCount() override;
|
||||||
|
|
||||||
/// @returns a hash of the array count.
|
|
||||||
virtual size_t Hash() const = 0;
|
|
||||||
|
|
||||||
/// @param t other array count
|
|
||||||
/// @returns true if this array count is equal to the given array count
|
|
||||||
virtual bool Equals(const ArrayCount& t) const = 0;
|
|
||||||
|
|
||||||
/// @param symbols the symbol table
|
/// @param symbols the symbol table
|
||||||
/// @returns the friendly name for this array count
|
/// @returns the friendly name for this array count
|
||||||
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
|
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
|
||||||
|
@ -59,9 +52,9 @@ class ConstantArrayCount final : public Castable<ConstantArrayCount, ArrayCount>
|
||||||
/// @returns a hash of the array count.
|
/// @returns a hash of the array count.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param other the other object
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal to other
|
||||||
bool Equals(const ArrayCount& t) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the symbol table
|
/// @param symbols the symbol table
|
||||||
/// @returns the friendly name for this array count
|
/// @returns the friendly name for this array count
|
||||||
|
@ -85,9 +78,9 @@ class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
|
||||||
/// @returns a hash of the array count.
|
/// @returns a hash of the array count.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param t other array count
|
/// @param other the other object
|
||||||
/// @returns true if this array count is equal to the given array count
|
/// @returns true if this array count is equal to other
|
||||||
bool Equals(const ArrayCount& t) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the symbol table
|
/// @param symbols the symbol table
|
||||||
/// @returns the friendly name for this array count
|
/// @returns the friendly name for this array count
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t Atomic::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
|
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Atomic::Equals(const type::Type& other) const {
|
bool Atomic::Equals(const type::UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Atomic>()) {
|
if (auto* o = other.As<Atomic>()) {
|
||||||
return o->subtype_ == subtype_;
|
return o->subtype_ == subtype_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ class Atomic final : public Castable<Atomic, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const type::Type& other) const override;
|
bool Equals(const type::UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the atomic type
|
/// @returns the atomic type
|
||||||
const type::Type* Type() const { return subtype_; }
|
const type::Type* Type() const { return subtype_; }
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t Bool::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<Bool>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<Bool>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bool::Equals(const Type& other) const {
|
bool Bool::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<Bool>();
|
return other.Is<Bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,9 @@ class Bool final : public Castable<Bool, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -40,7 +40,7 @@ size_t DepthMultisampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim());
|
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepthMultisampledTexture::Equals(const Type& other) const {
|
bool DepthMultisampledTexture::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<DepthMultisampledTexture>()) {
|
if (auto* o = other.As<DepthMultisampledTexture>()) {
|
||||||
return o->dim() == dim();
|
return o->dim() == dim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ class DepthMultisampledTexture final : public Castable<DepthMultisampledTexture,
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -41,7 +41,7 @@ size_t DepthTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
|
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepthTexture::Equals(const Type& other) const {
|
bool DepthTexture::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<DepthTexture>()) {
|
if (auto* o = other.As<DepthTexture>()) {
|
||||||
return o->dim() == dim();
|
return o->dim() == dim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ class DepthTexture final : public Castable<DepthTexture, Texture> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -30,7 +30,7 @@ size_t ExternalTexture::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExternalTexture::Equals(const Type& other) const {
|
bool ExternalTexture::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<ExternalTexture>();
|
return other.Is<ExternalTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@ class ExternalTexture final : public Castable<ExternalTexture, Texture> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t F16::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<F16>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<F16>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool F16::Equals(const Type& other) const {
|
bool F16::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<F16>();
|
return other.Is<F16>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ class F16 final : public Castable<F16, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t F32::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<F32>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<F32>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool F32::Equals(const Type& other) const {
|
bool F32::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<F32>();
|
return other.Is<F32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ class F32 final : public Castable<F32, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t I32::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<I32>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<I32>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I32::Equals(const Type& other) const {
|
bool I32::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<I32>();
|
return other.Is<I32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ class I32 final : public Castable<I32, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -15,15 +15,10 @@
|
||||||
#ifndef SRC_TINT_TYPE_MANAGER_H_
|
#ifndef SRC_TINT_TYPE_MANAGER_H_
|
||||||
#define SRC_TINT_TYPE_MANAGER_H_
|
#define SRC_TINT_TYPE_MANAGER_H_
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "src/tint/type/array_count.h"
|
|
||||||
#include "src/tint/type/node.h"
|
|
||||||
#include "src/tint/type/struct.h"
|
|
||||||
#include "src/tint/type/type.h"
|
#include "src/tint/type/type.h"
|
||||||
|
#include "src/tint/utils/hash.h"
|
||||||
#include "src/tint/utils/unique_allocator.h"
|
#include "src/tint/utils/unique_allocator.h"
|
||||||
|
|
||||||
namespace tint::type {
|
namespace tint::type {
|
||||||
|
@ -60,19 +55,23 @@ class Manager final {
|
||||||
static Manager Wrap(const Manager& inner) {
|
static Manager Wrap(const Manager& inner) {
|
||||||
Manager out;
|
Manager out;
|
||||||
out.types_.Wrap(inner.types_);
|
out.types_.Wrap(inner.types_);
|
||||||
out.nodes_.Wrap(inner.nodes_);
|
out.unique_nodes_.Wrap(inner.unique_nodes_);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param args the arguments used to construct the object.
|
/// @param args the arguments used to construct the type, unique node or node.
|
||||||
/// @return a pointer to an instance of `T` with the provided arguments.
|
/// @return a pointer to an instance of `T` with the provided arguments.
|
||||||
/// If an existing instance of `T` has been constructed, then the same
|
/// If NODE derives from UniqueNode and an existing instance of `T` has been
|
||||||
/// pointer is returned.
|
/// constructed, then the same pointer is returned.
|
||||||
template <typename TYPE,
|
template <typename NODE, typename... ARGS>
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, Type>>,
|
NODE* Get(ARGS&&... args) {
|
||||||
typename... ARGS>
|
if constexpr (traits::IsTypeOrDerived<NODE, Type>) {
|
||||||
TYPE* Get(ARGS&&... args) {
|
return types_.Get<NODE>(std::forward<ARGS>(args)...);
|
||||||
return types_.Get<TYPE>(std::forward<ARGS>(args)...);
|
} else if constexpr (traits::IsTypeOrDerived<NODE, UniqueNode>) {
|
||||||
|
return unique_nodes_.Get<NODE>(std::forward<ARGS>(args)...);
|
||||||
|
} else {
|
||||||
|
return nodes_.Create<NODE>(std::forward<ARGS>(args)...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param args the arguments used to create the temporary used for the search.
|
/// @param args the arguments used to create the temporary used for the search.
|
||||||
|
@ -85,68 +84,20 @@ class Manager final {
|
||||||
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param args the arguments used to construct the object.
|
|
||||||
/// @return a pointer to an instance of `T` with the provided arguments.
|
|
||||||
/// If an existing instance of `T` has been constructed, then the same
|
|
||||||
/// pointer is returned.
|
|
||||||
template <typename TYPE,
|
|
||||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, ArrayCount> ||
|
|
||||||
traits::IsTypeOrDerived<TYPE, StructMember>>,
|
|
||||||
typename... ARGS>
|
|
||||||
TYPE* GetNode(ARGS&&... args) {
|
|
||||||
return nodes_.Get<TYPE>(std::forward<ARGS>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @returns an iterator to the beginning of the types
|
/// @returns an iterator to the beginning of the types
|
||||||
TypeIterator begin() const { return types_.begin(); }
|
TypeIterator begin() const { return types_.begin(); }
|
||||||
/// @returns an iterator to the end of the types
|
/// @returns an iterator to the end of the types
|
||||||
TypeIterator end() const { return types_.end(); }
|
TypeIterator end() const { return types_.end(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Unique types owned by the manager
|
||||||
utils::UniqueAllocator<Type> types_;
|
utils::UniqueAllocator<Type> types_;
|
||||||
utils::UniqueAllocator<Node> nodes_;
|
/// Unique nodes (excluding types) owned by the manager
|
||||||
|
utils::UniqueAllocator<UniqueNode> unique_nodes_;
|
||||||
|
/// Non-unique nodes owned by the manager
|
||||||
|
utils::BlockAllocator<Node> nodes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::type
|
} // namespace tint::type
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
/// std::hash specialization for tint::type::Node
|
|
||||||
template <>
|
|
||||||
struct hash<tint::type::Node> {
|
|
||||||
/// @param type the type to obtain a hash from
|
|
||||||
/// @returns the hash of the type
|
|
||||||
size_t operator()(const tint::type::Node& type) const {
|
|
||||||
if (const auto* ac = type.As<tint::type::ArrayCount>()) {
|
|
||||||
return ac->Hash();
|
|
||||||
} else if (type.Is<tint::type::StructMember>()) {
|
|
||||||
return tint::TypeInfo::Of<tint::type::StructMember>().full_hashcode;
|
|
||||||
}
|
|
||||||
TINT_ASSERT(Type, false && "Unreachable");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// std::equal_to specialization for tint::type::Node
|
|
||||||
template <>
|
|
||||||
struct equal_to<tint::type::Node> {
|
|
||||||
/// @param a the first type to compare
|
|
||||||
/// @param b the second type to compare
|
|
||||||
/// @returns true if the two types are equal
|
|
||||||
bool operator()(const tint::type::Node& a, const tint::type::Node& b) const {
|
|
||||||
if (const auto* ac = a.As<tint::type::ArrayCount>()) {
|
|
||||||
if (const auto* bc = b.As<tint::type::ArrayCount>()) {
|
|
||||||
return ac->Equals(*bc);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (a.Is<tint::type::StructMember>()) {
|
|
||||||
return &a == &b;
|
|
||||||
}
|
|
||||||
TINT_ASSERT(Type, false && "Unreachable");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // SRC_TINT_TYPE_MANAGER_H_
|
#endif // SRC_TINT_TYPE_MANAGER_H_
|
||||||
|
|
|
@ -46,7 +46,7 @@ size_t Matrix::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, rows_, columns_, column_type_);
|
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, rows_, columns_, column_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Matrix::Equals(const Type& other) const {
|
bool Matrix::Equals(const UniqueNode& other) const {
|
||||||
if (auto* v = other.As<Matrix>()) {
|
if (auto* v = other.As<Matrix>()) {
|
||||||
return v->rows_ == rows_ && v->columns_ == columns_ && v->column_type_ == column_type_;
|
return v->rows_ == rows_ && v->columns_ == columns_ && v->column_type_ == column_type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ class Matrix final : public Castable<Matrix, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the type of the matrix
|
/// @returns the type of the matrix
|
||||||
const Type* type() const { return subtype_; }
|
const Type* type() const { return subtype_; }
|
||||||
|
|
|
@ -34,7 +34,7 @@ size_t MultisampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(), type_);
|
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(), type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultisampledTexture::Equals(const Type& other) const {
|
bool MultisampledTexture::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<MultisampledTexture>()) {
|
if (auto* o = other.As<MultisampledTexture>()) {
|
||||||
return o->dim() == dim() && o->type_ == type_;
|
return o->dim() == dim() && o->type_ == type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ class MultisampledTexture final : public Castable<MultisampledTexture, Texture>
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the subtype of the sampled texture
|
/// @returns the subtype of the sampled texture
|
||||||
const Type* type() const { return type_; }
|
const Type* type() const { return type_; }
|
||||||
|
|
|
@ -32,7 +32,7 @@ size_t Pointer::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
|
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pointer::Equals(const Type& other) const {
|
bool Pointer::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Pointer>()) {
|
if (auto* o = other.As<Pointer>()) {
|
||||||
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
||||||
o->access_ == access_;
|
o->access_ == access_;
|
||||||
|
|
|
@ -39,9 +39,9 @@ class Pointer final : public Castable<Pointer, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the pointee type
|
/// @returns the pointee type
|
||||||
const Type* StoreType() const { return subtype_; }
|
const Type* StoreType() const { return subtype_; }
|
||||||
|
|
|
@ -31,7 +31,7 @@ size_t Reference::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
|
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Reference::Equals(const Type& other) const {
|
bool Reference::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Reference>()) {
|
if (auto* o = other.As<Reference>()) {
|
||||||
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
|
||||||
o->access_ == access_;
|
o->access_ == access_;
|
||||||
|
|
|
@ -39,9 +39,9 @@ class Reference final : public Castable<Reference, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the pointee type
|
/// @returns the pointee type
|
||||||
const Type* StoreType() const { return subtype_; }
|
const Type* StoreType() const { return subtype_; }
|
||||||
|
|
|
@ -34,7 +34,7 @@ size_t SampledTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(), type_);
|
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(), type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SampledTexture::Equals(const Type& other) const {
|
bool SampledTexture::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<SampledTexture>()) {
|
if (auto* o = other.As<SampledTexture>()) {
|
||||||
return o->dim() == dim() && o->type_ == type_;
|
return o->dim() == dim() && o->type_ == type_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ class SampledTexture final : public Castable<SampledTexture, Texture> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the subtype of the sampled texture
|
/// @returns the subtype of the sampled texture
|
||||||
Type* type() const { return const_cast<Type*>(type_); }
|
Type* type() const { return const_cast<Type*>(type_); }
|
||||||
|
|
|
@ -31,7 +31,7 @@ size_t Sampler::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
|
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sampler::Equals(const Type& other) const {
|
bool Sampler::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Sampler>()) {
|
if (auto* o = other.As<Sampler>()) {
|
||||||
return o->kind_ == kind_;
|
return o->kind_ == kind_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ class Sampler final : public Castable<Sampler, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the sampler type
|
/// @returns the sampler type
|
||||||
ast::SamplerKind kind() const { return kind_; }
|
ast::SamplerKind kind() const { return kind_; }
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t StorageTexture::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(), texel_format_, access_);
|
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(), texel_format_, access_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageTexture::Equals(const Type& other) const {
|
bool StorageTexture::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<StorageTexture>()) {
|
if (auto* o = other.As<StorageTexture>()) {
|
||||||
return o->dim() == dim() && o->texel_format_ == texel_format_ && o->access_ == access_;
|
return o->dim() == dim() && o->texel_format_ == texel_format_ && o->access_ == access_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,9 @@ class StorageTexture final : public Castable<StorageTexture, Texture> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the storage subtype
|
/// @returns the storage subtype
|
||||||
Type* type() const { return subtype_; }
|
Type* type() const { return subtype_; }
|
||||||
|
|
|
@ -70,7 +70,7 @@ size_t Struct::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
|
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Struct::Equals(const Type& other) const {
|
bool Struct::Equals(const UniqueNode& other) const {
|
||||||
if (auto* o = other.As<Struct>()) {
|
if (auto* o = other.As<Struct>()) {
|
||||||
return o->name_ == name_;
|
return o->name_ == name_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,9 @@ class Struct : public Castable<Struct, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the source of the structure
|
/// @returns the source of the structure
|
||||||
tint::Source Source() const { return source_; }
|
tint::Source Source() const { return source_; }
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/type/node.h"
|
#include "src/tint/type/unique_node.h"
|
||||||
#include "src/tint/utils/enum_set.h"
|
#include "src/tint/utils/enum_set.h"
|
||||||
#include "src/tint/utils/vector.h"
|
#include "src/tint/utils/vector.h"
|
||||||
|
|
||||||
|
@ -46,18 +46,12 @@ enum Flag {
|
||||||
using Flags = utils::EnumSet<Flag>;
|
using Flags = utils::EnumSet<Flag>;
|
||||||
|
|
||||||
/// Base class for a type in the system
|
/// Base class for a type in the system
|
||||||
class Type : public Castable<Type, Node> {
|
class Type : public Castable<Type, UniqueNode> {
|
||||||
public:
|
public:
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
Type(Type&&);
|
Type(Type&&);
|
||||||
~Type() override;
|
~Type() override;
|
||||||
|
|
||||||
/// @returns a hash of the type.
|
|
||||||
virtual size_t Hash() const = 0;
|
|
||||||
|
|
||||||
/// @returns true if the this type is equal to the given type
|
|
||||||
virtual bool Equals(const Type&) const = 0;
|
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
/// declared in WGSL.
|
/// declared in WGSL.
|
||||||
|
|
|
@ -35,7 +35,7 @@ size_t U32::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<U32>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<U32>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool U32::Equals(const Type& other) const {
|
bool U32::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<U32>();
|
return other.Is<U32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ class U32 final : public Castable<U32, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/tint/type/unique_node.h"
|
||||||
|
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(tint::type::UniqueNode);
|
||||||
|
|
||||||
|
namespace tint::type {
|
||||||
|
|
||||||
|
UniqueNode::UniqueNode() = default;
|
||||||
|
|
||||||
|
UniqueNode::UniqueNode(const UniqueNode&) = default;
|
||||||
|
|
||||||
|
UniqueNode::~UniqueNode() = default;
|
||||||
|
|
||||||
|
} // namespace tint::type
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SRC_TINT_TYPE_UNIQUE_NODE_H_
|
||||||
|
#define SRC_TINT_TYPE_UNIQUE_NODE_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "src/tint/type/node.h"
|
||||||
|
|
||||||
|
namespace tint::type {
|
||||||
|
|
||||||
|
/// UniqueNode is the base class for objects that are de-duplicated by the Manager.
|
||||||
|
/// Deduplication is achieved by comparing a temporary object to the set of existing objects, using
|
||||||
|
/// Hash() and Equals(). If an existing object is found, then the pointer to that object is
|
||||||
|
/// returned, otherwise a new object is constructed, added to the Manager's set and returned.
|
||||||
|
class UniqueNode : public Castable<UniqueNode, Node> {
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
UniqueNode();
|
||||||
|
|
||||||
|
/// Copy constructor
|
||||||
|
UniqueNode(const UniqueNode&);
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tint::type
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
/// std::hash specialization for tint::type::UniqueNode
|
||||||
|
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(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// std::equal_to specialization for tint::type::UniqueNode
|
||||||
|
template <>
|
||||||
|
struct equal_to<tint::type::UniqueNode> {
|
||||||
|
/// @param a the first unique node to compare
|
||||||
|
/// @param b the second unique node to compare
|
||||||
|
/// @returns true if the two nodes are equal
|
||||||
|
bool operator()(const tint::type::UniqueNode& a, const tint::type::UniqueNode& b) const {
|
||||||
|
return &a == &b || a.Equals(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // SRC_TINT_TYPE_UNIQUE_NODE_H_
|
|
@ -41,7 +41,7 @@ size_t Vector::Hash() const {
|
||||||
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, width_, subtype_);
|
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, width_, subtype_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vector::Equals(const Type& other) const {
|
bool Vector::Equals(const UniqueNode& other) const {
|
||||||
if (auto* v = other.As<Vector>()) {
|
if (auto* v = other.As<Vector>()) {
|
||||||
return v->width_ == width_ && v->subtype_ == subtype_;
|
return v->width_ == width_ && v->subtype_ == subtype_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ class Vector final : public Castable<Vector, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @returns the type of the vector elements
|
/// @returns the type of the vector elements
|
||||||
const Type* type() const { return subtype_; }
|
const Type* type() const { return subtype_; }
|
||||||
|
|
|
@ -30,7 +30,7 @@ size_t Void::Hash() const {
|
||||||
return static_cast<size_t>(TypeInfo::Of<Void>().full_hashcode);
|
return static_cast<size_t>(TypeInfo::Of<Void>().full_hashcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Void::Equals(const Type& other) const {
|
bool Void::Equals(const UniqueNode& other) const {
|
||||||
return other.Is<Void>();
|
return other.Is<Void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ class Void final : public Castable<Void, Type> {
|
||||||
/// @returns a hash of the type.
|
/// @returns a hash of the type.
|
||||||
size_t Hash() const override;
|
size_t Hash() const override;
|
||||||
|
|
||||||
/// @param other the other type to compare against
|
/// @param other the other node to compare against
|
||||||
/// @returns true if the this type is equal to the given type
|
/// @returns true if the this type is equal to @p other
|
||||||
bool Equals(const Type& other) const override;
|
bool Equals(const UniqueNode& other) const override;
|
||||||
|
|
||||||
/// @param symbols the program's symbol table
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
|
|
Loading…
Reference in New Issue