aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/ipa-devirt.c8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-53.C58
-rw-r--r--gcc/tree.c7
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" } } */
diff --git a/gcc/tree.c b/gcc/tree.c
index 5fd3be1..b6cb9f6 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<tree, tree>;
fld_simplified_types = new hash_map<tree, tree>;