[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>
This commit is contained in:
dan sinclair 2020-04-02 02:41:30 +00:00 committed by David Neto
parent 66df06817f
commit cfe4f13b1b
5 changed files with 104 additions and 7 deletions

View File

@ -415,6 +415,7 @@ endif()
if(${TINT_BUILD_SPV_WRITER}) if(${TINT_BUILD_SPV_WRITER})
list(APPEND TINT_TEST_SRCS list(APPEND TINT_TEST_SRCS
writer/spirv/binary_writer_test.cc writer/spirv/binary_writer_test.cc
writer/spirv/builder_assign_test.cc
writer/spirv/builder_constructor_expression_test.cc writer/spirv/builder_constructor_expression_test.cc
writer/spirv/builder_entry_point_test.cc writer/spirv/builder_entry_point_test.cc
writer/spirv/builder_function_test.cc writer/spirv/builder_function_test.cc

View File

@ -17,13 +17,14 @@
#include <utility> #include <utility>
#include "spirv/unified1/spirv.h" #include "spirv/unified1/spirv.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/binding_decoration.h" #include "src/ast/binding_decoration.h"
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/builtin_decoration.h" #include "src/ast/builtin_decoration.h"
#include "src/ast/constructor_expression.h" #include "src/ast/constructor_expression.h"
#include "src/ast/decorated_variable.h" #include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/int_literal.h" #include "src/ast/int_literal.h"
#include "src/ast/location_decoration.h" #include "src/ast/location_decoration.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
@ -155,6 +156,21 @@ void Builder::iterate(std::function<void(const Instruction&)> 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) { bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
auto name = ep->name(); auto name = ep->name();
if (name.empty()) { if (name.empty()) {
@ -374,8 +390,10 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) {
return true; return true;
} }
uint32_t Builder::GenerateIdentifierExpression(ast::IdentifierExpression* expr) { uint32_t Builder::GenerateIdentifierExpression(
for (auto iter = variable_stack_.rbegin(); iter != variable_stack_.rend(); ++iter) { ast::IdentifierExpression* expr) {
for (auto iter = variable_stack_.rbegin(); iter != variable_stack_.rend();
++iter) {
auto& map = *iter; auto& map = *iter;
// TODO(dsinclair): handle names with namespaces in them ... // TODO(dsinclair): handle names with namespaces in them ...
@ -513,6 +531,9 @@ bool Builder::GenerateReturnStatement(ast::ReturnStatement* stmt) {
} }
bool Builder::GenerateStatement(ast::Statement* stmt) { bool Builder::GenerateStatement(ast::Statement* stmt) {
if (stmt->IsAssign()) {
return GenerateAssignStatement(stmt->AsAssign());
}
if (stmt->IsReturn()) { if (stmt->IsReturn()) {
return GenerateReturnStatement(stmt->AsReturn()); return GenerateReturnStatement(stmt->AsReturn());
} }

View File

@ -143,6 +143,10 @@ class Builder {
/// @returns the SPIR-V builtin or SpvBuiltInMax on error. /// @returns the SPIR-V builtin or SpvBuiltInMax on error.
SpvBuiltIn ConvertBuiltin(ast::Builtin builtin) const; 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 /// Generates an entry point instruction
/// @param ep the entry point /// @param ep the entry point
/// @returns true if the instruction was generated, false otherwise /// @returns true if the instruction was generated, false otherwise

View File

@ -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

View File

@ -16,14 +16,14 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
#include "src/ast/type/f32_type.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/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/builder.h"
#include "src/writer/spirv/spv_dump.h" #include "src/writer/spirv/spv_dump.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/variable.h"
namespace tint { namespace tint {
namespace writer { namespace writer {
@ -144,4 +144,3 @@ TEST_F(BuilderTest, DISABLED_IdentifierExpression_MultiName) {}
} // namespace spirv } // namespace spirv
} // namespace writer } // namespace writer
} // namespace tint } // namespace tint