On Wed, Nov 7, 2018 at 1:34 PM Jan Hubicka <hubi...@ucw.cz> wrote: > > Hi, > this patch make free_lang_data_in_type to free TYPE_VALUE of enum > unless it is an main variant of ODR type (in that case we use them to > produce ODR warnings). C++ represents enum values as CONST_DECLs that > are expensive to stream and unused, so I also updated free_lang_data to > replace them by C representation that only uses integer constants. > > This needs little change to type verifier. > > In addition to that ipa-devirt now frees the values after ODR warnings. > This reduces ltrans files from 450 to 370MB. > I have also updated duplicate printing to be more pareseable. > > Bootstrapped/regtested x86_64-linux, will commit it after > lto-bootstrapping uneless there are complains.
LGTM > Honza > > * ipa-devirt.c (odr_types_equivalent_p): Expect constants > than const decls in TREE_VALUE of enum. > (dump_type_inheritance_graph): Improve duplicate dumping. > (free_enum_values): New. > (build_type_inheritance_graph): Use it. > * tree.c (free_lang_data_in_type): Free TYPE_VALUES of enums > which are not main variants or not ODR types. > (verify_type_variant): Expect variants to have no TYPE_VALUES. > Index: ipa-devirt.c > =================================================================== > --- ipa-devirt.c (revision 265872) > +++ ipa-devirt.c (working copy) > @@ -1328,9 +1328,7 @@ odr_types_equivalent_p (tree t1, tree t2 > " is defined in another translation unit")); > return false; > } > - if (TREE_VALUE (v1) != TREE_VALUE (v2) > - && !operand_equal_p (DECL_INITIAL (TREE_VALUE (v1)), > - DECL_INITIAL (TREE_VALUE (v2)), 0)) > + if (TREE_VALUE (v1) != TREE_VALUE (v2)) > { > warn_odr (t1, t2, NULL, NULL, warn, warned, > G_("an enum with different values is defined" > @@ -2191,6 +2189,7 @@ static void > dump_type_inheritance_graph (FILE *f) > { > unsigned int i; > + unsigned int num_all_types = 0, num_types = 0, num_duplicates = 0; > if (!odr_types_ptr) > return; > fprintf (f, "\n\nType inheritance graph:\n"); > @@ -2201,26 +2200,70 @@ dump_type_inheritance_graph (FILE *f) > } > for (i = 0; i < odr_types.length (); i++) > { > - if (odr_types[i] && odr_types[i]->types && odr_types[i]->types->length > ()) > - { > - unsigned int j; > - fprintf (f, "Duplicate tree types for odr type %i\n", i); > - print_node (f, "", odr_types[i]->type, 0); > - for (j = 0; j < odr_types[i]->types->length (); j++) > - { > - tree t; > - fprintf (f, "duplicate #%i\n", j); > - print_node (f, "", (*odr_types[i]->types)[j], 0); > - t = (*odr_types[i]->types)[j]; > - while (TYPE_P (t) && TYPE_CONTEXT (t)) > - { > - t = TYPE_CONTEXT (t); > - print_node (f, "", t, 0); > - } > - putc ('\n',f); > + if (!odr_types[i]) > + continue; > + > + num_all_types++; > + if (!odr_types[i]->types || !odr_types[i]->types->length ()) > + continue; > + > + /* To aid ODR warnings we also mangle integer constants but do > + not consinder duplicates there. */ > + if (TREE_CODE (odr_types[i]->type) == INTEGER_TYPE) > + continue; > + > + /* It is normal to have one duplicate and one normal variant. */ > + if (odr_types[i]->types->length () == 1 > + && COMPLETE_TYPE_P (odr_types[i]->type) > + && !COMPLETE_TYPE_P ((*odr_types[i]->types)[0])) > + continue; > + > + num_types ++; > + > + unsigned int j; > + fprintf (f, "Duplicate tree types for odr type %i\n", i); > + print_node (f, "", odr_types[i]->type, 0); > + print_node (f, "", TYPE_NAME (odr_types[i]->type), 0); > + putc ('\n',f); > + for (j = 0; j < odr_types[i]->types->length (); j++) > + { > + tree t; > + num_duplicates ++; > + fprintf (f, "duplicate #%i\n", j); > + print_node (f, "", (*odr_types[i]->types)[j], 0); > + t = (*odr_types[i]->types)[j]; > + while (TYPE_P (t) && TYPE_CONTEXT (t)) > + { > + t = TYPE_CONTEXT (t); > + print_node (f, "", t, 0); > } > + print_node (f, "", TYPE_NAME ((*odr_types[i]->types)[j]), 0); > + putc ('\n',f); > } > } > + fprintf (f, "Out of %i types there are %i types with duplicates; " > + "%i duplicates overall\n", num_all_types, num_types, > num_duplicates); > +} > + > +/* Save some WPA->ltrans streaming by freeing enum values. */ > + > +static void > +free_enum_values () > +{ > + static bool enum_values_freed = false; > + if (enum_values_freed || !flag_wpa || !odr_types_ptr) > + return; > + enum_values_freed = true; > + unsigned int i; > + for (i = 0; i < odr_types.length (); i++) > + if (odr_types[i] && TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE) > + { > + TYPE_VALUES (odr_types[i]->type) = NULL; > + if (odr_types[i]->types) > + for (unsigned int j = 0; j < odr_types[i]->types->length (); j++) > + TYPE_VALUES ((*odr_types[i]->types)[j]) = NULL; > + } > + enum_values_freed = true; > } > > /* Initialize IPA devirt and build inheritance tree graph. */ > @@ -2233,7 +2276,10 @@ build_type_inheritance_graph (void) > dump_flags_t flags; > > if (odr_hash) > - return; > + { > + free_enum_values (); > + return; > + } > timevar_push (TV_IPA_INHERITANCE); > inheritance_dump_file = dump_begin (TDI_inheritance, &flags); > odr_hash = new odr_hash_type (23); > @@ -2278,6 +2324,7 @@ build_type_inheritance_graph (void) > dump_type_inheritance_graph (inheritance_dump_file); > dump_end (TDI_inheritance, inheritance_dump_file); > } > + free_enum_values (); > timevar_pop (TV_IPA_INHERITANCE); > } > > Index: tree.c > =================================================================== > --- tree.c (revision 265872) > +++ tree.c (working copy) > @@ -5345,6 +5348,20 @@ free_lang_data_in_type (tree type, struc > || SCALAR_FLOAT_TYPE_P (type) > || FIXED_POINT_TYPE_P (type)) > { > + if (TREE_CODE (type) == ENUMERAL_TYPE) > + { > + /* Type values are used only for C++ ODR checking. Drop them > + for all type variants and non-ODR types. */ > + if (TYPE_MAIN_VARIANT (type) != type > + || !type_with_linkage_p (type)) > + TYPE_VALUES (type) = NULL; > + else > + /* Simplify representation by recording only values rather > + than const decls. */ > + for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e)) > + if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL) > + TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e)); > + } > free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type)); > free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); > } > @@ -13525,7 +13556,8 @@ verify_type_variant (const_tree t, tree > } > > /* Check various uses of TYPE_VALUES_RAW. */ > - if (TREE_CODE (t) == ENUMERAL_TYPE) > + if (TREE_CODE (t) == ENUMERAL_TYPE > + && TYPE_VALUES (t)) > verify_variant_match (TYPE_VALUES); > else if (TREE_CODE (t) == ARRAY_TYPE) > verify_variant_match (TYPE_DOMAIN);