[llvm] [RemoveDIs] Update all docs to use debug records (PR #91768)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Fri May 10 09:49:28 PDT 2024
https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/91768
Following the landing of the [patch](https://github.com/llvm/llvm-project/pull/91724) that enables printing debug records by default, the documentation should be updated to refer to debug records as the primary debug info representation, with debug intrinsics being relegated to an optional alternative.
This patch performs a few updates:
- Replace references to intrinsics with references to records across all the documentation.
- Replace intrinsics with records in code examples.
- Move debug records prior to debug intrinsics in the SourceLevelDebugging document, and change text to refer to them as the primary representation.
- Add release notes describing the change.
>From 3fa9e42e1fec12cadea2c439f58c415f6086dff5 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 24 Jan 2024 13:58:40 +0000
Subject: [PATCH] [RemoveDIs] Update all docs to use debug records
---
llvm/docs/AssignmentTracking.md | 113 +++---
llvm/docs/HowToUpdateDebugInfo.rst | 16 +-
llvm/docs/InstrRefDebugInfo.md | 2 +-
llvm/docs/LangRef.rst | 83 ++--
llvm/docs/MIRLangRef.rst | 8 +-
llvm/docs/Passes.rst | 5 +-
llvm/docs/ReleaseNotes.rst | 4 +
llvm/docs/SourceLevelDebugging.rst | 373 +++++++++---------
.../MyFirstLanguageFrontend/LangImpl09.rst | 2 +-
9 files changed, 310 insertions(+), 296 deletions(-)
diff --git a/llvm/docs/AssignmentTracking.md b/llvm/docs/AssignmentTracking.md
index 5a8bc5844eef6..a24a8b0d797f8 100644
--- a/llvm/docs/AssignmentTracking.md
+++ b/llvm/docs/AssignmentTracking.md
@@ -11,7 +11,7 @@ The core idea is to track more information about source assignments in order
and preserve enough information to be able to defer decisions about whether to
use non-memory locations (register, constant) or memory locations until after
middle end optimisations have run. This is in opposition to using
-`llvm.dbg.declare` and `llvm.dbg.value`, which is to make the decision for most
+`#dbg_declare` and `#dbg_value`, which is to make the decision for most
variables early on, which can result in suboptimal variable locations that may
be either incorrect or incomplete.
@@ -26,19 +26,18 @@ except for development and testing.
**Enable in Clang**: `-Xclang -fexperimental-assignment-tracking`
That causes Clang to get LLVM to run the pass `declare-to-assign`. The pass
-converts conventional debug intrinsics to assignment tracking metadata and sets
+converts conventional debug records to assignment tracking metadata and sets
the module flag `debug-info-assignment-tracking` to the value `i1 true`. To
check whether assignment tracking is enabled for a module call
`isAssignmentTrackingEnabled(const Module &M)` (from `llvm/IR/DebugInfo.h`).
## Design and implementation
-### Assignment markers: `llvm.dbg.assign`
+### Assignment markers: `#dbg_assign`
-`llvm.dbg.value`, a conventional debug intrinsic, marks out a position in the
+`#dbg_value`, a conventional debug record, marks out a position in the
IR where a variable takes a particular value. Similarly, Assignment Tracking
-marks out the position of assignments with a new intrinsic called
-`llvm.dbg.assign`.
+marks out the position of assignments with a record called `#dbg_assign`.
In order to know where in IR it is appropriate to use a memory location for a
variable, each assignment marker must in some way refer to the store, if any
@@ -48,24 +47,23 @@ important benefit of referring to the store is that we can then build a two-way
mapping of stores<->markers that can be used to find markers that need to be
updated when stores are modified.
-An `llvm.dbg.assign` marker that is not linked to any instruction signals that
+An `#dbg_assign` marker that is not linked to any instruction signals that
the store that performed the assignment has been optimised out, and therefore
the memory location will not be valid for at least some part of the program.
-Here's the `llvm.dbg.assign` signature. Each parameter is wrapped in
-`MetadataAsValue`, and `Value *` type parameters are first wrapped in
-`ValueAsMetadata`:
+Here's the `#dbg_assign` signature. `Value *` type parameters are first wrapped
+in `ValueAsMetadata`:
```
-void @llvm.dbg.assign(Value *Value,
- DIExpression *ValueExpression,
- DILocalVariable *Variable,
- DIAssignID *ID,
- Value *Address,
- DIExpression *AddressExpression)
+ #dbg_assign(Value *Value,
+ DIExpression *ValueExpression,
+ DILocalVariable *Variable,
+ DIAssignID *ID,
+ Value *Address,
+ DIExpression *AddressExpression)
```
-The first three parameters look and behave like an `llvm.dbg.value`. `ID` is a
+The first three parameters look and behave like an `#dbg_value`. `ID` is a
reference to a store (see next section). `Address` is the destination address
of the store and it is modified by `AddressExpression`. An empty/undef/poison
address means the address component has been killed (the memory address is no
@@ -73,18 +71,13 @@ longer a valid location). LLVM currently encodes variable fragment information
in `DIExpression`s, so as an implementation quirk the `FragmentInfo` for
`Variable` is contained within `ValueExpression` only.
-The formal LLVM-IR signature is:
-```
-void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
-```
-
### Instruction link: `DIAssignID`
`DIAssignID` metadata is the mechanism that is currently used to encode the
store<->marker link. The metadata node has no operands and all instances are
`distinct`; equality is checked for by comparing addresses.
-`llvm.dbg.assign` intrinsics use a `DIAssignID` metadata node instance as an
+`#dbg_assign` records use a `DIAssignID` metadata node instance as an
operand. This way it refers to any store-like instruction that has the same
`DIAssignID` attachment. E.g. For this test.cpp,
@@ -102,9 +95,9 @@ we get:
define dso_local noundef i32 @_Z3funi(i32 noundef %a) #0 !dbg !8 {
entry:
%a.addr = alloca i32, align 4, !DIAssignID !13
- call void @llvm.dbg.assign(metadata i1 undef, metadata !14, metadata !DIExpression(), metadata !13, metadata i32* %a.addr, metadata !DIExpression()), !dbg !15
+ #dbg_assign(i1 undef, !14, !DIExpression(), !13, i32* %a.addr, !DIExpression(), !15)
store i32 %a, i32* %a.addr, align 4, !DIAssignID !16
- call void @llvm.dbg.assign(metadata i32 %a, metadata !14, metadata !DIExpression(), metadata !16, metadata i32* %a.addr, metadata !DIExpression()), !dbg !15
+ #dbg_assign(i32 %a, !14, !DIExpression(), !16, i32* %a.addr, !DIExpression(), !15)
%0 = load i32, i32* %a.addr, align 4, !dbg !17
ret i32 %0, !dbg !18
}
@@ -116,16 +109,16 @@ entry:
!16 = distinct !DIAssignID()
```
-The first `llvm.dbg.assign` refers to the `alloca` through `!DIAssignID !13`,
+The first `#dbg_assign` refers to the `alloca` through `!DIAssignID !13`,
and the second refers to the `store` through `!DIAssignID !16`.
### Store-like instructions
-In the absence of a linked `llvm.dbg.assign`, a store to an address that is
+In the absence of a linked `#dbg_assign`, a store to an address that is
known to be the backing storage for a variable is considered to represent an
assignment to that variable.
-This gives us a safe fall-back in cases where `llvm.dbg.assign` intrinsics have
+This gives us a safe fall-back in cases where `#dbg_assign` records have
been deleted, the `DIAssignID` attachment on the store has been dropped, or the
optimiser has made a once-indirect store (not tracked with Assignment Tracking)
direct.
@@ -139,61 +132,61 @@ direct.
instruction. In this case, the assignment is considered to take place in
multiple positions in the program.
-**Moving** a non-debug instruction: nothing new to do. Instructions linked to an
-`llvm.dbg.assign` have their initial IR position marked by the position of the
-`llvm.dbg.assign`.
+**Moving** a non-debug instruction: nothing new to do. Instructions linked to a
+`#dbg_assign` have their initial IR position marked by the position of the
+`#dbg_assign`.
**Deleting** a non-debug instruction: nothing new to do. Simple DSE does not
require any change; it’s safe to delete an instruction with a `DIAssignID`
-attachment. An `llvm.dbg.assign` that uses a `DIAssignID` that is not attached
+attachment. A `#dbg_assign` that uses a `DIAssignID` that is not attached
to any instruction indicates that the memory location isn’t valid.
**Merging** stores: In many cases no change is required as `DIAssignID`
attachments are automatically merged if `combineMetadata` is called. One way or
another, the `DIAssignID` attachments must be merged such that new store
-becomes linked to all the `llvm.dbg.assign` intrinsics that the merged stores
+becomes linked to all the `#dbg_assign` records that the merged stores
were linked to. This can be achieved simply by calling a helper function
`Instruction::mergeDIAssignID`.
-**Inlining** stores: As stores are inlined we generate `llvm.dbg.assign`
-intrinsics and `DIAssignID` attachments as if the stores represent source
+**Inlining** stores: As stores are inlined we generate `#dbg_assign`
+records and `DIAssignID` attachments as if the stores represent source
assignments, just like the in frontend. This isn’t perfect, as stores may have
been moved, modified or deleted before inlining, but it does at least keep the
information about the variable correct within the non-inlined scope.
-**Splitting** stores: SROA and passes that split stores treat `llvm.dbg.assign`
-intrinsics similarly to `llvm.dbg.declare` intrinsics. Clone the
-`llvm.dbg.assign` intrinsics linked to the store, update the FragmentInfo in
-the `ValueExpression`, and give the split stores (and cloned intrinsics) new
+**Splitting** stores: SROA and passes that split stores treat `#dbg_assign`
+records similarly to `#dbg_declare` records. Clone the
+`#dbg_assign` records linked to the store, update the FragmentInfo in
+the `ValueExpression`, and give the split stores (and cloned records) new
`DIAssignID` attachments each. In other words, treat the split stores as
separate assignments. For partial DSE (e.g. shortening a memset), we do the
-same except that `llvm.dbg.assign` for the dead fragment gets an `Undef`
+same except that `#dbg_assign` for the dead fragment gets an `Undef`
`Address`.
-**Promoting** allocas and store/loads: `llvm.dbg.assign` intrinsics implicitly
+**Promoting** allocas and store/loads: `#dbg_assign` records implicitly
describe joined values in memory locations at CFG joins, but this is not
necessarily the case after promoting (or partially promoting) the
variable. Passes that promote variables are responsible for inserting
-`llvm.dbg.assign` intrinsics after the resultant PHIs generated during
-promotion. `mem2reg` already has to do this (with `llvm.dbg.value`) for
-`llvm.dbg.declare`s. Where a store has no linked intrinsic, the store is
+`#dbg_assign` records after the resultant PHIs generated during
+promotion. `mem2reg` already has to do this (with `#dbg_value`) for
+`#dbg_declare`s. Where a store has no linked record, the store is
assumed to represent an assignment for variables stored at the destination
address.
-#### Debug intrinsic updates
+#### Debug record updates
-**Moving** a debug intrinsic: avoid moving `llvm.dbg.assign` intrinsics where
+**Moving** a debug record: avoid moving `#dbg_assign` records where
possible, as they represent a source-level assignment, whose position in the
program should not be affected by optimization passes.
-**Deleting** a debug intrinsic: Nothing new to do. Just like for conventional
-debug intrinsics, unless it is unreachable, it’s almost always incorrect to
-delete a `llvm.dbg.assign` intrinsic.
+**Deleting** a debug record: Nothing new to do. Just like for conventional
+debug records, unless it is unreachable, it’s almost always incorrect to
+delete a `#dbg_assign` record.
-### Lowering `llvm.dbg.assign` to MIR
+### Lowering `#dbg_assign` to MIR
-To begin with only SelectionDAG ISel will be supported. `llvm.dbg.assign`
-intrinsics are lowered to MIR `DBG_INSTR_REF` instructions. Before this happens
+To begin with only SelectionDAG ISel will be supported. `#dbg_assign`
+records are lowered to MIR `DBG_INSTR_REF` instructions. Before this happens
we need to decide where it is appropriate to use memory locations and where we
must use a non-memory location (or no location) for each variable. In order to
make those decisions we run a standard fixed-point dataflow analysis that makes
@@ -214,9 +207,9 @@ to tackle:
clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp for examples.
* `trackAssignments` doesn't yet work for variables that have their
- `llvm.dbg.declare` location modified by a `DIExpression`, e.g. when the
+ `#dbg_declare` location modified by a `DIExpression`, e.g. when the
address of the variable is itself stored in an `alloca` with the
- `llvm.dbg.declare` using `DIExpression(DW_OP_deref)`. See `indirectReturn` in
+ `#dbg_declare` using `DIExpression(DW_OP_deref)`. See `indirectReturn` in
llvm/test/DebugInfo/Generic/assignment-tracking/track-assignments.ll and in
clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp for an
example.
@@ -225,13 +218,13 @@ to tackle:
memory location is available without using a `DIAssignID`. This is because
the storage address is not computed by an instruction (it's an argument
value) and therefore we have nowhere to put the metadata attachment. To solve
- this we probably need another marker intrinsic to denote "the variable's
- stack home is X address" - similar to `llvm.dbg.declare` except that it needs
- to compose with `llvm.dbg.assign` intrinsics such that the stack home address
- is only selected as a location for the variable when the `llvm.dbg.assign`
- intrinsics agree it should be.
+ this we probably need another marker record to denote "the variable's
+ stack home is X address" - similar to `#dbg_declare` except that it needs
+ to compose with `#dbg_assign` records such that the stack home address
+ is only selected as a location for the variable when the `#dbg_assign`
+ records agree it should be.
-* Given the above (a special "the stack home is X" intrinsic), and the fact
+* Given the above (a special "the stack home is X" record), and the fact
that we can only track assignments with fixed offsets and sizes, I think we
can probably get rid of the address and address-expression part, since it
will always be computable with the info we have.
diff --git a/llvm/docs/HowToUpdateDebugInfo.rst b/llvm/docs/HowToUpdateDebugInfo.rst
index c64b5d1d0d98b..0236e76c3a3e2 100644
--- a/llvm/docs/HowToUpdateDebugInfo.rst
+++ b/llvm/docs/HowToUpdateDebugInfo.rst
@@ -151,7 +151,7 @@ Deleting an IR-level Instruction
When an ``Instruction`` is deleted, its debug uses change to ``undef``. This is
a loss of debug info: the value of one or more source variables becomes
-unavailable, starting with the ``llvm.dbg.value(undef, ...)``. When there is no
+unavailable, starting with the ``#dbg_value(undef, ...)``. When there is no
way to reconstitute the value of the lost instruction, this is the best
possible outcome. However, it's often possible to do better:
@@ -172,7 +172,7 @@ possible outcome. However, it's often possible to do better:
define i16 @foo(i16 %a) {
%b = sext i16 %a to i32
%c = and i32 %b, 15
- call void @llvm.dbg.value(metadata i32 %c, ...)
+ #dbg_value(i32 %c, ...)
%d = trunc i32 %c to i16
ret i16 %d
}
@@ -183,7 +183,7 @@ replaced with a simplified instruction:
.. code-block:: llvm
define i16 @foo(i16 %a) {
- call void @llvm.dbg.value(metadata i32 undef, ...)
+ #dbg_value(i32 undef, ...)
%simplified = and i16 %a, 15
ret i16 %simplified
}
@@ -204,7 +204,7 @@ This results in better debug info because the debug use of ``%c`` is preserved:
define i16 @foo(i16 %a) {
%simplified = and i16 %a, 15
- call void @llvm.dbg.value(metadata i16 %simplified, ...)
+ #dbg_value(i16 %simplified, ...)
ret i16 %simplified
}
@@ -249,7 +249,7 @@ module, and the second checks that this DI is still available after an
optimization has occurred, reporting any errors/warnings while doing so.
The instructions are assigned sequentially increasing line locations, and are
-immediately used by debug value intrinsics everywhere possible.
+immediately used by debug value records everywhere possible.
For example, here is a module before:
@@ -271,10 +271,10 @@ and after running ``opt -debugify``:
define void @f(i32* %x) !dbg !6 {
entry:
%x.addr = alloca i32*, align 8, !dbg !12
- call void @llvm.dbg.value(metadata i32** %x.addr, metadata !9, metadata !DIExpression()), !dbg !12
+ #dbg_value(i32** %x.addr, !9, !DIExpression(), !12)
store i32* %x, i32** %x.addr, align 8, !dbg !13
%0 = load i32*, i32** %x.addr, align 8, !dbg !14
- call void @llvm.dbg.value(metadata i32* %0, metadata !11, metadata !DIExpression()), !dbg !14
+ #dbg_value(i32* %0, !11, !DIExpression(), !14)
store i32 10, i32* %0, align 4, !dbg !15
ret void, !dbg !16
}
@@ -409,7 +409,7 @@ as follows:
$ clang -Xclang -fverify-debuginfo-preserve -Xclang -fverify-debuginfo-preserve-export=sample.json -g -O2 sample.c
Please do note that there are some known false positives, for source locations
-and debug intrinsic checking, so that will be addressed as a future work.
+and debug reecord checking, so that will be addressed as a future work.
Mutation testing for MIR-level transformations
----------------------------------------------
diff --git a/llvm/docs/InstrRefDebugInfo.md b/llvm/docs/InstrRefDebugInfo.md
index 3917989e4026d..eb7a0464b90a0 100644
--- a/llvm/docs/InstrRefDebugInfo.md
+++ b/llvm/docs/InstrRefDebugInfo.md
@@ -24,7 +24,7 @@ referring to instruction values:
```llvm
%2 = add i32 %0, %1
-call void @llvm.dbg.value(metadata i32 %2,
+ #dbg_value(metadata i32 %2,
```
In LLVM IR, the IR Value is synonymous with the instruction that computes the
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 6f5a4644ffc2b..846be85c4390d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6244,11 +6244,11 @@ DIExpression
""""""""""""
``DIExpression`` nodes represent expressions that are inspired by the DWARF
-expression language. They are used in :ref:`debug intrinsics<dbg_intrinsics>`
-(such as ``llvm.dbg.declare`` and ``llvm.dbg.value``) to describe how the
+expression language. They are used in :ref:`debug records<debug_records>`
+(such as ``#dbg_declare`` and ``#dbg_value``) to describe how the
referenced LLVM variable relates to the source language variable. Debug
-intrinsics are interpreted left-to-right: start by pushing the value/address
-operand of the intrinsic onto a stack, then repeatedly push and evaluate
+expressions are interpreted left-to-right: start by pushing the value/address
+operand of the record onto a stack, then repeatedly push and evaluate
opcodes from the DIExpression until the final variable description is produced.
The current supported opcode vocabulary is limited:
@@ -6336,23 +6336,24 @@ The current supported opcode vocabulary is limited:
IR for "*ptr = 4;"
--------------
- call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !20)
+ #dbg_value(i32 4, !17, !DIExpression(DW_OP_LLVM_implicit_pointer), !20)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !20 = !DIExpression(DW_OP_LLVM_implicit_pointer))
+ !20 = !DILocation(line: 10, scope: !12)
IR for "**ptr = 4;"
--------------
- call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !21)
+ #dbg_value(i32 4, !17,
+ !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer),
+ !21)
!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !21 = !DIExpression(DW_OP_LLVM_implicit_pointer,
- DW_OP_LLVM_implicit_pointer))
+ !21 = !DILocation(line: 10, scope: !12)
DWARF specifies three kinds of simple location descriptions: Register, memory,
and implicit location descriptions. Note that a location description is
@@ -6363,45 +6364,48 @@ sense that a debugger might modify its value), whereas *implicit locations*
describe merely the actual *value* of a source variable which might not exist
in registers or in memory (see ``DW_OP_stack_value``).
-A ``llvm.dbg.declare`` intrinsic describes an indirect value (the address) of a
-source variable. The first operand of the intrinsic must be an address of some
-kind. A DIExpression attached to the intrinsic refines this address to produce a
+A ``#dbg_declare`` record describes an indirect value (the address) of a
+source variable. The first operand of the record must be an address of some
+kind. A DIExpression operand to the record refines this address to produce a
concrete location for the source variable.
-A ``llvm.dbg.value`` intrinsic describes the direct value of a source variable.
-The first operand of the intrinsic may be a direct or indirect value. A
-DIExpression attached to the intrinsic refines the first operand to produce a
+A ``#dbg_value`` record describes the direct value of a source variable.
+The first operand of the record may be a direct or indirect value. A
+DIExpression operand to the record refines the first operand to produce a
direct value. For example, if the first operand is an indirect value, it may be
necessary to insert ``DW_OP_deref`` into the DIExpression in order to produce a
-valid debug intrinsic.
+valid debug record.
.. note::
A DIExpression is interpreted in the same way regardless of which kind of
- debug intrinsic it's attached to.
+ debug record it's attached to.
+
+ DIExpressions are always printed and parsed inline; they can never be
+ referenced by an ID (e.g. ``!1``).
.. code-block:: text
- !0 = !DIExpression(DW_OP_deref)
- !1 = !DIExpression(DW_OP_plus_uconst, 3)
- !1 = !DIExpression(DW_OP_constu, 3, DW_OP_plus)
- !2 = !DIExpression(DW_OP_bit_piece, 3, 7)
- !3 = !DIExpression(DW_OP_deref, DW_OP_constu, 3, DW_OP_plus, DW_OP_LLVM_fragment, 3, 7)
- !4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
- !5 = !DIExpression(DW_OP_constu, 42, DW_OP_stack_value)
+ !DIExpression(DW_OP_deref)
+ !DIExpression(DW_OP_plus_uconst, 3)
+ !DIExpression(DW_OP_constu, 3, DW_OP_plus)
+ !DIExpression(DW_OP_bit_piece, 3, 7)
+ !DIExpression(DW_OP_deref, DW_OP_constu, 3, DW_OP_plus, DW_OP_LLVM_fragment, 3, 7)
+ !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
+ !DIExpression(DW_OP_constu, 42, DW_OP_stack_value)
DIAssignID
""""""""""
``DIAssignID`` nodes have no operands and are always distinct. They are used to
-link together `@llvm.dbg.assign` intrinsics (:ref:`debug
-intrinsics<dbg_intrinsics>`) and instructions that store in IR. See `Debug Info
-Assignment Tracking <AssignmentTracking.html>`_ for more info.
+link together (:ref:`#dbg_assign records <debug_records>`) and instructions
+that store in IR. See `Debug Info Assignment Tracking
+<AssignmentTracking.html>`_ for more info.
.. code-block:: llvm
store i32 %a, ptr %a.addr, align 4, !DIAssignID !2
- llvm.dbg.assign(metadata %a, metadata !1, metadata !DIExpression(), !2, metadata %a.addr, metadata !DIExpression()), !dbg !3
+ #dbg_assign(%a, !1, !DIExpression(), !2, %a.addr, !DIExpression(), !3)
!2 = distinct !DIAssignID()
@@ -6415,17 +6419,18 @@ DIArgList
also be updated to mirror whatever we decide here.
``DIArgList`` nodes hold a list of constant or SSA value references. These are
-used in :ref:`debug intrinsics<dbg_intrinsics>` (currently only in
-``llvm.dbg.value``) in combination with a ``DIExpression`` that uses the
+used in :ref:`debug records<debug_records>` in combination with a
+``DIExpression`` that uses the
``DW_OP_LLVM_arg`` operator. Because a DIArgList may refer to local values
within a function, it must only be used as a function argument, must always be
inlined, and cannot appear in named metadata.
.. code-block:: text
- llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %b),
- metadata !16,
- metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus))
+ #dbg_value(!DIArgList(i32 %a, i32 %b),
+ !16,
+ !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus),
+ !26)
DIFlags
"""""""
@@ -12878,12 +12883,12 @@ an extra level of indentation. As an example:
#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.
+These debug records replace the prior :ref:`debug intrinsics<dbg_intrinsics>`.
+Debug records will be disabled if ``--write-experimental-debuginfo=false`` 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:
diff --git a/llvm/docs/MIRLangRef.rst b/llvm/docs/MIRLangRef.rst
index e248a14636a86..76d57767e5642 100644
--- a/llvm/docs/MIRLangRef.rst
+++ b/llvm/docs/MIRLangRef.rst
@@ -869,16 +869,16 @@ Where:
- ``debug-info-location`` identifies a DILocation metadata node.
-These metadata attributes correspond to the operands of a ``llvm.dbg.declare``
-IR intrinsic, see the :ref:`source level debugging<format_common_intrinsics>`
-documentation.
+These metadata attributes correspond to the operands of a ``#dbg_declare``
+IR debug record, see the :ref:`source level
+debugging<debug_records>` documentation.
Varying variable locations
^^^^^^^^^^^^^^^^^^^^^^^^^^
Variables that are not always on the stack or change location are specified
with the ``DBG_VALUE`` meta machine instruction. It is synonymous with the
-``llvm.dbg.value`` IR intrinsic, and is written:
+``#dbg_value`` IR record, and is written:
.. code-block:: text
diff --git a/llvm/docs/Passes.rst b/llvm/docs/Passes.rst
index 2edad5cd3c881..49f633e98d16f 100644
--- a/llvm/docs/Passes.rst
+++ b/llvm/docs/Passes.rst
@@ -935,8 +935,9 @@ declarations and removes them. Dead declarations are declarations of functions
for which no implementation is available (i.e., declarations for unused library
functions).
-``strip-debug-declare``: Strip all ``llvm.dbg.declare`` intrinsics
-------------------------------------------------------------------
+``strip-debug-declare``: Strip all ``llvm.dbg.declare`` intrinsics and
+``#dbg_declare`` records.
+-------------------------------------------------------------------
Performs code stripping. Similar to strip, but only strips
``llvm.dbg.declare`` intrinsics.
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 26f1d33f68009..731a310e9b473 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -55,6 +55,10 @@ Changes to the LLVM IR
* Renamed ``llvm.experimental.vector.splice`` intrinsic to ``llvm.vector.splice``.
* Renamed ``llvm.experimental.vector.interleave2`` intrinsic to ``llvm.vector.interleave2``.
* Renamed ``llvm.experimental.vector.deinterleave2`` intrinsic to ``llvm.vector.deinterleave2``.
+* LLVM has switched from using debug intrinsics in textual IR to using debug
+ records by default. Details of the change and instructions on how to update
+ any downstream tools and tests can be found in the `migration docs
+ <https://llvm.org/docs/RemoveDIsDebugInfo.html>`_.
Changes to LLVM infrastructure
------------------------------
diff --git a/llvm/docs/SourceLevelDebugging.rst b/llvm/docs/SourceLevelDebugging.rst
index 7f7e595eb14df..adf0083391a9a 100644
--- a/llvm/docs/SourceLevelDebugging.rst
+++ b/llvm/docs/SourceLevelDebugging.rst
@@ -43,7 +43,7 @@ important ones are:
debuggers, like GDB or DBX.
The approach used by the LLVM implementation is to use a small set of
-:ref:`intrinsic functions <format_common_intrinsics>` to define a mapping
+:ref:`debug records <debug_records>` to define a mapping
between LLVM program objects and the source-level objects. The description of
the source-level program is maintained in LLVM metadata in an
:ref:`implementation-defined format <ccxx_frontend>` (the C/C++ front-end
@@ -169,83 +169,96 @@ Debug information descriptors are `specialized metadata nodes
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``.
+generation: :ref:`debug records <debug_records>`, the current default, and
+:ref:`intrinsic function calls <format_common_intrinsics>`, which are
+non-default but currently supported for backwards compatibility - though these
+two models must never be mixed within an IR module.
-.. _format_common_intrinsics:
+.. _debug_records:
-Debugger intrinsic functions
+Debug Records
----------------------------
-LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
-track source local variables through optimization and code generation.
+Debug records define the value that a source variable has during execution of
+the program; they appear interleaved with instructions, although they are not
+instructions themselves and have no effect on the code generated by the
+compiler.
-``llvm.dbg.declare``
-^^^^^^^^^^^^^^^^^^^^
+LLVM uses several types of debug records to define source variables. The
+common syntax for these records is:
.. code-block:: llvm
- void @llvm.dbg.declare(metadata, metadata, metadata)
+ #dbg_<kind>([<arg>, ]* <DILocation>)
+ ; Using the intrinsic model, the above is equivalent to:
+ call void llvm.dbg.<kind>([metadata <arg>, ]*), !dbg <DILocation>
+
+Debug records are always printed with an extra level of indentation compared
+to instructions, and always have the prefix `#dbg_` and a list of
+comma-separated arguments in parentheses, as with a `call`.
+
+``#dbg_declare``
+^^^^^^^^^^^^^^^^
+
+.. code-block:: llvm
+
+ #dbg_declare([Value|MDNode], DILocalVariable, DIExpression, DILocation)
-This intrinsic provides information about a local element (e.g., variable).
-The first argument is metadata holding the address of variable, typically a
-static alloca in the function entry block. The second argument is a
+This record provides information about a local element (e.g., variable).
+The first argument is an SSA value corresponding to a variable address, and is
+typically a static alloca in the function entry block. The second argument is a
`local variable <LangRef.html#dilocalvariable>`_ containing a description of
the variable. The third argument is a `complex expression
-<LangRef.html#diexpression>`_. An `llvm.dbg.declare` intrinsic describes the
+<LangRef.html#diexpression>`_. The fourth argument is a `source location
+<LangRef.html#dilocation>`_. A ``#dbg_declare`` record describes the
*address* of a source variable.
-.. code-block:: text
+.. code-block:: llvm
%i.addr = alloca i32, align 4
- call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1,
- metadata !DIExpression()), !dbg !2
+ #dbg_declare(ptr %i.addr, !1, !DIExpression(), !2)
+ ; ...
!1 = !DILocalVariable(name: "i", ...) ; int i
!2 = !DILocation(...)
- ...
+ ; ...
%buffer = alloca [256 x i8], align 8
; The address of i is buffer+64.
- call void @llvm.dbg.declare(metadata [256 x i8]* %buffer, metadata !3,
- metadata !DIExpression(DW_OP_plus, 64)), !dbg !4
+ #dbg_declare(ptr %buffer, !3, !DIExpression(DW_OP_plus, 64), !4)
+ ; ...
!3 = !DILocalVariable(name: "i", ...) ; int i
!4 = !DILocation(...)
-A frontend should generate exactly one call to ``llvm.dbg.declare`` at the point
+A frontend should generate exactly one ``#dbg_declare`` record at the point
of declaration of a source variable. Optimization passes that fully promote the
-variable from memory to SSA values will replace this call with possibly multiple
-calls to `llvm.dbg.value`. Passes that delete stores are effectively partial
-promotion, and they will insert a mix of calls to ``llvm.dbg.value`` to track
-the source variable value when it is available. After optimization, there may be
-multiple calls to ``llvm.dbg.declare`` describing the program points where the
-variables lives in memory. All calls for the same concrete source variable must
-agree on the memory location.
+variable from memory to SSA values will replace this record with possibly
+multiple ``#dbg_value``` records. Passes that delete stores are effectively
+partial promotion, and they will insert a mix of ``#dbg_value`` records to
+track the source variable value when it is available. After optimization, there
+may be multiple ``#dbg_declare`` records describing the program points where
+the variables lives in memory. All calls for the same concrete source variable
+must agree on the memory location.
-``llvm.dbg.value``
-^^^^^^^^^^^^^^^^^^
+``#dbg_value``
+^^^^^^^^^^^^^^
.. code-block:: llvm
- void @llvm.dbg.value(metadata, metadata, metadata)
+ #dbg_value([Value|DIArgList|MDNode], DILocalVariable, DIExpression, DILocation)
-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
-argument is a `local variable <LangRef.html#dilocalvariable>`_ containing a
-description of the variable. The third argument is a `complex expression
-<LangRef.html#diexpression>`_.
+This record provides information when a user source variable is set to a new
+value. The first argument is the new value. The second argument is a `local
+variable <LangRef.html#dilocalvariable>`_ containing a description of the
+variable. The third argument is a `complex expression
+<LangRef.html#diexpression>`_. The fourth argument is a `source location
+<LangRef.html#dilocation>`_.
-An `llvm.dbg.value` intrinsic describes the *value* of a source variable
+A ``#dbg_value`` record describes the *value* of a source variable
directly, not its address. Note that the value operand of this intrinsic may
be indirect (i.e, a pointer to the source variable), provided that interpreting
the complex expression derives the direct value.
-``llvm.dbg.assign``
+``#dbg_assign``
^^^^^^^^^^^^^^^^^^^
.. toctree::
:hidden:
@@ -254,85 +267,87 @@ 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)
+ #dbg_assign( [Value|DIArgList|MDNode] Value,
+ DILocalVariable Variable,
+ DIExpression ValueExpression,
+ DIAssignID ID,
+ [Value|MDNode] Address,
+ DIExpression AddressExpression,
+ DILocation SourceLocation )
-This intrinsic marks the position in IR where a source assignment occurred. It
+This record marks the position in IR where a source assignment occurred. It
encodes the value of the variable. It references the store, if any, that
performs the assignment, and the destination address.
-The first three arguments are the same as for an ``llvm.dbg.value``. The fourth
+The first three arguments are the same as for a ``#dbg_value``. The fourth
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.
+destination of the store, the sixth is a `complex
+expression <LangRef.html#diexpression>`_ that modfies it, and the seventh is a
+`source location<LangRef.html#dilocation>`_.
-The formal LLVM-IR signature is:
+See :doc:`AssignmentTracking` for more info.
-.. code-block:: llvm
+Debugger intrinsic functions
+----------------------------
- void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+.. _format_common_intrinsics:
+In intrinsic-mode, LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
+track source local variables through optimization and code generation. These
+intrinsic functions each correspond to one of the debug records above, with a
+few syntactic differences: each argument to a debugger intrinsic must be wrapped
+as metadata, meaning it must be prefixed with ``metadata ``, and the
+``DILocation`` argument in each record must be a metadata attachment to the
+call instruction, meaning it appears after the argument list with the prefix
+``!dbg ``.
-See :doc:`AssignmentTracking` for more info.
+``llvm.dbg.declare``
+^^^^^^^^^^^^^^^^^^^^
-.. _debug_records:
+.. code-block:: llvm
-Debug Records
-----------------------------
+ void @llvm.dbg.declare(metadata, metadata, metadata)
-LLVM also has an alternative to intrinsic functions, debug records, which
-function similarly but are not instructions. The basic syntax for debug records
-is:
+This intrinsic is equivalent to ``#dbg_declare``:
.. 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>
+ #dbg_declare(i32* %i.addr, !1, !DIExpression(), !2)
+ call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1,
+ metadata !DIExpression()), !dbg !2
-A debug intrinsic function can be converted to a debug record with the
-following steps:
+``llvm.dbg.value``
+^^^^^^^^^^^^^^^^^^
-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``.
+.. code-block:: llvm
-For each kind of intrinsic function, there is an equivalent debug record.
+ void @llvm.dbg.value(metadata, metadata, metadata)
-``#dbg_declare``
-^^^^^^^^^^^^^^^^
+This intrinsic is equivalent to ``#dbg_value``:
.. code-block:: llvm
- #dbg_declare([Value|MDNode], DILocalVariable, DIExpression, DILocation)
-
-Equivalent to the ``llvm.dbg.declare`` intrinsic.
+ #dbg_value(i32 %i, !1, !DIExpression(), !2)
+ call void @llvm.dbg.value(metadata i32 %i, metadata !1,
+ metadata !DIExpression()), !dbg !2
-``#dbg_value``
-^^^^^^^^^^^^^^
+``llvm.dbg.assign``
+^^^^^^^^^^^^^^^^^^^
.. code-block:: llvm
- #dbg_value([Value|DIArgList|MDNode], DILocalVariable, DIExpression, DILocation)
-
-Equivalent to the ``llvm.dbg.value`` intrinsic.
+ void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
-``#dbg_assign``
-^^^^^^^^^^^^^^^
+This intrinsic is equivalent to ``#dbg_assign``:
.. code-block:: llvm
- #dbg_assign([Value|DIArgList|MDNode], DILocalVariable, DIExpression,
- DIAssignID, [Value|MDNode], DIExpression, DILocation)
+ #dbg_assign(i32 %i, !1, !DIExpression(), !2,
+ ptr %i.addr, !DIExpression(), !3)
+ call void @llvm.dbg.assign(
+ metadata i32 %i, metadata !1, metadata !DIExpression(), metadata !2,
+ metadata ptr %i.addr, metadata !DIExpression(), metadata !3), !dbg !3
-Equivalent to the ``llvm.dbg.assign`` intrinsic.
Object lifetimes and scoping
============================
@@ -371,11 +386,11 @@ Compiled to LLVM, this function would be represented like this:
%X = alloca i32, align 4
%Y = alloca i32, align 4
%Z = alloca i32, align 4
- call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14
+ #dbg_declare(ptr %X, !11, !DIExpression(), !14)
store i32 21, i32* %X, align 4, !dbg !14
- call void @llvm.dbg.declare(metadata i32* %Y, metadata !15, metadata !13), !dbg !16
+ #dbg_declare(ptr %Y, !15, !DIExpression(), !16)
store i32 22, i32* %Y, align 4, !dbg !16
- call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19
+ #dbg_declare(ptr %Z, !17, !DIExpression(), !19)
store i32 23, i32* %Z, align 4, !dbg !19
%0 = load i32, i32* %X, align 4, !dbg !20
store i32 %0, i32* %Z, align 4, !dbg !21
@@ -384,9 +399,6 @@ Compiled to LLVM, this function would be represented like this:
ret void, !dbg !24
}
- ; Function Attrs: nounwind readnone
- declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
-
attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
@@ -407,33 +419,32 @@ Compiled to LLVM, this function would be represented like this:
!10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
!11 = !DILocalVariable(name: "X", scope: !4, file: !1, line: 2, type: !12)
!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
- !13 = !DIExpression()
- !14 = !DILocation(line: 2, column: 9, scope: !4)
- !15 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12)
- !16 = !DILocation(line: 3, column: 9, scope: !4)
- !17 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12)
- !18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
- !19 = !DILocation(line: 5, column: 11, scope: !18)
- !20 = !DILocation(line: 6, column: 11, scope: !18)
- !21 = !DILocation(line: 6, column: 9, scope: !18)
- !22 = !DILocation(line: 8, column: 9, scope: !4)
- !23 = !DILocation(line: 8, column: 7, scope: !4)
- !24 = !DILocation(line: 9, column: 3, scope: !4)
+ !13 = !DILocation(line: 2, column: 9, scope: !4)
+ !14 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12)
+ !15 = !DILocation(line: 3, column: 9, scope: !4)
+ !16 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12)
+ !17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
+ !18 = !DILocation(line: 5, column: 11, scope: !18)
+ !29 = !DILocation(line: 6, column: 11, scope: !18)
+ !20 = !DILocation(line: 6, column: 9, scope: !18)
+ !21 = !DILocation(line: 8, column: 9, scope: !4)
+ !22 = !DILocation(line: 8, column: 7, scope: !4)
+ !23 = !DILocation(line: 9, column: 3, scope: !4)
This example illustrates a few important details about LLVM debugging
-information. In particular, it shows how the ``llvm.dbg.declare`` intrinsic and
+information. In particular, it shows how the ``#dbg_declare`` record and
location information, which are attached to an instruction, are applied
together to allow a debugger to analyze the relationship between statements,
variable definitions, and the code used to implement the function.
.. code-block:: llvm
- call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14
+ #dbg_declare(ptr %X, !11, !DIExpression(), !14)
; [debug line = 2:7] [debug variable = X]
-The first intrinsic ``%llvm.dbg.declare`` encodes debugging information for the
-variable ``X``. The metadata ``!dbg !14`` attached to the intrinsic provides
+The first record ``#dbg_declare`` encodes debugging information for the
+variable ``X``. The location ``!14`` at the end of the record provides
scope information for the variable ``X``.
.. code-block:: text
@@ -446,18 +457,18 @@ scope information for the variable ``X``.
Here ``!14`` is metadata providing `location information
<LangRef.html#dilocation>`_. In this example, scope is encoded by ``!4``, a
`subprogram descriptor <LangRef.html#disubprogram>`_. This way the location
-information attached to the intrinsics indicates that the variable ``X`` is
+information parameter to the records indicates that the variable ``X`` is
declared at line number 2 at a function level scope in function ``foo``.
Now lets take another example.
.. code-block:: llvm
- call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19
+ #dbg_declare(ptr %Z, !17, !DIExpression(), !19)
; [debug line = 5:9] [debug variable = Z]
-The third intrinsic ``%llvm.dbg.declare`` encodes debugging information for
-variable ``Z``. The metadata ``!dbg !19`` attached to the intrinsic provides
+The third record ``#dbg_declare`` encodes debugging information for
+variable ``Z``. The metadata ``!19`` at the end of the record provides
scope information for the variable ``Z``.
.. code-block:: text
@@ -479,18 +490,18 @@ In the example above, every variable assignment uniquely corresponds to a
memory store to the variable's position on the stack. However in heavily
optimized code LLVM promotes most variables into SSA values, which can
eventually be placed in physical registers or memory locations. To track SSA
-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:
+values through compilation, when objects are promoted to SSA values a
+``#dbg_value`` record is created for each assignment, recording the
+variable's new location. Compared with the ``#dbg_declare`` record:
-* A dbg.value terminates the effect of any preceding dbg.values for (any
+* 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 #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.
-Care must be taken to update ``llvm.dbg.value`` intrinsics when optimization
+Care must be taken to update ``#dbg_value`` records when optimization
passes alter or move instructions and blocks -- the developer could observe such
changes reflected in the value of variables when debugging the program. For any
execution of the optimized program, the set of variable values presented to the
@@ -501,7 +512,7 @@ damaging their understanding of the optimized program and undermining their
trust in the debugger.
Sometimes perfectly preserving variable locations is not possible, often when a
-redundant calculation is optimized out. In such cases, a ``llvm.dbg.value``
+redundant calculation is optimized out. In such cases, a ``#dbg_value``
with operand ``poison`` should be used, to terminate earlier variable locations
and let the debugger present ``optimized out`` to the developer. Withholding
these potentially stale variable values from the developer diminishes the
@@ -514,26 +525,26 @@ To illustrate some potential issues, consider the following example:
define i32 @foo(i32 %bar, i1 %cond) {
entry:
- call @llvm.dbg.value(metadata i32 0, metadata !1, metadata !2)
+ #dbg_value(i32 0, !1, !DIExpression(), !4)
br i1 %cond, label %truebr, label %falsebr
truebr:
%tval = add i32 %bar, 1
- call @llvm.dbg.value(metadata i32 %tval, metadata !1, metadata !2)
+ #dbg_value(i32 %tval, !1, !DIExpression(), !4)
%g1 = call i32 @gazonk()
br label %exit
falsebr:
%fval = add i32 %bar, 2
- call @llvm.dbg.value(metadata i32 %fval, metadata !1, metadata !2)
+ #dbg_value(i32 %fval, !1, !DIExpression(), !4)
%g2 = call i32 @gazonk()
br label %exit
exit:
%merge = phi [ %tval, %truebr ], [ %fval, %falsebr ]
%g = phi [ %g1, %truebr ], [ %g2, %falsebr ]
- call @llvm.dbg.value(metadata i32 %merge, metadata !1, metadata !2)
- call @llvm.dbg.value(metadata i32 %g, metadata !3, metadata !2)
+ #dbg_value(i32 %merge, !1, !DIExpression(), !4)
+ #dbg_value(i32 %g, !3, !DIExpression(), !4)
%plusten = add i32 %merge, 10
%toret = add i32 %plusten, %g
- call @llvm.dbg.value(metadata i32 %toret, metadata !1, metadata !2)
+ #dbg_value(i32 %toret, !1, !DIExpression(), !4)
ret i32 %toret
}
@@ -551,48 +562,48 @@ perhaps, be optimized into the following code:
ret i32 %toret
}
-What ``llvm.dbg.value`` intrinsics should be placed to represent the original variable
+What ``#dbg_value`` records should be placed to represent the original variable
locations in this code? Unfortunately the second, third and fourth
-dbg.values for ``!1`` in the source function have had their operands
+#dbg_values for ``!1`` in the source function have had their operands
(%tval, %fval, %merge) optimized out. Assuming we cannot recover them, we
-might consider this placement of dbg.values:
+might consider this placement of #dbg_values:
.. code-block:: llvm
define i32 @foo(i32 %bar, i1 %cond) {
entry:
- call @llvm.dbg.value(metadata i32 0, metadata !1, metadata !2)
+ #dbg_value(i32 0, !1, !DIExpression(), !4)
%g = call i32 @gazonk()
- call @llvm.dbg.value(metadata i32 %g, metadata !3, metadata !2)
+ #dbg_value(i32 %g, !3, !DIExpression(), !4)
%addoper = select i1 %cond, i32 11, i32 12
%plusten = add i32 %bar, %addoper
%toret = add i32 %plusten, %g
- call @llvm.dbg.value(metadata i32 %toret, metadata !1, metadata !2)
+ #dbg_value(i32 %toret, !1, !DIExpression(), !4)
ret i32 %toret
}
However, this will cause ``!3`` to have the return value of ``@gazonk()`` at
the same time as ``!1`` has the constant value zero -- a pair of assignments
that never occurred in the unoptimized program. To avoid this, we must terminate
-the range that ``!1`` has the constant value assignment by inserting a poison
-dbg.value before the dbg.value for ``!3``:
+the range that ``!1`` has the constant value assignment by inserting an poison
+#dbg_value before the #dbg_value for ``!3``:
.. code-block:: llvm
define i32 @foo(i32 %bar, i1 %cond) {
entry:
- call @llvm.dbg.value(metadata i32 0, metadata !1, metadata !2)
+ #dbg_value(i32 0, !1, !DIExpression(), !2)
%g = call i32 @gazonk()
- call @llvm.dbg.value(metadata i32 poison, metadata !1, metadata !2)
- call @llvm.dbg.value(metadata i32 %g, metadata !3, metadata !2)
+ #dbg_value(i32 poison, !1, !DIExpression(), !2)
+ #dbg_value(i32 %g, !3, !DIExpression(), !2)
%addoper = select i1 %cond, i32 11, i32 12
%plusten = add i32 %bar, %addoper
%toret = add i32 %plusten, %g
- call @llvm.dbg.value(metadata i32 %toret, metadata !1, metadata !2)
+ #dbg_value(i32 %toret, !1, !DIExpression(), !2)
ret i32 %toret
}
-There are a few other dbg.value configurations that mean it terminates
+There are a few other #dbg_value configurations that mean it terminates
dominating location definitions without adding a new location. The complete
list is:
@@ -602,16 +613,16 @@ list is:
* There are no location operands (empty ``DIArgList``) and the ``DIExpression``
is empty.
-This class of dbg.value that kills variable locations is called a "kill
-dbg.value" or "kill location", and for legacy reasons the term "undef
-dbg.value" may be used in existing code. The ``DbgVariableIntrinsic`` methods
+This class of #dbg_value that kills variable locations is called a "kill
+#dbg_value" or "kill location", and for legacy reasons the term "undef
+#dbg_value" may be used in existing code. The ``DbgVariableIntrinsic`` methods
``isKillLocation`` and ``setKillLocation`` should be used where possible rather
-than inspecting location operands directly to check or set whether a dbg.value
+than inspecting location operands directly to check or set whether a #dbg_value
is a kill location.
-In general, if any dbg.value has its operand optimized out and cannot be
-recovered, then a kill dbg.value is necessary to terminate earlier variable
-locations. Additional kill dbg.values may be necessary when the debugger can
+In general, if any #dbg_value has its operand optimized out and cannot be
+recovered, then a kill #dbg_value is necessary to terminate earlier variable
+locations. Additional kill #dbg_values may be necessary when the debugger can
observe re-ordering of assignments.
How variable location metadata is transformed during CodeGen
@@ -622,9 +633,9 @@ ultimately producing a mapping between source-level information and
instruction ranges. This
is relatively straightforwards for line number information, as mapping
instructions to line numbers is a simple association. For variable locations
-however the story is more complex. As each ``llvm.dbg.value`` intrinsic
+however the story is more complex. As each ``#dbg_value`` record
represents a source-level assignment of a value to a source variable, the
-variable location intrinsics effectively embed a small imperative program
+debug records effectively embed a small imperative program
within the LLVM IR. By the end of CodeGen, this becomes a mapping from each
variable to their machine locations over ranges of instructions.
From IR to object emission, the major transformations which affect variable
@@ -639,7 +650,7 @@ significantly change the ordering of the program, and occurs in a number of
different passes.
Some variable locations are not transformed during CodeGen. Stack locations
-specified by ``llvm.dbg.declare`` are valid and unchanging for the entire
+specified by ``#dbg_declare`` are valid and unchanging for the entire
duration of the function, and are recorded in a simple MachineFunction table.
Location changes in the prologue and epilogue of a function are also ignored:
frame setup and destruction may take several instructions, require a
@@ -668,11 +679,11 @@ otherwise transformed into a non-register, the variable location becomes
unavailable.
Locations that are unavailable are treated as if they have been optimized out:
-in IR the location would be assigned ``undef`` by a debug intrinsic, and in MIR
+in IR the location would be assigned ``undef`` by a debug record, and in MIR
the equivalent location is used.
After MIR locations are assigned to each variable, machine pseudo-instructions
-corresponding to each ``llvm.dbg.value`` intrinsic are inserted. There are two
+corresponding to each ``#dbg_value`` record are inserted. There are two
forms of this type of instruction.
The first form, ``DBG_VALUE``, appears thus:
@@ -684,14 +695,14 @@ The first form, ``DBG_VALUE``, appears thus:
And has the following operands:
* The first operand can record the variable location as a register,
a frame index, an immediate, or the base address register if the original
- debug intrinsic referred to memory. ``$noreg`` indicates the variable
- location is undefined, equivalent to an ``undef`` dbg.value operand.
+ debug record referred to memory. ``$noreg`` indicates the variable
+ location is undefined, equivalent to an ``undef`` #dbg_value operand.
* The type of the second operand indicates whether the variable location is
directly referred to by the DBG_VALUE, or whether it is indirect. The
``$noreg`` register signifies the former, an immediate operand (0) the
latter.
- * Operand 3 is the Variable field of the original debug intrinsic.
- * Operand 4 is the Expression field of the original debug intrinsic.
+ * Operand 3 is the Variable field of the original debug record.
+ * Operand 4 is the Expression field of the original debug record.
The second form, ``DBG_VALUE_LIST``, appears thus:
@@ -700,8 +711,8 @@ The second form, ``DBG_VALUE_LIST``, appears thus:
DBG_VALUE_LIST !123, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %1, %2
And has the following operands:
- * The first operand is the Variable field of the original debug intrinsic.
- * The second operand is the Expression field of the original debug intrinsic.
+ * The first operand is the Variable field of the original debug record.
+ * The second operand is the Expression field of the original debug record.
* Any number of operands, from the 3rd onwards, record a sequence of variable
location operands, which may take any of the same values as the first
operand of the ``DBG_VALUE`` instruction above. These variable location
@@ -710,7 +721,7 @@ And has the following operands:
<LangRef.html#diexpression>`_.
The position at which the DBG_VALUEs are inserted should correspond to the
-positions of their matching ``llvm.dbg.value`` intrinsics in the IR block. As
+positions of their matching ``#dbg_value`` records in the IR block. As
with optimization, LLVM aims to preserve the order in which variable
assignments occurred in the source program. However SelectionDAG performs some
instruction scheduling, which can reorder assignments (discussed below).
@@ -724,20 +735,20 @@ the following example:
define i32 @foo(i32* %addr) {
entry:
- call void @llvm.dbg.value(metadata i32 0, metadata !3, metadata !DIExpression()), !dbg !5
+ #dbg_value(i32 0, !3, !DIExpression(), !5)
br label %bb1, !dbg !5
bb1: ; preds = %bb1, %entry
%bar.0 = phi i32 [ 0, %entry ], [ %add, %bb1 ]
- call void @llvm.dbg.value(metadata i32 %bar.0, metadata !3, metadata !DIExpression()), !dbg !5
+ #dbg_value(i32 %bar.0, !3, !DIExpression(), !5)
%addr1 = getelementptr i32, i32 *%addr, i32 1, !dbg !5
- call void @llvm.dbg.value(metadata i32 *%addr1, metadata !3, metadata !DIExpression()), !dbg !5
+ #dbg_value(i32 *%addr1, !3, !DIExpression(), !5)
%loaded1 = load i32, i32* %addr1, !dbg !5
%addr2 = getelementptr i32, i32 *%addr, i32 %bar.0, !dbg !5
- call void @llvm.dbg.value(metadata i32 *%addr2, metadata !3, metadata !DIExpression()), !dbg !5
+ #dbg_value(i32 *%addr2, !3, !DIExpression(), !5)
%loaded2 = load i32, i32* %addr2, !dbg !5
%add = add i32 %bar.0, 1, !dbg !5
- call void @llvm.dbg.value(metadata i32 %add, metadata !3, metadata !DIExpression()), !dbg !5
+ #dbg_value(i32 %add, !3, !DIExpression(), !5)
%added = add i32 %loaded1, %loaded2
%cond = icmp ult i32 %added, %bar.0, !dbg !5
br i1 %cond, label %bb1, label %bb2, !dbg !5
@@ -779,12 +790,12 @@ If one compiles this IR with ``llc -o - -start-after=codegen-prepare -stop-after
$eax = COPY %8, debug-location !5
RET 0, $eax, debug-location !5
-Observe first that there is a DBG_VALUE instruction for every ``llvm.dbg.value``
-intrinsic in the source IR, ensuring no source level assignments go missing.
+Observe first that there is a DBG_VALUE instruction for every ``#dbg_value``
+record in the source IR, ensuring no source level assignments go missing.
Then consider the different ways in which variable locations have been recorded:
-* For the first dbg.value an immediate operand is used to record a zero value.
-* The dbg.value of the PHI instruction leads to a DBG_VALUE of virtual register
+* For the first #dbg_value an immediate operand is used to record a zero value.
+* The #dbg_value of the PHI instruction leads to a DBG_VALUE of virtual register
``%0``.
* The first GEP has its effect folded into the first load instruction
(as a 4-byte offset), but the variable location is salvaged by folding
@@ -792,7 +803,7 @@ Then consider the different ways in which variable locations have been recorded:
* The second GEP is also folded into the corresponding load. However, it is
insufficiently simple to be salvaged, and is emitted as a ``$noreg``
DBG_VALUE, indicating that the variable takes on an undefined location.
-* The final dbg.value has its Value placed in virtual register ``%1``.
+* The final #dbg_value has its Value placed in virtual register ``%1``.
Instruction Scheduling
----------------------
@@ -899,14 +910,14 @@ presents several difficulties:
br label %exit, !dbg !26
truebr:
- call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !24
- call void @llvm.dbg.value(metadata i32 1, metadata !23, metadata !DIExpression()), !dbg !24
+ #dbg_value(i32 %input, !30, !DIExpression(), !24)
+ #dbg_value(i32 1, !23, !DIExpression(), !24)
%value1 = add i32 %input, 1
br label %bb1
falsebr:
- call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !24
- call void @llvm.dbg.value(metadata i32 2, metadata !23, metadata !DIExpression()), !dbg !24
+ #dbg_value(i32 %input, !30, !DIExpression(), !24)
+ #dbg_value(i32 2, !23, !DIExpression(), !24)
%value2 = add i32 %input, 2
br label %bb1
@@ -920,13 +931,13 @@ Here the difficulties are:
* The value of the ``!23`` variable merges into ``%bb1``, but there is no PHI
node
-As mentioned above, the ``llvm.dbg.value`` intrinsics essentially form an
-imperative program embedded in the IR, with each intrinsic defining a variable
+As mentioned above, the ``#dbg_value`` records essentially form an
+imperative program embedded in the IR, with each record defining a variable
location. This *could* be converted to an SSA form by mem2reg, in the same way
that it uses use-def chains to identify control flow merges and insert phi
nodes for IR Values. However, because debug variable locations are defined for
every machine instruction, in effect every IR instruction uses every variable
-location, which would lead to a large number of debugging intrinsics being
+location, which would lead to a large number of debugging records being
generated.
Examining the example above, variable ``!30`` is assigned ``%input`` on both
@@ -935,8 +946,8 @@ constant values on either path. Where control flow merges in ``%bb1`` we would
want ``!30`` to keep its location (``%input``), but ``!23`` to become undefined
as we cannot determine at runtime what value it should have in %bb1 without
inserting a PHI node. mem2reg does not insert the PHI node to avoid changing
-codegen when debugging is enabled, and does not insert the other dbg.values
-to avoid adding very large numbers of intrinsics.
+codegen when debugging is enabled, and does not insert the other #dbg_values
+to avoid adding very large numbers of records.
Instead, LiveDebugValues determines variable locations when control
flow merges. A dataflow analysis is used to propagate locations between blocks:
diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst
index d9f11dd6d7790..c75d8814918aa 100644
--- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst
+++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst
@@ -416,7 +416,7 @@ argument allocas in ``FunctionAST::codegen``.
Here we're first creating the variable, giving it the scope (``SP``),
the name, source location, type, and since it's an argument, the argument
-index. Next, we create an ``lvm.dbg.declare`` call to indicate at the IR
+index. Next, we create a ``#dbg_declare`` record to indicate at the IR
level that we've got a variable in an alloca (and it gives a starting
location for the variable), and setting a source location for the
beginning of the scope on the declare.
More information about the llvm-commits
mailing list