[RemoveDIs] Add documentation for IR debug records (#81156)

This patch adds minimal documentation for the IR representation of the
RemoveDIs model of debug info. This patch assumes
that the default for all cases is still debug intrinsic functions, and
so does not update all existing text to refer to debug records, but only
adds a section in the LangRef and SourceLevelDebugging documents to
explain the new format.
This commit is contained in:
Stephen Tozer 2024-03-08 15:03:15 +00:00 committed by GitHub
parent ba2236d300
commit 01e5d4609b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 95 additions and 2 deletions

View File

@ -908,7 +908,8 @@ Syntax::
A function definition contains a list of basic blocks, forming the CFG (Control
Flow Graph) for the function. Each basic block may optionally start with a label
(giving the basic block a symbol table entry), contains a list of instructions,
(giving the basic block a symbol table entry), contains a list of instructions
and :ref:`debug records <debugrecords>`,
and ends with a :ref:`terminator <terminators>` instruction (such as a branch or
function return). If an explicit label name is not provided, a block is assigned
an implicit numbered label, using the next value from the same counter as used
@ -8541,7 +8542,10 @@ The LLVM instruction set consists of several different classifications
of instructions: :ref:`terminator instructions <terminators>`, :ref:`binary
instructions <binaryops>`, :ref:`bitwise binary
instructions <bitwiseops>`, :ref:`memory instructions <memoryops>`, and
:ref:`other instructions <otherops>`.
:ref:`other instructions <otherops>`. There are also :ref:`debug records
<debugrecords>`, which are not instructions themselves but are printed
interleaved with instructions to describe changes in the state of the program's
debug information at each position in the program's execution.
.. _terminators:
@ -12695,6 +12699,29 @@ Example:
%tok = cleanuppad within %cs []
.. _debugrecords:
Debug Records
-----------------------
Debug records appear interleaved with instructions, but are not instructions;
they are used only to define debug information, and have no effect on generated
code. They are distinguished from instructions by the use of a leading `#` and
an extra level of indentation. As an example:
.. code-block:: llvm
%inst1 = op1 %a, %b
#dbg_value(%inst1, !10, !DIExpression(), !11)
%inst2 = op2 %inst1, %c
These debug records are an optional replacement for
:ref:`debug intrinsics<dbg_intrinsics>`. Debug records will be output if the
``--write-experimental-debuginfo`` flag is passed to LLVM; it is an error for both
records and intrinsics to appear in the same module. More information about
debug records can be found in the `LLVM Source Level Debugging
<SourceLevelDebugging.html#format-common-intrinsics>`_ document.
.. _intrinsics:
Intrinsic Functions

View File

@ -167,6 +167,17 @@ conventions used by the C and C++ front-ends.
Debug information descriptors are `specialized metadata nodes
<LangRef.html#specialized-metadata>`_, first-class subclasses of ``Metadata``.
There are two models for defining the values of source variables at different
states of the program and tracking these values through optimization and code
generation: :ref:`intrinsic function calls <format_common_intrinsics>`, the
current default, and :ref:`debug records <debug_records>`, which are a new
non-instruction-based model
(for an explanation of how this works and why it is desirable, see the
`RemoveDIs <RemoveDIsDebugInfo.html>`_ document). Each module must use one or
the other; they may never be mixed within an IR module. To enable writing debug
records instead of intrinsic calls, use the flag
``--write-experimental-debuginfo``.
.. _format_common_intrinsics:
Debugger intrinsic functions
@ -268,6 +279,61 @@ The formal LLVM-IR signature is:
See :doc:`AssignmentTracking` for more info.
.. _debug_records:
Debug Records
----------------------------
LLVM also has an alternative to intrinsic functions, debug records, which
function similarly but are not instructions. The basic syntax for debug records
is:
.. code-block:: llvm
#dbg_<kind>([<arg>, ]* <DILocation>)
; Using the intrinsic model, the above is equivalent to:
call void llvm.dbg.<kind>([metadata <arg>, ]*), !dbg <DILocation>
A debug intrinsic function can be converted to a debug record with the
following steps:
1. Add an extra level of indentation.
2. Replace everything prior to the intrinsic kind (declare/value/assign) with
``#dbg_``.
3. Remove the leading ``metadata`` from the intrinsic's arguments.
4. Transfer the ``!dbg`` attachment to be an argument, dropping the leading
``!dbg``.
For each kind of intrinsic function, there is an equivalent debug record.
``#dbg_declare``
^^^^^^^^^^^^^^^^
.. code-block:: llvm
#dbg_declare([Value|MDNode], DILocalVariable, DIExpression, DILocation)
Equivalent to the ``llvm.dbg.declare`` intrinsic.
``#dbg_value``
^^^^^^^^^^^^^^
.. code-block:: llvm
#dbg_value([Value|DIArgList|MDNode], DILocalVariable, DIExpression, DILocation)
Equivalent to the ``llvm.dbg.value`` intrinsic.
``#dbg_assign``
^^^^^^^^^^^^^^^
.. code-block:: llvm
#dbg_assign([Value|DIArgList|MDNode], DILocalVariable, DIExpression,
DIAssignID, [Value|MDNode], DIExpression, DILocation)
Equivalent to the ``llvm.dbg.assign`` intrinsic.
Object lifetimes and scoping
============================