aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2018-11-07 15:12:20 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2018-11-07 14:12:20 +0000
commit7d3a67d7b0c01c0370226db7840c9ef6e054b56c (patch)
tree675a9609516280881e63e2682b1801765bd6fe6d
parent667b3ec15d86a3d9c22a7469c4353cd9432b4c76 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/ipa-devirt.c85
-rw-r--r--gcc/tree.c17
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);
}
diff --git a/gcc/tree.c b/gcc/tree.c
index b1f4ecf..11c0535 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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);