[PATCH] Fix PR83941

Richard Biener rguenther@suse.de
Tue Sep 25 13:05:00 GMT 2018


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  <rguenther@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;



More information about the Gcc-patches mailing list