[spirv-reader] use stack of statement lists
This is preparation for emitting nested control flow. Bug: tint:3 Change-Id: I90fc7edba8cb9937f722e6f5e94c7f222d34c403 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/21801 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
b83c651654
commit
7768f5b308
|
@ -367,10 +367,22 @@ FunctionEmitter::FunctionEmitter(ParserImpl* pi,
|
||||||
type_mgr_(ir_context_.get_type_mgr()),
|
type_mgr_(ir_context_.get_type_mgr()),
|
||||||
fail_stream_(pi->fail_stream()),
|
fail_stream_(pi->fail_stream()),
|
||||||
namer_(pi->namer()),
|
namer_(pi->namer()),
|
||||||
function_(function) {}
|
function_(function) {
|
||||||
|
statements_stack_.emplace_back(ast::StatementList{});
|
||||||
|
}
|
||||||
|
|
||||||
FunctionEmitter::~FunctionEmitter() = default;
|
FunctionEmitter::~FunctionEmitter() = default;
|
||||||
|
|
||||||
|
const ast::StatementList& FunctionEmitter::ast_body() {
|
||||||
|
assert(!statements_stack_.empty());
|
||||||
|
return statements_stack_[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionEmitter::AddStatement(std::unique_ptr<ast::Statement> statement) {
|
||||||
|
assert(!statements_stack_.empty());
|
||||||
|
statements_stack_.back().emplace_back(std::move(statement));
|
||||||
|
}
|
||||||
|
|
||||||
bool FunctionEmitter::Emit() {
|
bool FunctionEmitter::Emit() {
|
||||||
if (failed()) {
|
if (failed()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -389,7 +401,15 @@ bool FunctionEmitter::Emit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the body of the AST function node.
|
// Set the body of the AST function node.
|
||||||
parser_impl_.get_module().functions().back()->set_body(std::move(ast_body_));
|
if (statements_stack_.size() != 1) {
|
||||||
|
return Fail() << "internal error: statement-list stack should have 1 "
|
||||||
|
"element but has "
|
||||||
|
<< statements_stack_.size();
|
||||||
|
}
|
||||||
|
ast::StatementList body(std::move(statements_stack_[0]));
|
||||||
|
parser_impl_.get_module().functions().back()->set_body(std::move(body));
|
||||||
|
// Maintain the invariant by repopulating the one and only element.
|
||||||
|
statements_stack_[0] = ast::StatementList{};
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
@ -1363,7 +1383,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
|
||||||
// TODO(dneto): Add the initializer via Variable::set_constructor.
|
// TODO(dneto): Add the initializer via Variable::set_constructor.
|
||||||
auto var_decl_stmt =
|
auto var_decl_stmt =
|
||||||
std::make_unique<ast::VariableDeclStatement>(std::move(var));
|
std::make_unique<ast::VariableDeclStatement>(std::move(var));
|
||||||
ast_body_.emplace_back(std::move(var_decl_stmt));
|
AddStatement(std::move(var_decl_stmt));
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(inst.result_id());
|
identifier_values_.insert(inst.result_id());
|
||||||
}
|
}
|
||||||
|
@ -1445,7 +1465,7 @@ bool FunctionEmitter::EmitConstDefinition(
|
||||||
}
|
}
|
||||||
ast_const->set_constructor(std::move(ast_expr.expr));
|
ast_const->set_constructor(std::move(ast_expr.expr));
|
||||||
ast_const->set_is_const(true);
|
ast_const->set_is_const(true);
|
||||||
ast_body_.emplace_back(
|
AddStatement(
|
||||||
std::make_unique<ast::VariableDeclStatement>(std::move(ast_const)));
|
std::make_unique<ast::VariableDeclStatement>(std::move(ast_const)));
|
||||||
// Save this as an already-named value.
|
// Save this as an already-named value.
|
||||||
identifier_values_.insert(inst.result_id());
|
identifier_values_.insert(inst.result_id());
|
||||||
|
@ -1476,7 +1496,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
// TODO(dneto): Order of evaluation?
|
// TODO(dneto): Order of evaluation?
|
||||||
auto lhs = MakeExpression(inst.GetSingleWordInOperand(0));
|
auto lhs = MakeExpression(inst.GetSingleWordInOperand(0));
|
||||||
auto rhs = MakeExpression(inst.GetSingleWordInOperand(1));
|
auto rhs = MakeExpression(inst.GetSingleWordInOperand(1));
|
||||||
ast_body_.emplace_back(std::make_unique<ast::AssignmentStatement>(
|
AddStatement(std::make_unique<ast::AssignmentStatement>(
|
||||||
std::move(lhs.expr), std::move(rhs.expr)));
|
std::move(lhs.expr), std::move(rhs.expr)));
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,8 +172,10 @@ class FunctionEmitter {
|
||||||
/// @returns true if emission has failed.
|
/// @returns true if emission has failed.
|
||||||
bool failed() const { return !success(); }
|
bool failed() const { return !success(); }
|
||||||
|
|
||||||
|
/// Returns the body of the function. It is the bottom of the statement
|
||||||
|
/// stack.
|
||||||
/// @returns the body of the function.
|
/// @returns the body of the function.
|
||||||
const ast::StatementList& ast_body() { return ast_body_; }
|
const ast::StatementList& ast_body();
|
||||||
|
|
||||||
/// Records failure.
|
/// Records failure.
|
||||||
/// @returns a FailStream on which to emit diagnostics.
|
/// @returns a FailStream on which to emit diagnostics.
|
||||||
|
@ -188,7 +190,8 @@ class FunctionEmitter {
|
||||||
/// @returns true if emission has not yet failed.
|
/// @returns true if emission has not yet failed.
|
||||||
bool EmitFunctionDeclaration();
|
bool EmitFunctionDeclaration();
|
||||||
|
|
||||||
/// Emits the function body, populating |ast_body_|
|
/// Emits the function body, populating the bottom entry of the statements
|
||||||
|
/// stack.
|
||||||
/// @returns false if emission failed.
|
/// @returns false if emission failed.
|
||||||
bool EmitBody();
|
bool EmitBody();
|
||||||
|
|
||||||
|
@ -343,6 +346,9 @@ class FunctionEmitter {
|
||||||
/// or nullptr
|
/// or nullptr
|
||||||
BlockInfo* HeaderIfBreakable(const Construct* c);
|
BlockInfo* HeaderIfBreakable(const Construct* c);
|
||||||
|
|
||||||
|
/// Appends a new statement to the top of the statement stack.
|
||||||
|
void AddStatement(std::unique_ptr<ast::Statement> statement);
|
||||||
|
|
||||||
ParserImpl& parser_impl_;
|
ParserImpl& parser_impl_;
|
||||||
ast::Module& ast_module_;
|
ast::Module& ast_module_;
|
||||||
spvtools::opt::IRContext& ir_context_;
|
spvtools::opt::IRContext& ir_context_;
|
||||||
|
@ -352,7 +358,12 @@ class FunctionEmitter {
|
||||||
FailStream& fail_stream_;
|
FailStream& fail_stream_;
|
||||||
Namer& namer_;
|
Namer& namer_;
|
||||||
const spvtools::opt::Function& function_;
|
const spvtools::opt::Function& function_;
|
||||||
ast::StatementList ast_body_;
|
|
||||||
|
// A stack of statement lists. Each list is contained in a construct in
|
||||||
|
// the next deeper element of stack. The 0th entry represents the statements
|
||||||
|
// for the entire function. This stack is never empty.
|
||||||
|
std::vector<ast::StatementList> statements_stack_;
|
||||||
|
|
||||||
// The set of IDs that have already had an identifier name generated for it.
|
// The set of IDs that have already had an identifier name generated for it.
|
||||||
std::unordered_set<uint32_t> identifier_values_;
|
std::unordered_set<uint32_t> identifier_values_;
|
||||||
// Mapping from SPIR-V ID that is used at most once, to its AST expression.
|
// Mapping from SPIR-V ID that is used at most once, to its AST expression.
|
||||||
|
|
Loading…
Reference in New Issue