aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-cp.c13
-rw-r--r--gcc/ipa-devirt.c14
-rw-r--r--gcc/ipa-prop.c13
4 files changed, 48 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c7f0fd4..8bc3edf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2014-07-11 Jan Hubicka <hubicka@ucw.cz>
+
+ * 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.
+
2014-07-11 Vladimir Makarov <vmakarov@redhat.com>
* lra-constraints.c (remove_inheritance_pseudos): Process
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index b6d66d9..224b03a 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -789,6 +789,19 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
{
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));
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index e7add12..82b064b 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -341,6 +341,20 @@ types_same_for_odr (const_tree type1, const_tree type2)
|| 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.
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c6dd610..9ed9e5b 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -560,6 +560,19 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
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);