mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Resolver: compute canonical types and store them as semantic::Variable::Type
We define the canonical type as a type stripped of all aliases. For example, Canonical(alias<alias<vec3<alias<f32>>>>) is vec3<f32>. This change adds Resolver::Canonical(Type*) which caches and returns the resulting canonical type. We use this throughout the Resolver instead of UnwrapAliasIfNeeded(), and we store the result in semantic::Variable, returned from it's Type() member function. Also: * Wrote unit tests for Resolver::Canonical() * Added semantic::Variable::DeclaredType() as a convenience to retrieve the AST variable's type. * Updated post-resolve code (transforms) to make use of Type and DeclaredType appropriately, removing unnecessary calls to UnwrapAliasIfNeeded. * Added IntrinsicTableTest.MatchWithNestedAliasUnwrapping to ensure we don't need to pass canonical parameter types for instrinsic table lookups. * ProgramBuilder: added vecN and matMxN overloads that take a Type* arg to create them with alias types. Bug: tint:705 Change-Id: I58a3b62538356b8dad2b1161a19b38bcefdd5d62 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47360 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
2f25ecf8ba
commit
2543686412
@@ -65,8 +65,7 @@ Transform::Output BindingRemapper::Run(const Program* in,
|
||||
auto ac_it = remappings->access_controls.find(from);
|
||||
if (ac_it != remappings->access_controls.end()) {
|
||||
ast::AccessControl ac = ac_it->second;
|
||||
auto* var_ty = in->Sem().Get(var)->Type();
|
||||
auto* ty = var_ty->UnwrapAliasIfNeeded();
|
||||
auto* ty = in->Sem().Get(var)->Type();
|
||||
type::Type* inner_ty = nullptr;
|
||||
if (auto* old_ac = ty->As<type::AccessControl>()) {
|
||||
inner_ty = ctx.Clone(old_ac->type());
|
||||
|
||||
@@ -72,11 +72,11 @@ Transform::Output CanonicalizeEntryPointIO::Run(const Program* in,
|
||||
for (auto* param : func->params()) {
|
||||
auto param_name = ctx.Clone(param->symbol());
|
||||
auto* param_ty = ctx.src->Sem().Get(param)->Type();
|
||||
auto* param_declared_ty = ctx.src->Sem().Get(param)->DeclaredType();
|
||||
|
||||
ast::Expression* func_const_initializer = nullptr;
|
||||
|
||||
if (auto* struct_ty =
|
||||
param_ty->UnwrapAliasIfNeeded()->As<type::Struct>()) {
|
||||
if (auto* struct_ty = param_ty->As<type::Struct>()) {
|
||||
// Pull out all struct members and build initializer list.
|
||||
ast::ExpressionList init_values;
|
||||
for (auto* member : struct_ty->impl()->members()) {
|
||||
@@ -97,7 +97,7 @@ Transform::Output CanonicalizeEntryPointIO::Run(const Program* in,
|
||||
}
|
||||
|
||||
func_const_initializer =
|
||||
ctx.dst->Construct(ctx.Clone(param_ty), init_values);
|
||||
ctx.dst->Construct(ctx.Clone(param_declared_ty), init_values);
|
||||
} else {
|
||||
ast::DecorationList new_decorations = RemoveDecorations(
|
||||
&ctx, param->decorations(), [](const ast::Decoration* deco) {
|
||||
@@ -105,7 +105,7 @@ Transform::Output CanonicalizeEntryPointIO::Run(const Program* in,
|
||||
ast::LocationDecoration>();
|
||||
});
|
||||
new_struct_members.push_back(ctx.dst->Member(
|
||||
param_name, ctx.Clone(param_ty), new_decorations));
|
||||
param_name, ctx.Clone(param_declared_ty), new_decorations));
|
||||
func_const_initializer =
|
||||
ctx.dst->MemberAccessor(new_struct_param_symbol, param_name);
|
||||
}
|
||||
@@ -117,8 +117,8 @@ Transform::Output CanonicalizeEntryPointIO::Run(const Program* in,
|
||||
|
||||
// Create a function-scope const to replace the parameter.
|
||||
// Initialize it with the value extracted from the new struct parameter.
|
||||
auto* func_const = ctx.dst->Const(param_name, ctx.Clone(param_ty),
|
||||
func_const_initializer);
|
||||
auto* func_const = ctx.dst->Const(
|
||||
param_name, ctx.Clone(param_declared_ty), func_const_initializer);
|
||||
ctx.InsertBefore(func->body()->statements(), *func->body()->begin(),
|
||||
ctx.dst->WrapInStatement(func_const));
|
||||
|
||||
|
||||
@@ -141,7 +141,8 @@ void Spirv::HandleEntryPointIOTypes(CloneContext& ctx) const {
|
||||
|
||||
for (auto* param : func->params()) {
|
||||
Symbol new_var = HoistToInputVariables(
|
||||
ctx, func, ctx.src->Sem().Get(param)->Type(), param->decorations());
|
||||
ctx, func, ctx.src->Sem().Get(param)->Type(),
|
||||
ctx.src->Sem().Get(param)->DeclaredType(), param->decorations());
|
||||
|
||||
// Replace all uses of the function parameter with the new variable.
|
||||
for (auto* user : ctx.src->Sem().Get(param)->Users()) {
|
||||
@@ -153,9 +154,9 @@ void Spirv::HandleEntryPointIOTypes(CloneContext& ctx) const {
|
||||
if (!func->return_type()->Is<type::Void>()) {
|
||||
ast::StatementList stores;
|
||||
auto store_value_symbol = ctx.dst->Symbols().New();
|
||||
HoistToOutputVariables(ctx, func, func->return_type(),
|
||||
func->return_type_decorations(), {},
|
||||
store_value_symbol, stores);
|
||||
HoistToOutputVariables(
|
||||
ctx, func, func->return_type(), func->return_type(),
|
||||
func->return_type_decorations(), {}, store_value_symbol, stores);
|
||||
|
||||
// Create a function that writes a return value to all output variables.
|
||||
auto* store_value =
|
||||
@@ -251,8 +252,9 @@ Symbol Spirv::HoistToInputVariables(
|
||||
CloneContext& ctx,
|
||||
const ast::Function* func,
|
||||
type::Type* ty,
|
||||
type::Type* declared_ty,
|
||||
const ast::DecorationList& decorations) const {
|
||||
if (!ty->UnwrapAliasIfNeeded()->Is<type::Struct>()) {
|
||||
if (!ty->Is<type::Struct>()) {
|
||||
// Base case: create a global variable and return.
|
||||
ast::DecorationList new_decorations =
|
||||
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
|
||||
@@ -261,7 +263,7 @@ Symbol Spirv::HoistToInputVariables(
|
||||
});
|
||||
auto global_var_symbol = ctx.dst->Symbols().New();
|
||||
auto* global_var =
|
||||
ctx.dst->Var(global_var_symbol, ctx.Clone(ty),
|
||||
ctx.dst->Var(global_var_symbol, ctx.Clone(declared_ty),
|
||||
ast::StorageClass::kInput, nullptr, new_decorations);
|
||||
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, global_var);
|
||||
return global_var_symbol;
|
||||
@@ -269,10 +271,10 @@ Symbol Spirv::HoistToInputVariables(
|
||||
|
||||
// Recurse into struct members and build the initializer list.
|
||||
ast::ExpressionList init_values;
|
||||
auto* struct_ty = ty->UnwrapAliasIfNeeded()->As<type::Struct>();
|
||||
auto* struct_ty = ty->As<type::Struct>();
|
||||
for (auto* member : struct_ty->impl()->members()) {
|
||||
auto member_var =
|
||||
HoistToInputVariables(ctx, func, member->type(), member->decorations());
|
||||
auto member_var = HoistToInputVariables(
|
||||
ctx, func, member->type(), member->type(), member->decorations());
|
||||
init_values.push_back(ctx.dst->Expr(member_var));
|
||||
}
|
||||
|
||||
@@ -283,8 +285,9 @@ Symbol Spirv::HoistToInputVariables(
|
||||
}
|
||||
|
||||
// Create a function-scope variable for the struct.
|
||||
auto* initializer = ctx.dst->Construct(ctx.Clone(ty), init_values);
|
||||
auto* func_var = ctx.dst->Const(func_var_symbol, ctx.Clone(ty), initializer);
|
||||
auto* initializer = ctx.dst->Construct(ctx.Clone(declared_ty), init_values);
|
||||
auto* func_var =
|
||||
ctx.dst->Const(func_var_symbol, ctx.Clone(declared_ty), initializer);
|
||||
ctx.InsertBefore(func->body()->statements(), *func->body()->begin(),
|
||||
ctx.dst->WrapInStatement(func_var));
|
||||
return func_var_symbol;
|
||||
@@ -293,12 +296,13 @@ Symbol Spirv::HoistToInputVariables(
|
||||
void Spirv::HoistToOutputVariables(CloneContext& ctx,
|
||||
const ast::Function* func,
|
||||
type::Type* ty,
|
||||
type::Type* declared_ty,
|
||||
const ast::DecorationList& decorations,
|
||||
std::vector<Symbol> member_accesses,
|
||||
Symbol store_value,
|
||||
ast::StatementList& stores) const {
|
||||
// Base case.
|
||||
if (!ty->UnwrapAliasIfNeeded()->Is<type::Struct>()) {
|
||||
if (!ty->Is<type::Struct>()) {
|
||||
// Create a global variable.
|
||||
ast::DecorationList new_decorations =
|
||||
RemoveDecorations(&ctx, decorations, [](const ast::Decoration* deco) {
|
||||
@@ -307,7 +311,7 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx,
|
||||
});
|
||||
auto global_var_symbol = ctx.dst->Symbols().New();
|
||||
auto* global_var =
|
||||
ctx.dst->Var(global_var_symbol, ctx.Clone(ty),
|
||||
ctx.dst->Var(global_var_symbol, ctx.Clone(declared_ty),
|
||||
ast::StorageClass::kOutput, nullptr, new_decorations);
|
||||
ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, global_var);
|
||||
|
||||
@@ -322,11 +326,12 @@ void Spirv::HoistToOutputVariables(CloneContext& ctx,
|
||||
}
|
||||
|
||||
// Recurse into struct members.
|
||||
auto* struct_ty = ty->UnwrapAliasIfNeeded()->As<type::Struct>();
|
||||
auto* struct_ty = ty->As<type::Struct>();
|
||||
for (auto* member : struct_ty->impl()->members()) {
|
||||
member_accesses.push_back(ctx.Clone(member->symbol()));
|
||||
HoistToOutputVariables(ctx, func, member->type(), member->decorations(),
|
||||
member_accesses, store_value, stores);
|
||||
HoistToOutputVariables(ctx, func, member->type(), member->type(),
|
||||
member->decorations(), member_accesses, store_value,
|
||||
stores);
|
||||
member_accesses.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ class Spirv : public Transform {
|
||||
Symbol HoistToInputVariables(CloneContext& ctx,
|
||||
const ast::Function* func,
|
||||
type::Type* ty,
|
||||
type::Type* declared_ty,
|
||||
const ast::DecorationList& decorations) const;
|
||||
|
||||
/// Recursively create module-scope output variables for `ty` and build a list
|
||||
@@ -73,6 +74,7 @@ class Spirv : public Transform {
|
||||
void HoistToOutputVariables(CloneContext& ctx,
|
||||
const ast::Function* func,
|
||||
type::Type* ty,
|
||||
type::Type* declared_ty,
|
||||
const ast::DecorationList& decorations,
|
||||
std::vector<Symbol> member_accesses,
|
||||
Symbol store_value,
|
||||
|
||||
Reference in New Issue
Block a user