diff options
author | Jan Hubicka <jh@suse.cz> | 2018-11-07 15:12:20 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2018-11-07 14:12:20 +0000 |
commit | 7d3a67d7b0c01c0370226db7840c9ef6e054b56c (patch) | |
tree | 675a9609516280881e63e2682b1801765bd6fe6d /gcc | |
parent | 667b3ec15d86a3d9c22a7469c4353cd9432b4c76 (diff) | |
download | gcc-7d3a67d7b0c01c0370226db7840c9ef6e054b56c.zip gcc-7d3a67d7b0c01c0370226db7840c9ef6e054b56c.tar.gz gcc-7d3a67d7b0c01c0370226db7840c9ef6e054b56c.tar.bz2 |
ipa-devirt.c (odr_types_equivalent_p): Expect constants than const decls in TREE_VALUE of enum.
* 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.
From-SVN: r265875
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 85 | ||||
-rw-r--r-- | gcc/tree.c | 17 |
3 files changed, 93 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 899e3fa..c893ee2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2018-11-07 Jan Hubicka <jh@suse.cz> + + * 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. + 2018-11-07 Richard Biener <rguenther@suse.de> * ipa-inline.c (want_inline_small_function_p): Compute diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index d92e6f4..4676bdb 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1328,9 +1328,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, " 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 ()) + 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++) { - 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; + 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)) { - 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); + 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); } @@ -5345,6 +5345,20 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld) || 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 +13539,8 @@ verify_type_variant (const_tree t, tree tv) } /* 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); |