sem::Type: Replace GetDefaultAlignAndSize() with Size() and Align()

This is a cleaner API, and the implementation doesn't have to know a bunch of information about all the derived types.

Change-Id: I96bebcb9f3ceda86fa34bd8e70961dee63fd7e13
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59301
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton
2021-07-22 18:56:54 +00:00
committed by Tint LUCI CQ
parent f5ed2ba906
commit fced350b3d
26 changed files with 205 additions and 107 deletions

View File

@@ -68,5 +68,13 @@ std::string Array::FriendlyName(const SymbolTable& symbols) const {
return out.str();
}
uint32_t Array::Align() const {
return align_;
}
uint32_t Array::Size() const {
return size_;
}
} // namespace sem
} // namespace tint

View File

@@ -62,12 +62,12 @@ class Array : public Castable<Array, Type> {
/// @returns the byte alignment of the array
/// @note this may differ from the alignment of a structure member of this
/// array type, if the member is annotated with the `[[align(n)]]` decoration.
uint32_t Align() const { return align_; }
uint32_t Align() const override;
/// @returns the byte size of the array
/// @note this may differ from the size of a structure member of this array
/// type, if the member is annotated with the `[[size(n)]]` decoration.
uint32_t SizeInBytes() const { return size_; }
uint32_t Size() const override;
/// @returns the number of bytes from the start of one element of the
/// array to the start of the next element

View File

@@ -38,6 +38,14 @@ std::string Atomic::FriendlyName(const SymbolTable& symbols) const {
return out.str();
}
uint32_t Atomic::Size() const {
return subtype_->Size();
}
uint32_t Atomic::Align() const {
return subtype_->Align();
}
Atomic::Atomic(Atomic&&) = default;
Atomic::~Atomic() = default;

View File

@@ -44,6 +44,12 @@ class Atomic : public Castable<Atomic, Type> {
/// declared in WGSL.
std::string FriendlyName(const SymbolTable& symbols) const override;
/// @returns the size in bytes of the type.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type.
uint32_t Align() const override;
private:
sem::Type const* const subtype_;
};

View File

@@ -39,5 +39,13 @@ bool Bool::IsConstructible() const {
return true;
}
uint32_t Bool::Size() const {
return 4;
}
uint32_t Bool::Align() const {
return 4;
}
} // namespace sem
} // namespace tint

View File

@@ -48,6 +48,16 @@ class Bool : public Castable<Bool, Type> {
/// @returns true if constructible as per
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the size in bytes of the type.
/// @note: booleans are not host-sharable, but still may exist in workgroup
/// storage.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type.
/// @note: booleans are not host-sharable, but still may exist in workgroup
/// storage.
uint32_t Align() const override;
};
} // namespace sem

View File

@@ -39,5 +39,13 @@ bool F32::IsConstructible() const {
return true;
}
uint32_t F32::Size() const {
return 4;
}
uint32_t F32::Align() const {
return 4;
}
} // namespace sem
} // namespace tint

View File

@@ -42,6 +42,12 @@ class F32 : public Castable<F32, Type> {
/// @returns true if constructible as per
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the size in bytes of the type.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type.
uint32_t Align() const override;
};
} // namespace sem

View File

@@ -39,5 +39,13 @@ bool I32::IsConstructible() const {
return true;
}
uint32_t I32::Size() const {
return 4;
}
uint32_t I32::Align() const {
return 4;
}
} // namespace sem
} // namespace tint

View File

@@ -42,6 +42,12 @@ class I32 : public Castable<I32, Type> {
/// @returns true if constructible as per
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the size in bytes of the type.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type.
uint32_t Align() const override;
};
} // namespace sem

View File

@@ -53,5 +53,17 @@ bool Matrix::IsConstructible() const {
return true;
}
uint32_t Matrix::Size() const {
return column_type_->Align() * columns();
}
uint32_t Matrix::Align() const {
return column_type_->Align();
}
uint32_t Matrix::ColumnStride() const {
return column_type_->Align();
}
} // namespace sem
} // namespace tint

View File

@@ -58,6 +58,16 @@ class Matrix : public Castable<Matrix, Type> {
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the size in bytes of the type. This may include tail padding.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type. This may include tail
/// padding.
uint32_t Align() const override;
/// @returns the number of bytes between columns of the matrix
uint32_t ColumnStride() const;
private:
Type* const subtype_;
Vector* const column_type_;

View File

@@ -27,7 +27,7 @@ TEST_F(ArrayTest, CreateSizedArray) {
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 2u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->SizeInBytes(), 8u);
EXPECT_EQ(arr->Size(), 8u);
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 16u);
EXPECT_FALSE(arr->IsStrideImplicit());
@@ -40,7 +40,7 @@ TEST_F(ArrayTest, CreateRuntimeArray) {
EXPECT_EQ(arr->ElemType(), &u32);
EXPECT_EQ(arr->Count(), 0u);
EXPECT_EQ(arr->Align(), 4u);
EXPECT_EQ(arr->SizeInBytes(), 8u);
EXPECT_EQ(arr->Size(), 8u);
EXPECT_EQ(arr->Stride(), 32u);
EXPECT_EQ(arr->ImplicitStride(), 32u);
EXPECT_TRUE(arr->IsStrideImplicit());

View File

@@ -60,6 +60,14 @@ std::string Struct::type_name() const {
return declaration_->type_name();
}
uint32_t Struct::Align() const {
return align_;
}
uint32_t Struct::Size() const {
return size_;
}
std::string Struct::FriendlyName(const SymbolTable& symbols) const {
return symbols.NameFor(declaration_->name());
}

View File

@@ -86,13 +86,13 @@ class Struct : public Castable<Struct, Type> {
/// @note this may differ from the alignment of a structure member of this
/// structure type, if the member is annotated with the `[[align(n)]]`
/// decoration.
uint32_t Align() const { return align_; }
uint32_t Align() const override;
/// @returns the byte size of the structure
/// @note this may differ from the size of a structure member of this
/// structure type, if the member is annotated with the `[[size(n)]]`
/// decoration.
uint32_t Size() const { return size_; }
uint32_t Size() const override;
/// @returns the byte size of the members without the end of structure
/// alignment padding

View File

@@ -14,9 +14,6 @@
#include "src/sem/type.h"
#include "src/debug.h"
#include "src/sem/array.h"
#include "src/sem/atomic_type.h"
#include "src/sem/bool_type.h"
#include "src/sem/f32_type.h"
#include "src/sem/i32_type.h"
@@ -24,7 +21,6 @@
#include "src/sem/pointer_type.h"
#include "src/sem/reference_type.h"
#include "src/sem/sampler_type.h"
#include "src/sem/struct.h"
#include "src/sem/texture_type.h"
#include "src/sem/u32_type.h"
#include "src/sem/vector_type.h"
@@ -56,59 +52,12 @@ const Type* Type::UnwrapRef() const {
return type;
}
void Type::GetDefaultAlignAndSize(uint32_t& align, uint32_t& size) const {
TINT_ASSERT(Semantic, !As<Reference>());
TINT_ASSERT(Semantic, !As<Pointer>());
uint32_t Type::Size() const {
return 0;
}
static constexpr uint32_t vector_size[] = {
/* padding */ 0,
/* padding */ 0,
/*vec2*/ 8,
/*vec3*/ 12,
/*vec4*/ 16,
};
static constexpr uint32_t vector_align[] = {
/* padding */ 0,
/* padding */ 0,
/*vec2*/ 8,
/*vec3*/ 16,
/*vec4*/ 16,
};
if (is_scalar()) {
// Note: Also captures booleans, but these are not host-shareable.
align = 4;
size = 4;
return;
}
if (auto* vec = As<Vector>()) {
TINT_ASSERT(Semantic, vec->Width() >= 2 && vec->Width() <= 4);
align = vector_align[vec->Width()];
size = vector_size[vec->Width()];
return;
}
if (auto* mat = As<Matrix>()) {
TINT_ASSERT(Semantic, mat->columns() >= 2 && mat->columns() <= 4);
TINT_ASSERT(Semantic, mat->rows() >= 2 && mat->rows() <= 4);
align = vector_align[mat->rows()];
size = vector_align[mat->rows()] * mat->columns();
return;
}
if (auto* s = As<Struct>()) {
align = s->Align();
size = s->Size();
return;
}
if (auto* a = As<Array>()) {
align = a->Align();
size = a->SizeInBytes();
return;
}
if (auto* a = As<Atomic>()) {
return a->Type()->GetDefaultAlignAndSize(align, size);
}
TINT_ASSERT(Semantic, false);
uint32_t Type::Align() const {
return 0;
}
bool Type::IsConstructible() const {

View File

@@ -52,9 +52,14 @@ class Type : public Castable<Type, Node> {
/// @returns the inner type if this is a reference, `this` otherwise
const Type* UnwrapRef() const;
/// @param align the output default alignment in bytes for this type.
/// @param size the output default size in bytes for this type.
void GetDefaultAlignAndSize(uint32_t& align, uint32_t& size) const;
/// @returns the size in bytes of the type. This may include tail padding.
/// @note opaque types will return a size of 0.
virtual uint32_t Size() const;
/// @returns the alignment in bytes of the type. This may include tail
/// padding.
/// @note opaque types will return a size of 0.
virtual uint32_t Align() const;
/// @returns true if constructible as per
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types

View File

@@ -39,5 +39,13 @@ bool U32::IsConstructible() const {
return true;
}
uint32_t U32::Size() const {
return 4;
}
uint32_t U32::Align() const {
return 4;
}
} // namespace sem
} // namespace tint

View File

@@ -42,6 +42,12 @@ class U32 : public Castable<U32, Type> {
/// @returns true if constructible as per
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the size in bytes of the type.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type.
uint32_t Align() const override;
};
} // namespace sem

View File

@@ -45,5 +45,37 @@ bool Vector::IsConstructible() const {
return true;
}
uint32_t Vector::Size() const {
return SizeOf(width_);
}
uint32_t Vector::Align() const {
return AlignOf(width_);
}
uint32_t Vector::SizeOf(uint32_t width) {
switch (width) {
case 2:
return 8;
case 3:
return 12;
case 4:
return 16;
}
return 0; // Unreachable
}
uint32_t Vector::AlignOf(uint32_t width) {
switch (width) {
case 2:
return 8;
case 3:
return 16;
case 4:
return 16;
}
return 0; // Unreachable
}
} // namespace sem
} // namespace tint

View File

@@ -39,9 +39,6 @@ class Vector : public Castable<Vector, Type> {
/// @returns the name for th type
std::string type_name() const override;
/// @returns the width of the vector
uint32_t Width() const { return width_; }
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
@@ -51,6 +48,24 @@ class Vector : public Castable<Vector, Type> {
/// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool IsConstructible() const override;
/// @returns the number of elements in the vector
uint32_t Width() const { return width_; }
/// @returns the size in bytes of the type. This may include tail padding.
uint32_t Size() const override;
/// @returns the alignment in bytes of the type. This may include tail
/// padding.
uint32_t Align() const override;
/// @param width the width of the vector
/// @returns the size in bytes of a vector of the given width.
static uint32_t SizeOf(uint32_t width);
/// @param width the width of the vector
/// @returns the alignment in bytes of a vector of the given width.
static uint32_t AlignOf(uint32_t width);
private:
Type const* const subtype_;
uint32_t const width_;