This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix ICE in ipa-devirt while building firefox
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org, mjambor at suse dot cz
- Date: Fri, 11 Jul 2014 19:38:47 +0200
- Subject: Fix ICE in ipa-devirt while building firefox
- Authentication-results: sourceware.org; auth=none
Hi,
Firefox build ICEs in ipa-devirt (types_same_for_odr) not being able
to establish ODR equivalency for non-polymorphic types. This is because
ipa-prop and ipa-cp does call get_binfo_at_offset where it really wants
to propagate on types and offsets. Before this is fixed this patch avoids
the ICE by not doing the propagation when we don't know what to do.
Bootstrapped/regtested x86_64-linux, comitted.
Honza
* ipa-prop.c (ipa_binfo_from_known_type_jfunc): In LTO do not walk
non-polymorphic types.
* ipa-cp.c (ipa_get_jf_ancestor_result): Likewise.
* ipa-devirt.c (types_same_for_odr): Do not explode when one
of types is not polymorphic.
Index: ipa-prop.c
===================================================================
--- ipa-prop.c (revision 212457)
+++ ipa-prop.c (working copy)
@@ -560,6 +560,19 @@ ipa_binfo_from_known_type_jfunc (struct
if (!base_binfo)
return NULL_TREE;
+ /* FIXME: At LTO we can't propagate to non-polymorphic type, because
+ we have no ODR equivalency on those. This should be fixed by
+ propagating on types rather than binfos that would make type
+ matching here unnecesary. */
+ if (in_lto_p
+ && (TREE_CODE (jfunc->value.known_type.component_type) != RECORD_TYPE
+ || !TYPE_BINFO (jfunc->value.known_type.component_type)
+ || !BINFO_VTABLE (TYPE_BINFO (jfunc->value.known_type.component_type))))
+ {
+ if (!jfunc->value.known_type.offset)
+ return base_binfo;
+ return NULL;
+ }
return get_binfo_at_offset (base_binfo,
jfunc->value.known_type.offset,
jfunc->value.known_type.component_type);
Index: ipa-cp.c
===================================================================
--- ipa-cp.c (revision 212457)
+++ ipa-cp.c (working copy)
@@ -789,6 +789,19 @@ ipa_get_jf_ancestor_result (struct ipa_j
{
if (!ipa_get_jf_ancestor_type_preserved (jfunc))
return NULL;
+ /* FIXME: At LTO we can't propagate to non-polymorphic type, because
+ we have no ODR equivalency on those. This should be fixed by
+ propagating on types rather than binfos that would make type
+ matching here unnecesary. */
+ if (in_lto_p
+ && (TREE_CODE (ipa_get_jf_ancestor_type (jfunc)) != RECORD_TYPE
+ || !TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc))
+ || !BINFO_VTABLE (TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc)))))
+ {
+ if (!ipa_get_jf_ancestor_offset (jfunc))
+ return input;
+ return NULL;
+ }
return get_binfo_at_offset (input,
ipa_get_jf_ancestor_offset (jfunc),
ipa_get_jf_ancestor_type (jfunc));
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 212457)
+++ ipa-devirt.c (working copy)
@@ -341,6 +341,20 @@ types_same_for_odr (const_tree type1, co
|| type_in_anonymous_namespace_p (type2))
return false;
+ /* See if types are obvoiusly different (i.e. different codes
+ or polymorphis wrt non-polymorphic). This is not strictly correct
+ for ODR violating programs, but we can't do better without streaming
+ ODR names. */
+ if (TREE_CODE (type1) != TREE_CODE (type2))
+ return false;
+ if (TREE_CODE (type1) == RECORD_TYPE
+ && (TYPE_BINFO (type1) == NULL_TREE) != (TYPE_BINFO (type1) == NULL_TREE))
+ return false;
+ if (TREE_CODE (type1) == RECORD_TYPE && TYPE_BINFO (type1)
+ && (BINFO_VTABLE (TYPE_BINFO (type1)) == NULL_TREE)
+ != (BINFO_VTABLE (TYPE_BINFO (type2)) == NULL_TREE))
+ return false;
+
/* At the moment we have no way to establish ODR equivlaence at LTO
other than comparing virtual table pointrs of polymorphic types.
Eventually we should start saving mangled names in TYPE_NAME.