Copyright 2014-2025 The Khronos Group Inc.
This Specification is protected by copyright laws and contains material proprietary to Khronos. Except as described by these terms, it or any components may not be reproduced, republished, distributed, transmitted, displayed, broadcast or otherwise exploited in any manner without the express prior written permission of Khronos.
This Specification has been created under the Khronos Intellectual Property Rights Policy, which is Attachment A of the Khronos Group Membership Agreement available at www.khronos.org/files/member_agreement.pdf.
Khronos grants a conditional copyright license to use and reproduce the unmodified Specification for any purpose, without fee or royalty, EXCEPT no licenses to any patent, trademark or other intellectual property rights are granted under these terms. Parties desiring to implement the Specification and make use of Khronos trademarks in relation to that implementation, and receive reciprocal patent license protection under the Khronos Intellectual Property Rights Policy must become Adopters and confirm the implementation as conformant under the process defined by Khronos for this Specification; see https://www.khronos.org/adopters.
Khronos makes no, and expressly disclaims any, representations or warranties, express or implied, regarding this Specification, including, without limitation: merchantability, fitness for a particular purpose, non-infringement of any intellectual property, correctness, accuracy, completeness, timeliness, and reliability. Under no circumstances will Khronos, or any of its Promoters, Contributors or Members, or their respective partners, officers, directors, employees, agents or representatives be liable for any damages, whether direct, indirect, special or consequential damages for lost revenues, lost profits, or otherwise, arising from or in connection with these materials.
This Specification contains substantially unmodified functionality from, and is a successor to, Khronos specifications including all versions of "The SPIR Specification", "The OpenGL Shading Language", "The OpenGL ES Shading Language", as well as all Khronos OpenCL API and OpenCL programming language specifications.
The Khronos Intellectual Property Rights Policy defines the terms Scope, Compliant Portion, and Necessary Patent Claims.
Where this Specification uses technical terminology, defined in the Glossary or otherwise, that refer to enabling technologies that are not expressly set forth in this Specification, those enabling technologies are EXCLUDED from the Scope of this Specification. For clarity, enabling technologies not disclosed with particularity in this Specification (e.g. semiconductor manufacturing technology, hardware architecture, processor architecture or microarchitecture, memory architecture, compiler technology, object oriented technology, basic operating system technology, compression technology, algorithms, and so on) are NOT to be considered expressly set forth; only those application program interfaces and data structures disclosed with particularity are included in the Scope of this Specification.
For purposes of the Khronos Intellectual Property Rights Policy as it relates to the definition of Necessary Patent Claims, all recommended or optional features, behaviors and functionality set forth in this Specification, if implemented, are considered to be included as Compliant Portions.
Khronos® and Vulkan® are registered trademarks, and ANARI™, WebGL™, glTF™, NNEF™, OpenVX™, SPIR™, SPIR-V™, SYCL™, OpenVG™, Vulkan SC™, 3D Commerce™ and Kamaros™ are trademarks of The Khronos Group Inc. OpenXR™ is a trademark owned by The Khronos Group Inc. and is registered as a trademark in China, the European Union, Japan and the United Kingdom. OpenCL™ is a trademark of Apple Inc. used under license by Khronos. OpenGL® is a registered trademark and the OpenGL ES™ and OpenGL SC™ logos are trademarks of Hewlett Packard Enterprise used under license by Khronos. ASTC is a trademark of ARM Holdings PLC. All other product names, trademarks, and/or company names are used solely for identification and belong to their respective owners.
Contributors and Acknowledgments
-
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
1. Introduction
This is the specification of the OpenCL.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:
-
Sufficient for a back end to generate DWARF debug information for OpenCL C/C++ kernels
-
Easy translation between SPIR-V/LLVM
-
Clear
-
Concise
-
Extensible for other languages
-
Capable of representing debug information for an optimized IR
1.1. 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.
2. 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, and DebugValue
instructions can interleave with the instructions within a function.
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.
2.1. 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).
2.2. Forward references
Forward references (an operand <id> that appears before the Result <id> defining it) are generally not allowed, except for the following exceptions:
-
Each of DebugTypeComposite Members is a forward reference to a DebugTypeMember, DebugFunction, or DebugTypeInheritance.
-
A DebugFunction Function is a forward reference to an OpFunction.
3. Enumerations
3.1. 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 |
3.2. 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 |
3.3. 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 |
3.5. Type Qualifiers
Used by DebugTypeQualifier
| Qualifier tag code name | |
|---|---|
0 |
ConstType |
1 |
VolatileType |
2 |
RestrictType |
3 |
AtomicType |
3.6. 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 word integer literal. |
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 be a single word integer literals. |
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 word integer literal. |
9 |
Fragment |
2 |
Has the same semantics as BitPiece, but the offset operand defines location within the source variable. |
3.7. Imported Entities
Used by DebugImportedEntity
| Tag code name | |
|---|---|
0 |
ImportedModule |
1 |
ImportedDeclaration |
4. Instructions
4.1. Missing Debugging Information
4.2. Compilation Unit
DebugCompilationUnit |
|||||||||
9 |
12 |
<id> |
Result <id> |
<id> Set |
1 |
Literal Number |
Literal Number |
<id> Source |
Language |
4.3. Type instructions
DebugTypeBasic |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
2 |
<id> Name |
<id> Size |
|
DebugTypePointer |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
3 |
<id> Base Type |
Storage Class |
Literal |
DebugTypeQualifier |
|||||||
7 |
12 |
<id> |
Result <id> |
<id> Set |
4 |
<id> Base Type |
|
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 |
Literal Number |
Literal Number |
<id> Scope |
DebugTypeFunction |
||||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
8 |
Literal |
<id> Return Type |
Optional <id>, <id>, … Parameter Types |
DebugTypeEnum |
||||||||||||||
13+ |
12 |
<id> |
Result <id> |
<id> Set |
9 |
<id> Name |
<id> Underlying Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Size |
Literal Flags |
<id> Value, |
DebugTypeComposite Note: To represent a source language opaque type, this instruction must have no Members operands, Size operand must be DebugInfoNone, and Name must start with @ to avoid clashes with user defined names. |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
10 |
<id> Name |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Linkage Name |
<id> Size |
Literal |
<id>, <id>, … Members |
|
DebugTypeMember |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
11 |
<id> Name |
<id> Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Offset |
<id> Size |
Optional <id> Value |
|
DebugTypeInheritance |
||||||||||
10 |
12 |
<id> |
Result <id> |
<id> Set |
12 |
<id> Child |
<id> Parent |
<id> Offset |
<id> Size |
|
4.4. Templates
DebugTypeTemplateParameter |
|||||||||||
11 |
12 |
<id> |
Result <id> |
<id> Set |
15 |
<id> Name |
<id> Actual Type |
<id> Value |
<id> Source |
Literal Number |
Literal Number |
DebugTypeTemplateParameterPack |
||||||||||
10+ |
12 |
<id> |
Result <id> |
<id> Set |
17 |
<id> Name |
<id> Source |
Literal Number |
Literal Number |
<id>… Template parameters |
4.5. Global Variables
DebugGlobalVariable |
|||||||||||||||
14+ |
12 |
<id> |
Result <id> |
<id> Set |
18 |
<id> Name |
<id> Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Linkage Name |
<id> Variable |
Optional <id> Static Member Declaration |
|
4.6. Functions
DebugFunctionDeclaration |
|||||||||||||
13 |
12 |
<id> |
Result <id> |
<id> Set |
19 |
<id> Name |
<id> Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Linkage Name |
|
DebugFunction |
||||||||||||||||
15+ |
12 |
<id> |
Result <id> |
<id> Set |
20 |
<id> Name |
<id> Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
<id> Linkage Name |
Literal Number |
<id> Function |
Optional <id> Declaration |
|
4.7. Location Information
DebugLexicalBlock |
||||||||||
9+ |
12 |
<id> |
Result <id> |
<id> Set |
21 |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
Optional <id> Name |
DebugLexicalBlockDiscriminator |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
22 |
<id> Source |
Literal Number |
<id> Scope |
DebugScope |
|||||||
6+ |
12 |
<id> |
Result <id> |
<id> Set |
23 |
<id> Scope |
Optional |
DebugNoScope |
|||||
5 |
12 |
<id> |
Result <id> |
<id> Set |
24 |
DebugInlinedAt |
||||||||
7+ |
12 |
<id> |
Result <id> |
<id> Set |
25 |
Literal Number |
<id> Scope |
Optional <id> Inlined |
4.8. Local Variables
DebugLocalVariable |
|||||||||||||
12+ |
12 |
<id> |
Result <id> |
<id> Set |
26 |
<id> Name |
<id> Type |
<id> Source |
Literal Number |
Literal Number |
<id> Scope |
Literal |
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 |
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 |
Optional Literal |
|
DebugExpression |
||||||
5+ |
12 |
<id> |
Result <id> |
<id> Set |
31 |
Optional <id>… Operation |
4.9. Macros
DebugMacroUndef |
||||||||
8 |
12 |
<id> |
Result <id> |
<id> Set |
33 |
<id> Source |
Literal Number |
<id> Macro |
4.10. Imported Entities
DebugImportedEntity |
||||||||||||
12 |
12 |
<id> |
Result <id> |
<id> Set |
34 |
<id> Name |
Literal |
<id> Source |
<id> Entity |
Literal Number |
Literal Number |
<id> Scope |
5. Validation Rules
None.
6. Issues
-
Does the ABI used for the OpenCL C 2.0 blocks feature have to be declared somewhere else in the module?
RESOLVED: No. Block ABI is out of scope for this specification.
7. Revision History
| Rev | Date | Author | Changes |
|---|---|---|---|
0.99 Rev 1 |
2016-11-25 |
Alexey Sotkin |
Initial revision |
0.99 Rev 2 |
2016-12-08 |
Alexey Sotkin |
Added details for the type instructions |
0.99 Rev 3 |
2016-12-14 |
Alexey Sotkin |
Added details for the rest of instructions |
0.99 Rev 4 |
2016-12-21 |
Alexey Sotkin |
Applied comments after review |
0.99 Rev 5 |
2017-03-22 |
Alexey Sotkin |
Format the specification as extended instruction set |
0.99 Rev 6 |
2017-04-21 |
Alexey Sotkin |
Adding File and Line operands |
0.99 Rev 7 |
2017-06-05 |
Alexey Sotkin |
Moving Flags to operands. Adding several new instructions. |
0.99 Rev 8 |
2017-08-31 |
Alexey Sotkin |
Replacing File operand by Source operand. Fixing typos. Formatting |
0.99 Rev 9 |
2017-09-05 |
Alexey Sotkin |
Clarifying representation of opaque types |
0.99 Rev 10 |
2017-09-13 |
Alexey Sotkin |
Support of multidimensional arrays. Adding DebugFunctionDeclaration. Updating debug operations. |
0.99 Rev 11 |
2017-12-13 |
Alexey Sotkin |
Removing "Op" prefix |
0.99 Rev 12 |
2017-12-13 |
Alexey Sotkin |
Changing style of enum tokens to CamelCase |
1.00 Rev 1 |
2017-12-14 |
David Neto |
Approved by SPIR WG on 2017-09-22. Change to 1.00 Rev 1 |
2.00 Rev 1 |
2018-12-05 |
Alexey Sotkin |
Changing the name string in OpExtInstImport instruction. |
2.00 Rev.2 |
2018-12-19 |
Alexey Sotkin |
Added description of DebugOperations. |
2.00 Rev.2 |
2020-05-06 |
Jaebaek Seo |
Revising the overall specification to fix errors, typos, and grammar errors. |