From a52be6c9ec303ae2ef6b8105e0a8b5f9544ca962 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 9 Feb 2022 23:55:51 +0000 Subject: [PATCH] Add sem::Module Holds `DependencyOrderedDeclarations()`, which will hold the sorted dependency-graph ordered list of global declarations. Bug: tint:1266 Change-Id: I9840fae8689abd214973ea4785f71c3ae2587bbc Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79766 Reviewed-by: James Price Kokoro: Kokoro --- src/BUILD.gn | 3 ++ src/CMakeLists.txt | 2 ++ src/ast/module.cc | 58 ++++++++++++++++++----------------- src/ast/module.h | 20 +++++++++--- src/resolver/resolver.cc | 5 +++ src/resolver/resolver_test.cc | 23 ++++++++++++++ src/sem/info.h | 29 ++++++++++++------ src/sem/module.cc | 29 ++++++++++++++++++ src/sem/module.h | 52 +++++++++++++++++++++++++++++++ 9 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 src/sem/module.cc create mode 100644 src/sem/module.h diff --git a/src/BUILD.gn b/src/BUILD.gn index 4f4b25bb7c..7e67660863 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -398,6 +398,7 @@ libtint_source_set("libtint_core_all_src") { "sem/info.h", "sem/loop_statement.h", "sem/matrix_type.h", + "sem/module.h", "sem/multisampled_texture_type.h", "sem/node.h", "sem/parameter_usage.h", @@ -574,6 +575,8 @@ libtint_source_set("libtint_sem_src") { "sem/matrix_type.cc", "sem/matrix_type.h", "sem/member_accessor_expression.cc", + "sem/module.cc", + "sem/module.h", "sem/multisampled_texture_type.cc", "sem/multisampled_texture_type.h", "sem/node.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5bc1839bf..0e6f289e0c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -285,6 +285,8 @@ set(TINT_LIB_SRCS sem/pipeline_stage_set.h sem/node.cc sem/node.h + sem/module.cc + sem/module.h sem/sampler_texture_pair.h sem/statement.cc sem/struct.cc diff --git a/src/ast/module.cc b/src/ast/module.cc index 3f06a31855..bde99673c8 100644 --- a/src/ast/module.cc +++ b/src/ast/module.cc @@ -34,16 +34,8 @@ Module::Module(ProgramID pid, if (decl == nullptr) { continue; } - - Switch( - decl, // - [&](const ast::TypeDecl* type) { type_decls_.push_back(type); }, - [&](const Function* func) { functions_.push_back(func); }, - [&](const Variable* var) { global_variables_.push_back(var); }, - [&](Default) { - diag::List diagnostics; - TINT_ICE(AST, diagnostics) << "Unknown global declaration type"; - }); + diag::List diags; + BinGlobalDeclaration(decl, diags); } } @@ -58,6 +50,33 @@ const ast::TypeDecl* Module::LookupType(Symbol name) const { return nullptr; } +void Module::AddGlobalDeclaration(const tint::ast::Node* decl) { + diag::List diags; + BinGlobalDeclaration(decl, diags); + global_declarations_.emplace_back(decl); +} + +void Module::BinGlobalDeclaration(const tint::ast::Node* decl, + diag::List& diags) { + Switch( + decl, // + [&](const ast::TypeDecl* type) { + TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id); + type_decls_.push_back(type); + }, + [&](const Function* func) { + TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id); + functions_.push_back(func); + }, + [&](const Variable* var) { + TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id); + global_variables_.push_back(var); + }, + [&](Default) { + TINT_ICE(AST, diags) << "Unknown global declaration type"; + }); +} + void Module::AddGlobalVariable(const ast::Variable* var) { TINT_ASSERT(AST, var); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id); @@ -100,24 +119,7 @@ void Module::Copy(CloneContext* ctx, const Module* src) { << "src global declaration was nullptr"; continue; } - Switch( - decl, - [&](const ast::TypeDecl* type) { - TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id); - type_decls_.push_back(type); - }, - [&](const Function* func) { - TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id); - functions_.push_back(func); - }, - [&](const Variable* var) { - TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id); - global_variables_.push_back(var); - }, - [&](Default) { - TINT_ICE(AST, ctx->dst->Diagnostics()) - << "Unknown global declaration type"; - }); + BinGlobalDeclaration(decl, ctx->dst->Diagnostics()); } } diff --git a/src/ast/module.h b/src/ast/module.h index 012a73d644..5a1d8e8a2b 100644 --- a/src/ast/module.h +++ b/src/ast/module.h @@ -47,7 +47,7 @@ class Module : public Castable { /// Destructor ~Module() override; - /// @returns the ordered global declarations for the translation unit + /// @returns the declaration-ordered global declarations for the module const std::vector& GlobalDeclarations() const { return global_declarations_; } @@ -67,10 +67,14 @@ class Module : public Castable { return false; } - /// @returns the global variables for the translation unit + /// Adds a global declaration to the Builder. + /// @param decl the declaration to add + void AddGlobalDeclaration(const tint::ast::Node* decl); + + /// @returns the global variables for the module const VariableList& GlobalVariables() const { return global_variables_; } - /// @returns the global variables for the translation unit + /// @returns the global variables for the module VariableList& GlobalVariables() { return global_variables_; } /// Adds a type declaration to the Builder. @@ -81,14 +85,14 @@ class Module : public Castable { /// @param name the name of the type to search for const TypeDecl* LookupType(Symbol name) const; - /// @returns the declared types in the translation unit + /// @returns the declared types in the module const std::vector& TypeDecls() const { return type_decls_; } /// Add a function to the Builder /// @param func the function to add void AddFunction(const Function* func); - /// @returns the functions declared in the translation unit + /// @returns the functions declared in the module const FunctionList& Functions() const { return functions_; } /// Clones this node and all transitive child nodes using the `CloneContext` @@ -103,6 +107,12 @@ class Module : public Castable { void Copy(CloneContext* ctx, const Module* src); private: + /// Adds `decl` to either: + /// * #global_declarations_ + /// * #type_decls_ + /// * #functions_ + void BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags); + std::vector global_declarations_; std::vector type_decls_; FunctionList functions_; diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc index 05246eee3e..2a77c96cbd 100644 --- a/src/resolver/resolver.cc +++ b/src/resolver/resolver.cc @@ -60,6 +60,7 @@ #include "src/sem/if_statement.h" #include "src/sem/loop_statement.h" #include "src/sem/member_accessor_expression.h" +#include "src/sem/module.h" #include "src/sem/multisampled_texture_type.h" #include "src/sem/pointer_type.h" #include "src/sem/reference_type.h" @@ -99,6 +100,10 @@ bool Resolver::Resolve() { return false; } + // Create the semantic module + builder_->Sem().SetModule( + builder_->create(dependencies_.ordered_globals)); + bool result = ResolveInternal(); if (!result && !diagnostics_.contains_errors()) { diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc index 239a77a663..ba2add0ee2 100644 --- a/src/resolver/resolver_test.cc +++ b/src/resolver/resolver_test.cc @@ -39,6 +39,7 @@ #include "src/sem/call.h" #include "src/sem/function.h" #include "src/sem/member_accessor_expression.h" +#include "src/sem/module.h" #include "src/sem/reference_type.h" #include "src/sem/sampled_texture_type.h" #include "src/sem/statement.h" @@ -2161,6 +2162,28 @@ TEST_F(ResolverTest, TextureSampler_TextureDimensions) { EXPECT_TRUE(pairs[0].first != nullptr); EXPECT_TRUE(pairs[0].second == nullptr); } + +TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) { + auto* f0 = Func("f0", {}, ty.void_(), {}); + auto* v0 = Global("v0", ty.i32(), ast::StorageClass::kPrivate); + auto* a0 = Alias("a0", ty.i32()); + auto* s0 = Structure("s0", {Member("m", ty.i32())}); + auto* f1 = Func("f1", {}, ty.void_(), {}); + auto* v1 = Global("v1", ty.i32(), ast::StorageClass::kPrivate); + auto* a1 = Alias("a1", ty.i32()); + auto* s1 = Structure("s1", {Member("m", ty.i32())}); + auto* f2 = Func("f2", {}, ty.void_(), {}); + auto* v2 = Global("v2", ty.i32(), ast::StorageClass::kPrivate); + auto* a2 = Alias("a2", ty.i32()); + auto* s2 = Structure("s2", {Member("m", ty.i32())}); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + + ASSERT_NE(Sem().Module(), nullptr); + EXPECT_THAT(Sem().Module()->DependencyOrderedDeclarations(), + ElementsAre(f0, v0, a0, s0, f1, v1, a1, s1, f2, v2, a2, s2)); +} + } // namespace } // namespace resolver } // namespace tint diff --git a/src/sem/info.h b/src/sem/info.h index 72e2d3ecf9..232d252d7d 100644 --- a/src/sem/info.h +++ b/src/sem/info.h @@ -22,8 +22,10 @@ #include "src/sem/node.h" #include "src/sem/type_mappings.h" -namespace tint { -namespace sem { +namespace tint::sem { + +// Forward declarations +class Module; /// Info holds all the resolved semantic information for a Program. class Info { @@ -60,8 +62,8 @@ class Info { typename AST_OR_TYPE = CastableBase, typename RESULT = GetResultType> const RESULT* Get(const AST_OR_TYPE* node) const { - auto it = map.find(node); - if (it == map.end()) { + auto it = map_.find(node); + if (it == map_.end()) { return nullptr; } return As(it->second); @@ -76,7 +78,7 @@ class Info { const SemanticNodeTypeFor* sem_node) { // Check there's no semantic info already existing for the node TINT_ASSERT(Semantic, Get(node) == nullptr); - map.emplace(node, sem_node); + map_.emplace(node, sem_node); } /// Wrap returns a new Info created with the contents of `inner`. @@ -88,17 +90,26 @@ class Info { /// @return the Info that wraps `inner` static Info Wrap(const Info& inner) { Info out; - out.map = inner.map; + out.map_ = inner.map_; + out.module_ = inner.module_; return out; } + /// Assigns the semantic module. + /// @param module the module to assign. + void SetModule(sem::Module* module) { module_ = module; } + + /// @returns the semantic module. + const sem::Module* Module() const { return module_; } + private: // TODO(crbug.com/tint/724): Once finished, this map should be: // std::unordered_map - std::unordered_map map; + std::unordered_map map_; + // The semantic module + sem::Module* module_ = nullptr; }; -} // namespace sem -} // namespace tint +} // namespace tint::sem #endif // SRC_SEM_INFO_H_ diff --git a/src/sem/module.cc b/src/sem/module.cc new file mode 100644 index 0000000000..48c348fd38 --- /dev/null +++ b/src/sem/module.cc @@ -0,0 +1,29 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0(the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/sem/module.h" + +#include +#include + +TINT_INSTANTIATE_TYPEINFO(tint::sem::Module); + +namespace tint::sem { + +Module::Module(std::vector dep_ordered_decls) + : dep_ordered_decls_(std::move(dep_ordered_decls)) {} + +Module::~Module() = default; + +} // namespace tint::sem diff --git a/src/sem/module.h b/src/sem/module.h new file mode 100644 index 0000000000..07d790337a --- /dev/null +++ b/src/sem/module.h @@ -0,0 +1,52 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0(the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_SEM_MODULE_H_ +#define SRC_SEM_MODULE_H_ + +#include + +#include "src/sem/node.h" + +// Forward declarations +namespace tint::ast { +class Node; +class Module; +} // namespace tint::ast + +namespace tint::sem { + +/// Module holds the top-level semantic types, functions and global variables +/// used by a Program. +class Module : public Castable { + public: + /// Constructor + /// @param dep_ordered_decls the dependency-ordered module-scope declarations + explicit Module(std::vector dep_ordered_decls); + + /// Destructor + ~Module() override; + + /// @returns the dependency-ordered global declarations for the module + const std::vector& DependencyOrderedDeclarations() const { + return dep_ordered_decls_; + } + + private: + const std::vector dep_ordered_decls_; +}; + +} // namespace tint::sem + +#endif // SRC_SEM_MODULE_H_