ipa-devirt.c (polymorphic_call_target_d): Add n_odr_types.
authorJan Hubicka <hubicka@ucw.cz>
Thu, 27 Dec 2018 21:23:30 +0000 (22:23 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 27 Dec 2018 21:23:30 +0000 (21:23 +0000)
* 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
gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/devirt-53.C [new file with mode: 0644]
gcc/tree.c

index b8f39f1e1a290189afa64ebbed63d357edd0c342..310d4f03e0a07837bc1858aae73cfd4c8a0fa630 100644 (file)
@@ -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
index 399a6e027cf6daff2060cef1f1b1a67ec5634186..4ba0f0b330f6c99bf0fc64e9084e24d2f7471ebf 100644 (file)
@@ -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;
 
index 302a6550e07856b8dc26ebfb391c0569220dff51..4213903793641ac24de9ba33758374fe9d7bb752 100644 (file)
@@ -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 (file)
index 0000000..aea4f54
--- /dev/null
@@ -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"  } } */
index 5fd3be1e1f3d6abd359e9eb35ece40d7419be450..b6cb9f6f7b25683cceed995dd12090b7b561adab 100644 (file)
@@ -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>;