On Wed, Nov 6, 2024 at 3:36 PM Michal Jires <mji...@suse.cz> wrote: > > Die symbols are used for external references. > Typically during LTO, early debug emits 'die_symbol+offset' for each > possibly referenced DIE in future. Partitions in LTRANS phase then > use these references. > > Originally die symbols are handled only in root comp_unit and > in attributes. > > This patch allows die symbols to be attached to any DIE. > References then choose closest parent with die symbol. > > gcc/ChangeLog: > > * dwarf2out.cc (dwarf2out_die_ref_for_decl): > Choose closest parent with die_symbol. > (output_die): Output asm label. > (output_unit_die_symbol_list): New. > (output_comp_unit): Output die_symbol list. > (reset_dies): Reset all die_symbols. > (dwarf2out_finish): Don't reset comp_unit die_symbol. > --- > gcc/dwarf2out.cc | 80 +++++++++++++++++++++++++++--------------------- > 1 file changed, 45 insertions(+), 35 deletions(-) > > diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc > index e10a5c78fe9..bf1ac45ed73 100644 > --- a/gcc/dwarf2out.cc > +++ b/gcc/dwarf2out.cc > @@ -6039,14 +6039,14 @@ dwarf2out_die_ref_for_decl (tree decl, const char > **sym,
ah - here it is ... > /* Similar to get_ref_die_offset_label, but using the "correct" > label. */ > - *off = die->die_offset; > - while (die->die_parent) > + unsigned HOST_WIDE_INT unit_offset = die->die_offset; > + while (die->die_parent && (die->comdat_type_p || !die->die_id.die_symbol)) > die = die->die_parent; > - /* For the containing CU DIE we compute a die_symbol in > + /* Root CU DIE always contains die_symbol computed in > compute_comp_unit_symbol. */ > - if (die->die_tag == DW_TAG_compile_unit) > + if (!die->comdat_type_p && die->die_id.die_symbol) > { > - gcc_assert (die->die_id.die_symbol != NULL); > + *off = unit_offset - die->die_offset; > *sym = die->die_id.die_symbol; > return true; > } > @@ -10798,6 +10798,10 @@ output_die (dw_die_ref die) > unsigned long size; > unsigned ix; > > + if ((flag_generate_lto || flag_generate_offload) > + && !die->comdat_type_p && die->die_id.die_symbol) > + ASM_OUTPUT_LABEL (asm_out_file, die->die_id.die_symbol); > + > dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)", > (unsigned long)die->die_offset, > dwarf_tag_name (die->die_tag)); > @@ -11228,14 +11232,41 @@ output_compilation_unit_header (enum > dwarf_unit_type ut) > dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)"); > } > > +/* Output list of all die symbols in the DIE. */ > +static void > +output_unit_die_symbol_list (dw_die_ref die) > +{ > + if (!die->comdat_type_p && die->die_id.die_symbol) > + { > + const char* sym = die->die_id.die_symbol; > + /* ??? No way to get visibility assembled without a decl. */ > + tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, > + get_identifier (sym), char_type_node); > + TREE_PUBLIC (decl) = true; > + TREE_STATIC (decl) = true; > + DECL_ARTIFICIAL (decl) = true; > + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; > + DECL_VISIBILITY_SPECIFIED (decl) = true; > + targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); > +#ifdef ASM_WEAKEN_LABEL > + /* We prefer a .weak because that handles duplicates from duplicate > + archive members in a graceful way. */ > + ASM_WEAKEN_LABEL (asm_out_file, sym); > +#else > + targetm.asm_out.globalize_label (asm_out_file, sym); > +#endif > + } > + > + dw_die_ref c; > + FOR_EACH_CHILD (die, c, output_unit_die_symbol_list (c)); I'm not sure it will work this way together with the output_die hunk, instead assemblers likely expect all this to happen close to the actual label emission, so I suggest to only split out the visibiltiy/globalizing fancy and emit it from output_die instead. > +} > + > /* Output the compilation unit DIE and its children. */ > > static void > output_comp_unit (dw_die_ref die, int output_if_empty, > const unsigned char *dwo_id) > { > - const char *oldsym; > - > /* Unless we are outputting main CU, we may throw away empty ones. */ > if (!output_if_empty && die->die_child == NULL) > return; > @@ -11267,34 +11298,12 @@ output_comp_unit (dw_die_ref die, int > output_if_empty, > : DWARF_COMPILE_UNIT_HEADER_SIZE); > calc_die_sizes (die); > > - oldsym = die->die_id.die_symbol; > - > switch_to_section (debug_info_section); > ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label); > info_section_emitted = true; > > - /* For LTO cross unit DIE refs we want a symbol on the start of the > - debuginfo section, not on the CU DIE. */ > - if ((flag_generate_lto || flag_generate_offload) && oldsym) > - { > - /* ??? No way to get visibility assembled without a decl. */ > - tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, > - get_identifier (oldsym), char_type_node); > - TREE_PUBLIC (decl) = true; > - TREE_STATIC (decl) = true; > - DECL_ARTIFICIAL (decl) = true; > - DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; > - DECL_VISIBILITY_SPECIFIED (decl) = true; > - targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); > -#ifdef ASM_WEAKEN_LABEL > - /* We prefer a .weak because that handles duplicates from duplicate > - archive members in a graceful way. */ > - ASM_WEAKEN_LABEL (asm_out_file, oldsym); > -#else > - targetm.asm_out.globalize_label (asm_out_file, oldsym); > -#endif > - ASM_OUTPUT_LABEL (asm_out_file, oldsym); > - } > + if (flag_generate_lto || flag_generate_offload) > + output_unit_die_symbol_list (die); > > /* Output debugging information. */ > output_compilation_unit_header (dwo_id > @@ -11309,7 +11318,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty, > > /* Leave the marks on the main CU, so we can check them in > output_pubnames. */ > - if (oldsym) > + if (die->die_id.die_symbol) > unmark_dies (die); > } > > @@ -32297,6 +32306,10 @@ reset_dies (dw_die_ref die) > die->die_abbrev = 0; > remove_AT (die, DW_AT_sibling); > > + /* Reset die symbols so we don't output them twice. */ > + if (!die->comdat_type_p) > + die->die_id.die_symbol = NULL; > + > FOR_EACH_CHILD (die, c, reset_dies (c)); > } > > @@ -32388,9 +32401,6 @@ dwarf2out_finish (const char *filename) > reset_dies (ctnode->root_die); > } > > - /* Reset die CU symbol so we don't output it twice. */ > - comp_unit_die ()->die_id.die_symbol = NULL; > - > /* Remove DW_AT_macro and DW_AT_stmt_list from the early output. */ > remove_AT (comp_unit_die (), DW_AT_stmt_list); > if (have_macinfo) > -- > 2.47.0 >