[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 <dneto@google.com>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6f09163..2b9bbbc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -415,6 +415,7 @@
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 be9c570..69bcdb8 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -17,13 +17,14 @@
#include <utility>
#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 @@
}
}
+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 @@
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::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 479da1b..8bcad6e 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -143,6 +143,10 @@
/// @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 0000000..5c7430e
--- /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 <memory>
+
+#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<ast::IdentifierExpression>("var");
+ auto val = std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&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 ebf0159..0983c72 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 @@
} // namespace spirv
} // namespace writer
} // namespace tint
-