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. Because instantiations typically happen in .cc files, and the resulting type definition is unlikely to be useful as a comdat type unit, this patch avoids the problem by choosing not to move template instantiations into type units.
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-25 Cary Coutant <ccout...@google.com> gcc/ * dwarf2out.c (is_template_instantiation): New function. (should_move_die_to_comdat): Reject types that are template instantiations. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 190681) +++ gcc/dwarf2out.c (working copy) @@ -7277,6 +7277,21 @@ contains_subprogram_definition (dw_die_r return 0; } +/* Return non-zero if this DIE represents a template instantiation. */ + +static int +is_template_instantiation (dw_die_ref die) +{ + dw_die_ref c; + + FOR_EACH_CHILD (die, c, + if (c->die_tag == DW_TAG_template_type_param + || c->die_tag == DW_TAG_template_value_param + || c->die_tag == DW_TAG_GNU_template_template_param) + return 1); + return 0; +} + /* Return non-zero if this is a type DIE that should be moved to a COMDAT .debug_types section. */ @@ -7294,6 +7309,7 @@ should_move_die_to_comdat (dw_die_ref di if (is_declaration_die (die) || get_AT (die, DW_AT_abstract_origin) || is_nested_in_subprogram (die) + || is_template_instantiation (die) || contains_subprogram_definition (die)) return 0; return 1;