diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc index d1352e8a7c..5f148f037e 100644 --- a/src/tint/resolver/uniformity.cc +++ b/src/tint/resolver/uniformity.cc @@ -359,6 +359,14 @@ class UniformityGraph { return current_function_->CreateNode(std::move(tag_list), ast); } + /// Get the symbol name of an AST node. + /// @param ast the AST node to get the symbol name of + /// @returns the symbol name + template + inline std::string NameFor(const T* ast) { + return builder_->Symbols().NameFor(ast->symbol); + } + /// Process a function. /// @param func the function to process /// @returns true if there are no uniformity issues, false otherwise @@ -567,7 +575,7 @@ class UniformityGraph { // Add an edge from the variable exit node to its value at this point. auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() { - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); + auto name = NameFor(var->Declaration()); return CreateNode({name, "_value_", info.type, "_exit"}); }); exit_node->AddEdge(current_function_->variables.Get(var)); @@ -603,7 +611,7 @@ class UniformityGraph { // Add an edge from the variable exit node to its value at this point. auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() { - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); + auto name = NameFor(var->Declaration()); return CreateNode({name, "_value_", info.type, "_exit"}); }); @@ -676,8 +684,7 @@ class UniformityGraph { // Create input nodes for any variables declared before this loop. for (auto* v : current_function_->local_var_decls) { - auto name = builder_->Symbols().NameFor(v->Declaration()->symbol); - auto* in_node = CreateNode({name, "_value_forloop_in"}); + auto* in_node = CreateNode({NameFor(v->Declaration()), "_value_forloop_in"}); in_node->AddEdge(current_function_->variables.Get(v)); info.var_in_nodes.Replace(v, in_node); current_function_->variables.Set(v, in_node); @@ -694,7 +701,7 @@ class UniformityGraph { // Propagate assignments to the loop exit nodes. for (auto* var : current_function_->local_var_decls) { auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() { - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); + auto name = NameFor(var->Declaration()); return CreateNode({name, "_value_", info.type, "_exit"}); }); exit_node->AddEdge(current_function_->variables.Get(var)); @@ -752,8 +759,7 @@ class UniformityGraph { // Create input nodes for any variables declared before this loop. for (auto* v : current_function_->local_var_decls) { - auto name = builder_->Symbols().NameFor(v->Declaration()->symbol); - auto* in_node = CreateNode({name, "_value_forloop_in"}); + auto* in_node = CreateNode({NameFor(v->Declaration()), "_value_forloop_in"}); in_node->AddEdge(current_function_->variables.Get(v)); info.var_in_nodes.Replace(v, in_node); current_function_->variables.Set(v, in_node); @@ -771,7 +777,7 @@ class UniformityGraph { // Propagate assignments to the loop exit nodes. for (auto* var : current_function_->local_var_decls) { auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() { - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); + auto name = NameFor(var->Declaration()); return CreateNode({name, "_value_", info.type, "_exit"}); }); exit_node->AddEdge(current_function_->variables.Get(var)); @@ -855,8 +861,7 @@ class UniformityGraph { } // Create an exit node for the variable. - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); - auto* out_node = CreateNode({name, "_value_if_exit"}); + auto* out_node = CreateNode({NameFor(var->Declaration()), "_value_if_exit"}); // Add edges to the assigned value or the initial value. // Only add edges if the behavior for that block contains 'Next'. @@ -912,7 +917,7 @@ class UniformityGraph { // Create input nodes for any variables declared before this loop. for (auto* v : current_function_->local_var_decls) { - auto name = builder_->Symbols().NameFor(v->Declaration()->symbol); + auto name = NameFor(v->Declaration()); auto* in_node = CreateNode({name, "_value_loop_in"}, v->Declaration()); in_node->AddEdge(current_function_->variables.Get(v)); info.var_in_nodes.Replace(v, in_node); @@ -1011,7 +1016,7 @@ class UniformityGraph { // Add an edge from the variable exit node to its new value. auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() { - auto name = builder_->Symbols().NameFor(var->Declaration()->symbol); + auto name = NameFor(var->Declaration()); return CreateNode({name, "_value_", info.type, "_exit"}); }); exit_node->AddEdge(current_function_->variables.Get(var)); @@ -1091,10 +1096,9 @@ class UniformityGraph { return true; }; - auto name = builder_->Symbols().NameFor(ident->symbol); auto* var_user = sem_.Get(ident)->Unwrap()->As(); auto* sem = var_user->Variable(); - auto* node = CreateNode({name, "_ident_expr"}, ident); + auto* node = CreateNode({NameFor(ident), "_ident_expr"}, ident); return Switch( sem, @@ -1310,13 +1314,12 @@ class UniformityGraph { expr, [&](const ast::IdentifierExpression* i) { - auto name = builder_->Symbols().NameFor(i->symbol); auto* sem = sem_.Get(i)->UnwrapLoad()->As(); if (sem->Variable()->Is()) { return std::make_pair(cf, current_function_->may_be_non_uniform); } else if (auto* local = sem->Variable()->As()) { // Create a new value node for this variable. - auto* value = CreateNode({name, "_lvalue"}); + auto* value = CreateNode({NameFor(i), "_lvalue"}); auto* old_value = current_function_->variables.Set(local, value); // If i is part of an expression that is a partial reference to a variable (e.g. @@ -1353,8 +1356,7 @@ class UniformityGraph { // Cut the analysis short, since we only need to know the originating variable // that is being written to. auto* root_ident = sem_.Get(u)->RootIdentifier(); - auto name = builder_->Symbols().NameFor(root_ident->Declaration()->symbol); - auto* deref = CreateNode({name, "_deref"}); + auto* deref = CreateNode({NameFor(root_ident->Declaration()), "_deref"}); auto* old_value = current_function_->variables.Set(root_ident, deref); if (old_value) { @@ -1384,7 +1386,7 @@ class UniformityGraph { std::pair ProcessCall(Node* cf, const ast::CallExpression* call) { std::string name; if (call->target.name) { - name = builder_->Symbols().NameFor(call->target.name->symbol); + name = NameFor(call->target.name); } else { name = call->target.type->FriendlyName(builder_->Symbols()); } @@ -1691,8 +1693,7 @@ class UniformityGraph { auto* var = sem_.Get(ident)->UnwrapLoad()->As()->Variable(); std::string var_type = get_var_type(var); diagnostics_.add_note(diag::System::Resolver, - "reading from " + var_type + "'" + - builder_->Symbols().NameFor(ident->symbol) + + "reading from " + var_type + "'" + NameFor(ident) + "' may result in a non-uniform value", ident->source); }, @@ -1700,14 +1701,12 @@ class UniformityGraph { auto* var = sem_.Get(v); std::string var_type = get_var_type(var); diagnostics_.add_note(diag::System::Resolver, - "reading from " + var_type + "'" + - builder_->Symbols().NameFor(v->symbol) + + "reading from " + var_type + "'" + NameFor(v) + "' may result in a non-uniform value", v->source); }, [&](const ast::CallExpression* c) { - auto target_name = builder_->Symbols().NameFor( - c->target.name->As()->symbol); + auto target_name = NameFor(c->target.name); switch (non_uniform_source->type) { case Node::kFunctionCallReturnValue: { diagnostics_.add_note( @@ -1719,12 +1718,11 @@ class UniformityGraph { auto* arg = c->args[non_uniform_source->arg_index]; auto* var = sem_.Get(arg)->RootIdentifier(); std::string var_type = get_var_type(var); - diagnostics_.add_note( - diag::System::Resolver, - "reading from " + var_type + "'" + - builder_->Symbols().NameFor(var->Declaration()->symbol) + - "' may result in a non-uniform value", - var->Declaration()->source); + diagnostics_.add_note(diag::System::Resolver, + "reading from " + var_type + "'" + + NameFor(var->Declaration()) + + "' may result in a non-uniform value", + var->Declaration()->source); break; } case Node::kFunctionCallArgumentValue: { @@ -1796,13 +1794,12 @@ class UniformityGraph { if (auto* builtin = target->As()) { func_name = builtin->str(); } else if (auto* user = target->As()) { - func_name = builder_->Symbols().NameFor(user->Declaration()->symbol); + func_name = NameFor(user->Declaration()); } if (cause->type == Node::kFunctionCallArgumentValue) { // The requirement was on a function parameter. - auto param_name = builder_->Symbols().NameFor( - target->Parameters()[cause->arg_index]->Declaration()->symbol); + auto param_name = NameFor(target->Parameters()[cause->arg_index]->Declaration()); report(call->args[cause->arg_index]->source, "parameter '" + param_name + "' of '" + func_name + "' must be uniform"); @@ -1815,8 +1812,7 @@ class UniformityGraph { } } else if (cause->type == Node::kFunctionCallArgumentContents) { // The requirement was on the contents of a function parameter. - auto param_name = builder_->Symbols().NameFor( - target->Parameters()[cause->arg_index]->Declaration()->symbol); + auto param_name = NameFor(target->Parameters()[cause->arg_index]->Declaration()); report(call->args[cause->arg_index]->source, "contents of parameter '" + param_name + "' of '" + func_name + "' must be uniform");