aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-devirt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r--gcc/ipa-devirt.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index b72789c..8c375ff 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2025,6 +2025,8 @@ get_odr_type (tree type, bool insert)
if ((!slot || !*slot) && in_lto_p && can_be_vtable_hashed_p (type))
{
hash = hash_odr_vtable (type);
+ if (!odr_vtable_hash)
+ odr_vtable_hash = new odr_vtable_hash_type (23);
vtable_slot = odr_vtable_hash->find_slot_with_hash (type, hash,
insert ? INSERT : NO_INSERT);
}
@@ -2289,27 +2291,43 @@ dump_type_inheritance_graph (FILE *f)
"%i duplicates overall\n", num_all_types, num_types, num_duplicates);
}
-/* Save some WPA->ltrans streaming by freeing enum values. */
+/* Save some WPA->ltrans streaming by freeing stuff needed only for good
+ ODR warnings.
+ We free TYPE_VALUES of enums and also make TYPE_DECLs to not point back
+ to the type (which is needed to keep them in the same SCC and preserve
+ location information to output warnings) and subsequently we make all
+ TYPE_DECLS of same assembler name equivalent. */
static void
-free_enum_values ()
+free_odr_warning_data ()
{
- static bool enum_values_freed = false;
- if (enum_values_freed || !flag_wpa || !odr_types_ptr)
+ static bool odr_data_freed = false;
+
+ if (odr_data_freed || !flag_wpa || !odr_types_ptr)
return;
- enum_values_freed = true;
- unsigned int i;
- for (i = 0; i < odr_types.length (); i++)
+
+ odr_data_freed = true;
+
+ for (unsigned int i = 0; i < odr_types.length (); i++)
if (odr_types[i])
{
- if (TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE)
- TYPE_VALUES (odr_types[i]->type) = NULL;
+ tree t = odr_types[i]->type;
+
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ TYPE_VALUES (t) = NULL;
+ TREE_TYPE (TYPE_NAME (t)) = void_type_node;
+
if (odr_types[i]->types)
for (unsigned int j = 0; j < odr_types[i]->types->length (); j++)
- if (TREE_CODE ((*odr_types[i]->types)[j]) == ENUMERAL_TYPE)
- TYPE_VALUES ((*odr_types[i]->types)[j]) = NULL;
+ {
+ tree td = (*odr_types[i]->types)[j];
+
+ if (TREE_CODE (td) == ENUMERAL_TYPE)
+ TYPE_VALUES (td) = NULL;
+ TYPE_NAME (td) = TYPE_NAME (t);
+ }
}
- enum_values_freed = true;
+ odr_data_freed = true;
}
/* Initialize IPA devirt and build inheritance tree graph. */
@@ -2323,7 +2341,7 @@ build_type_inheritance_graph (void)
if (odr_hash)
{
- free_enum_values ();
+ free_odr_warning_data ();
return;
}
timevar_push (TV_IPA_INHERITANCE);
@@ -2370,7 +2388,7 @@ build_type_inheritance_graph (void)
dump_type_inheritance_graph (inheritance_dump_file);
dump_end (TDI_inheritance, inheritance_dump_file);
}
- free_enum_values ();
+ free_odr_warning_data ();
timevar_pop (TV_IPA_INHERITANCE);
}