From 2081ee43bf51005e2dbed2b271254d517e998fd0 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 19 May 2022 19:32:29 +0000 Subject: [PATCH] tint: Add sem::Materialize A new semantic expression node that wraps another semantic node. Used to indicate the point at which compile-time, abstract numeric typed expressions are implicitly converted to a concrete type. Bug: tint:1504 Change-Id: I52e256bbbdeaa9d9eff4cb93b6f937dd00bdc5cb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90531 Reviewed-by: David Neto Kokoro: Kokoro Commit-Queue: Ben Clayton --- src/tint/BUILD.gn | 2 ++ src/tint/CMakeLists.txt | 3 +++ src/tint/sem/expression.cc | 9 +++++++ src/tint/sem/expression.h | 3 +++ src/tint/sem/expression_test.cc | 39 +++++++++++++++++++++++++++ src/tint/sem/materialize.cc | 36 +++++++++++++++++++++++++ src/tint/sem/materialize.h | 48 +++++++++++++++++++++++++++++++++ test/tint/BUILD.gn | 1 + 8 files changed, 141 insertions(+) create mode 100644 src/tint/sem/expression_test.cc create mode 100644 src/tint/sem/materialize.cc create mode 100644 src/tint/sem/materialize.h diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 2f4fd62730..fbf443c303 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -616,6 +616,8 @@ libtint_source_set("libtint_sem_src") { "sem/info.h", "sem/loop_statement.cc", "sem/loop_statement.h", + "sem/materialize.cc", + "sem/materialize.h", "sem/matrix.cc", "sem/matrix.h", "sem/member_accessor_expression.cc", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index 2c03e8130b..85ec3dbab7 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -421,6 +421,8 @@ set(TINT_LIB_SRCS sem/if_statement.h sem/loop_statement.cc sem/loop_statement.h + sem/materialize.cc + sem/materialize.h sem/matrix.cc sem/matrix.h sem/multisampled_texture.cc @@ -799,6 +801,7 @@ if(TINT_BUILD_TESTS) sem/builtin_test.cc sem/depth_multisampled_texture_test.cc sem/depth_texture_test.cc + sem/expression_test.cc sem/external_texture_test.cc sem/f16_test.cc sem/f32_test.cc diff --git a/src/tint/sem/expression.cc b/src/tint/sem/expression.cc index 40fbb584c2..57ec68bf21 100644 --- a/src/tint/sem/expression.cc +++ b/src/tint/sem/expression.cc @@ -16,6 +16,8 @@ #include +#include "src/tint/sem/materialize.h" + TINT_INSTANTIATE_TYPEINFO(tint::sem::Expression); namespace tint::sem { @@ -37,4 +39,11 @@ Expression::Expression(const ast::Expression* declaration, Expression::~Expression() = default; +const Expression* Expression::UnwrapMaterialize() const { + if (auto* m = As()) { + return m->Expr(); + } + return this; +} + } // namespace tint::sem diff --git a/src/tint/sem/expression.h b/src/tint/sem/expression.h index 13f493b59c..a7838516bb 100644 --- a/src/tint/sem/expression.h +++ b/src/tint/sem/expression.h @@ -76,6 +76,9 @@ class Expression : public Castable { /// @return true of this expression may have side effects bool HasSideEffects() const { return has_side_effects_; } + /// @return the inner expression node if this is a Materialize, otherwise this. + const Expression* UnwrapMaterialize() const; + protected: /// The AST expression node for this semantic expression const ast::Expression* const declaration_; diff --git a/src/tint/sem/expression_test.cc b/src/tint/sem/expression_test.cc new file mode 100644 index 0000000000..fc1adeb88d --- /dev/null +++ b/src/tint/sem/expression_test.cc @@ -0,0 +1,39 @@ +// 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/tint/sem/expression.h" + +#include "src/tint/sem/test_helper.h" + +#include "src/tint/sem/materialize.h" + +using namespace tint::number_suffixes; // NOLINT + +namespace tint::sem { +namespace { + +using ExpressionTest = TestHelper; + +TEST_F(ExpressionTest, UnwrapMaterialize) { + auto* a = create(/* declaration */ nullptr, create(), /* statement */ nullptr, + Constant{}, + /* has_side_effects */ false, /* source_var */ nullptr); + auto* b = create(a, /* statement */ nullptr, Constant{create(), {1_a}}); + + EXPECT_EQ(a, a->UnwrapMaterialize()); + EXPECT_EQ(a, b->UnwrapMaterialize()); +} + +} // namespace +} // namespace tint::sem diff --git a/src/tint/sem/materialize.cc b/src/tint/sem/materialize.cc new file mode 100644 index 0000000000..76dd9d4405 --- /dev/null +++ b/src/tint/sem/materialize.cc @@ -0,0 +1,36 @@ +// 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/tint/sem/materialize.h" + +TINT_INSTANTIATE_TYPEINFO(tint::sem::Materialize); + +namespace tint::sem { + +Materialize::Materialize(const Expression* expr, const Statement* statement, Constant constant) + : Base(/* declaration */ expr->Declaration(), + /* type */ constant.Type(), + /* statement */ statement, + /* constant */ constant, + /* has_side_effects */ false, + /* source_var */ expr->SourceVariable()), + expr_(expr) { + // Materialize nodes only wrap compile-time expressions, and so the Materialize expression must + // have a constant value. + TINT_ASSERT(Semantic, constant.IsValid()); +} + +Materialize::~Materialize() = default; + +} // namespace tint::sem diff --git a/src/tint/sem/materialize.h b/src/tint/sem/materialize.h new file mode 100644 index 0000000000..a7c0e3af5e --- /dev/null +++ b/src/tint/sem/materialize.h @@ -0,0 +1,48 @@ +// 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_TINT_SEM_MATERIALIZE_H_ +#define SRC_TINT_SEM_MATERIALIZE_H_ + +#include "src/tint/sem/expression.h" + +namespace tint::sem { + +/// Materialize is a semantic expression which represents the materialization of a value of an +/// abstract numeric type to a value of a concrete type. +/// Abstract numeric materialization is implicit in WGSL, so the Materialize semantic node shares +/// the same AST node as the inner semantic node. +/// Abstract numerics types may only be used by compile-time expressions, so a Materialize semantic +/// node must have a valid Constant value. +class Materialize final : public Castable { + public: + /// Constructor + /// @param expr the inner expression, being materialized + /// @param statement the statement that owns this expression + /// @param constant the constant value of this expression + Materialize(const Expression* expr, const Statement* statement, Constant constant); + + /// Destructor + ~Materialize() override; + + /// @return the target of the call + const Expression* Expr() const { return expr_; } + + private: + Expression const* const expr_; +}; + +} // namespace tint::sem + +#endif // SRC_TINT_SEM_MATERIALIZE_H_ diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn index c89e1b57b7..2ef120246c 100644 --- a/test/tint/BUILD.gn +++ b/test/tint/BUILD.gn @@ -290,6 +290,7 @@ tint_unittests_source_set("tint_unittests_sem_src") { "../../src/tint/sem/builtin_test.cc", "../../src/tint/sem/depth_multisampled_texture_test.cc", "../../src/tint/sem/depth_texture_test.cc", + "../../src/tint/sem/expression_test.cc", "../../src/tint/sem/external_texture_test.cc", "../../src/tint/sem/f16_test.cc", "../../src/tint/sem/f32_test.cc",