https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86462
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- The differences are of the form <3><11d>: Abbrev Number: 9 (DW_TAG_lexical_block) <4><11e>: Abbrev Number: 10 (DW_TAG_GNU_call_site) to <3><11d>: Abbrev Number: 9 (DW_TAG_lexical_block) <11e> DW_AT_ranges : 0x560 <4><122>: Abbrev Number: 10 (DW_TAG_GNU_call_site) and similar <4><6ef>: Abbrev Number: 26 (DW_TAG_lexical_block) <4><6f0>: Abbrev Number: 26 (DW_TAG_lexical_block) <4><6f1>: Abbrev Number: 27 (DW_TAG_GNU_call_site) to <4><6f3>: Abbrev Number: 26 (DW_TAG_lexical_block) <6f4> DW_AT_ranges : 0x5a0 <4><6f8>: Abbrev Number: 26 (DW_TAG_lexical_block) <6f9> DW_AT_ranges : 0x5d0 <4><6fd>: Abbrev Number: 27 (DW_TAG_GNU_call_site) and I believe the fix involves emitting less lexical blocks in the first place, not not annotating already generated lexical block DIEs with ranges. For computer_time above the frontend generates computer_time (real(kind=8) & restrict tnow) { integer(kind=4) count_max; integer(kind=4) count_rate; integer(kind=4) counted; static logical(kind=4) first = 1; static logical(kind=4) first_flip; static real(kind=8) tfirst; real(kind=8) tmax; real(kind=8) trate; { integer(kind=4) count.0; integer(kind=4) count_rate.1; integer(kind=4) count_max.2; _gfortran_system_clock_4 (&count.0, &count_rate.1, &count_max.2); ... } and we output the lexical block because of the vars even though they are all DECL_IGNORED. This is because of the simplified logic in gen_block_die: /* Determine if this block directly contains any "significant" local declarations which we will need to output DIEs for. */ if (debug_info_level > DINFO_LEVEL_TERSE) /* We are not in terse mode so *any* local declaration counts as being a "significant" one. */ must_output_die = ((BLOCK_VARS (stmt) != NULL || BLOCK_NUM_NONLOCALIZED_VARS (stmt)) && (TREE_USED (stmt) || TREE_ASM_WRITTEN (stmt) || BLOCK_ABSTRACT (stmt))); else if ((TREE_USED (stmt) || TREE_ASM_WRITTEN (stmt) || BLOCK_ABSTRACT (stmt)) && !dwarf2out_ignore_block (stmt)) must_output_die = 1; Of course the question is why DECL_INGORED vars are retained in BLOCK_VARS at all. For code-generation local_decls is authorative, BLOCK_VARS is only for debug information generation. But BLOCK_VARS and gimple_bind_vars are too interwound to remove those easily which means the above code would need to walk BLOCK_VARS (and BLOCK_NONLOCALIZED_VARS). So with that fixed I get an overall saving (comparing trunk and gcc8 though): > bloaty induct2.o -- ../../gcc8-g/gcc/induct2.o VM SIZE FILE SIZE ++++++++++++++ GROWING ++++++++++++++ [ = ] 0 .rela.debug_loc +1.45Ki +1.3% [ = ] 0 .debug_loc +695 +0.9% [ = ] 0 .debug_line +167 +1.1% [ = ] 0 .rela.debug_ranges +48 +1.2% [ = ] 0 .rela.debug_info +24 +0.0% [ = ] 0 .debug_ranges +16 +0.9% [ = ] 0 .debug_abbrev +11 +0.8% [ = ] 0 [Unmapped] +3 +7.5% -------------- SHRINKING -------------- [ = ] 0 .debug_info -2.44Ki -3.3% -0.7% -740 .text -740 -0.7% [ = ] 0 .rela.text -288 -0.3% [ = ] 0 .symtab -96 -2.0% -6.6% -32 .rodata.cst8 -32 -6.6% [ = ] 0 .strtab -24 -0.8% [ = ] 0 .comment -21 -33.3% [ = ] 0 .debug_str -16 -0.3% -0.7% -772 TOTAL -1.23Ki -0.2% I will test diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 1127713cbaf..995a463bddc 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -25632,13 +25632,30 @@ gen_block_die (tree stmt, dw_die_ref context_die) /* Determine if this block directly contains any "significant" local declarations which we will need to output DIEs for. */ if (debug_info_level > DINFO_LEVEL_TERSE) - /* We are not in terse mode so *any* local declaration counts - as being a "significant" one. */ - must_output_die = ((BLOCK_VARS (stmt) != NULL - || BLOCK_NUM_NONLOCALIZED_VARS (stmt)) - && (TREE_USED (stmt) - || TREE_ASM_WRITTEN (stmt) - || BLOCK_ABSTRACT (stmt))); + { + /* We are not in terse mode so any local declaration that + is not ignored for debug purposes counts as being a + "significant" one. */ + if (TREE_USED (stmt) + || TREE_ASM_WRITTEN (stmt) + || BLOCK_ABSTRACT (stmt)) + { + for (tree var = BLOCK_VARS (stmt); var; var = DECL_CHAIN (var)) + if (!DECL_IGNORED_P (var)) + { + must_output_die = 1; + break; + } + if (!must_output_die) + for (unsigned i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); + ++i) + if (!DECL_IGNORED_P (BLOCK_NONLOCALIZED_VAR (stmt, i))) + { + must_output_die = 1; + break; + } + } + } else if ((TREE_USED (stmt) || TREE_ASM_WRITTEN (stmt) || BLOCK_ABSTRACT (stmt))