Contact
To report problems with this extension, please open a new issue at:
Contributors and Acknowledgments
-
Baldur Karlsson, Valve
Author of original OpenCL.DebugInfo.100 specification.
-
Alexey Sotkin, Intel
Contributors to original OpenCL.DebugInfo.100 specification.
-
Yaxun Liu, AMD
-
Brian Sumner, AMD
-
Ben Ashbaugh, Intel
-
Alexey Bader, Intel
-
Raun Krisch, Intel
-
Pratik Ashar, Intel
-
John Kessenich, Google
-
David Neto, Google
-
Neil Henning, Codeplay
-
Kerch Holt, Nvidia
-
Jaebaek Seo, Google
-
Spencer Fricke, LunarG
Notice
Copyright (c) 2019-2024 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html
Status
-
Complete
-
Approved by the SPIR Working Group: 2021-02-05
-
Ratified by the Khronos Group: 2021-03-19
Version
Last Modified Date |
2024-10-08 |
Revision |
11 |
Dependencies
This extension is written against the SPIR-V Specification, Version 1.4 Revision 1.
This instruction set requires SPIR-V 1.0.
Introduction
This is the specification of the NonSemantic.Shader.DebugInfo.100 extended instruction set.
This extended instruction set is imported into a SPIR-V module in the following manner:
The instructions below are capable of conveying debug information about the source program.
The design guidelines for these instructions are:
-
Similarity with OpenCL.DebugInfo.100, to re-use its tooling and benefit from its design work. To aid in future compatibility, new extended instructions in this extension begin at number 100.
-
Compatibility with rules regarding non-semantic instruction sets
-
Expansion to handle cases needed for Vulkan SPIR-V modules
This is a non-normative list of changes to the OpenCL.DebugInfo.100 specification:
-
OpExtInst instructions can no longer appear in any place in function bodies, but only within the valid locations inside a block (i.e. after OpPhi, before merge/branch instructions).
-
Forward references in any instruction are disallowed.
-
As the result of the above:
-
DebugTypeMember no longer has a parent
Parent <id>
, this is implicit from which DebugTypeComposite lists it as a member. -
DebugTypeInheritance has no
Child <id>
. This is also implicit based on which DebugTypeComposite lists it as a member. -
DebugFunction doesn’t contain a reference to the OpFunction Function <id>. Instead a new DebugFunctionDefinition instruction appears in the entry block of the OpFunction to indicate the corresponding DebugFunction.
-
-
DebugDeclare has an Indices parameter with the same meaning as DebugValue. This parameter is optional and so tools can treat it as if it were present in OpenCL.DebugInfo.100 too but with no values.
-
All literal parameters are passed as OpConstant values.
-
New instructions: DebugSourceContinued, DebugLine, DebugNoLine, DebugBuildIdentifier, DebugStoragePath, DebugEntryPoint, DebugTypeMatrix.
-
New flag FlagUnknownPhysicalLayout to indicate that implementations may have a different physical layout for composite types than specified.
-
DebugTypeBasic now takes a Flags operand to allow specifying FlagUnknownPhysicalLayout.
Terms
Lexical scope: One of DebugCompilationUnit, DebugFunction, DebugLexicalBlock, or DebugTypeComposite.
Local variable: A variable that is invisible in some lexical scopes. It depends on the definition of a local variable in the high-level language.
DWARF: The DWARF Debugging Standard, which is a debugging file format used by many compilers and debuggers to support source level debugging.
Binary Form
This section contains the semantics of the debug info extended instructions
using the OpExtInst instruction.
All Name operands are the <id> of OpString instructions, which represents
the name of the entry (type, variable, function, etc.) as it appears in the
source program.
Result Type of all instructions below is the <id> of OpTypeVoid.
Set operand in all instructions below is the result of an OpExtInstImport
instruction.
DebugScope, DebugNoScope,
DebugDeclare, DebugValue,
DebugLine, DebugNoLine, and
DebugFunctionDefinition
instructions can interleave with the instructions within a function, but must appear
within valid locations in a block as required by SPV_KHR_non_semantic_info. In
particular this means they cannot come before any OpPhi or function-level variable
declarations in a block, and they cannot come after a Merge Instruction.
DebugLine and DebugNoLine cannot appear outside
of a block. Line number information for global objects such as variable declarations
should be specified using the line and column values within those declarations.
All other instructions from this extended instruction set should be located
after the logical layout section 9 "All type declarations (OpTypeXXX instructions),
all constant instructions, and all global variable declarations …" and before
section 10 "All function declaration" in section 2.4
Logical Layout of a Module
of the core SPIR-V specification.
Debug info for source language opaque types is represented by
DebugTypeComposite without Members operands.
Size of the composite must be DebugInfoNone and Name
must start with @ symbol to avoid clashes with user defined names.
Removing Instructions
All instructions in this extended set have no semantic impact and can be safely removed. This is easily done if all debug instructions are removed together, at once. However, when removing a subset, for example, inlining a function, there may be dangling references to <id> that have been removed. These can be replaced with the Result <id> of the DebugInfoNone instruction.
All <id> referred to must be defined (dangling references are not allowed).
Forward references
Forward references are not allowed, to be compliant with SPV_KHR_non_semantic_info.
Enumerations
Instruction Enumeration
Instruction number |
Instruction name |
---|---|
0 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
Debug Info Flags
Value | Flag Name |
---|---|
1 << 0 |
FlagIsProtected |
1 << 1 |
FlagIsPrivate |
1<<0 | 1<<1 |
FlagIsPublic |
1 << 2 |
FlagIsLocal |
1 << 3 |
FlagIsDefinition |
1 << 4 |
FlagFwdDecl |
1 << 5 |
FlagArtificial |
1 << 6 |
FlagExplicit |
1 << 7 |
FlagPrototyped |
1 << 8 |
FlagObjectPointer |
1 << 9 |
FlagStaticMember |
1 << 10 |
FlagIndirectVariable |
1 << 11 |
FlagLValueReference |
1 << 12 |
FlagRValueReference |
1 << 13 |
FlagIsOptimized |
1 << 14 |
FlagIsEnumClass |
1 << 15 |
FlagTypePassByValue |
1 << 16 |
FlagTypePassByReference |
1 << 17 |
FlagUnknownPhysicalLayout |
Build Identifier Flags
Used by DebugBuildIdentifier
Value | Flag Name | Description |
---|---|---|
1 << 0 |
IdentifierPossibleDuplicates |
The same identifier may be generated for different input sources that compile to the same result, and so is not fully unique. This could be e.g. multiple different source code variations which compile to the exact same SPIR-V binary. |
Base Type Attribute Encodings
Used by DebugTypeBasic
Encoding code name | |
---|---|
0 |
Unspecified |
1 |
Address |
2 |
Boolean |
3 |
Float |
4 |
Signed |
5 |
SignedChar |
6 |
Unsigned |
7 |
UnsignedChar |
Type Qualifiers
Used by DebugTypeQualifier
Qualifier tag code name | |
---|---|
0 |
ConstType |
1 |
VolatileType |
2 |
RestrictType |
3 |
AtomicType |
Debug Operations
These operations are used to form a DWARF expression.
Such expressions provide information about the current location
(described by DebugDeclare) or value
(described by DebugValue) of a variable.
Operations in an expression are to be applied on a stack.
Initially, the stack contains one element: the address or value of the source variable.
Used by DebugOperation
Operation encodings | No. of Operands | Description | |
---|---|---|---|
0 |
Deref |
0 |
Pops the top stack entry, treats it as an address, pushes the value retrieved from that address. |
1 |
Plus |
0 |
Pops the top two entries from the stack, adds them together and push the result. |
2 |
Minus |
0 |
Pops the top two entries from the stack, subtracts the former top entry from the former second to top entry and push the result. |
3 |
PlusUconst |
1 |
Pops the top stack entry, adds the addend operand to it, and pushes the result. The operand must be a single 32-bit integer OpConstant. |
4 |
BitPiece |
2 |
Describes an object or value that may be contained in part of a register or stored in more than one location. The first operand is offset in bit from the location defined by the preceding operation. The second operand is size of the piece in bits. The operands must each be a single 32-bit integer OpConstant. |
5 |
Swap |
0 |
Swaps the top two stack values. |
6 |
Xderef |
0 |
Pops the top two entries from the stack. Treats the former top entry as an address and the former second to top entry as an address space. The value retrieved from the address in the given address space is pushed. |
7 |
StackValue |
0 |
Describes an object that doesn’t exist in memory but it’s value is known and is at the top of the DWARF expression stack. |
8 |
Constu |
1 |
Pushes a constant value onto the stack. The value operand must be a single 32-bit integer OpConstant. |
9 |
Fragment |
2 |
Has the same semantics as BitPiece, but the offset operand defines location within the source variable. |
Instructions
Missing Debugging Information
Debug Info Metadata
DebugBuildIdentifier |
|||||||
7 |
12 |
<id> |
Result <id> |
<id> Set |
105 |
<id> Identifier |
<id> Flags |
DebugStoragePath |
||||||
6 |
12 |
<id> |
Result <id> |
<id> Set |
106 |
<id> Path |
Compilation Unit
DebugCompilationUnit |
|||||||||
9 |
12 |
<id> |
Result <id> |
<id> Set |
1 |
<id> Version |
<id> DWARF version |
<id> Source |
<id> Language |
DebugEntryPoint |
|||||||||
9 |
12 |
<id> |
Result <id> |
<id> Set |
107 |
<id> Entry Point |
<id> Compilation Unit |
<id> Compiler Signature |
<id> Command-line Arguments |
Type instructions
DebugTypeBasic |
|||||||||
9 |
12 |
<id> |
Result <id> |
<id> Set |
2 |
<id> Name |
<id> Size |
<id> Encoding |
<id> Flags |
DebugTypePointer |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
3 |
<id> Base Type |
<id> Storage Class |
<id> Flags |
DebugTypeQualifier |
|||||||
7 |
12 |
<id> |
Result <id> |
<id> Set |
4 |
<id> Base Type |
<id> Type Qualifier |
DebugTypeArray |
|||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
5 |
<id> Base Type |
<id> Component Count, … |
DebugTypedef |
|||||||||||
11 |
12 |
<id> |
Result <id> |
<id> Set |
7 |
<id> Name |
<id> Base Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
DebugTypeFunction |
||||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
8 |
<id> Flags |
<id> Return Type |
Optional <id>, <id>, … Parameter Types |
DebugTypeEnum |
||||||||||||||
13+ |
12 |
<id> |
Result <id> |
<id> Set |
9 |
<id> Name |
<id> Underlying Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Size |
<id> Flags |
<id> Value, |
DebugTypeComposite |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
10 |
<id> Name |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Linkage Name |
<id> Size |
<id> Flags |
<id>, <id>, … Members |
DebugTypeMember |
||||||||||||||
13+ |
12 |
<id> |
Result <id> |
<id> Set |
11 |
<id> Name |
<id> Type |
<id> Source |
<id> Line |
<id> Column |
<id> Offset |
<id> Size |
<id> Flags |
Optional <id> Value |
DebugTypeInheritance |
|||||||||
9 |
12 |
<id> |
Result <id> |
<id> Set |
12 |
<id> Parent |
<id> Offset |
<id> Size |
<id> Flags |
Templates
DebugTypeTemplateParameter |
|||||||||||
11 |
12 |
<id> |
Result <id> |
<id> Set |
15 |
<id> Name |
<id> Actual Type |
<id> Value |
<id> Source |
<id> Line |
<id> Column |
DebugTypeTemplateParameterPack |
||||||||||
10+ |
12 |
<id> |
Result <id> |
<id> Set |
17 |
<id> Name |
<id> Source |
<id> Line |
<id> Column |
<id>… Template parameters |
Global Variables
DebugGlobalVariable |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
18 |
<id> Name |
<id> Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Linkage Name |
<id> Variable |
<id> Flags |
Optional <id> Static Member Declaration |
Functions
DebugFunctionDeclaration |
|||||||||||||
13 |
12 |
<id> |
Result <id> |
<id> Set |
19 |
<id> Name |
<id> Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Linkage Name |
<id> Flags |
DebugFunction |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
20 |
<id> Name |
<id> Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Linkage Name |
<id> Flags |
<id> Scope Line |
Optional <id> Declaration |
Location Information
DebugLexicalBlock |
||||||||||
9+ |
12 |
<id> |
Result <id> |
<id> Set |
21 |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
Optional <id> Name |
DebugLexicalBlockDiscriminator |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
22 |
<id> Source |
<id> Discriminator |
<id> Parent |
DebugScope |
|||||||
6+ |
12 |
<id> |
Result <id> |
<id> Set |
23 |
<id> Scope |
Optional |
DebugInlinedAt |
||||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
25 |
<id> Line |
<id> Scope |
Optional <id> Inlined |
DebugLine |
||||||||||
10 |
12 |
<id> |
Result <id> |
<id> Set |
103 |
<id> Source |
<id> Line Start |
<id> Line End |
<id> Column Start |
<id> Column End |
Local Variables
DebugLocalVariable |
|||||||||||||
12+ |
12 |
<id> |
Result <id> |
<id> Set |
26 |
<id> Name |
<id> Type |
<id> Source |
<id> Line |
<id> Column |
<id> Parent |
<id> Flags |
Optional |
DebugInlinedVariable |
|||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
27 |
<id> Variable |
<id> Inlined |
DebugDeclare |
|||||||||
8+ |
12 |
<id> |
Result <id> |
<id> Set |
28 |
<id> Local Variable |
<id> Variable |
<id> Expression |
<id>, <id>, … Indexes |
DebugValue |
|||||||||
8+ |
12 |
<id> |
Result <id> |
<id> Set |
29 |
<id> Local Variable |
<id> Value |
<id> Expression |
<id>, <id>, … Indexes |
DebugOperation |
|||||||
6+ |
12 |
<id> |
Result <id> |
<id> Set |
30 |
<id> Operation |
Optional <id> |
DebugExpression |
||||||
5+ |
12 |
<id> |
Result <id> |
<id> Set |
31 |
Optional <id>… Operation |
Macros
DebugMacroUndef |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
33 |
<id> Source |
<id> Line |
<id> Macro |
Imported Entities
DebugImportedEntity |
||||||||||||
12 |
12 |
<id> |
Result <id> |
<id> Set |
34 |
<id> Name |
<id> Tag |
<id> Source |
<id> Entity |
<id> Line |
<id> Column |
<id> Parent |
Validation Rules
None.
Issues
-
Should this specification only contain references to the OpenCL.DebugInfo.100 specification with changes, or duplicate it in its entirety?
RESOLVED: The spec is duplicated. The number of changes is significant enough that having to read two specifications to understand this one is not desirable. It’s also not guaranteed that changes to OpenCL.DebugInfo.100 should be automatically reflected in this extension.
-
Should DebugSourceContinued exist or should DebugSource take an optional list of <id>s instead of just a single optional <id>?
RESOLVED: We mirror OpSource and OpSourceContinued both because it is an existing pattern for specifying overflowing strings longer than a 16-bit length allows, as well as for compatibility with OpenCL.DebugInfo.100 which only allows a single <id> for its DebugSource.
-
Should we add a DebugNoLine or use OpNoLine?
RESOLVED: We have added DebugNoLine for symmetry and to clearly separate from OpLine and OpNoLine.
Revision History
Rev | Date | Author | Changes |
---|---|---|---|
1.00 Rev 1 |
2020-11-02 |
Baldur Karlsson |
Initial revision |
1.00 Rev 2 |
2020-11-02 |
Baldur Karlsson |
Changed to comply with non-semantic restrictions. |
1.00 Rev 3 |
2020-11-17 |
Baldur Karlsson |
Added DebugSourceContinued, DebugLine/DebugNoLine, DebugBuildIdentifier, DebugStoragePath, DebugEntryPoint, DebugTypeMatrix. |
1.00 Rev 4 |
2020-12-08 |
Baldur Karlsson |
Grammar fixes, added FlagUnknownPhysicalLayout and Indexes parameter in DebugValue. Limited where DebugLine type instructions can appear. |
1.00 Rev 5 |
2020-01-04 |
Baldur Karlsson |
Add Flags parameter to DebugTypeBasic. |
1.00 Rev 6 |
2020-01-22 |
Baldur Karlsson |
Rename extended instruction set. |
1.00 Rev 7 |
2021-07-01 |
Baldur Karlsson |
Clarify runtime array sizing. |
1.00 Rev 8 |
2021-07-27 |
Baldur Karlsson |
Clarify that DebugFunctionDefinition can be in |
1.00 Rev 9 |
2022-02-28 |
Baldur Karlsson |
Clarify that DebugEntryPoint refers to a DebugFunction, not an OpEntryPoint. |
1.00 Rev 10 |
2024-08-07 |
Victor Lomüller |
Fix that in DebugLine the Column end operand can be equal to Column start operand. |
1.00 Rev 11 |
2024-10-08 |
Spencer Fricke |
Fix using Scope instead of Parent operand name. |