[llvm] [llvm][DebugInfo] Encode DW_AT_object_pointer on method declarations with DW_FORM_implicit_const (PR #124790)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 29 02:09:41 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Michael Buch (Michael137)
<details>
<summary>Changes</summary>
We started attaching `DW_AT_object_pointer`s on method declarations in https://github.com/llvm/llvm-project/pull/122742. However, that caused the `.debug_info` section size to increase significantly (by around ~10% on some projects). This was mainly due to the large number of new `DW_FORM_ref4` values. This patch tries to address that regression by changing the `DW_FORM_ref4` to a `DW_FORM_implicit_const` for declarations. The value of `DW_FORM_implicit_const` will be the *index* of the object parameter in the list of formal parameters of the subprogram (i.e., if the first `DW_TAG_formal_parameter` is the object pointer, the `DW_FORM_implicit_const` would be `0`). The DWARFv5 spec only mentions the use of the `reference` attribute class to for `DW_AT_object_pointer`. So using a `DW_FORM_impilicit_const` would be an extension to (and not something mandated/specified by) the standard. Though it'd make sense to extend the wording in the spec to allow for this optimization.
That way we don't pay for the 4 byte references on every attribute occurrence. In a local build of clang this barely affected the `.debug_info` section size (but did increase `.debug_abbrev` by up to 10%, which doesn't impact the total debug-info size much however).
We guarded this on LLDB tuning (since using `DW_FORM_implicit_const` for this purpose may surprise consumers) and DWARFv5 (since that's where `DW_FORM_implicit_const` was first standardized).
---
Patch is 230.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/124790.diff
6 Files Affected:
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (+21-7)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h (+4-2)
- (modified) llvm/test/DebugInfo/NVPTX/debug-info.ll (+2548-2578)
- (added) llvm/test/DebugInfo/X86/DW_AT_object_pointer-non-standard-index.ll (+79)
- (modified) llvm/test/DebugInfo/X86/DW_AT_object_pointer.ll (+15-7)
- (modified) llvm/test/tools/llvm-dwarfdump/X86/statistics.ll (+3-3)
``````````diff
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index d3450b8b0556fde..05bcaa9405e7dd7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -849,9 +849,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
}
}
-DIE *DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {
+std::optional<unsigned>
+DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {
// Args[0] is the return type.
- DIE *ObjectPointer = nullptr;
+ std::optional<unsigned> ObjectPointerIndex;
for (unsigned i = 1, N = Args.size(); i < N; ++i) {
const DIType *Ty = Args[i];
if (!Ty) {
@@ -863,13 +864,14 @@ DIE *DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {
if (Ty->isArtificial())
addFlag(Arg, dwarf::DW_AT_artificial);
if (Ty->isObjectPointer()) {
- assert(!ObjectPointer && "Can't have more than one object pointer");
- ObjectPointer = &Arg;
+ assert(!ObjectPointerIndex &&
+ "Can't have more than one object pointer");
+ ObjectPointerIndex = i;
}
}
}
- return ObjectPointer;
+ return ObjectPointerIndex;
}
void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {
@@ -1366,8 +1368,20 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
// Add arguments. Do not add arguments for subprogram definition. They will
// be handled while processing variables.
- if (auto *ObjectPointer = constructSubprogramArguments(SPDie, Args))
- addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, *ObjectPointer);
+ //
+ // Encode the object pointer as an index instead of a DIE reference in order
+ // to minimize the affect on the .debug_info size.
+ if (std::optional<unsigned> ObjectPointerIndex =
+ constructSubprogramArguments(SPDie, Args)) {
+ if (getDwarfDebug().tuneForLLDB() &&
+ getDwarfDebug().getDwarfVersion() >= 5) {
+ // 0th index in Args is the return type, hence adjust by 1. In DWARF
+ // we want the first parameter to be at index 0.
+ assert(*ObjectPointerIndex > 0);
+ addSInt(SPDie, dwarf::DW_AT_object_pointer,
+ dwarf::DW_FORM_implicit_const, *ObjectPointerIndex - 1);
+ }
+ }
}
addThrownTypes(SPDie, SP->getThrownTypes());
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 7a5295d826a483b..afbe90899421045 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -269,8 +269,10 @@ class DwarfUnit : public DIEUnit {
/// Construct function argument DIEs.
///
- /// \returns DIE of the object pointer if one exists. Nullptr otherwise.
- DIE *constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args);
+ /// \returns The index of the object parameter in \c Args if one exists.
+ /// Returns std::nullopt otherwise.
+ std::optional<unsigned> constructSubprogramArguments(DIE &Buffer,
+ DITypeRefArray Args);
/// Create a DIE with the given Tag, add the DIE to its parent, and
/// call insertDIE if MD is not null.
diff --git a/llvm/test/DebugInfo/NVPTX/debug-info.ll b/llvm/test/DebugInfo/NVPTX/debug-info.ll
index 51fb692789e2265..62b30a1f15aff11 100644
--- a/llvm/test/DebugInfo/NVPTX/debug-info.ll
+++ b/llvm/test/DebugInfo/NVPTX/debug-info.ll
@@ -98,2584 +98,2554 @@ if.end: ; preds = %if.then, %entry
; CHECK-DAG: .file {{[0-9]+}} "{{.*}}/usr/local/cuda/include{{/|\\\\}}vector_types.h"
; CHECK: .section .debug_loc
-; CHECK-NEXT: {
-; CHECK-NEXT:$L__debug_loc0:
-; CHECK-NEXT:.b64 $L__tmp8
-; CHECK-NEXT:.b64 $L__tmp10
-; CHECK-NEXT:.b8 5 // Loc expr size
-; CHECK-NEXT:.b8 0
-; CHECK-NEXT:.b8 144 // DW_OP_regx
-; CHECK-NEXT:.b8 177 // 2450993
-; CHECK-NEXT:.b8 204 //
-; CHECK-NEXT:.b8 149 //
-; CHECK-NEXT:.b8 1 //
-; CHECK-NEXT:.b64 0
-; CHECK-NEXT:.b64 0
-; CHECK-NEXT:$L__debug_loc1:
-; CHECK-NEXT:.b64 $L__tmp5
-; CHECK-NEXT:.b64 $L__func_end0
-; CHECK-NEXT:.b8 5 // Loc expr size
-; CHECK-NEXT:.b8 0
-; CHECK-NEXT:.b8 144 // DW_OP_regx
-; CHECK-NEXT:.b8 177 // 2454065
-; CHECK-NEXT:.b8 228 //
-; CHECK-NEXT:.b8 149 //
-; CHECK-NEXT:.b8 1 //
-; CHECK-NEXT:.b64 0
-; CHECK-NEXT:.b64 0
-; CHECK-NEXT: }
-; CHECK-NEXT: .section .debug_abbrev
-; CHECK-NEXT: {
-; CHECK-NEXT:.b8 1 // Abbreviation Code
-; CHECK-NEXT:.b8 17 // DW_TAG_compile_unit
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 37 // DW_AT_producer
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 19 // DW_AT_language
-; CHECK-NEXT:.b8 5 // DW_FORM_data2
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 16 // DW_AT_stmt_list
-; CHECK-NEXT:.b8 6 // DW_FORM_data4
-; CHECK-NEXT:.b8 27 // DW_AT_comp_dir
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 2 // Abbreviation Code
-; CHECK-NEXT:.b8 19 // DW_TAG_structure_type
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 11 // DW_AT_byte_size
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 3 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 135 // DW_AT_MIPS_linkage_name
-; CHECK-NEXT:.b8 64
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 60 // DW_AT_declaration
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 63 // DW_AT_external
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 4 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 135 // DW_AT_MIPS_linkage_name
-; CHECK-NEXT:.b8 64
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 60 // DW_AT_declaration
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 100 // DW_AT_object_pointer
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 63 // DW_AT_external
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 5 // Abbreviation Code
-; CHECK-NEXT:.b8 5 // DW_TAG_formal_parameter
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 52 // DW_AT_artificial
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 6 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 60 // DW_AT_declaration
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 100 // DW_AT_object_pointer
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 63 // DW_AT_external
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 50 // DW_AT_accessibility
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 7 // Abbreviation Code
-; CHECK-NEXT:.b8 5 // DW_TAG_formal_parameter
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 8 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 135 // DW_AT_MIPS_linkage_name
-; CHECK-NEXT:.b8 64
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 60 // DW_AT_declaration
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 100 // DW_AT_object_pointer
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 63 // DW_AT_external
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 50 // DW_AT_accessibility
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 9 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 135 // DW_AT_MIPS_linkage_name
-; CHECK-NEXT:.b8 64
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 60 // DW_AT_declaration
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 100 // DW_AT_object_pointer
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 63 // DW_AT_external
-; CHECK-NEXT:.b8 12 // DW_FORM_flag
-; CHECK-NEXT:.b8 50 // DW_AT_accessibility
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 10 // Abbreviation Code
-; CHECK-NEXT:.b8 36 // DW_TAG_base_type
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 62 // DW_AT_encoding
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 11 // DW_AT_byte_size
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 11 // Abbreviation Code
-; CHECK-NEXT:.b8 13 // DW_TAG_member
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 56 // DW_AT_data_member_location
-; CHECK-NEXT:.b8 10 // DW_FORM_block1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 12 // Abbreviation Code
-; CHECK-NEXT:.b8 15 // DW_TAG_pointer_type
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 13 // Abbreviation Code
-; CHECK-NEXT:.b8 38 // DW_TAG_const_type
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 14 // Abbreviation Code
-; CHECK-NEXT:.b8 16 // DW_TAG_reference_type
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 73 // DW_AT_type
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 15 // Abbreviation Code
-; CHECK-NEXT:.b8 46 // DW_TAG_subprogram
-; CHECK-NEXT:.b8 0 // DW_CHILDREN_no
-; CHECK-NEXT:.b8 71 // DW_AT_specification
-; CHECK-NEXT:.b8 19 // DW_FORM_ref4
-; CHECK-NEXT:.b8 32 // DW_AT_inline
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 16 // Abbreviation Code
-; CHECK-NEXT:.b8 19 // DW_TAG_structure_type
-; CHECK-NEXT:.b8 1 // DW_CHILDREN_yes
-; CHECK-NEXT:.b8 3 // DW_AT_name
-; CHECK-NEXT:.b8 8 // DW_FORM_string
-; CHECK-NEXT:.b8 11 // DW_AT_byte_size
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 58 // DW_AT_decl_file
-; CHECK-NEXT:.b8 11 // DW_FORM_data1
-; CHECK-NEXT:.b8 59 // DW_AT_decl_line
-; CHECK-NEXT:.b8 5 // DW_FORM_data2
-; CHECK-NEXT:.b8 0 // EOM(1)
-; CHECK-NEXT:.b8 0 // EOM(2)
-; CHECK-NEXT:.b8 17 // Abbreviat...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/124790
More information about the llvm-commits
mailing list