[spirv-reader] Set some source locations

Set source location on function variable declarations, const
declarations, and most normal instructions.

Bug: tint:3
Change-Id: I469afcdf1b7d8f6d1e64617189a6fa329056737f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27700
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
David Neto 2020-08-31 18:52:54 +00:00 committed by Commit Bot service account
parent 3588406b78
commit 7653485162
4 changed files with 70 additions and 15 deletions

View File

@ -426,6 +426,12 @@ class StructuredTraverser {
std::unordered_set<uint32_t> visited_;
};
/// @param src a source record
/// @returns true if |src| is a non-default Source
bool HasSource(const Source& src) {
return src.line != 0 || src.column != 0;
}
} // namespace
BlockInfo::BlockInfo(const spvtools::opt::BasicBlock& bb)
@ -525,6 +531,14 @@ ast::Statement* FunctionEmitter::AddStatement(
return result;
}
ast::Statement* FunctionEmitter::AddStatementForInstruction(
std::unique_ptr<ast::Statement> statement,
const spvtools::opt::Instruction& inst) {
auto* node = AddStatement(std::move(statement));
ApplySourceForInstruction(node, inst);
return node;
}
ast::Statement* FunctionEmitter::LastStatement() {
assert(!statements_stack_.empty());
const auto& statement_list = statements_stack_.back().statements_;
@ -1655,7 +1669,7 @@ bool FunctionEmitter::EmitFunctionVariables() {
// TODO(dneto): Add the initializer via Variable::set_constructor.
auto var_decl_stmt =
std::make_unique<ast::VariableDeclStatement>(std::move(var));
AddStatement(std::move(var_decl_stmt));
AddStatementForInstruction(std::move(var_decl_stmt), inst);
// Save this as an already-named value.
identifier_values_.insert(inst.result_id());
}
@ -2430,7 +2444,6 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
// Only emit this part of the basic block once.
return true;
}
// Returns the given list of local definition IDs, sorted by their index.
auto sorted_by_index = [this](const std::vector<uint32_t>& ids) {
auto sorted = ids;
@ -2514,8 +2527,8 @@ bool FunctionEmitter::EmitConstDefinition(
}
ast_const->set_constructor(std::move(ast_expr.expr));
ast_const->set_is_const(true);
AddStatement(
std::make_unique<ast::VariableDeclStatement>(std::move(ast_const)));
AddStatementForInstruction(
std::make_unique<ast::VariableDeclStatement>(std::move(ast_const)), inst);
// Save this as an already-named value.
identifier_values_.insert(inst.result_id());
return success();
@ -2528,9 +2541,11 @@ bool FunctionEmitter::EmitConstDefOrWriteToHoistedVar(
const auto* def_info = GetDefInfo(result_id);
if (def_info && def_info->requires_hoisted_def) {
// Emit an assignment of the expression to the hoisted variable.
AddStatement(std::make_unique<ast::AssignmentStatement>(
AddStatementForInstruction(
std::make_unique<ast::AssignmentStatement>(
std::make_unique<ast::IdentifierExpression>(namer_.Name(result_id)),
std::move(ast_expr.expr)));
std::move(ast_expr.expr)),
inst);
return true;
}
return EmitConstDefinition(inst, std::move(ast_expr));
@ -2593,8 +2608,9 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
// TODO(dneto): Order of evaluation?
auto lhs = MakeExpression(ptr_id);
auto rhs = MakeExpression(value_id);
AddStatement(std::make_unique<ast::AssignmentStatement>(
std::move(lhs.expr), std::move(rhs.expr)));
AddStatementForInstruction(std::make_unique<ast::AssignmentStatement>(
std::move(lhs.expr), std::move(rhs.expr)),
inst);
return success();
}
case SpvOpLoad: {
@ -3456,8 +3472,10 @@ bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) {
}
if (result_type->IsVoid()) {
return nullptr != AddStatement(std::make_unique<ast::CallStatement>(
std::move(call_expr)));
return nullptr !=
AddStatementForInstruction(
std::make_unique<ast::CallStatement>(std::move(call_expr)),
inst);
}
return EmitConstDefOrWriteToHoistedVar(inst,
@ -3491,6 +3509,18 @@ TypedExpression FunctionEmitter::MakeSimpleSelect(
return {};
}
void FunctionEmitter::ApplySourceForInstruction(
ast::Node* node,
const spvtools::opt::Instruction& inst) {
if (!node) {
return;
}
const Source& existing = node->source();
if (!HasSource(existing)) {
node->set_source(parser_impl_.GetSourceForInst(&inst));
}
}
} // namespace spirv
} // namespace reader
} // namespace tint

View File

@ -705,6 +705,23 @@ class FunctionEmitter {
/// @returns a pointer to the statement.
ast::Statement* AddStatement(std::unique_ptr<ast::Statement> statement);
/// Appends a new statement to the top of the statement stack, and attaches
/// source location information from the given instruction. Does nothing if
/// the statement is null.
/// @param statement the new statement
/// @returns a pointer to the statement.
ast::Statement* AddStatementForInstruction(
std::unique_ptr<ast::Statement> statement,
const spvtools::opt::Instruction& inst);
/// Sets the source information for the given instruction to the given
/// node, if the node doesn't already have a source record. Does nothing
/// if |nodes| is null.
/// @param node the AST node
/// @param inst the SPIR-V instruction
void ApplySourceForInstruction(ast::Node* node,
const spvtools::opt::Instruction& inst);
/// @returns the last statetment in the top of the statement stack.
ast::Statement* LastStatement();

View File

@ -502,8 +502,12 @@ void ParserImpl::RegisterLineNumbers() {
run_on_debug_insts);
}
Source ParserImpl::GetSourceForResultIdForTest(uint32_t id) {
const auto* inst = def_use_mgr_->GetDef(id);
Source ParserImpl::GetSourceForResultIdForTest(uint32_t id) const {
return GetSourceForInst(def_use_mgr_->GetDef(id));
}
Source ParserImpl::GetSourceForInst(
const spvtools::opt::Instruction* inst) const {
auto where = inst_source_.find(inst);
if (where == inst_source_.end()) {
return {};

View File

@ -362,11 +362,15 @@ class ParserImpl : Reader {
return builtin_position_;
}
/// Look up the source record for the SPIR-V instruction with the given
/// Returns the source record for the SPIR-V instruction with the given
/// result ID.
/// @param id the SPIR-V result id.
/// @return the Source record, or a default one
Source GetSourceForResultIdForTest(uint32_t id);
Source GetSourceForResultIdForTest(uint32_t id) const;
/// Returns the soruce record for the given instruction.
/// @param inst the SPIR-V instruction
/// @return the Source record, or a default one
Source GetSourceForInst(const spvtools::opt::Instruction* inst) const;
private:
/// Converts a specific SPIR-V type to a Tint type. Integer case