aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-10-04 20:29:03 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-10-04 18:29:03 +0000
commit049e6d36cd8661e7dc1c7dc474cb6b1227543af6 (patch)
tree1163da82a2e60b73864668cdd54636ba6277fe01
parent3daa7bbf7912030a760199f31a0926a11365a76f (diff)
downloadgcc-049e6d36cd8661e7dc1c7dc474cb6b1227543af6.zip
gcc-049e6d36cd8661e7dc1c7dc474cb6b1227543af6.tar.gz
gcc-049e6d36cd8661e7dc1c7dc474cb6b1227543af6.tar.bz2
devirt-46.C: New testcase.
* g++.dg/ipa/devirt-46.C: New testcase. * ipa-prop.c (ipa_compute_jump_functions_for_edge): Call get_dynamic_type; drop TODO. * ipa-polymorphic-call.c (ipa_polymorphic_call_context::get_dynamic_type): Be ready for otr_type to be unknown. From-SVN: r215890
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-polymorphic-call.c10
-rw-r--r--gcc/ipa-prop.c5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-46.C27
5 files changed, 48 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8bc17b..d338270 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2014-10-04 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-prop.c (ipa_compute_jump_functions_for_edge): Call
+ get_dynamic_type; drop TODO.
+ * ipa-polymorphic-call.c
+ (ipa_polymorphic_call_context::get_dynamic_type): Be ready
+ for otr_type to be unknown.
+
2014-10-04 Trevor Saunders <tsaunders@mozilla.com>
* common/config/score/score-common.c: Remove.
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index a9b037a..ecbd78c 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -1390,12 +1390,13 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
This is because we do not update INSTANCE when walking inwards. */
HOST_WIDE_INT instance_offset = offset;
- otr_type = TYPE_MAIN_VARIANT (otr_type);
+ if (otr_type)
+ otr_type = TYPE_MAIN_VARIANT (otr_type);
/* Walk into inner type. This may clear maybe_derived_type and save us
from useless work. It also makes later comparsions with static type
easier. */
- if (outer_type)
+ if (outer_type && otr_type)
{
if (!restrict_to_inner_class (otr_type))
return false;
@@ -1484,8 +1485,9 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
/* We look for vtbl pointer read. */
ao.size = POINTER_SIZE;
ao.max_size = ao.size;
- ao.ref_alias_set
- = get_deref_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
+ if (otr_type)
+ ao.ref_alias_set
+ = get_deref_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
if (dump_file)
{
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c5bcb3a..d5ecea4 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1898,10 +1898,11 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
tree param_type = ipa_get_callee_param_type (cs, n);
if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
{
+ tree instance;
struct ipa_polymorphic_call_context context (cs->caller->decl,
arg, cs->call_stmt,
- NULL);
- /* TODO: We should also handle dynamic types. */
+ &instance);
+ context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
*ipa_get_ith_polymorhic_call_context (args, n) = context;
if (!context.useless_p ())
useful_context = true;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9db549e..4672a68 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-10-04 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/ipa/devirt-46.C: New testcase.
+
2014-10-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/36534
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-46.C b/gcc/testsuite/g++.dg/ipa/devirt-46.C
new file mode 100644
index 0000000..a6da9c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-46.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-ipa-cp -fdump-ipa-inline-details -fno-early-inlining -fdump-tree-optimized" } */
+struct A {
+ virtual int foo(){return 1;}
+};
+struct B:A {
+ virtual int foo(){return 2;}
+};
+static void
+test (struct A *a)
+{
+ if (a->foo() != 2)
+ __builtin_abort ();
+}
+int
+m()
+{
+ struct A *a = new B;
+ test (a);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a speculative target\[^\\n\]*B::foo" 1 "inline" } } */
+/* { dg-final { scan-ipa-dump-not "OBJ_TYPE_REF" "optimized" } } */
+/* { dg-final { scan-ipa-dump-not "abort" "optimized" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
+/* { dg-final { cleanup-ipa-dump "optimized" } } */