[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>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index f4ae488..f9a3ccb 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -426,6 +426,12 @@
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 @@
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 @@
// 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 @@
// 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 @@
}
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 @@
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>(
- std::make_unique<ast::IdentifierExpression>(namer_.Name(result_id)),
- std::move(ast_expr.expr)));
+ AddStatementForInstruction(
+ std::make_unique<ast::AssignmentStatement>(
+ std::make_unique<ast::IdentifierExpression>(namer_.Name(result_id)),
+ std::move(ast_expr.expr)),
+ inst);
return true;
}
return EmitConstDefinition(inst, std::move(ast_expr));
@@ -2593,8 +2608,9 @@
// 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 @@
}
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 @@
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
diff --git a/src/reader/spirv/function.h b/src/reader/spirv/function.h
index 007c756..b62994f 100644
--- a/src/reader/spirv/function.h
+++ b/src/reader/spirv/function.h
@@ -705,6 +705,23 @@
/// @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();
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index ee755f2..70aed3b 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -502,8 +502,12 @@
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 {};
diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h
index 28c3523..deeed0a 100644
--- a/src/reader/spirv/parser_impl.h
+++ b/src/reader/spirv/parser_impl.h
@@ -362,11 +362,15 @@
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