Extend `DebugInfoFinder` to collect and expose macro debug information
(`DIMacro` and `DIMacroFile` nodes).
Also update `ModuleDebugInfoPrinter` to display macro information
including the macro type, name, value, and source location.
-----
The motivation behind this PR is that `DebugInfoFinder` is key for the
[SPIRV-LLVM-Translator](https://github.com/KhronosGroup/SPIRV-LLVM-Translator)
and also for future support of debug info in the SPIRV backend in LLVM.
This new lookup of `DIMacro` with their `DIMacroFile` when available
simplifies the logic around the translation for this debug information.
Convert "denormal-fp-math" and "denormal-fp-math-f32" into a first
class denormal_fpenv attribute. Previously the query for the effective
denormal mode involved two string attribute queries with parsing. I'm
introducing more uses of this, so it makes sense to convert this
to a more efficient encoding. The old representation was also awkward
since it was split across two separate attributes. The new encoding
just stores the default and float modes as bitfields, largely avoiding
the need to consider if the other mode is set.
The syntax in the common cases looks like this:
`denormal_fpenv(preservesign,preservesign)`
`denormal_fpenv(float: preservesign,preservesign)`
`denormal_fpenv(dynamic,dynamic float: preservesign,preservesign)`
I wasn't sure about reusing the float type name instead of adding a
new keyword. It's parsed as a type but only accepts float. I'm also
debating switching the name to subnormal to match the current
preferred IEEE terminology (also used by nofpclass and other
contexts).
This has a behavior change when using the command flag debug
options to set the denormal mode. The behavior of the flag
ignored functions with an explicit attribute set, per
the default and f32 version. Now that these are one attribute,
the flag logic can't distinguish which of the two components
were explicitly set on the function. Only one test appeared to
rely on this behavior, so I just avoided using the flags in it.
This also does not perform all the code cleanups this enables.
In particular the attributor handling could be cleaned up.
I also guessed at how to support this in MLIR. I followed
MemoryEffects as a reference; it appears bitfields are expanded
into arguments to attributes, so the representation there is
a bit uglier with the 2 2-element fields flattened into 4 arguments.
This is an attempt to merge https://reviews.llvm.org/D144006 with LTO
fix.
The last merge attempt was
https://github.com/llvm/llvm-project/pull/75385.
The issue with it was investigated in
https://github.com/llvm/llvm-project/pull/75385#issuecomment-2386684121.
The problem happens when
1. Several modules are being linked.
2. There are several DISubprograms that initially belong to different
modules but represent the same source code function (for example, a
function included from the same source code file).
3. Some of such DISubprograms survive IR linking. It may happen if one
of them is inlined somewhere or if the functions that have these
DISubprograms attached have internal linkage.
4. Each of these DISubprograms has a local type that corresponds to the
same source code type. These types are initially from different modules,
but have the same ODR identifier.
If the same (in the sense of ODR identifier/ODR uniquing rules) local
type is present in two modules, and these modules are linked together,
the type gets uniqued. A DIType, that happens to be loaded first,
survives linking, and the references on other types with the same ODR
identifier from the modules loaded later are replaced with the
references on the DIType loaded first. Since defintion subprograms, in
scope of which these types are located, are not deduplicated, the linker
output may contain multiple DISubprogram's having the same (uniqued)
type in their retainedNodes lists.
Further compilation of such modules causes crashes.
To tackle that,
* previous solution to handle LTO linking with local types in
retainedNodes is removed (cloneLocalTypes() function),
* for each loaded distinct (definition) DISubprogram, its retainedNodes
list is scanned after loading, and DITypes with a scope of another
subprogram are removed. If something from a Function corresponding to
the DISubprogram references uniqued type, we rely on cross-CU links.
Additionally:
* a check is added to Verifier to report about local types located in a
wrong retainedNodes list,
Original commit message follows.
---------
RFC https://discourse.llvm.org/t/rfc-dwarfdebug-fix-and-improve-handling-imported-entities-types-and-static-local-in-subprogram-and-lexical-block-scopes/68544
Similar to imported declarations, the patch tracks function-local types in
DISubprogram's 'retainedNodes' field. DwarfDebug is adjusted in accordance with
the aforementioned metadata change and provided a support of function-local
types scoped within a lexical block.
The patch assumes that DICompileUnit's 'enums field' no longer tracks local
types and DwarfDebug would assert if any locally-scoped types get placed there.
Authored-by: Kristina Bessonova <kbessonova@accesssoftek.com>
Co-authored-by: Jeremy Morse <jeremy.morse@sony.com>
This change adds support for emitting the enhanced PTX debugging
directives `function_name` and `inlined_at` as part of the `.loc`
directive in the NVPTX backend.
`.loc` syntax -
>.loc file_index line_number column_position
`.loc` syntax with `inlined_at` attribute -
>.loc file_index line_number column_position,function_name label {+
immediate }, inlined_at file_index2 line_number2 column_position2
`inlined_at` attribute specified as part of the `.loc` directive
indicates PTX instructions that are generated from a function that got
inlined. It specifies the source location at which the specified
function is inlined. `file_index2`, `line_number2`, and
`column_position2` specify the location at which the function is
inlined.
The `function_name` attribute specifies an offset in the DWARF section-
`.debug_str`. Offset is specified as a label expression or a label +
immediate expression, where label is defined in the `.debug_str`
section. DWARF section `.debug_str` contains ASCII null-terminated
strings that specify the name of the function that is inlined.
These attributes were introduced in PTX ISA version 7.2 (see NVIDIA’s
documentation:
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc
).
To support these features, the PR introduces a new `NVPTXDwarfDebug`
class derived from `DwarfDebug`, which implements NVPTX-specific logic
for emitting these directives. The base DwarfDebug infrastructure is
extended with new virtual functions (`initializeTargetDebugInfo()` and
`recordTargetSourceLine()`) that enable the NVPTX backend to generate
this additional debug information.
The MC layer is also updated to emit the NVPTX-specific `.loc`
attributes (function_name and inlined_at). The implementation applies to
PTX ISA 7.2 and later when the debug-info emission kind is either
lineTableOnly or DebugDirectiveOnly. A new command-line option,
`--line-info-inlined-at=<true/false>`, is added to control whether the
inlined_at attribute is generated.
Note - The `NVCC` compiler already emits the `.loc` directive with
`inlined_at` when compiled with `-lineinfo` option.
Currently, when SDAG is run on AArch64 and an `optnone` function is
encountered, the selector is chosen as FastISel. AArch64 makes use of
GlobalISel at O0 and this patch aims to align `optnone` with this
functionality.
A flag is exposed to enable this functionality for a given backend but,
as AArch64 is currently the only backend I could find using GlobalISel
at O0 this is the only one with it implemented. This flag is set when
the target supports GlobalISel & GlobalISel hasn't been forced by the
user, the target machine or by being at an optimisation level lower than
`EnableGlobalISelAtO`.
If this happens, the GlobalISel passes are included as shown in
`llvm/test/CodeGen/AArch64/O3-pipeline.ll` and skipped by IRTranslator
for functions not marked as `optnone`.
In updating the tests based on this functionality, I found some unused
check lines or run lines that mixed SDAG with GlobalISel pass names
which have been fixed.
---------
Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
Currently, there's code to suppress pairing, but we don't actually need
to suppress that; we just need to suppress the formation of
pre-decrement/post-increment instructions.
Pairing saves an instruction in some cases, and enables packed unwind in
some cases.
Entry value operations could previously not be combined with other
operations in debug expressions, meaning that we had to skip emitting
call site values in such cases. This DIExpression limitation was removed
in 57a371d7010802804343d17b85ac5e0d28d0f309, so we should be free to
emit call site values for such cases now, for example:
extern void call(int, int);
void entry_value (int param) {
call(param + 222, param - 444);
}
This change exposed a call site parameter entry order issue in the
dbgcall-site-expr-entry-value.mir test case. That ordering issue is
tracked in #43998, and I don't think there is anything inherent in this
patch that caused that.
For example, given code like this:
int local = value();
callee(local);
return local;
resulting in assembly like:
movl %eax, %ebx // %eax = local
movl %eax, %edi
callq callee@PLT
the call site value generation did not understand that the value of
local is stored in the callee-saved %ebx during the call, and did not
emit any call site value. This patch addresses that, resulting in:
DW_TAG_call_site_parameter
DW_AT_location (DW_OP_reg5 RDI)
DW_AT_call_value (DW_OP_breg3 RBX+0)
This code does not keep track if any succeeding instructions save
registers, meaning that it fails to emit a call site value for a case
like this:
movq %rax, %rdi
movq %rax, %rbx
callq callee@PLT
The test case dbgcall-site-preserved-clobbered.mir has been added for
that. This should be rather easy to address, but can be done in a
follow-up patch.
Building a clang-21 RelWithDebInfo binary for x86-64 without/with this
patch results in a ~1.8% increase of the number of call site parameter
entries with a location (from 1792876 to 1825718). This also reduces the
number of call site parameter entries using DW_OP_entry_value locations,
which are not guaranteed to be printable as they require the frame above
to provide a call site value for that parameter, from 57718 to 34871.
Fixes#43464.
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Similar to other portings, except this time we do not refactor to an
impl since there is a single runOnMachineFunction definition that can
easily be made static. Test coverage added.
Similar to other pass portings. Refactor into an implementation class,
rename the old pass, and add a wrapper around the implementation for the
new pass manager. Handle PSI/MBFI similar to other backend passes.
PR #142970 Added for Windows targets to emit minimal codeview metadata
even when debug info is disabled. This crashes the backend for UEFI
x86_64-uefi triple as llvm.dbg.cu is expected unconditionally there.
Handling it correctly in AsmPrinter and adding a regression test.
This patch ports X86FixupLEAs to the new pass manager and adds some test
coverage.
Reviewers: paperchalice, arsenm, RKSimon, phoebewang
Pull Request: https://github.com/llvm/llvm-project/pull/173744
Version 0.13 of the Xqci Qualcomm uC Vendor Extension has been marked as
frozen. We've had assembler support for this since LLVM20 and code
generation support since LLVM21. I think we have enough coverage in the
code base to mark the extension as non-experimental.
Without this patch DW_AT_call_target is used for all indirect call address
location expressions. The DWARF spec says:
For indirect calls or jumps where the address is not computable without use
of registers or memory locations that might be clobbered by the call the
DW_AT_call_target_clobbered attribute is used instead of the
DW_AT_call_target attribute.
This patch implements that behaviour.
Fixes#70949. Prior to PR #151378 memory locations were incorrect; that
patch prevented the emission of the incorrect locations.
This patch fixes the underlying issue.
Instead of this:
```
0x00018cff: DW_TAG_imported_declaration
DW_AT_decl_line (12)
DW_AT_import (0x0000000000018cfb)
```
print:
```
0x00018cff: DW_TAG_imported_declaration
DW_AT_decl_line (12)
DW_AT_import (0x0000000000018cfb "platform")
```
Where `0x0000000000018cfb` in this example could be a `DW_TAG_module`
with `DW_AT_name ("platform")`
SelectionDAG uses the DAGCombiner to fold a load followed by a sext to a
load and sext instruction. For example, in x86 we will see that
```
%1 = load i32, ptr @GlobArr
#dbg_value(i32 %1, !43, !DIExpression(), !52)
%2 = sext i32 %1 to i64, !dbg !53
```
is converted to:
```
%0:gr64_nosp = MOVSX64rm32 $rip, 1, $noreg, @GlobArr, $noreg, debug-instr-number 1, debug-location !51
DBG_VALUE $noreg, $noreg, !"Idx", !DIExpression(), debug-location !52
```
The `DBG_VALUE` needs to be transferred correctly to the new combined
instruction, and it needs to be appended with a `DIExpression` which
contains a `DW_OP_LLVM_fragment`, describing that the lower bits of the
virtual register contain the value.
This patch fixes the above described problem.
Consider this Ada type:
```
type Array_Type is array (Natural range <>) of Integer;
type Record_Type (L1, L2 : Natural) is record
I1 : Integer;
A1 : Array_Type (1 .. L1);
I2 : Integer;
A2 : Array_Type (1 .. L2);
I3 : Integer;
end record;
```
Here, the array fields have lengths that depend on the discriminants of
the record type. However, in this case the array lengths cannot be
expressed as DWARF location expressions, with the issue being that "A2"
has a non-constant offset, but an expression involving
DW_OP_push_object_address will push the address of the field -- with no
way to find the location of "L2".
In a case like this, I believe the correct DWARF is to emit the array
ranges using a direct reference to the discriminant, like:
```
<3><1156>: Abbrev Number: 1 (DW_TAG_member)
<1157> DW_AT_name : l1
...
<3><1177>: Abbrev Number: 6 (DW_TAG_array_type)
<1178> DW_AT_name : (indirect string, offset: 0x1a0b): vla__record_type__T4b
<117c> DW_AT_type : <0x1287>
<1180> DW_AT_sibling : <0x118e>
<4><1184>: Abbrev Number: 7 (DW_TAG_subrange_type)
<1185> DW_AT_type : <0x1280>
<1189> DW_AT_upper_bound : <0x1156>
```
(FWIW this is what GCC has done for years.)
This patch makes this possible in LLVM, by letting a DISubrangeType
refer to a DIDerivedType. gnat-llvm can then arrange for the DIE
reference to be correct by setting the array type's scope to be the
record.
This patch makes DWARF fission compatible with RISC-V relaxations by
using indirect addressing for the DW_AT_high_pc attribute. This
eliminates the remaining relocations in .dwo files.
Currently, -gsplit-dwarf and -mrelax are incompatible options in Clang.
The issue is that .dwo files should not contain any relocations, as they
are not processed by the linker. However, relaxable code emits
relocations in DWARF for debug ranges that reside in the .dwo file when
DWARF fission is enabled.
This patch makes DWARF fission compatible with RISC-V relaxations. It
uses the StartxEndx DWARF forms in .debug_rnglists.dwo, which allow
referencing addresses from .debug_addr instead of using absolute
addresses. This approach eliminates relocations from .dwo files.
In functions that have been seriously deformed during optimisation,
there can be call instructions with line-zero immediately after frame
setup (see C reproducer in the test added). Our previous algorithms for
prologue_end ignored these, meaning someone entering a function at
prologue_end would break-in after a function call had completed. Prefer
instead to place prologue_end and the function scope-line on the line
zero call: this isn't false (it's the first meaningful instruction of the
function) and is approximately true. Given a less than ideal function,
this is an OK solution.
This test was failing on chromium builds with error:
```
/Volumes/Work/s/w/ir/x/w/llvm_build/bin/llc -o - /Volumes/Work/s/w/ir/x/w/llvm-llvm-project/llvm/test/DebugInfo/AArch64/instr-ref-target-hooks-sp-clobber.mir -run-pass=livedebugvalues | /Volumes/Work/s/w/ir/x/w/llvm_build/bin/FileCheck /Volumes/Work/s/w/ir/x/w/llvm-llvm-project/llvm/test/DebugInfo/AArch64/instr-ref-target-hooks-sp-clobber.mir # RUN: at line 8
+ /Volumes/Work/s/w/ir/x/w/llvm_build/bin/llc -o - /Volumes/Work/s/w/ir/x/w/llvm-llvm-project/llvm/test/DebugInfo/AArch64/instr-ref-target-hooks-sp-clobber.mir -run-pass=livedebugvalues
+ /Volumes/Work/s/w/ir/x/w/llvm_build/bin/FileCheck /Volumes/Work/s/w/ir/x/w/llvm-llvm-project/llvm/test/DebugInfo/AArch64/instr-ref-target-hooks-sp-clobber.mir
error: YAML:121:3: unknown key 'stackSizePPR'
stackSizePPR: 0
^~~~~~~~~~~~
FileCheck error: '<stdin>' is empty.
FileCheck command line: /Volumes/Work/s/w/ir/x/w/llvm_build/bin/FileCheck /Volumes/Work/s/w/ir/x/w/llvm-llvm-project/llvm/test/DebugInfo/AArch64/instr-ref-target-hooks-sp-clobber.mir
```
This is an attempt to reland the failing test
This path is updating the reading capabilities of the LLVM DWARF parser
for a llvm-dwp patch https://github.com/llvm/llvm-project/pull/167457
that will emit .dwp files where the compile units are DWARF32 and the
.debug_str_offsets tables will be emitted as DWARF64 to allow .debug_str
sections that exceed 4GB in size.
We shouldn't be calling `getUnversionedName` unconditionally because
DWARFv6-enabled Clang will emit versioned language names that are
versioned (i.e., `sourceLanguageName`...see new test case). We need to
check `hasVersionedName` and pick the appropriate API based on that.
Otherwise we assert in `getUnversionedName`.
These checks ensure that retained nodes of a DISubprogram belong to the
subprogram.
Tests with incorrect IR are fixed. We should not have variables of one subprogram present in retained nodes of other subprograms.
Also, interface for accessing DISubprogram's retained nodes is slightly
refactored. `DISubprogram::visitRetainedNodes` and
`DISubprogram::forEachRetainedNode` are added to avoid repeating checks
like
```
if (const auto *LV = dyn_cast<DILocalVariable>(N))
...
else if (const auto *L = dyn_cast<DILabel>(N))
...
else if (const auto *IE = dyn_cast<DIImportedEntity>(N))
...
```
This change enhances debug info metadata handling to support node
references in the `extraData` field for `DW_TAG_member`,
`DW_TAG_variable`, and `DW_TAG_inheritance` tags.
The change enables LLVM to handle both direct constant values (e.g.,
extraData: i8 1) and node references (e.g., extraData: !18 where !18 =
!{ i8 1 }).
The debug info attached to the BUNDLE is the first instruction in the
BUNDLE, even if a better debug info (line:column) is present in the
later instructions of the bundle. The patch tries to get a better debug
info first. If not, then a worse debug info without line number is
chosen.
---------
Co-authored-by: Vladislav Dzhidzhoev <dzhidzhoev@gmail.com>
Co-authored-by: Orlando Cazalet-Hyams <orlandoch.och@gmail.com>
Previously, sign-extending a 1-bit boolean operand in `#DBG_VALUE` would
convert `true` to -1 (i.e., 0xffffffffffffffff). However, DWARF treats
booleans as unsigned values, so this resulted in the attribute
`DW_AT_const_value(0xffffffffffffffff)` being emitted. As a result, the
debugger would display the value as `255` instead of `true`.
This change modifies the behavior to use zero-extension for 1-bit values
instead, ensuring that `true` is represented as 1. Consequently, the
DWARF attribute emitted is now `DW_AT_const_value(1)`, which allows the
debugger to correctly display the boolean as `true`.