|  | ======================================================= | 
|  | 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 |