sem: Fold together sem::Struct and sem::StructType

There's now no need to have both.
Removes a whole bunch of Sem().Get() smell, and simplifies the resolver.

Bug: tint:724
Fixed: tint:761
Change-Id: I756a32680ac52441fd6eebf6fc53dd507ef5e538
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49961
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton
2021-05-07 14:49:34 +00:00
committed by Commit Bot service account
parent 33d0f6aa08
commit ba6ab5e6bd
86 changed files with 962 additions and 1313 deletions

View File

@@ -77,12 +77,12 @@ 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::StructType*, Symbol> buffer_size_intrinsics;
auto get_buffer_size_intrinsic = [&](sem::StructType* buffer_type) {
std::unordered_map<sem::Struct*, Symbol> buffer_size_intrinsics;
auto get_buffer_size_intrinsic = [&](sem::Struct* buffer_type) {
return utils::GetOrCreate(buffer_size_intrinsics, buffer_type, [&] {
auto name = ctx.dst->Sym();
auto* buffer_typename =
ctx.dst->ty.type_name(ctx.Clone(buffer_type->impl()->name()));
ctx.dst->ty.type_name(ctx.Clone(buffer_type->Declaration()->name()));
auto* func = ctx.dst->create<ast::Function>(
name,
ast::VariableList{
@@ -100,8 +100,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
ctx.dst->ASTNodes().Create<BufferSizeIntrinsic>(ctx.dst->ID()),
},
ast::DecorationList{});
ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), buffer_type->impl(),
func);
ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(),
buffer_type->Declaration(), func);
return name;
});
};
@@ -141,7 +141,7 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
auto* storage_buffer_expr = accessor->structure();
auto* storage_buffer_sem = sem.Get(storage_buffer_expr);
auto* storage_buffer_type =
storage_buffer_sem->Type()->UnwrapAll()->As<sem::StructType>();
storage_buffer_sem->Type()->UnwrapAll()->As<sem::Struct>();
// Generate BufferSizeIntrinsic for this storage type if we haven't
// already
@@ -149,7 +149,7 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
if (!storage_buffer_type) {
TINT_ICE(ctx.dst->Diagnostics())
<< "arrayLength(X.Y) expected X to be sem::StructType, got "
<< "arrayLength(X.Y) expected X to be sem::Struct, got "
<< storage_buffer_type->FriendlyName(ctx.src->Symbols());
break;
}
@@ -176,12 +176,8 @@ Output CalculateArrayLength::Run(const Program* in, const DataMap&) {
// First time this array length is used for this block.
// Let's calculate it.
// Semantic info for the storage buffer structure
auto* storage_buffer_type_sem =
ctx.src->Sem().Get(storage_buffer_type);
// Semantic info for the runtime array structure member
auto* array_member_sem =
storage_buffer_type_sem->Members().back();
auto* array_member_sem = storage_buffer_type->Members().back();
// Construct the variable that'll hold the result of
// RWByteAddressBuffer.GetDimensions()

View File

@@ -110,12 +110,11 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
std::function<ast::Expression*()> func_const_initializer;
if (auto* struct_ty = param_ty->As<sem::StructType>()) {
auto* str = ctx.src->Sem().Get(struct_ty);
if (auto* str = param_ty->As<sem::Struct>()) {
// Pull out all struct members and build initializer list.
std::vector<Symbol> member_names;
for (auto* member : str->Members()) {
if (member->Type()->UnwrapAll()->Is<sem::StructType>()) {
if (member->Type()->UnwrapAll()->Is<sem::Struct>()) {
TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct";
}
@@ -202,11 +201,10 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
} else {
ast::StructMemberList new_struct_members;
if (auto* struct_ty = ret_type->As<sem::StructType>()) {
auto* str = ctx.src->Sem().Get(struct_ty);
if (auto* str = ret_type->As<sem::Struct>()) {
// Rebuild struct with only the entry point IO attributes.
for (auto* member : str->Members()) {
if (member->Type()->UnwrapAll()->Is<sem::StructType>()) {
if (member->Type()->UnwrapAll()->Is<sem::Struct>()) {
TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct";
}
@@ -251,7 +249,7 @@ Output CanonicalizeEntryPointIO::Run(const Program* in, const DataMap&) {
};
ast::ExpressionList ret_values;
if (ret_type->Is<sem::StructType>()) {
if (ret_type->Is<sem::Struct>()) {
if (!ret->value()->Is<ast::IdentifierExpression>()) {
// Create a const to hold the return value expression to avoid
// re-evaluating it multiple times.

View File

@@ -331,7 +331,7 @@ void InsertGlobal(CloneContext& ctx,
}
/// @returns the unwrapped, user-declared constructed type of ty.
ast::NamedType* ConstructedTypeOf(sem::Type* ty) {
const ast::NamedType* ConstructedTypeOf(sem::Type* ty) {
while (true) {
if (auto* ptr = ty->As<sem::Pointer>()) {
ty = ptr->type();
@@ -341,8 +341,8 @@ ast::NamedType* ConstructedTypeOf(sem::Type* ty) {
ty = access->type();
continue;
}
if (auto* str = ty->As<sem::StructType>()) {
return str->impl();
if (auto* str = ty->As<sem::Struct>()) {
return str->Declaration();
}
// Not a constructed type
return nullptr;
@@ -421,7 +421,7 @@ struct DecomposeStorageAccess::State {
/// @param el_ty the storage buffer element type
/// @return the name of the function that performs the load
Symbol LoadFunc(CloneContext& ctx,
ast::NamedType* insert_after,
const ast::NamedType* insert_after,
sem::Type* buf_ty,
sem::Type* el_ty) {
return utils::GetOrCreate(load_funcs, TypePair{buf_ty, el_ty}, [&] {
@@ -451,9 +451,7 @@ struct DecomposeStorageAccess::State {
ctx.dst->Add("offset", i * MatrixColumnStride(mat_ty));
values.emplace_back(ctx.dst->Call(load, "buffer", offset));
}
} else if (auto* str_ty = el_ty->As<sem::StructType>()) {
auto& sem = ctx.src->Sem();
auto* str = sem.Get(str_ty);
} else if (auto* str = el_ty->As<sem::Struct>()) {
for (auto* member : str->Members()) {
auto* offset = ctx.dst->Add("offset", member->Offset());
Symbol load = LoadFunc(ctx, insert_after, buf_ty,
@@ -492,7 +490,7 @@ struct DecomposeStorageAccess::State {
/// @param el_ty the storage buffer element type
/// @return the name of the function that performs the store
Symbol StoreFunc(CloneContext& ctx,
ast::NamedType* insert_after,
const ast::NamedType* insert_after,
sem::Type* buf_ty,
sem::Type* el_ty) {
return utils::GetOrCreate(store_funcs, TypePair{buf_ty, el_ty}, [&] {
@@ -525,9 +523,7 @@ struct DecomposeStorageAccess::State {
auto* call = ctx.dst->Call(store, "buffer", offset, access);
body.emplace_back(ctx.dst->create<ast::CallStatement>(call));
}
} else if (auto* str_ty = el_ty->As<sem::StructType>()) {
auto& sem = ctx.src->Sem();
auto* str = sem.Get(str_ty);
} else if (auto* str = el_ty->As<sem::Struct>()) {
for (auto* member : str->Members()) {
auto* offset = ctx.dst->Add("offset", member->Offset());
auto* access = ctx.dst->MemberAccessor(
@@ -676,9 +672,8 @@ Output DecomposeStorageAccess::Run(const Program* in, const DataMap&) {
}
} else {
if (auto access = state.TakeAccess(accessor->structure())) {
auto* str_ty = access.type->As<sem::StructType>();
auto* member =
sem.Get(str_ty)->FindMember(accessor->member()->symbol());
auto* str_ty = access.type->As<sem::Struct>();
auto* member = str_ty->FindMember(accessor->member()->symbol());
auto offset = member->Offset();
state.AddAccess(accessor,
{

View File

@@ -133,7 +133,7 @@ Output FirstIndexOffset::Run(const Program* in, const DataMap& data) {
instance_index_offset = offset;
offset += 4;
}
auto struct_type =
auto* struct_type =
ctx.dst->Structure(ctx.dst->Sym(), std::move(members),
{ctx.dst->create<ast::StructBlockDecoration>()});

View File

@@ -96,7 +96,7 @@ void Hlsl::PromoteInitializersToConstVar(CloneContext& ctx) const {
}
auto* src_ty = src_sem_expr->Type();
if (src_ty->IsAnyOf<sem::ArrayType, sem::StructType>()) {
if (src_ty->IsAnyOf<sem::ArrayType, sem::Struct>()) {
// Create a new symbol for the constant
auto dst_symbol = ctx.dst->Sym();
// Clone the type

View File

@@ -288,7 +288,7 @@ Symbol Spirv::HoistToInputVariables(
sem::Type* ty,
ast::Type* declared_ty,
const ast::DecorationList& decorations) const {
if (!ty->Is<sem::StructType>()) {
if (!ty->Is<sem::Struct>()) {
// Base case: create a global variable and return.
ast::DecorationList new_decorations =
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
@@ -305,8 +305,8 @@ Symbol Spirv::HoistToInputVariables(
// Recurse into struct members and build the initializer list.
std::vector<Symbol> init_value_names;
auto* struct_ty = ty->As<sem::StructType>();
for (auto* member : ctx.src->Sem().Get(struct_ty)->Members()) {
auto* struct_ty = ty->As<sem::Struct>();
for (auto* member : struct_ty->Members()) {
auto member_var = HoistToInputVariables(
ctx, func, member->Type(), member->Declaration()->type(),
member->Declaration()->decorations());
@@ -342,7 +342,7 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx,
Symbol store_value,
ast::StatementList& stores) const {
// Base case.
if (!ty->Is<sem::StructType>()) {
if (!ty->Is<sem::Struct>()) {
// Create a global variable.
ast::DecorationList new_decorations =
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
@@ -366,8 +366,8 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx,
}
// Recurse into struct members.
auto* struct_ty = ty->As<sem::StructType>();
for (auto* member : ctx.src->Sem().Get(struct_ty)->Members()) {
auto* struct_ty = ty->As<sem::Struct>();
for (auto* member : struct_ty->Members()) {
member_accesses.push_back(ctx.Clone(member->Declaration()->symbol()));
HoistToOutputVariables(ctx, func, member->Type(),
member->Declaration()->type(),

View File

@@ -107,8 +107,9 @@ ast::Type* Transform::CreateASTTypeFor(CloneContext* ctx, const sem::Type* ty) {
if (auto* a = ty->As<sem::Alias>()) {
return ctx->dst->create<ast::TypeName>(ctx->Clone(a->symbol()));
}
if (auto* s = ty->As<sem::StructType>()) {
return ctx->dst->create<ast::TypeName>(ctx->Clone(s->impl()->name()));
if (auto* s = ty->As<sem::Struct>()) {
return ctx->dst->create<ast::TypeName>(
ctx->Clone(s->Declaration()->name()));
}
TINT_UNREACHABLE(ctx->dst->Diagnostics())
<< "Unhandled type: " << ty->TypeInfo().name;

View File

@@ -98,7 +98,10 @@ TEST_F(CreateASTTypeForTest, Array) {
TEST_F(CreateASTTypeForTest, AccessControl) {
auto* ac = create([](ProgramBuilder& b) {
auto str = b.Structure("S", {}, {});
auto* decl = b.Structure("S", {}, {});
auto* str =
b.create<sem::Struct>(decl, sem::StructMemberList{}, 4 /* align */,
4 /* size */, 4 /* size_no_padding */);
return b.create<sem::AccessControl>(ast::AccessControl::kReadOnly, str);
});
ASSERT_TRUE(ac->Is<ast::AccessControl>());
@@ -109,8 +112,9 @@ TEST_F(CreateASTTypeForTest, AccessControl) {
TEST_F(CreateASTTypeForTest, Struct) {
auto* str = create([](ProgramBuilder& b) {
auto* impl = b.Structure("S", {}, {}).ast;
return b.create<sem::StructType>(const_cast<ast::Struct*>(impl));
auto* decl = b.Structure("S", {}, {});
return b.create<sem::Struct>(decl, sem::StructMemberList{}, 4 /* align */,
4 /* size */, 4 /* size_no_padding */);
});
ASSERT_TRUE(str->Is<ast::TypeName>());
EXPECT_EQ(

View File

@@ -204,7 +204,7 @@ struct State {
// Creating the struct type
static const char kStructName[] = "TintVertexData";
auto struct_type = ctx.dst->Structure(
auto* struct_type = ctx.dst->Structure(
ctx.dst->Symbols().New(kStructName),
{
ctx.dst->Member(GetStructBufferName(),
@@ -432,7 +432,7 @@ struct State {
/// @param struct_ty the structure type
void ProcessStructParameter(ast::Function* func,
ast::Variable* param,
ast::Struct* struct_ty) {
const ast::Struct* struct_ty) {
auto param_sym = ctx.Clone(param->symbol());
// Process the struct members.
@@ -486,7 +486,7 @@ struct State {
new_members.push_back(
ctx.dst->Member(member_sym, member_type, std::move(member_decos)));
}
auto new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members);
auto* new_struct = ctx.dst->Structure(ctx.dst->Sym(), new_members);
// Create a new function parameter with this struct.
auto* new_param = ctx.dst->Param(ctx.dst->Sym(), new_struct);
@@ -513,8 +513,8 @@ struct State {
// Process entry point parameters.
for (auto* param : func->params()) {
auto* sem = ctx.src->Sem().Get(param);
if (auto* str = sem->Type()->As<sem::StructType>()) {
ProcessStructParameter(func, param, str->impl());
if (auto* str = sem->Type()->As<sem::Struct>()) {
ProcessStructParameter(func, param, str->Declaration());
} else {
ProcessNonStructParameter(func, param);
}