Skip to content

[LangRef] Clarify definition of fragments and debug intrinsics #82019

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

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 65 additions & 19 deletions llvm/docs/SourceLevelDebugging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,42 @@ debugging information influences optimization passes then it will be reported
as a failure. See :doc:`TestingGuide` for more information on LLVM test
infrastructure and how to run various tests.

.. _variables_and_variable_fragments:

Variables and Variable Fragments
================================

In the context of this document a "variable" refers generally to any source
language object which can have a value, including at least:

- Variables
- Constants
- Formal parameters

.. note::

There is no special provision for "true" constants in LLVM today, and
they are instead treated as local or global variables.

A variable is represented by a `local variable <LangRef.html#dilocalvariable>`_
or `global variable <LangRef.html#diglobalvariable>`_ metadata node.

A variable fragment (or just "fragment") is a contiguous span of bits of a
variable.

A debug intrinsic which refers to a ``DIExpression`` ending with a
``DW_OP_LLVM_fragment`` operation describes a fragment of the variable it
refers to.

The operands of the ``DW_OP_LLVM_fragment`` operation encode the bit offset of
the fragment relative to the start of the variable, and the size of the
fragment in bits, respectively.

.. note::

The ``DW_OP_LLVM_fragment`` operation acts only to encode the fragment
information, and does not have an effect on the semantics of the expression.

.. _format:

Debugging information format
Expand Down Expand Up @@ -180,7 +216,9 @@ track source local variables through optimization and code generation.

.. code-block:: llvm

void @llvm.dbg.declare(metadata, metadata, metadata)
void @llvm.dbg.declare(metadata <type> <value>,
metadata <!DILocalVariable>,
metadata <!DIExpression>)

This intrinsic provides information about a local element (e.g., variable).
The first argument is metadata holding the address of variable, typically a
Expand Down Expand Up @@ -221,7 +259,9 @@ agree on the memory location.

.. code-block:: llvm

void @llvm.dbg.value(metadata, metadata, metadata)
void @llvm.dbg.value(metadata <<type> <value>|!DIArgList>,
metadata <!DILocalVariable>,
metadata <!DIExpression>)

This intrinsic provides information when a user source variable is set to a new
value. The first argument is the new value (wrapped as metadata). The second
Expand All @@ -243,12 +283,12 @@ the complex expression derives the direct value.

.. code-block:: llvm

void @llvm.dbg.assign(Value *Value,
DIExpression *ValueExpression,
DILocalVariable *Variable,
DIAssignID *ID,
Value *Address,
DIExpression *AddressExpression)
void @llvm.dbg.assign(metadata <<type> <value>|!DIArgList>,
metadata <!DIExpression>,
metadata <!DILocalVariable>,
metadata <!DIAssignID>,
metadata <type> <value>,
metadata <!DIExpression>)

This intrinsic marks the position in IR where a source assignment occurred. It
encodes the value of the variable. It references the store, if any, that
Expand All @@ -259,13 +299,6 @@ argument is a ``DIAssignID`` used to reference a store. The fifth is the
destination of the store (wrapped as metadata), and the sixth is a `complex
expression <LangRef.html#diexpression>`_ that modifies it.

The formal LLVM-IR signature is:

.. code-block:: llvm

void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)


See :doc:`AssignmentTracking` for more info.

Object lifetimes and scoping
Expand Down Expand Up @@ -417,10 +450,23 @@ values through compilation, when objects are promoted to SSA values an
``llvm.dbg.value`` intrinsic is created for each assignment, recording the
variable's new location. Compared with the ``llvm.dbg.declare`` intrinsic:

* A dbg.value terminates the effect of any preceding dbg.values for (any
overlapping fragments of) the specified variable.
* The dbg.value's position in the IR defines where in the instruction stream
the variable's value changes.
* A ``llvm.dbg.value`` intrinsic terminates the effects that any preceding
``llvm.dbg.value`` intrinsics have on any common bits of a common variable.

.. note::

The current implementation generally terminates the effect of every
intrinsic in its entirety if any of its effects would be terminated, rather
than carrying forward the effect of previous intrinsics for non-overlapping
bits as it would be permitted to do by this definition. This is allowed
just as dropping any debug information at any point in the compilation is
allowed.

One exception to this is :doc:`AssignmentTracking` where certain
memory-based locations are carried forward partially in some situations.

* The ``llvm.dbg.value``'s position in the IR defines where in the instruction
stream the variable's value changes.
* Operands can be constants, indicating the variable is assigned a
constant value.

Expand Down