Skip to content

Commit 83876d9

Browse files
authored
Add NonSemantic.Graph.DebugInfo instruction set (KhronosGroup#6666)
Signed-off-by: Kevin Petit <kevin.petit@arm.com>
1 parent 18b08af commit 83876d9

11 files changed

Lines changed: 476 additions & 4 deletions

File tree

Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ $(1)/core_tables_header.inc \
222222
$(GRAMMAR_DIR)/extinst.debuginfo.grammar.json \
223223
$(GRAMMAR_DIR)/extinst.glsl.std.450.grammar.json \
224224
$(GRAMMAR_DIR)/extinst.nonsemantic.clspvreflection.grammar.json \
225+
$(GRAMMAR_DIR)/extinst.nonsemantic.graph.debuginfo.grammar.json \
225226
$(GRAMMAR_DIR)/extinst.nonsemantic.shader.debuginfo.100.grammar.json \
226227
$(GRAMMAR_DIR)/extinst.nonsemantic.vkspreflection.grammar.json \
227228
$(GRAMMAR_DIR)/extinst.opencl.debuginfo.100.grammar.json \

BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ create_grammar_tables_target(
5555
ExtInst("nonsemantic.shader.debuginfo", prefix="SHDEBUG100_"),
5656
ExtInst("tosa.001000.1", target="spirv_ext_inst_tosa_001000_1", prefix="TOSA_"),
5757
ExtInst("arm.motion-engine.100", target="spirv_ext_inst_arm_motion_engine_100"),
58+
ExtInst("nonsemantic.graph.debuginfo", target="spirv_ext_inst_non_semantic_graph_debuginfo_grammar_unified1"),
5859
] + [ExtInst(e) for e in [
5960
"spv-amd-shader-explicit-vertex-parameter",
6061
"spv-amd-shader-trinary-minmax",

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ vars = {
1414

1515
're2_revision': '972a15cedd008d846f1a39b2e88ce48d7f166cbd',
1616

17-
'spirv_headers_revision': '58006c901d1d5c37dece6b6610e9af87fa951375',
17+
'spirv_headers_revision': '82dfca37143878c848d8df1f9e4d746f65e6827e',
1818

1919
'mimalloc_revision': 'fef6b0dd70f9d7fa0750b0d0b9fbb471203b94cd',
2020
}

include/spirv-tools/libspirv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ typedef enum spv_ext_inst_type_t {
361361
SPV_EXT_INST_TYPE_DEBUGINFO,
362362
SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
363363
SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
364+
SPV_EXT_INST_TYPE_NONSEMANTIC_GRAPH_DEBUGINFO,
364365
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100,
365366
SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION,
366367
SPV_EXT_INST_TYPE_TOSA_001000_1,

source/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(EI_ns_clspvreflect "${GRAMMAR_DIR}/extinst.nonsemantic.clspvreflection.gramm
3333
set(EI_ns_vkspreflect "${GRAMMAR_DIR}/extinst.nonsemantic.vkspreflection.grammar.json")
3434
set(EI_tosa_001000_1 "${GRAMMAR_DIR}/extinst.tosa.001000.1.grammar.json")
3535
set(EI_arm_motion_engine_100 "${GRAMMAR_DIR}/extinst.arm.motion-engine.100.grammar.json")
36+
set(EI_ns_graph_debug_info "${GRAMMAR_DIR}/extinst.nonsemantic.graph.debuginfo.grammar.json")
3637

3738
set(CORE_TABLES_BODY_INC_FILE ${spirv-tools_BINARY_DIR}/core_tables_body.inc)
3839
set(CORE_TABLES_HEADER_INC_FILE ${spirv-tools_BINARY_DIR}/core_tables_header.inc)
@@ -54,6 +55,7 @@ add_custom_command(OUTPUT ${CORE_TABLES_BODY_INC_FILE} ${CORE_TABLES_HEADER_INC_
5455
--extinst=,${EI_ns_vkspreflect}
5556
--extinst=TOSA_,${EI_tosa_001000_1}
5657
--extinst=,${EI_arm_motion_engine_100}
58+
--extinst=,${EI_ns_graph_debug_info}
5759
DEPENDS ${GGT_SCRIPT}
5860
${SPIRV_CORE_GRAMMAR_JSON_FILE}
5961
${EI_glsl}
@@ -69,6 +71,7 @@ add_custom_command(OUTPUT ${CORE_TABLES_BODY_INC_FILE} ${CORE_TABLES_HEADER_INC_
6971
${EI_ns_vkspreflect}
7072
${EI_tosa_001000_1}
7173
${EI_arm_motion_engine_100}
74+
${EI_ns_graph_debug_info}
7275
COMMENT "Generate grammar tables")
7376
add_custom_target(spirv-tools-tables DEPENDS ${CORE_TABLES_BODY_INC_FILE} ${CORE_TABLES_HEADER_INC_FILE})
7477

source/ext_inst.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) {
5151
if (!strncmp("NonSemantic.Shader.DebugInfo.", name, 29)) {
5252
return SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
5353
}
54+
if (!strncmp("NonSemantic.Graph.DebugInfo.", name, 28)) {
55+
return SPV_EXT_INST_TYPE_NONSEMANTIC_GRAPH_DEBUGINFO;
56+
}
5457
if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) {
5558
return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION;
5659
}
@@ -75,6 +78,7 @@ bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) {
7578
if (type == SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN ||
7679
type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
7780
type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION ||
81+
type == SPV_EXT_INST_TYPE_NONSEMANTIC_GRAPH_DEBUGINFO ||
7882
type == SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION) {
7983
return true;
8084
}

source/val/validate_extensions.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "source/val/validation_state.h"
3434
#include "spirv-tools/libspirv.h"
3535
#include "spirv/unified1/NonSemanticClspvReflection.h"
36+
#include "spirv/unified1/NonSemanticGraphDebugInfo.h"
3637
#include "spirv/unified1/NonSemanticShaderDebugInfo.h"
3738

3839
namespace spvtools {
@@ -83,6 +84,55 @@ bool IsUint32Constant(ValidationState_t& _, uint32_t id) {
8384
return IsIntScalar(_, inst->type_id(), true, true);
8485
}
8586

87+
bool IsGraphDebugInfoDebugGraph(const Instruction* inst) {
88+
return spvIsExtendedInstruction(inst->opcode()) &&
89+
inst->ext_inst_type() ==
90+
SPV_EXT_INST_TYPE_NONSEMANTIC_GRAPH_DEBUGINFO &&
91+
inst->word(4) == NonSemanticGraphDebugInfoDebugGraph;
92+
}
93+
94+
bool IsTopLevelCompositeOfTensors(ValidationState_t& _, uint32_t type_id) {
95+
const auto* type = _.FindDef(type_id);
96+
if (!type) return false;
97+
98+
if (type->opcode() == spv::Op::OpTypeArray ||
99+
type->opcode() == spv::Op::OpTypeRuntimeArray) {
100+
const auto* element_type = _.FindDef(type->word(2));
101+
return element_type && element_type->opcode() == spv::Op::OpTypeTensorARM;
102+
}
103+
104+
if (type->opcode() == spv::Op::OpTypeStruct) {
105+
for (uint32_t word_index = 2; word_index < type->words().size();
106+
++word_index) {
107+
const auto* member_type = _.FindDef(type->word(word_index));
108+
if (!member_type || member_type->opcode() != spv::Op::OpTypeTensorARM) {
109+
return false;
110+
}
111+
}
112+
return true;
113+
}
114+
115+
return false;
116+
}
117+
118+
bool IsInstructionInGraph(ValidationState_t& _, uint32_t inst_id,
119+
uint32_t graph_id) {
120+
bool in_graph = false;
121+
for (const auto& module_inst : _.ordered_instructions()) {
122+
if (module_inst.opcode() == spv::Op::OpGraphARM) {
123+
in_graph = module_inst.id() == graph_id;
124+
}
125+
126+
if (in_graph && module_inst.id() == inst_id) return true;
127+
128+
if (in_graph && module_inst.opcode() == spv::Op::OpGraphEndARM) {
129+
in_graph = false;
130+
}
131+
}
132+
133+
return false;
134+
}
135+
86136
uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) {
87137
auto inst = _.FindDef(id);
88138
return inst->word(3);
@@ -1354,6 +1404,33 @@ spv_result_t ValidateExtInstImport(ValidationState_t& _,
13541404
_.RegisterShaderDebugInfo(inst->id());
13551405
}
13561406

1407+
const std::string nsgdi_prefix = "NonSemantic.Graph.DebugInfo.";
1408+
if (name.find(nsgdi_prefix) == 0) {
1409+
auto version_string = name.substr(nsgdi_prefix.size());
1410+
if (version_string.empty()) {
1411+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1412+
<< "NonSemantic.Graph.DebugInfo import does not encode the "
1413+
"version correctly";
1414+
}
1415+
char* end_ptr;
1416+
uint32_t ver = static_cast<uint32_t>(
1417+
std::strtoul(version_string.c_str(), &end_ptr, 10));
1418+
if (end_ptr && *end_ptr != '\0') {
1419+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1420+
<< "NonSemantic.Graph.DebugInfo import does not encode the "
1421+
"version correctly";
1422+
}
1423+
if (ver == 0 || ver > NonSemanticGraphDebugInfoRevision) {
1424+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1425+
<< "NonSemantic.Graph.DebugInfo import version " << ver
1426+
<< " is not supported";
1427+
}
1428+
if (!_.HasExtension(kSPV_ARM_graph)) {
1429+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1430+
<< "NonSemantic.Graph.DebugInfo requires SPV_ARM_graph";
1431+
}
1432+
}
1433+
13571434
return SPV_SUCCESS;
13581435
}
13591436

@@ -4196,6 +4273,96 @@ spv_result_t ValidateExtInstDebugInfo(ValidationState_t& _,
41964273
return SPV_SUCCESS;
41974274
}
41984275

4276+
spv_result_t ValidateExtInstGraphDebugInfo(ValidationState_t& _,
4277+
const Instruction* inst) {
4278+
if (!_.IsVoidType(inst->type_id())) {
4279+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4280+
<< GetExtInstName(_, inst) << ": "
4281+
<< "expected result type must be a result id of OpTypeVoid";
4282+
}
4283+
4284+
const auto ext_inst_key =
4285+
NonSemanticGraphDebugInfoInstructions(inst->word(4));
4286+
switch (ext_inst_key) {
4287+
case NonSemanticGraphDebugInfoDebugGraph: {
4288+
CHECK_OPERAND("Graph", spv::Op::OpGraphARM, 5);
4289+
CHECK_OPERAND("Name", spv::Op::OpString, 6);
4290+
break;
4291+
}
4292+
4293+
case NonSemanticGraphDebugInfoDebugOperation: {
4294+
const auto* debug_graph = _.FindDef(inst->word(5));
4295+
if (!debug_graph || !IsGraphDebugInfoDebugGraph(debug_graph)) {
4296+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4297+
<< GetExtInstName(_, inst) << ": expected operand DebugGraph "
4298+
<< "must be a result id of NonSemantic.Graph.DebugInfo "
4299+
<< "DebugGraph";
4300+
}
4301+
CHECK_OPERAND("Name", spv::Op::OpString, 6);
4302+
if (inst->words().size() < 8) {
4303+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4304+
<< GetExtInstName(_, inst) << ": expected operand "
4305+
<< "Instructions must contain at least one instruction";
4306+
}
4307+
4308+
const uint32_t graph_id = debug_graph->word(5);
4309+
for (uint32_t word_index = 7; word_index < inst->words().size();
4310+
++word_index) {
4311+
const uint32_t instruction_id = inst->word(word_index);
4312+
if (!IsInstructionInGraph(_, instruction_id, graph_id)) {
4313+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4314+
<< GetExtInstName(_, inst) << ": expected operand "
4315+
<< "Instructions must be result ids of instructions within "
4316+
<< "the graph described by DebugGraph";
4317+
}
4318+
}
4319+
break;
4320+
}
4321+
4322+
case NonSemanticGraphDebugInfoDebugTensor: {
4323+
const auto* tensor = _.FindDef(inst->word(5));
4324+
const uint32_t tensor_type_id = tensor ? tensor->type_id() : 0;
4325+
const auto* tensor_type = _.FindDef(tensor_type_id);
4326+
const bool is_tensor =
4327+
tensor_type && tensor_type->opcode() == spv::Op::OpTypeTensorARM;
4328+
const bool is_composite_tensor =
4329+
IsTopLevelCompositeOfTensors(_, tensor_type_id);
4330+
if (!is_tensor && !is_composite_tensor) {
4331+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4332+
<< GetExtInstName(_, inst) << ": expected operand Tensor "
4333+
<< "must be a value of OpTypeTensorARM or a composite type "
4334+
<< "whose top-level constituents are OpTypeTensorARM";
4335+
}
4336+
CHECK_OPERAND("Name", spv::Op::OpString, 6);
4337+
4338+
const bool has_index = inst->words().size() > 7;
4339+
if (is_composite_tensor && !has_index) {
4340+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4341+
<< GetExtInstName(_, inst) << ": expected operand Index "
4342+
<< "must be present when Tensor has composite type";
4343+
}
4344+
if (has_index) {
4345+
if (!is_composite_tensor) {
4346+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4347+
<< GetExtInstName(_, inst) << ": expected operand Tensor "
4348+
<< "must have composite type when Index is present";
4349+
}
4350+
if (!IsUint32Constant(_, inst->word(7))) {
4351+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
4352+
<< GetExtInstName(_, inst) << ": expected operand Index "
4353+
<< "must be a result id of 32-bit unsigned OpConstant";
4354+
}
4355+
}
4356+
break;
4357+
}
4358+
4359+
default:
4360+
break;
4361+
}
4362+
4363+
return SPV_SUCCESS;
4364+
}
4365+
41994366
spv_result_t ValidateExtInstNonsemanticClspvReflection(
42004367
ValidationState_t& _, const Instruction* inst) {
42014368
auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
@@ -4236,6 +4403,8 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
42364403
return ValidateExtInstDebugInfo(_, inst);
42374404
} else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
42384405
return ValidateExtInstNonsemanticClspvReflection(_, inst);
4406+
} else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_GRAPH_DEBUGINFO) {
4407+
return ValidateExtInstGraphDebugInfo(_, inst);
42394408
}
42404409

42414410
return SPV_SUCCESS;

source/val/validate_layout.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ spv_result_t GraphScopedInstructions(ValidationState_t& _,
400400
}
401401
break;
402402
default:
403+
if ((opcode == spv::Op::OpExtInst) &&
404+
spvExtInstIsNonSemantic(inst->ext_inst_type())) {
405+
break;
406+
}
407+
403408
if (_.graph_definition_region() == kGraphDefinitionOutside) {
404409
return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
405410
<< "Op" << spvOpcodeString(opcode)

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ set(TEST_SOURCES
109109
ext_inst.cldebug100_test.cpp
110110
ext_inst.debuginfo_test.cpp
111111
ext_inst.glsl_test.cpp
112+
ext_inst.graph_debuginfo_test.cpp
112113
ext_inst.non_semantic_test.cpp
113114
ext_inst.opencl_test.cpp
114115
ext_inst.tosa_test.cpp

0 commit comments

Comments
 (0)