From 32de3b92725b8acd87fb4511651602e68f474130 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sat, 4 Oct 2014 18:29:03 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@215890 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/ipa-polymorphic-call.c | 10 ++++++---- gcc/ipa-prop.c | 5 +++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/ipa/devirt-46.C | 27 +++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/devirt-46.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8bc17b8699..d33827012e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-10-04 Jan Hubicka + + * 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 * common/config/score/score-common.c: Remove. diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index a9b037a5211..ecbd78ce33d 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 c5bcb3a908f..d5ecea41303 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 9db549ee6d3..4672a6830f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-10-04 Jan Hubicka + + * g++.dg/ipa/devirt-46.C: New testcase. + 2014-10-04 Francois-Xavier Coudert 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 00000000000..a6da9c9f62b --- /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" } } */ -- 2.11.4.GIT