On Tue, 25 Sep 2018, Richard Biener wrote:

> 
> This gets rid of 99% of the useless late DIE to early DIE forwarders
> (those which do not have any attributes besides the 
> DW_AT_abstract_origin).  I've wanted to do this for a long time but
> only now was able to verify that creating the concrete instances
> lazily in lookup_decl_die and friend works.
> 
> So the patch replaces BLOCK_DIE uses in dwarf2out.c with lookup_block_die
> and equate_block_to_die "forwarders" that do the lazy concrete instance
> DIE creation and adjusts lookup_decl_die accordingly.  It then switches
> dwarf2out_register_external_die to populate a decl -> { symbol, offset }
> map rather than using DIEs for the recording (and adjusts
> dwarf2out_die_ref_for_decl to look into that map in WPA phase).
> 
> The rest of the patch deals with cases where we are outputting references
> to DIEs and replaces existing hacks with easier querying of the new map.
> It also makes sure to output DW_TAG_imported_unit DIEs first rather than
> spread over the DIE tree and consistently so.
> 
> LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
> 
> I do consider backporting this given it makes the debug info so much
> easier to read (actual size only shriks by about 10%).  A backport of
> the patch passed LTO bootstrap and regtest but I'll leave this on
> trunk for a while to spot issues.
> 
> I said 99% above because I did spot some stray remains when digging
> through cc1 debug info.  Have to see if I can easily debug that.

The following gets rid of the remaining issues (also fixing a mistake
I made with DW_TAG_imported_unit which is now created over and over
again).  It also does a few simplifications where possible.

LTO bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

Richard.

2018-09-25  Richard Biener  <rguent...@suse.de>

        PR debug/83941
        * dwarf2out.c (add_AT_external_die_ref): Remove now redundant
        GC-ification.
        (maybe_create_die_with_external_ref): Do not create
        DW_TAG_imported_unit here.
        (add_abstract_origin_attribute): Handle external BLOCK refs.
        (dwarf2out_abstract_function): Simplify LTO case.
        (dwarf2out_early_finish): Create DW_TAG_imported_unit explicitely
        rather than using maybe_create_die_with_external_ref.

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c     (revision 264564)
+++ gcc/dwarf2out.c     (working copy)
@@ -5868,7 +5868,7 @@ add_AT_external_die_ref (dw_die_ref die,
   /* ???  We probably want to share these, thus put a ref to the DIE
      we create here to the external_die_map entry.  */
   dw_die_ref ref = new_die_raw (die->die_tag);
-  ref->die_id.die_symbol = IDENTIFIER_POINTER (get_identifier (symbol));
+  ref->die_id.die_symbol = symbol;
   ref->die_offset = offset;
   ref->with_offset = 1;
   add_AT_die_ref (die, attr_kind, ref);
@@ -5966,8 +5966,6 @@ maybe_create_die_with_external_ref (tree
     case TRANSLATION_UNIT_DECL:
       {
        die = comp_unit_die ();
-       dw_die_ref import = new_die (DW_TAG_imported_unit, die, NULL_TREE);
-       add_AT_external_die_ref (import, DW_AT_import, sym, off);
        /* We re-target all CU decls to the LTRANS CU DIE, so no need
           to create a DIE for the original CUs.  */
        return die;
@@ -21134,19 +21132,21 @@ add_abstract_origin_attribute (dw_die_re
 {
   dw_die_ref origin_die = NULL;
 
-  if (DECL_P (origin))
+  /* For late LTO debug output we want to refer directly to the abstract
+     DIE in the early debug rather to the possibly existing concrete
+     instance and avoid creating that just for this purpose.  */
+  sym_off_pair *desc;
+  if (in_lto_p
+      && external_die_map
+      && (desc = external_die_map->get (origin)))
     {
-      sym_off_pair *desc;
-      if (in_lto_p
-         && external_die_map
-         && (desc = external_die_map->get (origin)))
-       {
-         add_AT_external_die_ref (die, DW_AT_abstract_origin,
-                                  desc->sym, desc->off);
-         return;
-       }
-      origin_die = lookup_decl_die (origin);
+      add_AT_external_die_ref (die, DW_AT_abstract_origin,
+                              desc->sym, desc->off);
+      return;
     }
+
+  if (DECL_P (origin))
+    origin_die = lookup_decl_die (origin);
   else if (TYPE_P (origin))
     origin_die = lookup_type_die (origin);
   else if (TREE_CODE (origin) == BLOCK)
@@ -22458,21 +22458,15 @@ dwarf2out_abstract_function (tree decl)
   if (DECL_IGNORED_P (decl))
     return;
 
-  /* Do not lazily create a DIE for decl here just because we
-     got called via debug_hooks->outlining_inline_function.  */
-  if (in_lto_p
-      && external_die_map
-      && external_die_map->get (decl))
+  /* In LTO we're all set.  We already created abstract instances
+     early and we want to avoid creating a concrete instance of that
+     if we don't output it.  */
+  if (in_lto_p)
     return;
 
   old_die = lookup_decl_die (decl);
-  /* With early debug we always have an old DIE unless we are in LTO
-     and the user did not compile but only link with debug.  */
-  if (in_lto_p && ! old_die)
-    return;
   gcc_assert (old_die != NULL);
-  if (get_AT (old_die, DW_AT_inline)
-      || get_AT (old_die, DW_AT_abstract_origin))
+  if (get_AT (old_die, DW_AT_inline))
     /* We've already generated the abstract instance.  */
     return;
 
@@ -31908,7 +31910,13 @@ dwarf2out_early_finish (const char *file
          unsigned i;
          tree tu;
          FOR_EACH_VEC_SAFE_ELT (all_translation_units, i, tu)
-           maybe_create_die_with_external_ref (tu);
+           if (sym_off_pair *desc = external_die_map->get (tu))
+             {
+               dw_die_ref import = new_die (DW_TAG_imported_unit,
+                                            comp_unit_die (), NULL_TREE);
+               add_AT_external_die_ref (import, DW_AT_import,
+                                        desc->sym, desc->off);
+             }
        }
 
       early_dwarf_finished = true;

Reply via email to