Commit 7d3a67d7 by Jan Hubicka Committed by Jan Hubicka

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
parent 667b3ec1
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> 2018-11-07 Richard Biener <rguenther@suse.de>
* ipa-inline.c (want_inline_small_function_p): Compute * ipa-inline.c (want_inline_small_function_p): Compute
...@@ -1328,9 +1328,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, ...@@ -1328,9 +1328,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
" is defined in another translation unit")); " is defined in another translation unit"));
return false; return false;
} }
if (TREE_VALUE (v1) != TREE_VALUE (v2) if (TREE_VALUE (v1) != TREE_VALUE (v2))
&& !operand_equal_p (DECL_INITIAL (TREE_VALUE (v1)),
DECL_INITIAL (TREE_VALUE (v2)), 0))
{ {
warn_odr (t1, t2, NULL, NULL, warn, warned, warn_odr (t1, t2, NULL, NULL, warn, warned,
G_("an enum with different values is defined" G_("an enum with different values is defined"
...@@ -2191,6 +2189,7 @@ static void ...@@ -2191,6 +2189,7 @@ static void
dump_type_inheritance_graph (FILE *f) dump_type_inheritance_graph (FILE *f)
{ {
unsigned int i; unsigned int i;
unsigned int num_all_types = 0, num_types = 0, num_duplicates = 0;
if (!odr_types_ptr) if (!odr_types_ptr)
return; return;
fprintf (f, "\n\nType inheritance graph:\n"); fprintf (f, "\n\nType inheritance graph:\n");
...@@ -2201,26 +2200,70 @@ dump_type_inheritance_graph (FILE *f) ...@@ -2201,26 +2200,70 @@ dump_type_inheritance_graph (FILE *f)
} }
for (i = 0; i < odr_types.length (); i++) 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; tree t;
fprintf (f, "Duplicate tree types for odr type %i\n", i); num_duplicates ++;
print_node (f, "", odr_types[i]->type, 0); fprintf (f, "duplicate #%i\n", j);
for (j = 0; j < odr_types[i]->types->length (); 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; t = TYPE_CONTEXT (t);
fprintf (f, "duplicate #%i\n", j); print_node (f, "", t, 0);
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);
} }
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. */ /* Initialize IPA devirt and build inheritance tree graph. */
...@@ -2233,7 +2276,10 @@ build_type_inheritance_graph (void) ...@@ -2233,7 +2276,10 @@ build_type_inheritance_graph (void)
dump_flags_t flags; dump_flags_t flags;
if (odr_hash) if (odr_hash)
return; {
free_enum_values ();
return;
}
timevar_push (TV_IPA_INHERITANCE); timevar_push (TV_IPA_INHERITANCE);
inheritance_dump_file = dump_begin (TDI_inheritance, &flags); inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
odr_hash = new odr_hash_type (23); odr_hash = new odr_hash_type (23);
...@@ -2278,6 +2324,7 @@ build_type_inheritance_graph (void) ...@@ -2278,6 +2324,7 @@ build_type_inheritance_graph (void)
dump_type_inheritance_graph (inheritance_dump_file); dump_type_inheritance_graph (inheritance_dump_file);
dump_end (TDI_inheritance, inheritance_dump_file); dump_end (TDI_inheritance, inheritance_dump_file);
} }
free_enum_values ();
timevar_pop (TV_IPA_INHERITANCE); timevar_pop (TV_IPA_INHERITANCE);
} }
......
...@@ -5345,6 +5345,20 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld) ...@@ -5345,6 +5345,20 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
|| SCALAR_FLOAT_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)
|| FIXED_POINT_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_MIN_VALUE (type));
free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type));
} }
...@@ -13525,7 +13539,8 @@ verify_type_variant (const_tree t, tree tv) ...@@ -13525,7 +13539,8 @@ verify_type_variant (const_tree t, tree tv)
} }
/* Check various uses of TYPE_VALUES_RAW. */ /* 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); verify_variant_match (TYPE_VALUES);
else if (TREE_CODE (t) == ARRAY_TYPE) else if (TREE_CODE (t) == ARRAY_TYPE)
verify_variant_match (TYPE_DOMAIN); verify_variant_match (TYPE_DOMAIN);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment