Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RemoveDIs] Add documentation for IR debug records #81156

Merged
merged 4 commits into from
Mar 8, 2024

Conversation

SLTozer
Copy link
Contributor

@SLTozer SLTozer commented Feb 8, 2024

This patch adds minimal documentation for the IR representation of the RemoveDIs model of debug info, which is implemented in a separate pair of PRs (#79281 and #79818). 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.

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 8, 2024

@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-debuginfo

Author: Stephen Tozer (SLTozer)

Changes

This patch adds minimal documentation for the IR representation of the RemoveDIs model of debug info, which is implemented in a separate pair of PRs (#79281 and #79818). 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.


Full diff: https://github.com/llvm/llvm-project/pull/81156.diff

2 Files Affected:

  • (modified) llvm/docs/LangRef.rst (+29-2)
  • (modified) llvm/docs/SourceLevelDebugging.rst (+65)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index fd2e3aacd0169c..61778caec61b76 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -877,7 +877,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
@@ -8510,7 +8511,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 true 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:
 
@@ -12664,6 +12668,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>`, which 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 the
+meaning of debug records can be found in the `LLVM Source Level Debugging
+<SourceLevelDebugging.html#format-common-intrinsics>`_ document.
+
 .. _intrinsics:
 
 Intrinsic Functions
diff --git a/llvm/docs/SourceLevelDebugging.rst b/llvm/docs/SourceLevelDebugging.rst
index e1df7c355ee092..8fe61340c1761b 100644
--- a/llvm/docs/SourceLevelDebugging.rst
+++ b/llvm/docs/SourceLevelDebugging.rst
@@ -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,60 @@ 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
+
+  call void llvm.dbg.<type>([metadata <arg>, ]*), !dbg <DILocation> ; Intrinsic model
+    #dbg_<type>([<arg>, ]*, <DILocation>)                           ; Record model
+
+A debug intrinsic function can therefore be converted to a debug record with the
+following steps:
+
+1. Add an extra level of indentation.
+2. Replace everything prior to the intrinsic type (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 variety of intrinsic function, there is an equivalent debug record.
+
+``#dbg_declare``
+^^^^^^^^^^^^^^^^
+
+.. code-block:: llvm
+
+    #dbg_declare(Value, DILocalVariable, DIExpression, DILocation)
+
+Equivalent to the ``llvm.dbg.declare`` intrinsic.
+
+``#dbg_value``
+^^^^^^^^^^^^^^
+
+.. code-block:: llvm
+
+    #dbg_value([Value|DIArgList], DILocalVariable, DIExpression, DILocation)
+
+Equivalent to the ``llvm.dbg.value`` intrinsic.
+
+``#dbg_assign``
+^^^^^^^^^^^^^^^
+
+.. code-block:: llvm
+
+    #dbg_assign([Value|DIArgList], DILocalVariable, DIExpression, DIAssignID,
+                Value, DIExpression, DILocation)
+
+Equivalent to the ``llvm.dbg.assign`` intrinsic.
+
 Object lifetimes and scoping
 ============================
 

llvm/docs/SourceLevelDebugging.rst Outdated Show resolved Hide resolved
call void llvm.dbg.<type>([metadata <arg>, ]*), !dbg <DILocation> ; Intrinsic model
#dbg_<type>([<arg>, ]*, <DILocation>) ; Record model

A debug intrinsic function can therefore be converted to a debug record with the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brevity: therefore (doesn't add anything to the text)

llvm/docs/SourceLevelDebugging.rst Outdated Show resolved Hide resolved
llvm/docs/SourceLevelDebugging.rst Outdated Show resolved Hide resolved
@SLTozer
Copy link
Contributor Author

SLTozer commented Feb 8, 2024

Thanks for the quick and detailed review! Patch updated.

Copy link
Contributor

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for writing more docs!

Copy link
Member

@jryans jryans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall, thanks! 😄

%inst2 = op2 %inst1, %c

These debug records are an optional replacement for
:ref:`debug intrinsics<dbg_intrinsics>`. Debug records will be output iff the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you were going for "if and only if", but I think it's clear enough to just use standard "if" here.

Suggested change
:ref:`debug intrinsics<dbg_intrinsics>`. Debug records will be output iff the
:ref:`debug intrinsics<dbg_intrinsics>`. Debug records will be output if the

@SLTozer SLTozer merged commit 01e5d46 into llvm:main Mar 8, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants