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
>

Reply via email to