| ======================================================= | 
 | How to Update Debug Info: A Guide for LLVM Pass Authors | 
 | ======================================================= | 
 |  | 
 | .. contents:: | 
 |    :local: | 
 |  | 
 | Introduction | 
 | ============ | 
 |  | 
 | Certain kinds of code transformations can inadvertently result in a loss of | 
 | debug info, or worse, make debug info misrepresent the state of a program. | 
 |  | 
 | This document specifies how to correctly update debug info in various kinds of | 
 | code transformations, and offers suggestions for how to create targeted debug | 
 | info tests for arbitrary transformations. | 
 |  | 
 | For more on the philosophy behind LLVM debugging information, see | 
 | :doc:`SourceLevelDebugging`. | 
 |  | 
 | Rules for updating debug locations | 
 | ================================== | 
 |  | 
 | .. _WhenToPreserveLocation: | 
 |  | 
 | When to preserve an instruction location | 
 | ---------------------------------------- | 
 |  | 
 | A transformation should preserve the debug location of an instruction if the | 
 | instruction either remains in its basic block, or if its basic block is folded | 
 | into a predecessor that branches unconditionally. The APIs to use are | 
 | ``IRBuilder``, or ``Instruction::setDebugLoc``. | 
 |  | 
 | The purpose of this rule is to ensure that common block-local optimizations | 
 | preserve the ability to set breakpoints on source locations corresponding to | 
 | the instructions they touch. Debugging, crash logs, and SamplePGO accuracy | 
 | would be severely impacted if that ability were lost. | 
 |  | 
 | Examples of transformations that should follow this rule include: | 
 |  | 
 | * Instruction scheduling. Block-local instruction reordering should not drop | 
 |   source locations, even though this may lead to jumpy single-stepping | 
 |   behavior. | 
 |  | 
 | * Simple jump threading. For example, if block ``B1`` unconditionally jumps to | 
 |   ``B2``, *and* is its unique predecessor, instructions from ``B2`` can be | 
 |   hoisted into ``B1``. Source locations from ``B2`` should be preserved. | 
 |  | 
 | * Peephole optimizations that replace or expand an instruction, like ``(add X | 
 |   X) => (shl X 1)``. The location of the ``shl`` instruction should be the same | 
 |   as the location of the ``add`` instruction. | 
 |  | 
 | * Tail duplication. For example, if blocks ``B1`` and ``B2`` both | 
 |   unconditionally branch to ``B3`` and ``B3`` can be folded into its | 
 |   predecessors, source locations from ``B3`` should be preserved. | 
 |  | 
 | Examples of transformations for which this rule *does not* apply include: | 
 |  | 
 | * LICM. E.g., if an instruction is moved from the loop body to the preheader, | 
 |   the rule for :ref:`dropping locations<WhenToDropLocation>` applies. | 
 |  | 
 | .. _WhenToMergeLocation: | 
 |  | 
 | When to merge instruction locations | 
 | ----------------------------------- | 
 |  | 
 | A transformation should merge instruction locations if it replaces multiple | 
 | instructions with a single merged instruction, *and* that merged instruction | 
 | does not correspond to any of the original instructions' locations. The API to | 
 | use is ``Instruction::applyMergedLocation``. | 
 |  | 
 | The purpose of this rule is to ensure that a) the single merged instruction | 
 | has a location with an accurate scope attached, and b) to prevent misleading | 
 | single-stepping (or breakpoint) behavior. Often, merged instructions are memory | 
 | accesses which can trap: having an accurate scope attached greatly assists in | 
 | crash triage by identifying the (possibly inlined) function where the bad | 
 | memory access occurred. This rule is also meant to assist SamplePGO by banning | 
 | scenarios in which a sample of a block containing a merged instruction is | 
 | misattributed to a block containing one of the instructions-to-be-merged. | 
 |  | 
 | Examples of transformations that should follow this rule include: | 
 |  | 
 | * Merging identical loads/stores which occur on both sides of a CFG diamond | 
 |   (see the ``MergedLoadStoreMotion`` pass). | 
 |  | 
 | * Merging identical loop-invariant stores (see the LICM utility | 
 |   ``llvm::promoteLoopAccessesToScalars``). | 
 |  | 
 | * Peephole optimizations which combine multiple instructions together, like | 
 |   ``(add (mul A B) C) => llvm.fma.f32(A, B, C)``.  Note that the location of | 
 |   the ``fma`` does not exactly correspond to the locations of either the | 
 |   ``mul`` or the ``add`` instructions. | 
 |  | 
 | Examples of transformations for which this rule *does not* apply include: | 
 |  | 
 | * Block-local peepholes which delete redundant instructions, like | 
 |   ``(sext (zext i8 %x to i16) to i32) => (zext i8 %x to i32)``. The inner | 
 |   ``zext`` is modified but remains in its block, so the rule for | 
 |   :ref:`preserving locations<WhenToPreserveLocation>` should apply. | 
 |  | 
 | * Converting an if-then-else CFG diamond into a ``select``. Preserving the | 
 |   debug locations of speculated instructions can make it seem like a condition | 
 |   is true when it's not (or vice versa), which leads to a confusing | 
 |   single-stepping experience. The rule for | 
 |   :ref:`dropping locations<WhenToDropLocation>` should apply here. | 
 |  | 
 | * Hoisting identical instructions which appear in several successor blocks into | 
 |   a predecessor block (see ``BranchFolder::HoistCommonCodeInSuccs``). In this | 
 |   case there is no single merged instruction. The rule for | 
 |   :ref:`dropping locations<WhenToDropLocation>` applies. | 
 |  | 
 | .. _WhenToDropLocation: | 
 |  | 
 | When to drop an instruction location | 
 | ------------------------------------ | 
 |  | 
 | A transformation should drop debug locations if the rules for | 
 | :ref:`preserving<WhenToPreserveLocation>` and | 
 | :ref:`merging<WhenToMergeLocation>` debug locations do not apply. The API to | 
 | use is ``Instruction::setDebugLoc()``. | 
 |  | 
 | The purpose of this rule is to prevent erratic or misleading single-stepping | 
 | behavior in situations in which an instruction has no clear, unambiguous | 
 | relationship to a source location. | 
 |  | 
 | To handle an instruction without a location, the DWARF generator | 
 | defaults to allowing the last-set location after a label to cascade forward, or | 
 | to setting a line 0 location with viable scope information if no previous | 
 | location is available. | 
 |  | 
 | See the discussion in the section about | 
 | :ref:`merging locations<WhenToMergeLocation>` for examples of when the rule for | 
 | dropping locations applies. | 
 |  | 
 | Rules for updating debug values | 
 | =============================== | 
 |  | 
 | 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 | 
 | way to reconstitute the value of the lost instruction, this is the best | 
 | possible outcome. However, it's often possible to do better: | 
 |  | 
 | * If the dying instruction can be RAUW'd, do so. The | 
 |   ``Value::replaceAllUsesWith`` API transparently updates debug uses of the | 
 |   dying instruction to point to the replacement value. | 
 |  | 
 | * If the dying instruction cannot be RAUW'd, call ``llvm::salvageDebugInfo`` on | 
 |   it. This makes a best-effort attempt to rewrite debug uses of the dying | 
 |   instruction by describing its effect as a ``DIExpression``. | 
 |  | 
 | * If one of the **operands** of a dying instruction would become trivially | 
 |   dead, use ``llvm::replaceAllDbgUsesWith`` to rewrite the debug uses of that | 
 |   operand. Consider the following example function: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |   define i16 @foo(i16 %a) { | 
 |     %b = sext i16 %a to i32 | 
 |     %c = and i32 %b, 15 | 
 |     call void @llvm.dbg.value(metadata i32 %c, ...) | 
 |     %d = trunc i32 %c to i16 | 
 |     ret i16 %d | 
 |   } | 
 |  | 
 | Now, here's what happens after the unnecessary truncation instruction ``%d`` is | 
 | replaced with a simplified instruction: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |   define i16 @foo(i16 %a) { | 
 |     call void @llvm.dbg.value(metadata i32 undef, ...) | 
 |     %simplified = and i16 %a, 15 | 
 |     ret i16 %simplified | 
 |   } | 
 |  | 
 | Note that after deleting ``%d``, all uses of its operand ``%c`` become | 
 | trivially dead. The debug use which used to point to ``%c`` is now ``undef``, | 
 | and debug info is needlessly lost. | 
 |  | 
 | To solve this problem, do: | 
 |  | 
 | .. code-block:: cpp | 
 |  | 
 |   llvm::replaceAllDbgUsesWith(%c, theSimplifiedAndInstruction, ...) | 
 |  | 
 | This results in better debug info because the debug use of ``%c`` is preserved: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |   define i16 @foo(i16 %a) { | 
 |     %simplified = and i16 %a, 15 | 
 |     call void @llvm.dbg.value(metadata i16 %simplified, ...) | 
 |     ret i16 %simplified | 
 |   } | 
 |  | 
 | You may have noticed that ``%simplified`` is narrower than ``%c``: this is not | 
 | a problem, because ``llvm::replaceAllDbgUsesWith`` takes care of inserting the | 
 | necessary conversion operations into the DIExpressions of updated debug uses. | 
 |  | 
 | Deleting a MIR-level MachineInstr | 
 | --------------------------------- | 
 |  | 
 | TODO | 
 |  | 
 | How to automatically convert tests into debug info tests | 
 | ======================================================== | 
 |  | 
 | .. _IRDebugify: | 
 |  | 
 | Mutation testing for IR-level transformations | 
 | --------------------------------------------- | 
 |  | 
 | An IR test case for a transformation can, in many cases, be automatically | 
 | mutated to test debug info handling within that transformation. This is a | 
 | simple way to test for proper debug info handling. | 
 |  | 
 | The ``debugify`` utility | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | The ``debugify`` testing utility is just a pair of passes: ``debugify`` and | 
 | ``check-debugify``. | 
 |  | 
 | The first applies synthetic debug information to every instruction of the | 
 | 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. | 
 |  | 
 | For example, here is a module before: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |    define void @f(i32* %x) { | 
 |    entry: | 
 |      %x.addr = alloca i32*, align 8 | 
 |      store i32* %x, i32** %x.addr, align 8 | 
 |      %0 = load i32*, i32** %x.addr, align 8 | 
 |      store i32 10, i32* %0, align 4 | 
 |      ret void | 
 |    } | 
 |  | 
 | and after running ``opt -debugify``: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |    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 | 
 |      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 | 
 |      store i32 10, i32* %0, align 4, !dbg !15 | 
 |      ret void, !dbg !16 | 
 |    } | 
 |  | 
 |    !llvm.dbg.cu = !{!0} | 
 |    !llvm.debugify = !{!3, !4} | 
 |    !llvm.module.flags = !{!5} | 
 |  | 
 |    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) | 
 |    !1 = !DIFile(filename: "debugify-sample.ll", directory: "/") | 
 |    !2 = !{} | 
 |    !3 = !{i32 5} | 
 |    !4 = !{i32 2} | 
 |    !5 = !{i32 2, !"Debug Info Version", i32 3} | 
 |    !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8) | 
 |    !7 = !DISubroutineType(types: !2) | 
 |    !8 = !{!9, !11} | 
 |    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) | 
 |    !10 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_unsigned) | 
 |    !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 3, type: !10) | 
 |    !12 = !DILocation(line: 1, column: 1, scope: !6) | 
 |    !13 = !DILocation(line: 2, column: 1, scope: !6) | 
 |    !14 = !DILocation(line: 3, column: 1, scope: !6) | 
 |    !15 = !DILocation(line: 4, column: 1, scope: !6) | 
 |    !16 = !DILocation(line: 5, column: 1, scope: !6) | 
 |  | 
 | Using ``debugify`` | 
 | ^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | A simple way to use ``debugify`` is as follows: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |   $ opt -debugify -pass-to-test -check-debugify sample.ll | 
 |  | 
 | This will inject synthetic DI to ``sample.ll`` run the ``pass-to-test`` and | 
 | then check for missing DI. The ``-check-debugify`` step can of course be | 
 | omitted in favor of more customizable FileCheck directives. | 
 |  | 
 | Some other ways to run debugify are available: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |    # Same as the above example. | 
 |    $ opt -enable-debugify -pass-to-test sample.ll | 
 |  | 
 |    # Suppresses verbose debugify output. | 
 |    $ opt -enable-debugify -debugify-quiet -pass-to-test sample.ll | 
 |  | 
 |    # Prepend -debugify before and append -check-debugify -strip after | 
 |    # each pass on the pipeline (similar to -verify-each). | 
 |    $ opt -debugify-each -O2 sample.ll | 
 |  | 
 | In order for ``check-debugify`` to work, the DI must be coming from | 
 | ``debugify``. Thus, modules with existing DI will be skipped. | 
 |  | 
 | ``debugify`` can be used to test a backend, e.g: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |    $ opt -debugify < sample.ll | llc -o - | 
 |  | 
 | There is also a MIR-level debugify pass that can be run before each backend | 
 | pass, see: | 
 | :ref:`Mutation testing for MIR-level transformations<MIRDebugify>`. | 
 |  | 
 | ``debugify`` in regression tests | 
 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
 |  | 
 | The output of the ``debugify`` pass must be stable enough to use in regression | 
 | tests. Changes to this pass are not allowed to break existing tests. | 
 |  | 
 | .. note:: | 
 |  | 
 |    Regression tests must be robust. Avoid hardcoding line/variable numbers in | 
 |    check lines. In cases where this can't be avoided (say, if a test wouldn't | 
 |    be precise enough), moving the test to its own file is preferred. | 
 |  | 
 | .. _MIRDebugify: | 
 |  | 
 | Mutation testing for MIR-level transformations | 
 | ---------------------------------------------- | 
 |  | 
 | A variant of the ``debugify`` utility described in | 
 | :ref:`Mutation testing for IR-level transformations<IRDebugify>` can be used | 
 | for MIR-level transformations as well: much like the IR-level pass, | 
 | ``mir-debugify`` inserts sequentially increasing line locations to each | 
 | ``MachineInstr`` in a ``Module`` (although there is no equivalent MIR-level | 
 | ``check-debugify`` pass). | 
 |  | 
 | For example, here is a snippet before: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |   name:            test | 
 |   body:             | | 
 |     bb.1 (%ir-block.0): | 
 |       %0:_(s32) = IMPLICIT_DEF | 
 |       %1:_(s32) = IMPLICIT_DEF | 
 |       %2:_(s32) = G_CONSTANT i32 2 | 
 |       %3:_(s32) = G_ADD %0, %2 | 
 |       %4:_(s32) = G_SUB %3, %1 | 
 |  | 
 | and after running ``llc -run-pass=mir-debugify``: | 
 |  | 
 | .. code-block:: llvm | 
 |  | 
 |   name:            test | 
 |   body:             | | 
 |     bb.0 (%ir-block.0): | 
 |       %0:_(s32) = IMPLICIT_DEF debug-location !12 | 
 |       DBG_VALUE %0(s32), $noreg, !9, !DIExpression(), debug-location !12 | 
 |       %1:_(s32) = IMPLICIT_DEF debug-location !13 | 
 |       DBG_VALUE %1(s32), $noreg, !11, !DIExpression(), debug-location !13 | 
 |       %2:_(s32) = G_CONSTANT i32 2, debug-location !14 | 
 |       DBG_VALUE %2(s32), $noreg, !9, !DIExpression(), debug-location !14 | 
 |       %3:_(s32) = G_ADD %0, %2, debug-location !DILocation(line: 4, column: 1, scope: !6) | 
 |       DBG_VALUE %3(s32), $noreg, !9, !DIExpression(), debug-location !DILocation(line: 4, column: 1, scope: !6) | 
 |       %4:_(s32) = G_SUB %3, %1, debug-location !DILocation(line: 5, column: 1, scope: !6) | 
 |       DBG_VALUE %4(s32), $noreg, !9, !DIExpression(), debug-location !DILocation(line: 5, column: 1, scope: !6) | 
 |  | 
 | By default, ``mir-debugify`` inserts ``DBG_VALUE`` instructions **everywhere** | 
 | it is legal to do so.  In particular, every (non-PHI) machine instruction that | 
 | defines a register must be followed by a ``DBG_VALUE`` use of that def.  If | 
 | an instruction does not define a register, but can be followed by a debug inst, | 
 | MIRDebugify inserts a ``DBG_VALUE`` that references a constant.  Insertion of | 
 | ``DBG_VALUE``'s can be disabled by setting ``-debugify-level=locations``. | 
 |  | 
 | To run MIRDebugify once, simply insert ``mir-debugify`` into your ``llc`` | 
 | invocation, like: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |   # Before some other pass. | 
 |   $ llc -run-pass=mir-debugify,other-pass ... | 
 |  | 
 |   # After some other pass. | 
 |   $ llc -run-pass=other-pass,mir-debugify ... | 
 |  | 
 | To run MIRDebugify before each pass in a pipeline, use | 
 | ``-debugify-and-strip-all-safe``. This can be combined with ``-start-before`` | 
 | and ``-start-after``. For example: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |   $ llc -debugify-and-strip-all-safe -run-pass=... <other llc args> | 
 |   $ llc -debugify-and-strip-all-safe -O1 <other llc args> | 
 |  | 
 | To strip out all debug info from a test, use ``mir-strip-debug``, like: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |   $ llc -run-pass=mir-debugify,other-pass,mir-strip-debug | 
 |  | 
 | It can be useful to combine ``mir-debugify`` and ``mir-strip-debug`` to | 
 | identify backend transformations which break in the presence of debug info. | 
 | For example, to run the AArch64 backend tests with all normal passes | 
 | "sandwiched" in between MIRDebugify and MIRStripDebugify mutation passes, run: | 
 |  | 
 | .. code-block:: bash | 
 |  | 
 |   $ llvm-lit test/CodeGen/AArch64 -Dllc="llc -debugify-and-strip-all-safe" | 
 |  | 
 | Using LostDebugLocObserver | 
 | -------------------------- | 
 |  | 
 | TODO |