From f7293b9dfab5e6e760f65934f76bbaa7184b0f45 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 27 Dec 2018 22:23:30 +0100 Subject: [PATCH] ipa-devirt.c (polymorphic_call_target_d): Add n_odr_types. * ipa-devirt.c (polymorphic_call_target_d): Add n_odr_types. (polymorphic_call_target_hasher::hash): Hash it. (polymorphic_call_target_hasher::equal): Compare it. (possible_polymorphic_call_targets): Set it. * tree.c (free_lang_data): Rebuild type inheritance graph even on non-LTO path. * g++.dg/ipa/devirt-53.C: New testcase. From-SVN: r267438 --- gcc/ChangeLog | 9 +++++ gcc/ipa-devirt.c | 8 +++- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/ipa/devirt-53.C | 58 ++++++++++++++++++++++++++++ gcc/tree.c | 7 +++- 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/devirt-53.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8f39f1e1a2..310d4f03e0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-12-27 Jan Hubicka + + * ipa-devirt.c (polymorphic_call_target_d): Add n_odr_types. + (polymorphic_call_target_hasher::hash): Hash it. + (polymorphic_call_target_hasher::equal): Compare it. + (possible_polymorphic_call_targets): Set it. + * tree.c (free_lang_data): Rebuild type inheritance graph even on + non-LTO path. + 2018-12-27 Martin Liska PR gcov-profile/88225 diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 399a6e027cf..4ba0f0b330f 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -2759,6 +2759,7 @@ struct polymorphic_call_target_d vec targets; tree decl_warning; int type_warning; + unsigned int n_odr_types; bool complete; bool speculative; }; @@ -2784,6 +2785,7 @@ polymorphic_call_target_hasher::hash (const polymorphic_call_target_d *odr_query hstate.add_hwi (odr_query->type->id); hstate.merge_hash (TYPE_UID (odr_query->context.outer_type)); hstate.add_hwi (odr_query->context.offset); + hstate.add_hwi (odr_query->n_odr_types); if (odr_query->context.speculative_outer_type) { @@ -2814,7 +2816,9 @@ polymorphic_call_target_hasher::equal (const polymorphic_call_target_d *t1, == t2->context.maybe_in_construction && t1->context.maybe_derived_type == t2->context.maybe_derived_type && (t1->context.speculative_maybe_derived_type - == t2->context.speculative_maybe_derived_type)); + == t2->context.speculative_maybe_derived_type) + /* Adding new type may affect outcome of target search. */ + && t1->n_odr_types == t2->n_odr_types); } /* Remove entry in polymorphic call target cache hash. */ @@ -3220,6 +3224,7 @@ possible_polymorphic_call_targets (tree otr_type, key.otr_token = otr_token; key.speculative = speculative; key.context = context; + key.n_odr_types = odr_types.length (); slot = polymorphic_call_target_hash->find_slot (&key, INSERT); if (cache_token) *cache_token = (void *)*slot; @@ -3436,6 +3441,7 @@ possible_polymorphic_call_targets (tree otr_type, (*slot)->targets = nodes; (*slot)->complete = complete; + (*slot)->n_odr_types = odr_types.length (); if (completep) *completep = complete; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 302a6550e07..42139037936 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-12-27 Jan Hubicka + + * g++.dg/ipa/devirt-53.C: New testcase. + 2018-12-27 Steven G. Kargl PR fortran/81027 diff --git a/gcc/testsuite/g++.dg/ipa/devirt-53.C b/gcc/testsuite/g++.dg/ipa/devirt-53.C new file mode 100644 index 00000000000..aea4f54346f --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-53.C @@ -0,0 +1,58 @@ +// { dg-do assemble } +// { dg-options "-O2 -fdump-tree-fre1-details -std=c++11 -Wno-return-type" } +typedef unsigned a; +enum b : a; +class c { +public: + virtual a d(); +}; +using e = int; +class f; +class h { +public: + f *operator->(); +}; +class i { +public: + ~i() { j->d(); } + c *j; +}; +template class k : i { +public: + k(g *); +}; +class l; +class m { + virtual b n(const e &, l **); +}; +class o { +protected: + h p; +}; +class G { + virtual b r(const e &, l **); +}; +class l : G {}; +class q { +public: + q(l *); + template void s(t); +}; +class f : c { + a d(); + virtual b r(e); + +public: + class L : public l, o, m { + b r(const e &y, l **) { p->r(y); } + b n(const e &, l **) { k a = this; } + }; +}; +c u; +void fn1() { + c v; + k b(&u); + q(new f::L).s(v); +} +/* Check that f::d appears as possible target. */ +/* { dg-final { scan-tree-dump "f::d" "fre" } } */ diff --git a/gcc/tree.c b/gcc/tree.c index 5fd3be1e1f3..b6cb9f6f7b2 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6191,7 +6191,12 @@ free_lang_data (void) /* If we are the LTO frontend we have freed lang-specific data already. */ if (in_lto_p || (!flag_generate_lto && !flag_generate_offload)) - return 0; + { + /* Rebuild type inheritance graph even when not doing LTO to get + consistent profile data. */ + rebuild_type_inheritance_graph (); + return 0; + } fld_incomplete_types = new hash_map; fld_simplified_types = new hash_map; -- 2.30.2