This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[google/gcc-4_7, trunk] Fix problem with -fdebug-types-section and template instantiations, take 2
- From: ccoutant at google dot com (Cary Coutant)
- To: gcc-patches at gcc dot gnu dot org, jason at redhat dot com, saugustine at google dot com
- Date: Tue, 28 Aug 2012 22:56:54 -0700 (PDT)
- Subject: [google/gcc-4_7, trunk] Fix problem with -fdebug-types-section and template instantiations, take 2
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.
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);