dwarf2out.c (struct die_struct): Add removed flag.
authorRichard Biener <rguenther@suse.de>
Wed, 28 Sep 2016 14:30:19 +0000 (14:30 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 28 Sep 2016 14:30:19 +0000 (14:30 +0000)
2016-09-28  Richard Biener  <rguenther@suse.de>

* dwarf2out.c (struct die_struct): Add removed flag.
(lookup_type_die): If the DIE is marked as removed, clear
TYPE_SYMTAB_DIE and return NULL.
(lookup_decl_die): If the DIE is marked as removed, remove it
from the hash and return NULL.
(mark_removed): New helper.
(prune_unused_types_prune): Call it for removed DIEs.
(gen_subprogram_die): Move the premark_used_types call to after
DIEs for the functions scopes are generated.
(process_scope_var): Do not re-create pruned types or type decls.
Make sure to also re-parent type decls.
(dwarf2out_finish): Move unused type pruning and debug_types
handling ...
(dwarf2out_early_finish): ... here.

From-SVN: r240578

gcc/ChangeLog
gcc/dwarf2out.c

index f69a301d049bdc485461f1b7aff012d07057b5b0..c03ac5358ef18cb7d1c10d231cdbc64c663d87b8 100644 (file)
@@ -1,3 +1,20 @@
+2016-09-28  Richard Biener  <rguenther@suse.de>
+
+       * dwarf2out.c (struct die_struct): Add removed flag.
+       (lookup_type_die): If the DIE is marked as removed, clear
+       TYPE_SYMTAB_DIE and return NULL.
+       (lookup_decl_die): If the DIE is marked as removed, remove it
+       from the hash and return NULL.
+       (mark_removed): New helper.
+       (prune_unused_types_prune): Call it for removed DIEs.
+       (gen_subprogram_die): Move the premark_used_types call to after
+       DIEs for the functions scopes are generated.
+       (process_scope_var): Do not re-create pruned types or type decls.
+       Make sure to also re-parent type decls.
+       (dwarf2out_finish): Move unused type pruning and debug_types
+       handling ...
+       (dwarf2out_early_finish): ... here.
+
 2016-09-29  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc-c.c: New file.
index 51cab42f1a0d141b237cffc0ba353ba124da9291..b6d6aceb9177c72ccdc99ec83cbd1d3af573fd59 100644 (file)
@@ -2687,6 +2687,10 @@ typedef struct GTY((chain_circular ("%h.die_sib"), for_user)) die_struct {
   /* Die is used and must not be pruned as unused.  */
   BOOL_BITFIELD die_perennial_p : 1;
   BOOL_BITFIELD comdat_type_p : 1; /* DIE has a type signature */
+  /* Whether this DIE was removed from the DIE tree, for example via
+     prune_unused_types.  We don't consider those present from the
+     DIE lookup routines.  */
+  BOOL_BITFIELD removed : 1;
   /* Lots of spare bits.  */
 }
 die_node;
@@ -5066,7 +5070,13 @@ new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
 static inline dw_die_ref
 lookup_type_die (tree type)
 {
-  return TYPE_SYMTAB_DIE (type);
+  dw_die_ref die = TYPE_SYMTAB_DIE (type);
+  if (die && die->removed)
+    {
+      TYPE_SYMTAB_DIE (type) = NULL;
+      return NULL;
+    }
+  return die;
 }
 
 /* Given a TYPE_DIE representing the type TYPE, if TYPE is an
@@ -5131,7 +5141,16 @@ decl_die_hasher::equal (die_node *x, tree y)
 static inline dw_die_ref
 lookup_decl_die (tree decl)
 {
-  return decl_die_table->find_with_hash (decl, DECL_UID (decl));
+  dw_die_ref *die = decl_die_table->find_slot_with_hash (decl, DECL_UID (decl),
+                                                        NO_INSERT);
+  if (!die)
+    return NULL;
+  if ((*die)->removed)
+    {
+      decl_die_table->clear_slot (die);
+      return NULL;
+    }
+  return *die;
 }
 
 /* Returns a hash value for X (which really is a var_loc_list).  */
@@ -20415,8 +20434,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
   int declaration = (current_function_decl != decl
                     || class_or_namespace_scope_p (context_die));
 
-  premark_used_types (DECL_STRUCT_FUNCTION (decl));
-
   /* Now that the C++ front end lazily declares artificial member fns, we
      might need to retrofit the declaration into its class.  */
   if (!declaration && !origin && !old_die
@@ -21138,6 +21155,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
       call_site_count = -1;
       tail_call_site_count = -1;
     }
+
+  /* Mark used types after we have created DIEs for the functions scopes.  */
+  premark_used_types (DECL_STRUCT_FUNCTION (decl));
 }
 
 /* Returns a hash value for X (which really is a die_struct).  */
@@ -23221,9 +23241,16 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
 
   if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
     die = lookup_decl_die (decl_or_origin);
-  else if (TREE_CODE (decl_or_origin) == TYPE_DECL
-           && TYPE_DECL_IS_STUB (decl_or_origin))
-    die = lookup_type_die (TREE_TYPE (decl_or_origin));
+  else if (TREE_CODE (decl_or_origin) == TYPE_DECL)
+    {
+      if (TYPE_DECL_IS_STUB (decl_or_origin))
+       die = lookup_type_die (TREE_TYPE (decl_or_origin));
+      else
+       die = lookup_decl_die (decl_or_origin);
+      /* Avoid re-creating the DIE late if it was optimized as unused early.  */
+      if (! die && ! early_dwarf)
+       return;
+    }
   else
     die = NULL;
 
@@ -26176,6 +26203,16 @@ prune_unused_types_update_strings (dw_die_ref die)
       }
 }
 
+/* Mark DIE and its children as removed.  */
+
+static void
+mark_removed (dw_die_ref die)
+{
+  dw_die_ref c;
+  die->removed = true;
+  FOR_EACH_CHILD (die, c, mark_removed (c));
+}
+
 /* Remove from the tree DIE any dies that aren't marked.  */
 
 static void
@@ -26205,12 +26242,14 @@ prune_unused_types_prune (dw_die_ref die)
              die->die_child = prev;
            }
          c->die_sib = NULL;
+         mark_removed (c);
          return;
        }
       else
        {
          next = c->die_sib;
          c->die_sib = NULL;
+         mark_removed (c);
        }
 
     if (c != prev->die_sib)
@@ -27816,32 +27855,6 @@ dwarf2out_finish (const char *)
   resolve_addr (comp_unit_die ());
   move_marked_base_types ();
 
-  if (flag_eliminate_unused_debug_types)
-    prune_unused_types ();
-
-  /* Generate separate COMDAT sections for type DIEs. */
-  if (use_debug_types)
-    {
-      break_out_comdat_types (comp_unit_die ());
-
-      /* Each new type_unit DIE was added to the limbo die list when created.
-         Since these have all been added to comdat_type_list, clear the
-         limbo die list.  */
-      limbo_die_list = NULL;
-
-      /* For each new comdat type unit, copy declarations for incomplete
-         types to make the new unit self-contained (i.e., no direct
-         references to the main compile unit).  */
-      for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
-        copy_decls_for_unworthy_types (ctnode->root_die);
-      copy_decls_for_unworthy_types (comp_unit_die ());
-
-      /* In the process of copying declarations from one unit to another,
-         we may have left some declarations behind that are no longer
-         referenced.  Prune them.  */
-      prune_unused_types ();
-    }
-
   /* Generate separate CUs for each of the include files we've seen.
      They will go into limbo_die_list.  */
   if (flag_eliminate_dwarf2_dups)
@@ -28177,6 +28190,33 @@ dwarf2out_early_finish (const char *filename)
     }
   deferred_asm_name = NULL;
 
+  if (flag_eliminate_unused_debug_types)
+    prune_unused_types ();
+
+  /* Generate separate COMDAT sections for type DIEs. */
+  if (use_debug_types)
+    {
+      break_out_comdat_types (comp_unit_die ());
+
+      /* Each new type_unit DIE was added to the limbo die list when created.
+         Since these have all been added to comdat_type_list, clear the
+         limbo die list.  */
+      limbo_die_list = NULL;
+
+      /* For each new comdat type unit, copy declarations for incomplete
+         types to make the new unit self-contained (i.e., no direct
+         references to the main compile unit).  */
+      for (comdat_type_node *ctnode = comdat_type_list;
+          ctnode != NULL; ctnode = ctnode->next)
+        copy_decls_for_unworthy_types (ctnode->root_die);
+      copy_decls_for_unworthy_types (comp_unit_die ());
+
+      /* In the process of copying declarations from one unit to another,
+         we may have left some declarations behind that are no longer
+         referenced.  Prune them.  */
+      prune_unused_types ();
+    }
+
   /* The early debug phase is now finished.  */
   early_dwarf_finished = true;
 }