Patchwork [google/gcc-4_7,trunk] Fix problem with -fdebug-types-section and template instantiations, take 2

login
register
mail settings
Submitter Cary Coutant
Date Aug. 29, 2012, 5:56 a.m.
Message ID <20120829055654.B777DE0838@ccoutant.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/180623/
State New
Headers show

Comments

Cary Coutant - Aug. 29, 2012, 5:56 a.m.
This patch is for trunk and the google/gcc-4_7 branch.

When a class template instantiation is moved into a separate type unit,
it can bring along a lot of other referenced types into the type unit,
especially if the template is derived from another (large) type that
does not have an actually have a type definition in a type unit of its
own. When there are many instantiations of the same template, we get
a lot of duplication, and in the worst case (a template with several
parameters, instantiated multiple times along each dimension), GCC
can end up taking a long time and exhausting available memory.

This combinatorial explosion is being caused by copy_decls_walk, where
it finds a type DIE that is referenced by the type unit, but is not
itself a type unit, and copies a declaration for that type into the
type unit in order to resolve the reference within the type unit.
In the process, copy_decls_walk also copies all of the children of
that DIE. In the case of a base class with member function templates,
every one of the instantiated member functions is copied into every
type unit that references the base class.

I don't believe that it's necessary to copy the children of the class
declaration at all, and this patch simply removes the code that copies
those children. If there's a reference in the type unit to one of the
children of that class, that one child will get copied in as needed.

Bootstraps and passes regression tests. Also tested with a large
internal test case that previously resulted in out-of-memory during
compilation.

Google ref b/7041390.


2012-08-28   Cary Coutant  <ccoutant@google.com>

	* gcc/dwarf2out.c (clone_tree_partial): Remove.
	(copy_decls_walk): Don't copy children of a declaration
	into a type unit.
Hans-Peter Nilsson - Aug. 29, 2012, 6:12 a.m.
On Tue, 28 Aug 2012, Cary Coutant wrote:
> 2012-08-28   Cary Coutant  <ccoutant@google.com>
>
> 	* gcc/dwarf2out.c (clone_tree_partial): Remove.
> 	(copy_decls_walk): Don't copy children of a declaration
> 	into a type unit.

Can't say anything about the patch but watch out with the
changelog entry: put it in the gcc/ChangeLog but without the
"gcc/" prefix.

brgds, H-P
Cary Coutant - Aug. 29, 2012, 7:03 p.m.
> This patch is for trunk and the google/gcc-4_7 branch.
>
> 2012-08-28   Cary Coutant  <ccoutant@google.com>
>
>         * gcc/dwarf2out.c (clone_tree_partial): Remove.
>         (copy_decls_walk): Don't copy children of a declaration
>         into a type unit.

For trunk, I've submitted a new patch that combines this one with a
previous pending patch.

Still looking for an approval for google/gcc-4_7 branch...

-cary
Sterling Augustine - Aug. 29, 2012, 7:06 p.m.
On Wed, Aug 29, 2012 at 12:03 PM, Cary Coutant <ccoutant@google.com> wrote:
>> This patch is for trunk and the google/gcc-4_7 branch.
>>
>> 2012-08-28   Cary Coutant  <ccoutant@google.com>
>>
>>         * gcc/dwarf2out.c (clone_tree_partial): Remove.
>>         (copy_decls_walk): Don't copy children of a declaration
>>         into a type unit.
>
> For trunk, I've submitted a new patch that combines this one with a
> previous pending patch.
>
> Still looking for an approval for google/gcc-4_7 branch...
>
> -cary

This is OK for google 4.7

Patch

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 190681)
+++ gcc/dwarf2out.c	(working copy)
@@ -7745,40 +7745,6 @@  copy_ancestor_tree (dw_die_ref unit, dw_
   return copy;
 }
 
-/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations.
-   Enter all the cloned children into the hash table decl_table.  */
-
-static dw_die_ref
-clone_tree_partial (dw_die_ref die, htab_t decl_table)
-{
-  dw_die_ref c;
-  dw_die_ref clone;
-  struct decl_table_entry *entry;
-  void **slot;
-
-  if (die->die_tag == DW_TAG_subprogram)
-    clone = clone_as_declaration (die);
-  else
-    clone = clone_die (die);
-
-  slot = htab_find_slot_with_hash (decl_table, die,
-				   htab_hash_pointer (die), INSERT);
-  /* Assert that DIE isn't in the hash table yet.  If it would be there
-     before, the ancestors would be necessarily there as well, therefore
-     clone_tree_partial wouldn't be called.  */
-  gcc_assert (*slot == HTAB_EMPTY_ENTRY);
-  entry = XCNEW (struct decl_table_entry);
-  entry->orig = die;
-  entry->copy = clone;
-  *slot = entry;
-
-  if (die->die_tag != DW_TAG_subprogram)
-    FOR_EACH_CHILD (die, c,
-		    add_child_die (clone, clone_tree_partial (c, decl_table)));
-
-  return clone;
-}
-
 /* Walk the DIE and its children, looking for references to incomplete
    or trivial types that are unmarked (i.e., that are not in the current
    type_unit).  */
@@ -7826,11 +7792,6 @@  copy_decls_walk (dw_die_ref unit, dw_die
               entry->copy = copy;
               *slot = entry;
 
-	      FOR_EACH_CHILD (targ, c,
-			      add_child_die (copy,
-					     clone_tree_partial (c,
-								 decl_table)));
-
               /* Make sure the cloned tree is marked as part of the
                  type unit.  */
               mark_dies (copy);