This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix ICE in ipa-devirt while building firefox


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]