tint: Make sure enable directives go first in ordered_globals

This patch change DependencyAnalysis::SortGlobals() to make sure that
'enable' directive nodes go before any other global declarations in the
sorted global node list, and thus ensure that all extensions will be
registered by reslover before dealing with any other global declarations.
This is necessary because some transforms will add AST nodes before any
other global nodes, and these added nodes should be handled by resolver
after 'enable' nodes are handled.

Bug: tint:1472
Change-Id: Idc2253fc055b0f121cb0cafcaca5275c23ed7b0d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/93760
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
Reviewed-by: Ben Clayton <bclayton@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Zhaoming Jiang 2022-06-16 08:30:17 +00:00 committed by Dawn LUCI CQ
parent 33563dc7d7
commit 418e873ad2
2 changed files with 25 additions and 1 deletions

View File

@ -569,8 +569,18 @@ struct DependencyAnalysis {
return; // This code assumes there are no undeclared identifiers. return; // This code assumes there are no undeclared identifiers.
} }
std::unordered_set<const Global*> visited; // Make sure all 'enable' directives go before any other global declarations.
for (auto* global : declaration_order_) { for (auto* global : declaration_order_) {
if (auto* enable = global->node->As<ast::Enable>()) {
sorted_.add(enable);
}
}
for (auto* global : declaration_order_) {
if (global->node->Is<ast::Enable>()) {
// Skip 'enable' directives here, as they are already added.
continue;
}
utils::UniqueVector<const Global*> stack; utils::UniqueVector<const Global*> stack;
TraverseDependencies( TraverseDependencies(
global, global,

View File

@ -1080,6 +1080,20 @@ INSTANTIATE_TEST_SUITE_P(Functions,
ResolverDependencyGraphOrderedGlobalsTest, ResolverDependencyGraphOrderedGlobalsTest,
testing::Combine(testing::ValuesIn(kFuncDeclKinds), testing::Combine(testing::ValuesIn(kFuncDeclKinds),
testing::ValuesIn(kFuncUseKinds))); testing::ValuesIn(kFuncUseKinds)));
TEST_F(ResolverDependencyGraphOrderedGlobalsTest, EnableFirst) {
// Test that enable nodes always go before any other global declaration.
// Although all enable directives in a valid WGSL program must go before any other global
// declaration, a transform may produce such a AST tree that has some declarations before enable
// nodes. DependencyGraph should deal with these cases.
auto* var_1 = Global("SYMBOL1", ty.i32(), nullptr);
auto* enable_1 = Enable(ast::Extension::kF16);
auto* var_2 = Global("SYMBOL2", ty.f32(), nullptr);
auto* enable_2 = Enable(ast::Extension::kF16);
EXPECT_THAT(AST().GlobalDeclarations(), ElementsAre(var_1, enable_1, var_2, enable_2));
EXPECT_THAT(Build().ordered_globals, ElementsAre(enable_1, enable_2, var_1, var_2));
}
} // namespace ordered_globals } // namespace ordered_globals
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////