writer/msl: Begin migration to ast::Types

The MSL writer doesn't really care much for ast::Types, so most of the work here is repointing the logic to fetch the resolved, semantic type.

Bug: tint:724
Change-Id: I017b83c9f661cc01cbde377991aab184c1733348
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49529
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-04-30 20:19:09 +00:00 committed by Commit Bot service account
parent 44539d85b2
commit f34cb1fe70
4 changed files with 52 additions and 36 deletions

View File

@ -886,10 +886,12 @@ bool GeneratorImpl::EmitContinue(ast::ContinueStatement*) {
}
bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
auto* type = TypeOf(expr);
if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
out_ << "{";
} else {
if (!EmitType(expr->type(), "")) {
if (!EmitType(type, "")) {
return false;
}
out_ << "(";
@ -898,7 +900,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
// If the type constructor is empty then we need to construct with the zero
// value for all components.
if (expr->values().empty()) {
if (!EmitZeroValue(expr->type())) {
if (!EmitZeroValue(type)) {
return false;
}
} else {
@ -915,7 +917,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
}
}
if (expr->type()->IsAnyOf<sem::ArrayType, sem::StructType>()) {
if (type->IsAnyOf<sem::ArrayType, sem::StructType>()) {
out_ << "}";
} else {
out_ << ")";
@ -923,7 +925,10 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
return true;
}
bool GeneratorImpl::EmitZeroValue(sem::Type* type) {
bool GeneratorImpl::EmitZeroValue(typ::Type type) {
if (!type.sem) {
type.sem = program_->Sem().Get(type.ast);
}
if (type->Is<sem::Bool>()) {
out_ << "false";
} else if (type->Is<sem::F32>()) {
@ -1891,7 +1896,11 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) {
return true;
}
bool GeneratorImpl::EmitType(sem::Type* type, const std::string& name) {
bool GeneratorImpl::EmitType(typ::Type type, const std::string& name) {
if (!type.sem) {
type.sem = program_->Sem().Get(type.ast);
}
std::string access_str = "";
if (auto* ac = type->As<sem::AccessControl>()) {
if (ac->access_control() == ast::AccessControl::kReadOnly) {
@ -2025,7 +2034,11 @@ bool GeneratorImpl::EmitType(sem::Type* type, const std::string& name) {
return true;
}
bool GeneratorImpl::EmitPackedType(sem::Type* type, const std::string& name) {
bool GeneratorImpl::EmitPackedType(typ::Type type, const std::string& name) {
if (!type.sem) {
type.sem = program_->Sem().Get(type.ast);
}
if (auto* alias = type->As<sem::Alias>()) {
return EmitPackedType(alias->type(), name);
}
@ -2077,16 +2090,11 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
increment_indent();
uint32_t msl_offset = 0;
for (auto* mem : str->impl()->members()) {
for (auto* mem : sem_str->Members()) {
make_indent();
auto* sem_mem = program_->Sem().Get(mem);
if (!sem_mem) {
TINT_ICE(diagnostics_) << "struct member missing semantic info";
return false;
}
auto wgsl_offset = sem_mem->Offset();
auto name = program_->Symbols().NameFor(mem->Declaration()->symbol());
auto wgsl_offset = mem->Offset();
if (is_host_shareable) {
if (wgsl_offset < msl_offset) {
@ -2107,25 +2115,24 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
add_byte_offset_comment(msl_offset);
if (!EmitPackedType(mem->type(),
program_->Symbols().NameFor(mem->symbol()))) {
if (!EmitPackedType(mem->Type(), name)) {
return false;
}
} else {
if (!EmitType(mem->type(), program_->Symbols().NameFor(mem->symbol()))) {
if (!EmitType(mem->Type(), name)) {
return false;
}
}
auto* ty = mem->type()->UnwrapAliasIfNeeded();
auto* ty = mem->Type()->UnwrapAliasIfNeeded();
// Array member name will be output with the type
if (!ty->Is<sem::ArrayType>()) {
out_ << " " << program_->Symbols().NameFor(mem->symbol());
out_ << " " << name;
}
// Emit decorations
for (auto* deco : mem->decorations()) {
for (auto* deco : mem->Declaration()->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
auto attr = builtin_to_attribute(builtin->value());
if (attr.empty()) {
@ -2163,9 +2170,9 @@ bool GeneratorImpl::EmitStructType(const sem::StructType* str) {
// Calculate new MSL offset
auto size_align = MslPackedTypeSizeAndAlign(ty);
if (msl_offset % size_align.align) {
TINT_ICE(diagnostics_) << "Misaligned MSL structure member "
<< ty->FriendlyName(program_->Symbols()) << " "
<< program_->Symbols().NameFor(mem->symbol());
TINT_ICE(diagnostics_)
<< "Misaligned MSL structure member "
<< ty->FriendlyName(program_->Symbols()) << " " << name;
return false;
}
msl_offset += size_align.size;

View File

@ -195,14 +195,14 @@ class GeneratorImpl : public TextGenerator {
/// @param type the type to generate
/// @param name the name of the variable, only used for array emission
/// @returns true if the type is emitted
bool EmitType(sem::Type* type, const std::string& name);
bool EmitType(typ::Type type, const std::string& name);
/// Handles generating an MSL-packed storage type.
/// If the type does not have a packed form, the standard non-packed form is
/// emitted.
/// @param type the type to generate
/// @param name the name of the variable, only used for array emission
/// @returns true if the type is emitted
bool EmitPackedType(sem::Type* type, const std::string& name);
bool EmitPackedType(typ::Type type, const std::string& name);
/// Handles generating a struct declaration
/// @param str the struct to generate
/// @returns true if the struct is emitted
@ -227,7 +227,7 @@ class GeneratorImpl : public TextGenerator {
/// Emits the zero value for the given type
/// @param type the type to emit the value for
/// @returns true if the zero value was successfully emitted.
bool EmitZeroValue(sem::Type* type);
bool EmitZeroValue(typ::Type type);
/// Determines if the function needs the input struct passed to it.
/// @param func the function to check
@ -273,6 +273,12 @@ class GeneratorImpl : public TextGenerator {
return program_->TypeOf(expr);
}
/// @returns the resolved type of the ast::Type `type`
/// @param type the type
const sem::Type* TypeOf(ast::Type* type) const {
return program_->TypeOf(type);
}
// A pair of byte size and alignment `uint32_t`s.
struct SizeAndAlign {
uint32_t size;

View File

@ -31,13 +31,15 @@ using MslBinaryTest = TestParamHelper<BinaryData>;
TEST_P(MslBinaryTest, Emit) {
auto params = GetParam();
auto* type = ((params.op == ast::BinaryOp::kLogicalAnd) ||
(params.op == ast::BinaryOp::kLogicalOr))
? static_cast<sem::Type*>(ty.bool_())
: static_cast<sem::Type*>(ty.u32());
auto type = [&]() {
return ((params.op == ast::BinaryOp::kLogicalAnd) ||
(params.op == ast::BinaryOp::kLogicalOr))
? static_cast<typ::Type>(ty.bool_())
: static_cast<typ::Type>(ty.u32());
};
auto* left = Var("left", type, ast::StorageClass::kFunction);
auto* right = Var("right", type, ast::StorageClass::kFunction);
auto* left = Var("left", type(), ast::StorageClass::kFunction);
auto* right = Var("right", type(), ast::StorageClass::kFunction);
auto* expr =
create<ast::BinaryExpression>(params.op, Expr("left"), Expr("right"));

View File

@ -602,7 +602,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
}
TEST_F(MslGeneratorImplTest, EmitType_U32) {
auto u32 = ty.u32();
auto* u32 = create<sem::U32>();
GeneratorImpl& gen = Build();
@ -715,11 +715,12 @@ INSTANTIATE_TEST_SUITE_P(
"texturecube_array<float, access::sample>"}));
TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
sem::MultisampledTexture s(ast::TextureDimension::k2d, ty.u32());
auto* u32 = create<sem::U32>();
auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, u32);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ms, "")) << gen.error();
EXPECT_EQ(gen.result(), "texture2d_ms<uint, access::sample>");
}