From cfe4f13b1b3b70153a42aa2434c0bcdf9714cc25 Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Thu, 2 Apr 2020 02:41:30 +0000 Subject: [PATCH] [spirv-writer] Add assignment statements This Cl adds assignment statement generation to the SPIR-V writer. Bug: tint:5 Change-Id: I17876c0211e4b4e061d39e08fc6a433098252f38 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18621 Reviewed-by: David Neto --- src/CMakeLists.txt | 1 + src/writer/spirv/builder.cc | 27 ++++++- src/writer/spirv/builder.h | 4 ++ src/writer/spirv/builder_assign_test.cc | 72 +++++++++++++++++++ .../spirv/builder_ident_expression_test.cc | 7 +- 5 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 src/writer/spirv/builder_assign_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f09163c86..2b9bbbc5ea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -415,6 +415,7 @@ endif() if(${TINT_BUILD_SPV_WRITER}) list(APPEND TINT_TEST_SRCS writer/spirv/binary_writer_test.cc + writer/spirv/builder_assign_test.cc writer/spirv/builder_constructor_expression_test.cc writer/spirv/builder_entry_point_test.cc writer/spirv/builder_function_test.cc diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index be9c570dca..69bcdb8c48 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -17,13 +17,14 @@ #include #include "spirv/unified1/spirv.h" +#include "src/ast/assignment_statement.h" #include "src/ast/binding_decoration.h" #include "src/ast/bool_literal.h" -#include "src/ast/identifier_expression.h" #include "src/ast/builtin_decoration.h" #include "src/ast/constructor_expression.h" #include "src/ast/decorated_variable.h" #include "src/ast/float_literal.h" +#include "src/ast/identifier_expression.h" #include "src/ast/int_literal.h" #include "src/ast/location_decoration.h" #include "src/ast/return_statement.h" @@ -155,6 +156,21 @@ void Builder::iterate(std::function cb) const { } } +bool Builder::GenerateAssignStatement(ast::AssignmentStatement* assign) { + auto lhs_id = GenerateExpression(assign->lhs()); + if (lhs_id == 0) { + return false; + } + auto rhs_id = GenerateExpression(assign->rhs()); + if (rhs_id == 0) { + return false; + } + + push_function_inst(spv::Op::OpStore, + {Operand::Int(lhs_id), Operand::Int(rhs_id)}); + return true; +} + bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) { auto name = ep->name(); if (name.empty()) { @@ -374,8 +390,10 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) { return true; } -uint32_t Builder::GenerateIdentifierExpression(ast::IdentifierExpression* expr) { - for (auto iter = variable_stack_.rbegin(); iter != variable_stack_.rend(); ++iter) { +uint32_t Builder::GenerateIdentifierExpression( + ast::IdentifierExpression* expr) { + for (auto iter = variable_stack_.rbegin(); iter != variable_stack_.rend(); + ++iter) { auto& map = *iter; // TODO(dsinclair): handle names with namespaces in them ... @@ -513,6 +531,9 @@ bool Builder::GenerateReturnStatement(ast::ReturnStatement* stmt) { } bool Builder::GenerateStatement(ast::Statement* stmt) { + if (stmt->IsAssign()) { + return GenerateAssignStatement(stmt->AsAssign()); + } if (stmt->IsReturn()) { return GenerateReturnStatement(stmt->AsReturn()); } diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h index 479da1b33c..8bcad6e594 100644 --- a/src/writer/spirv/builder.h +++ b/src/writer/spirv/builder.h @@ -143,6 +143,10 @@ class Builder { /// @returns the SPIR-V builtin or SpvBuiltInMax on error. SpvBuiltIn ConvertBuiltin(ast::Builtin builtin) const; + /// Generates an assignment statement + /// @param assign the statement to generate + /// @returns true if the statement was successfully generated + bool GenerateAssignStatement(ast::AssignmentStatement* assign); /// Generates an entry point instruction /// @param ep the entry point /// @returns true if the instruction was generated, false otherwise diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc new file mode 100644 index 0000000000..5c7430ed9d --- /dev/null +++ b/src/writer/spirv/builder_assign_test.cc @@ -0,0 +1,72 @@ +// Copyright 2020 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 + +#include "gtest/gtest.h" +#include "src/ast/assignment_statement.h" +#include "src/ast/float_literal.h" +#include "src/ast/identifier_expression.h" +#include "src/ast/scalar_constructor_expression.h" +#include "src/ast/type/f32_type.h" +#include "src/ast/type/vector_type.h" +#include "src/writer/spirv/builder.h" +#include "src/writer/spirv/spv_dump.h" + +namespace tint { +namespace writer { +namespace spirv { +namespace { + +using BuilderTest = testing::Test; + +TEST_F(BuilderTest, Assign_Var) { + ast::type::F32Type f32; + ast::type::VectorType vec(&f32, 3); + + ast::Variable v("var", ast::StorageClass::kOutput, &f32); + + Builder b; + EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); + ASSERT_FALSE(b.has_error()) << b.error(); + + auto ident = std::make_unique("var"); + auto val = std::make_unique( + std::make_unique(&f32, 1.0f)); + + ast::AssignmentStatement assign(std::move(ident), std::move(val)); + + b.push_function(Function{}); + + EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); + EXPECT_FALSE(b.has_error()); + + EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 +%2 = OpTypePointer Output %3 +%1 = OpVariable %2 Output +%4 = OpConstant %3 1 +)"); + + EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %4 +)"); +} + +TEST_F(BuilderTest, DISABLED_Assign_StructMember) {} + +TEST_F(BuilderTest, DISABLED_Assign_Vector) {} + +} // namespace +} // namespace spirv +} // namespace writer +} // namespace tint diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc index ebf0159597..0983c72da6 100644 --- a/src/writer/spirv/builder_ident_expression_test.cc +++ b/src/writer/spirv/builder_ident_expression_test.cc @@ -16,14 +16,14 @@ #include "gtest/gtest.h" #include "src/ast/float_literal.h" +#include "src/ast/identifier_expression.h" #include "src/ast/scalar_constructor_expression.h" #include "src/ast/type/f32_type.h" -#include "src/ast/type_constructor_expression.h" #include "src/ast/type/vector_type.h" +#include "src/ast/type_constructor_expression.h" +#include "src/ast/variable.h" #include "src/writer/spirv/builder.h" #include "src/writer/spirv/spv_dump.h" -#include "src/ast/identifier_expression.h" -#include "src/ast/variable.h" namespace tint { namespace writer { @@ -144,4 +144,3 @@ TEST_F(BuilderTest, DISABLED_IdentifierExpression_MultiName) {} } // namespace spirv } // namespace writer } // namespace tint -