cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
authorJan Hubicka <hubicka@ucw.cz>
Fri, 3 Oct 2014 19:52:11 +0000 (21:52 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 3 Oct 2014 19:52:11 +0000 (19:52 +0000)
* cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
* lto-cgraph.c (lto_output_edge, input_edge): Stream
in_polymorphic_cdtor
* cgraph.c (symbol_table::create_edge): Compute in_polymorphic_cdtor.
(cgraph_edge::make_speculative): Copy in_polymorphic_cdtor.
* cgraphclones.c (cgraph_edge::clone): Likewise.
* ipa-prop.c (update_jump_functions_after_inlining,
try_make_edge_direct_virtual_call): Pass in_polymorphic_cdtor
to possible_dynamic_type_change.
(decl_maybe_in_construction_p): Allow empty OUTER_TYPE and BASE.
(ipa_polymorphic_call_context::possible_dynamic_type_change): Add
IN_POLY_CDOTR argument.

From-SVN: r215871

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa-prop.c
gcc/lto-cgraph.c

index 7e1272c82c3540b7fdaf27fbe0deff3c510d35f8..4bf61ab521241bd6c2d79bba57927b3f6b0e05dc 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-03  Jan Hubicka  <hubicka@ucw.cz>
+
+       * cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
+       * lto-cgraph.c (lto_output_edge, input_edge): Stream
+       in_polymorphic_cdtor
+       * cgraph.c (symbol_table::create_edge): Compute in_polymorphic_cdtor.
+       (cgraph_edge::make_speculative): Copy in_polymorphic_cdtor.
+       * cgraphclones.c (cgraph_edge::clone): Likewise.
+       * ipa-prop.c (update_jump_functions_after_inlining, 
+       try_make_edge_direct_virtual_call): Pass in_polymorphic_cdtor
+       to possible_dynamic_type_change.
+       (decl_maybe_in_construction_p): Allow empty OUTER_TYPE and BASE.
+       (ipa_polymorphic_call_context::possible_dynamic_type_change): Add
+       IN_POLY_CDOTR argument.
+
 2014-10-03  Jakub Jelinek  <jakub@redhat.com>
 
        * config/i386/i386.c (ix86_expand_vec_perm_vpermi2): Fix up formatting.
index fdcaf79b3585b7be550cdb071765b0c02f9bed17..a46e1883fd0d24264aeb747c99e99f5f7f2ab6ce 100644 (file)
@@ -819,6 +819,12 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
   edge->indirect_inlining_edge = 0;
   edge->speculative = false;
   edge->indirect_unknown_callee = indir_unknown_callee;
+  if (flag_devirtualize && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
+    edge->in_polymorphic_cdtor
+      = decl_maybe_in_construction_p (NULL, NULL, call_stmt,
+                                     caller->decl);
+  else
+    edge->in_polymorphic_cdtor = caller->thunk.thunk_p;
   if (call_stmt && caller->call_site_hash)
     cgraph_add_edge_to_call_site_hash (edge);
 
@@ -1033,6 +1039,7 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
   else
     e2->can_throw_external = can_throw_external;
   e2->lto_stmt_uid = lto_stmt_uid;
+  e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
   count -= e2->count;
   frequency -= e2->frequency;
   symtab->call_edge_duplication_hooks (this, e2);
index 8bc6fc945d193f122e66a20d305247b701f45915..5ed078acfa9aac563c26bc94c1b9a1f29bc1d38c 100644 (file)
@@ -1333,7 +1333,7 @@ public:
   void offset_by (HOST_WIDE_INT);
   /* Use when we can not track dynamic type change.  This speculatively assume
      type change is not happening.  */
-  void possible_dynamic_type_change (tree otr_type = NULL);
+  void possible_dynamic_type_change (bool, tree otr_type = NULL);
   /* Assume that both THIS and a given context is valid and strenghten THIS
      if possible.  Return true if any strenghtening was made.
      If actual type the context is being used in is known, OTR_TYPE should be
@@ -1512,6 +1512,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
      Optimizers may later redirect direct call to clone, so 1) and 3)
      do not need to necesarily agree with destination.  */
   unsigned int speculative : 1;
+  /* Set to true when caller is a constructor or destructor of polymorphic
+     type.  */
+  unsigned in_polymorphic_cdtor : 1;
 
 private:
   /* Remove the edge from the list of the callers of the callee.  */
index 37b234f78911671392618559e6a11efece770cd3..c487c13f3db277b56f4ddbaaf4d9b53e5aa735ff 100644 (file)
@@ -159,6 +159,7 @@ cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
   new_edge->can_throw_external = can_throw_external;
   new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
   new_edge->speculative = speculative;
+  new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
   if (update_original)
     {
       count -= new_edge->count;
index 5ac5dc5200bc6220ff3b1e44c7415f5de1dd872d..c5bcb3a908f5f44132b07e2b13c450ed17339642 100644 (file)
@@ -2652,7 +2652,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 
              /* TODO: Make type preserved safe WRT contexts.  */
              if (!dst->value.ancestor.agg_preserved)
-               ctx.possible_dynamic_type_change ();
+               ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
              ctx.offset_by (dst->value.ancestor.offset);
              if (!ctx.useless_p ())
                {
@@ -2722,7 +2722,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 
                  /* TODO: Make type preserved safe WRT contexts.  */
                  if (!dst->value.ancestor.agg_preserved)
-                   ctx.possible_dynamic_type_change ();
+                   ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
                  if (!ctx.useless_p ())
                    {
                      if (!dst_ctx)
@@ -3128,7 +3128,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
 
       /* TODO: We want to record if type change happens.  
         Old code did not do that that seems like a bug.  */
-      ctx.possible_dynamic_type_change (ie->indirect_info->otr_type);
+      ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
+                                       ie->indirect_info->otr_type);
 
       updated = ie->indirect_info->context.combine_with
                  (ctx, ie->indirect_info->otr_type);
index 0584946d5b0edf4f70c1639b8a61c0422b46557a..a48e61eb89339e8e28837d7a79c32ee1803a05c7 100644 (file)
@@ -284,6 +284,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
   bp_pack_value (&bp, edge->speculative, 1);
   bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
   bp_pack_value (&bp, edge->can_throw_external, 1);
+  bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
   if (edge->indirect_unknown_callee)
     {
       int flags = edge->indirect_info->ecf_flags;
@@ -1366,6 +1367,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes,
   edge->inline_failed = inline_failed;
   edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1);
   edge->can_throw_external = bp_unpack_value (&bp, 1);
+  edge->in_polymorphic_cdtor = bp_unpack_value (&bp, 1);
   if (indirect)
     {
       if (bp_unpack_value (&bp, 1))