diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2018-12-27 22:23:30 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2018-12-27 21:23:30 +0000 |
commit | f7293b9dfab5e6e760f65934f76bbaa7184b0f45 (patch) | |
tree | 6a2c9e2c7738fe46774569842e7ff2063b3b67cb /gcc | |
parent | 03b2d3defa7ef8c258d48f4bfbd66a08c27ea19c (diff) | |
download | gcc-f7293b9dfab5e6e760f65934f76bbaa7184b0f45.zip gcc-f7293b9dfab5e6e760f65934f76bbaa7184b0f45.tar.gz gcc-f7293b9dfab5e6e760f65934f76bbaa7184b0f45.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-53.C | 58 | ||||
-rw-r--r-- | gcc/tree.c | 7 |
5 files changed, 84 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8f39f1..310d4f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-12-27 Jan Hubicka <hubicka@ucw.cz> + + * 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 <mliska@suse.cz> PR gcov-profile/88225 diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 399a6e0..4ba0f0b 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -2759,6 +2759,7 @@ struct polymorphic_call_target_d vec <cgraph_node *> 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 302a655..4213903 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-12-27 Jan Hubicka <hubicka@ucw.cz> + + * g++.dg/ipa/devirt-53.C: New testcase. + 2018-12-27 Steven G. Kargl <kargl@gcc.gnu.org> 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 0000000..aea4f54 --- /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 g> 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 <class t> 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<l> a = this; } + }; +}; +c u; +void fn1() { + c v; + k<c> b(&u); + q(new f::L).s(v); +} +/* Check that f::d appears as possible target. */ +/* { dg-final { scan-tree-dump "f::d" "fre" } } */ @@ -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<tree, tree>; fld_simplified_types = new hash_map<tree, tree>; |