ast: Remove Function::set_body()

Bug: tint:390
Change-Id: I525086868c6470ba39fe8c4ede7390e74c9489ff
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35012
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-12-07 21:17:47 +00:00 committed by Commit Bot service account
parent 2190a8f480
commit 602c025aa0
6 changed files with 109 additions and 69 deletions

View File

@ -153,9 +153,6 @@ class Function : public Castable<Function, Node> {
// function is empty // function is empty
const Statement* get_last_statement() const; const Statement* get_last_statement() const;
/// Sets the body of the function
/// @param body the function body
void set_body(BlockStatement* body) { body_ = body; }
/// @returns the function body /// @returns the function body
const BlockStatement* body() const { return body_; } const BlockStatement* body() const { return body_; }
/// @returns the function body /// @returns the function body

View File

@ -185,12 +185,11 @@ TEST_F(FunctionTest, IsValid) {
params.push_back( params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32)); create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(block);
EXPECT_TRUE(f.IsValid()); EXPECT_TRUE(f.IsValid());
} }
@ -253,13 +252,13 @@ TEST_F(FunctionTest, IsValid_NullBodyStatement) {
params.push_back( params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32)); create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
block->append(nullptr); body->append(nullptr);
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(block);
EXPECT_FALSE(f.IsValid()); EXPECT_FALSE(f.IsValid());
} }
@ -271,13 +270,12 @@ TEST_F(FunctionTest, IsValid_InvalidBodyStatement) {
params.push_back( params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32)); create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
block->append(nullptr); body->append(nullptr);
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(block);
EXPECT_FALSE(f.IsValid()); EXPECT_FALSE(f.IsValid());
} }
@ -285,12 +283,10 @@ TEST_F(FunctionTest, ToStr) {
type::Void void_type; type::Void void_type;
type::I32 i32; type::I32 i32;
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
Function f(Source{}, "func", {}, &void_type, create<BlockStatement>(), Function f(Source{}, "func", {}, &void_type, body, FunctionDecorationList{});
FunctionDecorationList{});
f.set_body(block);
std::ostringstream out; std::ostringstream out;
f.to_str(out, 2); f.to_str(out, 2);
@ -306,11 +302,11 @@ TEST_F(FunctionTest, ToStr_WithDecoration) {
type::Void void_type; type::Void void_type;
type::I32 i32; type::I32 i32;
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
Function f( Function f(
Source{}, "func", {}, &void_type, block, Source{}, "func", {}, &void_type, body,
FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6, Source{})}); FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6, Source{})});
std::ostringstream out; std::ostringstream out;
@ -332,12 +328,11 @@ TEST_F(FunctionTest, ToStr_WithParams) {
params.push_back( params.push_back(
create<Variable>(Source{}, "var", StorageClass::kNone, &i32)); create<Variable>(Source{}, "var", StorageClass::kNone, &i32));
auto* block = create<BlockStatement>(); auto* body = create<BlockStatement>();
block->append(create<DiscardStatement>()); body->append(create<DiscardStatement>());
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(block);
std::ostringstream out; std::ostringstream out;
f.to_str(out, 2); f.to_str(out, 2);
@ -386,9 +381,8 @@ TEST_F(FunctionTest, GetLastStatement) {
auto* body = create<BlockStatement>(); auto* body = create<BlockStatement>();
auto* stmt = create<DiscardStatement>(); auto* stmt = create<DiscardStatement>();
body->append(stmt); body->append(stmt);
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(body);
EXPECT_EQ(f.get_last_statement(), stmt); EXPECT_EQ(f.get_last_statement(), stmt);
} }
@ -398,9 +392,8 @@ TEST_F(FunctionTest, GetLastStatement_nullptr) {
VariableList params; VariableList params;
auto* body = create<BlockStatement>(); auto* body = create<BlockStatement>();
Function f(Source{}, "func", params, &void_type, create<BlockStatement>(), Function f(Source{}, "func", params, &void_type, body,
FunctionDecorationList{}); FunctionDecorationList{});
f.set_body(body);
EXPECT_EQ(f.get_last_statement(), nullptr); EXPECT_EQ(f.get_last_statement(), nullptr);
} }

View File

@ -702,7 +702,8 @@ bool FunctionEmitter::Emit() {
return true; return true;
} }
if (!EmitFunctionDeclaration()) { FunctionDeclaration decl;
if (!ParseFunctionDeclaration(&decl)) {
return false; return false;
} }
@ -716,8 +717,12 @@ bool FunctionEmitter::Emit() {
"element but has " "element but has "
<< statements_stack_.size(); << statements_stack_.size();
} }
auto* body = statements_stack_[0].statements_; auto* body = statements_stack_[0].statements_;
parser_impl_.get_module().functions().back()->set_body(body); ast_module_.AddFunction(create<ast::Function>(
decl.source, decl.name, std::move(decl.params), decl.return_type, body,
std::move(decl.decorations)));
// Maintain the invariant by repopulating the one and only element. // Maintain the invariant by repopulating the one and only element.
statements_stack_.clear(); statements_stack_.clear();
PushNewStatementBlock(constructs_[0].get(), 0, nullptr, nullptr, nullptr); PushNewStatementBlock(constructs_[0].get(), 0, nullptr, nullptr, nullptr);
@ -725,7 +730,7 @@ bool FunctionEmitter::Emit() {
return success(); return success();
} }
bool FunctionEmitter::EmitFunctionDeclaration() { bool FunctionEmitter::ParseFunctionDeclaration(FunctionDeclaration* decl) {
if (failed()) { if (failed()) {
return false; return false;
} }
@ -774,11 +779,11 @@ bool FunctionEmitter::EmitFunctionDeclaration() {
if (ep_info_ != nullptr) { if (ep_info_ != nullptr) {
decos.emplace_back(create<ast::StageDecoration>(ep_info_->stage, Source{})); decos.emplace_back(create<ast::StageDecoration>(ep_info_->stage, Source{}));
} }
auto* ast_fn =
create<ast::Function>(Source{}, name, std::move(ast_params), ret_ty,
create<ast::BlockStatement>(), std::move(decos));
ast_module_.AddFunction(ast_fn); decl->name = name;
decl->params = std::move(ast_params);
decl->return_type = ret_ty;
decl->decorations = std::move(decos);
return success(); return success();
} }
@ -4114,6 +4119,9 @@ ast::Expression* FunctionEmitter::ConvertTexelForStorage(
return ast_module_.create<ast::BitcastExpression>(dest_type, texel_prefix); return ast_module_.create<ast::BitcastExpression>(dest_type, texel_prefix);
} }
FunctionEmitter::FunctionDeclaration::FunctionDeclaration() = default;
FunctionEmitter::FunctionDeclaration::~FunctionDeclaration() = default;
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader
} // namespace tint } // namespace tint

View File

@ -328,12 +328,6 @@ class FunctionEmitter {
/// @returns the parser implementation /// @returns the parser implementation
ParserImpl* parser() { return &parser_impl_; } ParserImpl* parser() { return &parser_impl_; }
/// Emits the declaration, which comprises the name, parameters, and
/// return type. The function AST node is appended to the module
/// AST node.
/// @returns true if emission has not yet failed.
bool EmitFunctionDeclaration();
/// Emits the function body, populating the bottom entry of the statements /// Emits the function body, populating the bottom entry of the statements
/// stack. /// stack.
/// @returns false if emission failed. /// @returns false if emission failed.
@ -700,6 +694,31 @@ class FunctionEmitter {
const spvtools::opt::Instruction& image_access); const spvtools::opt::Instruction& image_access);
private: private:
/// FunctionDeclaration contains the parsed information for a function header.
struct FunctionDeclaration {
/// Constructor
FunctionDeclaration();
/// Destructor
~FunctionDeclaration();
/// Parsed header source
Source source;
/// Function name
std::string name;
/// Function parameters
ast::VariableList params;
/// Function return type
ast::type::Type* return_type;
/// Function decorations
ast::FunctionDecorationList decorations;
};
/// Parse the function declaration, which comprises the name, parameters, and
/// return type, populating `decl`.
/// @param decl the FunctionDeclaration to populate
/// @returns true if emission has not yet failed.
bool ParseFunctionDeclaration(FunctionDeclaration* decl);
/// @returns the store type for the OpVariable instruction, or /// @returns the store type for the OpVariable instruction, or
/// null on failure. /// null on failure.
ast::type::Type* GetVariableStoreType( ast::type::Type* GetVariableStoreType(

View File

@ -49,7 +49,7 @@ std::string CommonTypes() {
)"; )";
} }
TEST_F(SpvParserTest, EmitFunctionDeclaration_VoidFunctionWithoutParams) { TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(CommonTypes() + R"(
%100 = OpFunction %void None %voidfn %100 = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
@ -58,15 +58,20 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_VoidFunctionWithoutParams) {
)")); )"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
EXPECT_TRUE(fe.EmitFunctionDeclaration()); EXPECT_TRUE(fe.Emit());
EXPECT_THAT(p->module().to_str(), HasSubstr(R"( auto got = p->module().to_str();
auto* expect = R"(Module{
Function x_100 -> __void Function x_100 -> __void
() ()
{ {
})")); Return{}
}
}
)";
EXPECT_EQ(got, expect);
} }
TEST_F(SpvParserTest, EmitFunctionDeclaration_NonVoidResultType) { TEST_F(SpvParserTest, Emit_NonVoidResultType) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(CommonTypes() + R"(
%fn_ret_float = OpTypeFunction %float %fn_ret_float = OpTypeFunction %float
%100 = OpFunction %float None %fn_ret_float %100 = OpFunction %float None %fn_ret_float
@ -76,16 +81,25 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_NonVoidResultType) {
)")); )"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
EXPECT_TRUE(fe.EmitFunctionDeclaration()); EXPECT_TRUE(fe.Emit());
EXPECT_THAT(p->module().to_str(), HasSubstr(R"( auto got = p->module().to_str();
auto* expect = R"(Module{
Function x_100 -> __f32 Function x_100 -> __f32
() ()
{ {
})")); Return{
{
ScalarConstructor[not set]{0.000000}
}
}
}
}
)";
EXPECT_EQ(got, expect);
} }
TEST_F(SpvParserTest, EmitFunctionDeclaration_MixedParamTypes) { TEST_F(SpvParserTest, Emit_MixedParamTypes) {
auto p = parser(test::Assemble(Names({"a", "b", "c"}) + CommonTypes() + R"( auto p = parser(test::Assemble(Names({"a", "b", "c"}) + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int %fn_mixed_params = OpTypeFunction %float %uint %float %int
@ -99,9 +113,10 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_MixedParamTypes) {
)")); )"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
EXPECT_TRUE(fe.EmitFunctionDeclaration()); EXPECT_TRUE(fe.Emit());
EXPECT_THAT(p->module().to_str(), HasSubstr(R"( auto got = p->module().to_str();
auto* expect = R"(Module{
Function x_100 -> __void Function x_100 -> __void
( (
VariableConst{ VariableConst{
@ -121,10 +136,14 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_MixedParamTypes) {
} }
) )
{ {
})")); Return{}
}
}
)";
EXPECT_EQ(got, expect);
} }
TEST_F(SpvParserTest, EmitFunctionDeclaration_GenerateParamNames) { TEST_F(SpvParserTest, Emit_GenerateParamNames) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int %fn_mixed_params = OpTypeFunction %float %uint %float %int
@ -138,9 +157,10 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_GenerateParamNames) {
)")); )"));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100)); FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
EXPECT_TRUE(fe.EmitFunctionDeclaration()); EXPECT_TRUE(fe.Emit());
EXPECT_THAT(p->module().to_str(), HasSubstr(R"( auto got = p->module().to_str();
auto* expect = R"(Module{
Function x_100 -> __void Function x_100 -> __void
( (
VariableConst{ VariableConst{
@ -160,7 +180,11 @@ TEST_F(SpvParserTest, EmitFunctionDeclaration_GenerateParamNames) {
} }
) )
{ {
})")); Return{}
}
}
)";
EXPECT_EQ(got, expect);
} }
} // namespace } // namespace

View File

@ -143,12 +143,6 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Void void_type; ast::type::Void void_type;
ast::Function func(
Source{}, "main", {}, &void_type, create<ast::BlockStatement>(),
ast::FunctionDecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
});
auto* body = create<ast::BlockStatement>(); auto* body = create<ast::BlockStatement>();
body->append(create<ast::AssignmentStatement>( body->append(create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>("my_out"), create<ast::IdentifierExpression>("my_out"),
@ -160,7 +154,12 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
body->append(create<ast::AssignmentStatement>( body->append(create<ast::AssignmentStatement>(
create<ast::IdentifierExpression>("my_out"), create<ast::IdentifierExpression>("my_out"),
create<ast::IdentifierExpression>("my_in"))); create<ast::IdentifierExpression>("my_in")));
func.set_body(body);
ast::Function func(
Source{}, "main", {}, &void_type, body,
ast::FunctionDecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}),
});
auto* v_in = auto* v_in =
create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32); create<ast::Variable>(Source{}, "my_in", ast::StorageClass::kInput, &f32);