[mlir][spirv] Add SPIR-V NonSemantic.Graph.DebugInfo#199519
Conversation
|
@llvm/pr-subscribers-mlir-spirv @llvm/pr-subscribers-mlir-tosa Author: Davide Grohmann (davidegrohmann) ChangesAdd serialization and deserialization support for the NonSemantic.Graph.DebugInfo.1 extended instruction set used with ARM graph modules. Definition: Serialize DebugGraph, DebugOperation, and DebugTensor records when debug info is enabled. DebugOperation now references the DebugGraph result id, and debug graph records are emitted before operations that reference them. DebugTensor records cover graph inputs, graph outputs, and tensor-typed spirv.Constant results. Deserialize the debug records back into MLIR locations for graphs, TOSA operation results, tensors, and materialized tensor constants. Avoid default-inserting empty Values while applying debug records, and diagnose undefined debug ids instead. Add round-trip lit coverage for FileLineColLoc, NameLoc, FusedLoc, grouped TOSA ops, and missing extension diagnostics. Add a binary-level serialization unit test for DebugGraph/DebugOperation references, ordering, and DebugTensor records for inputs, outputs, and constants. Patch is 46.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199519.diff 10 Files Affected:
diff --git a/mlir/include/mlir/Target/SPIRV/SPIRVExtInstSets.h b/mlir/include/mlir/Target/SPIRV/SPIRVExtInstSets.h
new file mode 100644
index 0000000000000..88ee32c5defb1
--- /dev/null
+++ b/mlir/include/mlir/Target/SPIRV/SPIRVExtInstSets.h
@@ -0,0 +1,40 @@
+//===- SPIRVExtInstSets.h - SPIR-V ext inst sets ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares extended instruction set constants used by SPIR-V
+// (de)serialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_SPIRV_SPIRVEXTINSTSETS_H
+#define MLIR_TARGET_SPIRV_SPIRVEXTINSTSETS_H
+
+#include "llvm/ADT/StringRef.h"
+#include <cstdint>
+
+namespace mlir {
+namespace spirv {
+
+/// Extension set name for TOSA ops.
+constexpr StringLiteral extTosa("TOSA.001000.1");
+
+/// Extension set name for non-semantic graph debug info.
+constexpr StringLiteral extDebugInfo("NonSemantic.Graph.DebugInfo.1");
+
+/// Instruction opcodes in the NonSemantic.Graph.DebugInfo.1 extended
+/// instruction set.
+enum class GraphDebugInfoExtInst : uint32_t {
+ DebugGraph = 1,
+ DebugOperation = 2,
+ DebugTensor = 3,
+};
+
+} // namespace spirv
+} // namespace mlir
+
+#endif // MLIR_TARGET_SPIRV_SPIRVEXTINSTSETS_H
diff --git a/mlir/lib/Conversion/TosaToSPIRVTosa/TosaToSPIRVTosaPass.cpp b/mlir/lib/Conversion/TosaToSPIRVTosa/TosaToSPIRVTosaPass.cpp
index bef30e84b3289..b5ae5c0275b26 100644
--- a/mlir/lib/Conversion/TosaToSPIRVTosa/TosaToSPIRVTosaPass.cpp
+++ b/mlir/lib/Conversion/TosaToSPIRVTosa/TosaToSPIRVTosaPass.cpp
@@ -51,6 +51,7 @@ spirv::VerCapExtAttr getDefaultVerCapExtAttr(MLIRContext *context) {
spirv::Extension::SPV_EXT_replicated_composites,
spirv::Extension::SPV_KHR_bfloat16,
spirv::Extension::SPV_EXT_float8,
+ spirv::Extension::SPV_KHR_non_semantic_info,
},
context);
}
diff --git a/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp b/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
index f65b559ed1369..54cd47716a254 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
@@ -17,6 +17,7 @@
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
#include "mlir/Target/SPIRV/SPIRVBinaryUtils.h"
+#include "mlir/Target/SPIRV/SPIRVExtInstSets.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
@@ -35,6 +36,12 @@ static inline spirv::Opcode extractOpcode(uint32_t word) {
return static_cast<spirv::Opcode>(word & 0xffff);
}
+/// Returns a NameLoc location from the given debug info string.
+static inline NameLoc getLocFromDebugInfoString(OpBuilder &builder,
+ StringRef source) {
+ return NameLoc::get(builder.getStringAttr(source));
+}
+
//===----------------------------------------------------------------------===//
// Instruction
//===----------------------------------------------------------------------===//
@@ -42,7 +49,10 @@ static inline spirv::Opcode extractOpcode(uint32_t word) {
Value spirv::Deserializer::getValue(uint32_t id) {
if (auto constInfo = getConstant(id)) {
// Materialize a `spirv.Constant` op at every use site.
- return spirv::ConstantOp::create(opBuilder, unknownLoc, constInfo->second,
+ Location loc = unknownLoc;
+ if (auto locAttr = constantLocMap.lookup(id))
+ loc = Location(locAttr);
+ return spirv::ConstantOp::create(opBuilder, loc, constInfo->second,
constInfo->first);
}
if (std::optional<std::pair<Attribute, Type>> constCompositeReplicateInfo =
@@ -171,8 +181,13 @@ LogicalResult spirv::Deserializer::processInstruction(
return processCapability(operands);
case spirv::Opcode::OpExtension:
return processExtension(operands);
- case spirv::Opcode::OpExtInst:
+ case spirv::Opcode::OpExtInst: {
+ auto setIt = operands.size() >= 4 ? extendedInstSets.find(operands[2])
+ : extendedInstSets.end();
+ if (setIt != extendedInstSets.end() && setIt->second == extDebugInfo)
+ return processDebugInfoExtInst(operands, deferInstructions);
return processExtInst(operands);
+ }
case spirv::Opcode::OpExtInstImport:
return processExtInstImport(operands);
case spirv::Opcode::OpMemberName:
@@ -388,6 +403,97 @@ LogicalResult spirv::Deserializer::processUndef(ArrayRef<uint32_t> operands) {
return success();
}
+LogicalResult
+spirv::Deserializer::processDebugInfoExtInst(ArrayRef<uint32_t> operands,
+ bool deferInstructions) {
+ if (deferInstructions) {
+ deferredInstructions.emplace_back(spirv::Opcode::OpExtInst, operands);
+ return success();
+ }
+
+ if (operands.size() < 4) {
+ return emitError(unknownLoc,
+ "OpExtInst must have at least 4 operands, result type "
+ "<id>, result <id>, set <id> and instruction opcode");
+ }
+
+ auto &extensionSetName = extendedInstSets[operands[2]];
+ assert(extensionSetName == extDebugInfo);
+
+ auto getDebugLoc = [&](uint32_t stringID) -> FailureOr<Location> {
+ auto stringIt = debugInfoMap.find(stringID);
+ if (stringIt == debugInfoMap.end()) {
+ emitError(unknownLoc, "undefined string <id> ")
+ << stringID << " in DebugInfo";
+ return failure();
+ }
+ Location loc = getLocFromDebugInfoString(opBuilder, stringIt->second);
+ return loc;
+ };
+
+ auto instructionID = static_cast<spirv::GraphDebugInfoExtInst>(operands[3]);
+ switch (instructionID) {
+ case spirv::GraphDebugInfoExtInst::DebugGraph: {
+ if (operands.size() < 6)
+ return emitError(unknownLoc, "DebugGraph must have graph and string IDs");
+ auto &graphID = operands[4];
+ auto &stringID = operands[5];
+ auto graphIt = graphMap.find(graphID);
+ if (graphIt == graphMap.end())
+ return emitError(unknownLoc, "undefined graph <id> ")
+ << graphID << " in DebugGraph";
+ FailureOr<Location> loc = getDebugLoc(stringID);
+ if (failed(loc))
+ return failure();
+ graphIt->second->setLoc(*loc);
+ break;
+ }
+ case spirv::GraphDebugInfoExtInst::DebugOperation: {
+ if (operands.size() < 7)
+ return emitError(unknownLoc,
+ "DebugOperation must have graph, string and "
+ "instruction IDs");
+ auto &stringID = operands[5];
+ FailureOr<Location> loc = getDebugLoc(stringID);
+ if (failed(loc))
+ return failure();
+ SmallVector<uint32_t> operationIDs;
+ operationIDs.append(std::next(operands.begin(), 6), operands.end());
+ for (auto &operationID : operationIDs) {
+ auto valueIt = valueMap.find(operationID);
+ if (valueIt == valueMap.end())
+ return emitError(unknownLoc, "undefined operation <id> ")
+ << operationID << " in DebugOperation";
+ valueIt->second.setLoc(*loc);
+ }
+ break;
+ }
+ case spirv::GraphDebugInfoExtInst::DebugTensor: {
+ if (operands.size() < 6)
+ return emitError(unknownLoc, "DebugTensor must have tensor and string IDs");
+ auto &stringID = operands[5];
+ auto &tensorID = operands[4];
+ FailureOr<Location> loc = getDebugLoc(stringID);
+ if (failed(loc))
+ return failure();
+ if (constantMap.contains(tensorID)) {
+ constantLocMap[tensorID] = *loc;
+ break;
+ }
+ auto valueIt = valueMap.find(tensorID);
+ if (valueIt == valueMap.end())
+ return emitError(unknownLoc, "undefined tensor <id> ")
+ << tensorID << " in DebugTensor";
+ valueIt->second.setLoc(*loc);
+ break;
+ }
+ default:
+ return failure();
+ }
+
+ return success();
+}
+
LogicalResult spirv::Deserializer::processExtInst(ArrayRef<uint32_t> operands) {
if (operands.size() < 4) {
return emitError(unknownLoc,
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
index b2adbb5518789..d2b7dbaad4655 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.h
@@ -563,6 +563,11 @@ class Deserializer {
/// other entries.
LogicalResult processExtInst(ArrayRef<uint32_t> operands);
+ /// Processes a SPIR-V OpExtInst with given `operands` for a DebugInfo
+ /// extension instruction.
+ LogicalResult processDebugInfoExtInst(ArrayRef<uint32_t> operands,
+ bool deferInstructions);
+
/// Dispatches the deserialization of extended instruction set operation based
/// on the extended instruction set name, and instruction opcode. This is
/// autogenerated from ODS.
@@ -632,6 +637,9 @@ class Deserializer {
/// (and type) here. Later when it's used, we materialize the constant.
DenseMap<uint32_t, std::pair<Attribute, Type>> constantMap;
+ // Result <id> to debug location for constants materialized from constantMap.
+ DenseMap<uint32_t, LocationAttr> constantLocMap;
+
// Result <id> to replicated constant attribute and type mapping.
///
/// In the SPIR-V binary format, OpConstantCompositeReplicateEXT is placed in
diff --git a/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp b/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
index 841fc55a8627a..83341519fbc9e 100644
--- a/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
@@ -16,6 +16,7 @@
#include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h"
#include "mlir/IR/RegionGraphTraits.h"
#include "mlir/Target/SPIRV/SPIRVBinaryUtils.h"
+#include "mlir/Target/SPIRV/SPIRVExtInstSets.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
@@ -24,6 +25,33 @@
using namespace mlir;
+namespace {
+// Location::print() emits MLIR syntax such as `loc("name")` or
+// `loc(fused["op", "file":1:2])`. NonSemantic.Graph.DebugInfo stores the
+// source/debug name itself in an OpString, so keep this conversion to the
+// payload string explicit.
+std::string getDebugInfoStringFromLoc(Location loc) {
+ if (auto fileLineCol = dyn_cast<FileLineColLoc>(loc)) {
+ return fileLineCol.getFilename().str() + ":" +
+ std::to_string(fileLineCol.getLine()) + ":" +
+ std::to_string(fileLineCol.getColumn());
+ }
+ if (auto nameLoc = dyn_cast<NameLoc>(loc)) {
+ return nameLoc.getName().str();
+ }
+ if (auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
+ std::ostringstream result;
+ std::transform(
+ fusedLoc.getLocations().begin(), fusedLoc.getLocations().end(),
+ std::ostream_iterator<std::string>(result, ";"),
+ [&](const Location loc) { return getDebugInfoStringFromLoc(loc); });
+
+ return result.str();
+ }
+ return "";
+}
+} // namespace
+
/// A pre-order depth-first visitor function for processing basic blocks.
///
/// Visits the basic blocks starting from the given `headerBlock` in pre-order
@@ -61,6 +89,9 @@ LogicalResult Serializer::processConstantOp(spirv::ConstantOp op) {
if (auto resultID =
prepareConstant(op.getLoc(), op.getType(), op.getValue())) {
valueIDMap[op.getResult()] = resultID;
+ if (isa<spirv::TensorArmType>(op.getType()) &&
+ failed(encodeDebugInfoTensorInst(op.getResult())))
+ return failure();
return success();
}
return failure();
@@ -386,6 +417,121 @@ LogicalResult Serializer::processFuncOp(spirv::FuncOp op) {
return success();
}
+LogicalResult Serializer::encodeDebugStringInst(const std::string &str,
+ uint32_t &stringID) {
+ if (!options.emitDebugInfo)
+ return success();
+
+ SmallVector<uint32_t, 2> operands;
+ stringID = getNextID();
+ operands.push_back(stringID);
+ spirv::encodeStringLiteralInto(operands, str);
+ encodeInstructionInto(debug, spirv::Opcode::OpString, operands);
+
+ return success();
+}
+
+LogicalResult Serializer::encodeDebugInfoGraphInst(spirv::GraphARMOp op,
+ uint32_t &debugGraphID) {
+ if (!options.emitDebugInfo)
+ return success();
+
+ processVoidType(typesGlobalValues);
+
+ uint32_t stringID = 0;
+ if (failed(encodeDebugStringInst(getDebugInfoStringFromLoc(op.getLoc()),
+ stringID)))
+ return failure();
+
+ SmallVector<uint32_t, 6> operands;
+ operands.push_back(getTypeID(getVoidType()));
+ debugGraphID = getNextID();
+ operands.push_back(debugGraphID);
+ uint32_t graphID = getOrCreateFunctionID(op.getName());
+ operands.push_back(graphID);
+ operands.push_back(stringID);
+
+ if (failed(encodeExtensionInstruction(
+ nullptr, extDebugInfo,
+ static_cast<uint32_t>(GraphDebugInfoExtInst::DebugGraph), operands,
+ graphsDebugInfo)))
+ return failure();
+
+ return success();
+}
+
+LogicalResult
+Serializer::encodeDebugInfoOperationInst(uint32_t debugGraphID,
+ SetVector<Operation *> ops) {
+ if (!options.emitDebugInfo)
+ return success();
+
+ if (ops.empty())
+ return success();
+
+ SmallVector<uint32_t, 4> instructionIDs;
+ for (auto op : ops)
+ for (auto result : op->getOpResults())
+ instructionIDs.push_back(getValueID(result));
+
+ if (instructionIDs.empty())
+ return success();
+
+ processVoidType(typesGlobalValues);
+
+ uint32_t stringID = 0;
+ if (failed(encodeDebugStringInst(getDebugInfoStringFromLoc(ops[0]->getLoc()),
+ stringID)))
+ return failure();
+
+ SmallVector<uint32_t, 5> operands;
+ operands.push_back(getTypeID(getVoidType()));
+ operands.push_back(getNextID());
+ operands.push_back(debugGraphID);
+ operands.push_back(stringID);
+ operands.append(instructionIDs);
+
+ if (failed(encodeExtensionInstruction(
+ nullptr, extDebugInfo,
+ static_cast<uint32_t>(GraphDebugInfoExtInst::DebugOperation),
+ operands,
+ graphsDebugInfo)))
+ return failure();
+
+ return success();
+}
+
+LogicalResult Serializer::encodeDebugInfoTensorInst(Value tensor) {
+ if (!options.emitDebugInfo)
+ return success();
+
+ processVoidType(typesGlobalValues);
+
+ auto it = valueIDMap.find(tensor);
+ if (it == valueIDMap.end())
+ return success();
+ auto tensorID = it->second;
+
+ uint32_t stringID = 0;
+ if (failed(encodeDebugStringInst(getDebugInfoStringFromLoc(tensor.getLoc()),
+ stringID)))
+ return failure();
+
+ SmallVector<uint32_t, 4> operands;
+ operands.push_back(getTypeID(getVoidType()));
+ operands.push_back(getNextID());
+ operands.push_back(tensorID);
+ operands.push_back(stringID);
+
+ if (failed(encodeExtensionInstruction(
+ nullptr, extDebugInfo,
+ static_cast<uint32_t>(GraphDebugInfoExtInst::DebugTensor), operands,
+ graphsDebugInfo)))
+ return failure();
+
+ return success();
+}
+
LogicalResult Serializer::processGraphARMOp(spirv::GraphARMOp op) {
if (op.getNumResults() < 1) {
return op.emitError("cannot serialize graph with no return types");
@@ -423,6 +569,9 @@ LogicalResult Serializer::processGraphARMOp(spirv::GraphARMOp op) {
encodeInstructionInto(functionHeader, spirv::Opcode::OpGraphInputARM,
inputOperands);
+
+ if (failed(encodeDebugInfoTensorInst(arg)))
+ return failure();
}
if (failed(processBlock(&op.front(), /*omitLabel=*/true)))
@@ -443,6 +592,15 @@ LogicalResult Serializer::processGraphARMOp(spirv::GraphARMOp op) {
functionHeader.clear();
functionBody.clear();
+ uint32_t debugGraphID = 0;
+ if (failed(encodeDebugInfoGraphInst(op, debugGraphID)))
+ return failure();
+
+ for (const auto &[loc, ops] : tosaOpsMap[funcID]) {
+ if (failed(encodeDebugInfoOperationInst(debugGraphID, ops)))
+ return failure();
+ }
+
return success();
}
@@ -492,6 +650,9 @@ Serializer::processGraphOutputsARMOp(spirv::GraphOutputsARMOp op) {
outputOperands.push_back(outputID);
outputOperands.push_back(indexID);
+ if (failed(encodeDebugInfoTensorInst(value)))
+ return failure();
+
encodeInstructionInto(functionBody, spirv::Opcode::OpGraphSetOutputARM,
outputOperands);
}
diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index 11a7bf66d792d..553fcce6c5ea7 100644
--- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
@@ -173,6 +173,7 @@ void Serializer::collect(SmallVectorImpl<uint32_t> &binary) {
binary.append(typesGlobalValues.begin(), typesGlobalValues.end());
binary.append(functions.begin(), functions.end());
binary.append(graphs.begin(), graphs.end());
+ binary.append(graphsDebugInfo.begin(), graphsDebugInfo.end());
}
#ifndef NDEBUG
@@ -632,6 +633,16 @@ Serializer::processTypeImpl(Location loc, Type type, uint32_t &typeID,
return emitError(loc, "failed to process type: ") << type;
}
+void Serializer::processVoidType(SmallVectorImpl<uint32_t> &binary) {
+ auto voidType = getVoidType();
+ uint32_t voidTypeID = getTypeID(voidType);
+ if (!voidTypeID) {
+ voidTypeID = getNextID();
+ encodeInstructionInto(binary, spirv::Opcode::OpTypeVoid, {voidTypeID});
+ typeIDMap[voidType] = voidTypeID;
+ }
+}
+
LogicalResult Serializer::prepareBasicType(
Location loc, Type type, uint32_t resultID, spirv::Opcode &typeEnum,
SmallVectorImpl<uint32_t> &operands, bool &deferSerialization,
@@ -1612,7 +1623,7 @@ LogicalResult Serializer::emitPhiForBlockArguments(Block *block) {
LogicalResult Serializer::encodeExtensionInstruction(
Operation *op, StringRef extensionSetName, uint32_t extensionOpcode,
- ArrayRef<uint32_t> operands) {
+ ArrayRef<uint32_t> operands, SmallVectorImpl<uint32_t> &binary) {
// Check if the extension has been imported.
auto &setID = extendedInstSetIDMap[extensionSetName];
if (!setID) {
@@ -1635,8 +1646,20 @@ LogicalResult Serializer::encodeExtensionInstruction(
extInstOperands.push_back(setID);
extInstOperands.push_back(extensionOpcode);
extInstOperands.append(std::next(operands.begin(), 2), operands.end());
- encodeInstructionInto(functionBody, spirv::Opcode::OpExtInst,
- extInstOperands);
+ encodeInstructionInto(binary, spirv::Opcode::OpExtInst, extInstOperands);
+ return success();
+}
+
+LogicalResult Serializer::encodeExtensionInstruction(
+ Operation *op, StringRef extensionSetName, uint32_t extensionOpcode,
+ ArrayRef<uint32_t> operands) {
+ if (failed(encodeExtensionInstruction(op, extensionSetName, extensionOpcode,
+ operands, functionBody)))
+ return failure();
+
+ if (extensionSetName == extTosa)
+ updateTosaOpsMap(op);
+
return success();
}
@@ -1751,8 +1774,10 @@ LogicalResult Serializer::processOpWithoutGrammarAttr(Operation *op,
for (Value operand : op->getOperands())
operands.push_back(getValueID(operand));
- if (failed(emitDebugLine(functionBody, loc)))
- return failure();
+ if (extInstSet != extTosa)
+ // OpLine cannot be present in graphs
+ if (failed(emitDebugLine(functionBody, loc)))
+ return failure();
if (extInstSet.empty()) {
encodeInstructionInto(functionBody, static_cast<spirv::Opcode>(opcode),
@@ -1772,6 +1797,16 @@ LogicalResult Serializer::processOpWithoutGrammarAttr(Operation *op,
return success();
}
+void Serializer::updateTosaOpsMap(Operation *op) {
+ if (!options.emitDebugInfo)
+ return;
+
+ if (auto graphOp = dyn_cast<spirv::GraphARMOp>(op->getParentOp())) {
+ if (auto graphID = getFunctionID(graphOp.getName()))
+ tosaOpsMap[graphID][op->getLoc()].insert(op);
+ }
+}
+
LogicalResult Serializer::emitDecoration(uint32_t target,
spirv::Decoration decoration,
ArrayRef<uint32_t> params) {
diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.h b/mlir/lib/Target/SPIRV/...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
a84778a to
af91b92
Compare
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
41bf39f to
f8581a4
Compare
IgWod
left a comment
There was a problem hiding this comment.
Looks good % two small comments.
f8581a4 to
4235b59
Compare
IgWod
left a comment
There was a problem hiding this comment.
No more comments from me, thanks!
4235b59 to
68eae6e
Compare
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
Add serialization and deserialization support for the NonSemantic.Graph.DebugInfo.1 extended instruction set used with ARM graph modules. Definition: https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Graph.DebugInfo.asciidoc Serialize DebugGraph, DebugOperation, and DebugTensor records when debug info is enabled. DebugOperation now references the DebugGraph result id, and debug graph records are emitted before operations that reference them. DebugTensor records cover graph inputs, graph outputs, and tensor-typed spirv.Constant results. Deserialize the debug records back into MLIR locations for graphs, TOSA operation results, tensors, and materialized tensor constants. Avoid default-inserting empty Values while applying debug records, and diagnose undefined debug ids instead. Add round-trip lit coverage for FileLineColLoc, NameLoc, FusedLoc, grouped TOSA ops, and missing extension diagnostics. Add a binary-level serialization unit test for DebugGraph/DebugOperation references, ordering, and DebugTensor records for inputs, outputs, and constants. Signed-off-by: Mohammadreza Ameri Mahabadian <mohammadreza.amerimahabadian@arm.com> Signed-off-by: Davide Grohmann <davide.grohmann@arm.com> Change-Id: If71c026aa08b2bf9052eba35b173e1ce4498cb9d
cbe96e3 to
b9025eb
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/228/builds/260 Here is the relevant piece of the build log for the reference |
Add serialization and deserialization support for the SPIR-V
NonSemantic.Graph.DebugInfo.1 extended instruction set used by ARM graph
modules.
When debug info emission is enabled, serialize DebugGraph, DebugOperation,
and DebugTensor records for graph objects, TOSA operations, graph tensors,
and tensor constants. Emit the records after the SPIR-V objects they
reference, and make DebugOperation point at the DebugGraph result id.
Deserialize these records back into MLIR locations and diagnose malformed
or undefined debug-info references.
Enable SPV_KHR_non_semantic_info in the default TOSA-to-SPIR-V target
environment so debug info can be emitted by default.
Specification:
https://github.com/KhronosGroup/SPIRV-Registry/blob/main/nonsemantic/NonSemantic.Graph.DebugInfo.asciidoc