]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
dwarf2out: Use DW_LNS_advance_pc instead of DW_LNS_fixed_advance_pc if possible ...
authorJakub Jelinek <jakub@redhat.com>
Thu, 28 Aug 2025 08:09:14 +0000 (10:09 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 28 Aug 2025 08:09:14 +0000 (10:09 +0200)
In the usual case we use .loc directives and don't emit the line table
manually.  And assembler usually uses DW_LNS_advance_pc which has
uleb128 argument and in most cases will have just a single byte operand.
But if we do emit it for whatever reason (old or buggy assembler or
-gno-as-loc{,view}-support option), we do use DW_LNS_fixed_advance_pc
instead, which has fixed 2 byte operand.  That is both wasteful
in the usual case of very small advances, and more importantly will
just result in assembler errors if we need to advance over more than 65535
bytes.
The following patch uses DW_LNS_advance_pc instead if assembler supports
.uleb128 directive with a difference of two labels in the same section.
This is only possible if Minimum Instruction Length in the .debug_line
header is 1 (otherwise DW_LNS_advance_pc operand is multiplied by that
value and DW_LNS_fixed_advance_pc is not), but we emit 1 for that
on all targets.
Looking at dwarf2out.o (from dwarf2out.cc with this patch)
compiled with compilers before/after this change with additional -fpic
-gno-as-loc{,view}-support options, I see .debug_line section shrunk from
878067 bytes to 773381 bytes, so shrink by 12%.
Admittedly gas generated .debug_line is even smaller, 501374 bytes (with
-fpic and without -gno-as-loc{,view}-support options).

2025-08-28  Jakub Jelinek  <jakub@redhat.com>

PR debug/119367
* dwarf2out.cc (output_one_line_info_table) <case LI_adv_address>: If
HAVE_AS_LEB128, use DW_LNS_advance_pc with dw2_asm_output_delta_uleb128
instead of DW_LNS_fixed_advance_pc with dw2_asm_output_delta.

gcc/dwarf2out.cc

index d1a55dbcbcbfe6d7606955edc8419491c2abdeed..0bd8474bc370fe0b3903243557e0f6b7834c0d50 100644 (file)
@@ -12997,9 +12997,25 @@ output_one_line_info_table (dw_line_info_table *table)
 
            view++;
 
-           dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, "fixed advance PC, increment view to %i", view);
-           dw2_asm_output_delta (2, line_label, prev_label,
-                                 "from %s to %s", prev_label, line_label);
+           if (HAVE_AS_LEB128)
+             {
+               /* Using DW_LNS_advance_pc with label delta is only valid if
+                  Minimum Instruction Length in the header is 1, but that is
+                  what we use on all targets.  */
+               dw2_asm_output_data (1, DW_LNS_advance_pc,
+                                    "advance PC, increment view to %i", view);
+               dw2_asm_output_delta_uleb128 (line_label, prev_label,
+                                             "from %s to %s", prev_label,
+                                             line_label);
+             }
+           else
+             {
+               dw2_asm_output_data (1, DW_LNS_fixed_advance_pc,
+                                    "fixed advance PC, increment view to %i",
+                                    view);
+               dw2_asm_output_delta (2, line_label, prev_label,
+                                     "from %s to %s", prev_label, line_label);
+             }
 
            prev_addr = ent;
            break;