mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 17:35:30 +00:00
sem: Fold together sem::Array and sem::ArrayType
There's now no need to have both. Removes a whole bunch of Sem().Get() smell, and simplifies the resolver. Also fixes a long-standing issue where an array with an explicit, but equal-to-implicit-stride attribute would result in a different type to an array without the decoration. Bug: tint:724 Fixed: tint:782 Change-Id: I0202459009cd45be427cdb621993a5a3b07ff51e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50301 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
6732e8561c
commit
4cd5eea87e
@@ -42,7 +42,7 @@ ast::ArrayAccessorExpression* BoundArrayAccessors::Transform(
|
||||
auto& diags = ctx->dst->Diagnostics();
|
||||
|
||||
auto* ret_type = ctx->src->Sem().Get(expr->array())->Type()->UnwrapAll();
|
||||
if (!ret_type->Is<sem::ArrayType>() && !ret_type->Is<sem::Matrix>() &&
|
||||
if (!ret_type->Is<sem::Array>() && !ret_type->Is<sem::Matrix>() &&
|
||||
!ret_type->Is<sem::Vector>()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -52,10 +52,10 @@ ast::ArrayAccessorExpression* BoundArrayAccessors::Transform(
|
||||
|
||||
uint32_t size = 0;
|
||||
bool is_vec = ret_type->Is<sem::Vector>();
|
||||
bool is_arr = ret_type->Is<sem::ArrayType>();
|
||||
bool is_arr = ret_type->Is<sem::Array>();
|
||||
if (is_vec || is_arr) {
|
||||
size = is_vec ? ret_type->As<sem::Vector>()->size()
|
||||
: ret_type->As<sem::ArrayType>()->size();
|
||||
: ret_type->As<sem::Array>()->Count();
|
||||
} else {
|
||||
// The row accessor would have been an embedded array accessor and already
|
||||
// handled, so we just need to do columns here.
|
||||
|
||||
@@ -77,8 +77,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
|
||||
// get_buffer_size_intrinsic() emits the function decorated with
|
||||
// BufferSizeIntrinsic that is transformed by the HLSL writer into a call to
|
||||
// [RW]ByteAddressBuffer.GetDimensions().
|
||||
std::unordered_map<sem::Struct*, Symbol> buffer_size_intrinsics;
|
||||
auto get_buffer_size_intrinsic = [&](sem::Struct* buffer_type) {
|
||||
std::unordered_map<const sem::Struct*, Symbol> buffer_size_intrinsics;
|
||||
auto get_buffer_size_intrinsic = [&](const sem::Struct* buffer_type) {
|
||||
return utils::GetOrCreate(buffer_size_intrinsics, buffer_type, [&] {
|
||||
auto name = ctx.dst->Sym();
|
||||
auto* buffer_typename =
|
||||
|
||||
@@ -175,8 +175,8 @@ std::unique_ptr<Offset> Mul(LHS&& lhs_, RHS&& rhs_) {
|
||||
|
||||
/// TypePair is a pair of types that can be used as a unordered map or set key.
|
||||
struct TypePair {
|
||||
sem::Type* first;
|
||||
sem::Type* second;
|
||||
sem::Type const* first;
|
||||
sem::Type const* second;
|
||||
bool operator==(const TypePair& rhs) const {
|
||||
return first == rhs.first && second == rhs.second;
|
||||
}
|
||||
@@ -188,20 +188,20 @@ struct TypePair {
|
||||
};
|
||||
|
||||
/// @returns the size in bytes of a scalar
|
||||
uint32_t ScalarSize(sem::Type*) {
|
||||
uint32_t ScalarSize(const sem::Type*) {
|
||||
// TODO(bclayton): Assumes 32-bit elements
|
||||
return 4;
|
||||
}
|
||||
|
||||
/// @returns the numer of bytes between columns of the given matrix
|
||||
uint32_t MatrixColumnStride(sem::Matrix* mat) {
|
||||
uint32_t MatrixColumnStride(const sem::Matrix* mat) {
|
||||
return ScalarSize(mat->type()) * ((mat->rows() == 2) ? 2 : 4);
|
||||
}
|
||||
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function to load the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
|
||||
sem::Type* ty) {
|
||||
const sem::Type* ty) {
|
||||
using Intrinsic = DecomposeStorageAccess::Intrinsic;
|
||||
|
||||
auto intrinsic = [builder](Intrinsic::Type type) {
|
||||
@@ -260,7 +260,7 @@ DecomposeStorageAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
|
||||
/// @returns a DecomposeStorageAccess::Intrinsic decoration that can be applied
|
||||
/// to a stub function to store the type `ty`.
|
||||
DecomposeStorageAccess::Intrinsic* IntrinsicStoreFor(ProgramBuilder* builder,
|
||||
sem::Type* ty) {
|
||||
const sem::Type* ty) {
|
||||
using Intrinsic = DecomposeStorageAccess::Intrinsic;
|
||||
|
||||
auto intrinsic = [builder](Intrinsic::Type type) {
|
||||
@@ -331,7 +331,7 @@ void InsertGlobal(CloneContext& ctx,
|
||||
}
|
||||
|
||||
/// @returns the unwrapped, user-declared constructed type of ty.
|
||||
const ast::NamedType* ConstructedTypeOf(sem::Type* ty) {
|
||||
const ast::NamedType* ConstructedTypeOf(const sem::Type* ty) {
|
||||
while (true) {
|
||||
if (auto* ptr = ty->As<sem::Pointer>()) {
|
||||
ty = ptr->type();
|
||||
@@ -350,7 +350,7 @@ const ast::NamedType* ConstructedTypeOf(sem::Type* ty) {
|
||||
}
|
||||
|
||||
/// @returns the given type with all pointers and aliases removed.
|
||||
sem::Type* UnwrapPtrAndAlias(sem::Type* ty) {
|
||||
const sem::Type* UnwrapPtrAndAlias(const sem::Type* ty) {
|
||||
return ty->UnwrapPtrIfNeeded()->UnwrapAliasIfNeeded()->UnwrapPtrIfNeeded();
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ sem::Type* UnwrapPtrAndAlias(sem::Type* ty) {
|
||||
struct StorageBufferAccess {
|
||||
sem::Expression const* var = nullptr; // Storage buffer variable
|
||||
std::unique_ptr<Offset> offset; // The byte offset on var
|
||||
sem::Type* type = nullptr; // The type of the access
|
||||
sem::Type const* type = nullptr; // The type of the access
|
||||
operator bool() const { return var; } // Returns true if valid
|
||||
};
|
||||
|
||||
@@ -422,8 +422,8 @@ struct DecomposeStorageAccess::State {
|
||||
/// @return the name of the function that performs the load
|
||||
Symbol LoadFunc(CloneContext& ctx,
|
||||
const ast::NamedType* insert_after,
|
||||
sem::Type* buf_ty,
|
||||
sem::Type* el_ty) {
|
||||
const sem::Type* buf_ty,
|
||||
const sem::Type* el_ty) {
|
||||
return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] {
|
||||
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
|
||||
ast::VariableList params = {
|
||||
@@ -458,13 +458,11 @@ struct DecomposeStorageAccess::State {
|
||||
member->Type()->UnwrapAll());
|
||||
values.emplace_back(ctx.dst->Call(load, "buffer", offset));
|
||||
}
|
||||
} else if (auto* arr_ty = el_ty->As<sem::ArrayType>()) {
|
||||
auto& sem = ctx.src->Sem();
|
||||
auto* arr = sem.Get(arr_ty);
|
||||
for (uint32_t i = 0; i < arr_ty->size(); i++) {
|
||||
} else if (auto* arr = el_ty->As<sem::Array>()) {
|
||||
for (uint32_t i = 0; i < arr->Count(); i++) {
|
||||
auto* offset = ctx.dst->Add("offset", arr->Stride() * i);
|
||||
Symbol load = LoadFunc(ctx, insert_after, buf_ty,
|
||||
arr_ty->type()->UnwrapAll());
|
||||
arr->ElemType()->UnwrapAll());
|
||||
values.emplace_back(ctx.dst->Call(load, "buffer", offset));
|
||||
}
|
||||
}
|
||||
@@ -491,8 +489,8 @@ struct DecomposeStorageAccess::State {
|
||||
/// @return the name of the function that performs the store
|
||||
Symbol StoreFunc(CloneContext& ctx,
|
||||
const ast::NamedType* insert_after,
|
||||
sem::Type* buf_ty,
|
||||
sem::Type* el_ty) {
|
||||
const sem::Type* buf_ty,
|
||||
const sem::Type* el_ty) {
|
||||
return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] {
|
||||
auto* buf_ast_ty = CreateASTTypeFor(&ctx, buf_ty);
|
||||
auto* el_ast_ty = CreateASTTypeFor(&ctx, el_ty);
|
||||
@@ -533,14 +531,12 @@ struct DecomposeStorageAccess::State {
|
||||
auto* call = ctx.dst->Call(store, "buffer", offset, access);
|
||||
body.emplace_back(ctx.dst->create<ast::CallStatement>(call));
|
||||
}
|
||||
} else if (auto* arr_ty = el_ty->As<sem::ArrayType>()) {
|
||||
auto& sem = ctx.src->Sem();
|
||||
auto* arr = sem.Get(arr_ty);
|
||||
for (uint32_t i = 0; i < arr_ty->size(); i++) {
|
||||
} else if (auto* arr = el_ty->As<sem::Array>()) {
|
||||
for (uint32_t i = 0; i < arr->Count(); i++) {
|
||||
auto* offset = ctx.dst->Add("offset", arr->Stride() * i);
|
||||
auto* access = ctx.dst->IndexAccessor("value", ctx.dst->Expr(i));
|
||||
Symbol store = StoreFunc(ctx, insert_after, buf_ty,
|
||||
arr_ty->type()->UnwrapAll());
|
||||
arr->ElemType()->UnwrapAll());
|
||||
auto* call = ctx.dst->Call(store, "buffer", offset, access);
|
||||
body.emplace_back(ctx.dst->create<ast::CallStatement>(call));
|
||||
}
|
||||
@@ -689,14 +685,13 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) {
|
||||
if (auto* accessor = node->As<ast::ArrayAccessorExpression>()) {
|
||||
if (auto access = state.TakeAccess(accessor->array())) {
|
||||
// X[Y]
|
||||
if (auto* arr_ty = access.type->As<sem::ArrayType>()) {
|
||||
auto stride = sem.Get(arr_ty)->Stride();
|
||||
auto offset = Mul(stride, accessor->idx_expr());
|
||||
if (auto* arr = access.type->As<sem::Array>()) {
|
||||
auto offset = Mul(arr->Stride(), accessor->idx_expr());
|
||||
state.AddAccess(accessor,
|
||||
{
|
||||
access.var,
|
||||
Add(std::move(access.offset), std::move(offset)),
|
||||
arr_ty->type()->UnwrapAll(),
|
||||
arr->ElemType()->UnwrapAll(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ void Hlsl::PromoteInitializersToConstVar(CloneContext& ctx) const {
|
||||
}
|
||||
|
||||
auto* src_ty = src_sem_expr->Type();
|
||||
if (src_ty->IsAnyOf<sem::ArrayType, sem::Struct>()) {
|
||||
if (src_ty->IsAnyOf<sem::Array, sem::Struct>()) {
|
||||
// Create a new symbol for the constant
|
||||
auto dst_symbol = ctx.dst->Sym();
|
||||
// Clone the type
|
||||
|
||||
@@ -230,7 +230,7 @@ void Spirv::HandleSampleMaskBuiltins(CloneContext& ctx) const {
|
||||
// Use the same name as the old variable.
|
||||
auto var_name = ctx.Clone(var->symbol());
|
||||
// Use `array<u32, 1>` for the new variable.
|
||||
auto type = ctx.dst->ty.array(ctx.dst->ty.u32(), 1u);
|
||||
auto* type = ctx.dst->ty.array(ctx.dst->ty.u32(), 1u);
|
||||
// Create the new variable.
|
||||
auto* var_arr = ctx.dst->Var(var->source(), var_name, type,
|
||||
var->declared_storage_class(), nullptr,
|
||||
|
||||
@@ -95,10 +95,13 @@ ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) {
|
||||
auto* el = CreateASTTypeFor(ctx, v->type());
|
||||
return ctx->dst->create<ast::Vector>(el, v->size());
|
||||
}
|
||||
if (auto* a = ty->As<sem::ArrayType>()) {
|
||||
auto* el = CreateASTTypeFor(ctx, a->type());
|
||||
auto decos = ctx->Clone(a->decorations());
|
||||
return ctx->dst->create<ast::Array>(el, a->size(), std::move(decos));
|
||||
if (auto* a = ty->As<sem::Array>()) {
|
||||
auto* el = CreateASTTypeFor(ctx, a->ElemType());
|
||||
ast::DecorationList decos;
|
||||
if (!a->IsStrideImplicit()) {
|
||||
decos.emplace_back(ctx->dst->create<ast::StrideDecoration>(a->Stride()));
|
||||
}
|
||||
return ctx->dst->create<ast::Array>(el, a->Count(), std::move(decos));
|
||||
}
|
||||
if (auto* ac = ty->As<sem::AccessControl>()) {
|
||||
auto* el = CreateASTTypeFor(ctx, ac->type());
|
||||
|
||||
@@ -76,16 +76,23 @@ TEST_F(CreateASTTypeForTest, Vector) {
|
||||
ASSERT_EQ(vec->As<ast::Vector>()->size(), 2u);
|
||||
}
|
||||
|
||||
TEST_F(CreateASTTypeForTest, Array) {
|
||||
TEST_F(CreateASTTypeForTest, ArrayImplicitStride) {
|
||||
auto* arr = create([](ProgramBuilder& b) {
|
||||
return b.create<sem::ArrayType>(b.create<sem::F32>(), 4,
|
||||
ast::DecorationList{
|
||||
b.create<ast::StrideDecoration>(32u),
|
||||
});
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2, 4, 4, 32u, true);
|
||||
});
|
||||
ASSERT_TRUE(arr->Is<ast::Array>());
|
||||
ASSERT_TRUE(arr->As<ast::Array>()->type()->Is<ast::F32>());
|
||||
ASSERT_EQ(arr->As<ast::Array>()->size(), 4u);
|
||||
ASSERT_EQ(arr->As<ast::Array>()->size(), 2u);
|
||||
ASSERT_EQ(arr->As<ast::Array>()->decorations().size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
|
||||
auto* arr = create([](ProgramBuilder& b) {
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2, 4, 4, 32u, false);
|
||||
});
|
||||
ASSERT_TRUE(arr->Is<ast::Array>());
|
||||
ASSERT_TRUE(arr->As<ast::Array>()->type()->Is<ast::F32>());
|
||||
ASSERT_EQ(arr->As<ast::Array>()->size(), 2u);
|
||||
ASSERT_EQ(arr->As<ast::Array>()->decorations().size(), 1u);
|
||||
ASSERT_TRUE(
|
||||
arr->As<ast::Array>()->decorations()[0]->Is<ast::StrideDecoration>());
|
||||
@@ -95,7 +102,6 @@ TEST_F(CreateASTTypeForTest, Array) {
|
||||
->stride(),
|
||||
32u);
|
||||
}
|
||||
|
||||
TEST_F(CreateASTTypeForTest, AccessControl) {
|
||||
auto* ac = create([](ProgramBuilder& b) {
|
||||
auto* decl = b.Structure("S", {}, {});
|
||||
|
||||
Reference in New Issue
Block a user