]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.
authorJan Hubicka <hubicka@ucw.cz>
Tue, 29 Jul 2014 09:39:06 +0000 (11:39 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 29 Jul 2014 09:39:06 +0000 (09:39 +0000)
* cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.
* cgraph.h (cgraph_indirect_call_info): Add speculative data.
* gimple-fold.c (fold_gimple_assign): Fix check for virtual
call.
* ipa-devirt.c (ipa_dummy_polymorphic_call_context): Update
(contains_type_p): Forward declare.
(polymorphic_call_target_hasher::hash): Hash speculative info.
(polymorphic_call_target_hasher::equal): Compare speculative info.
(get_class_context): Handle speuclation.
(contains_type_p): Update.
(get_polymorphic_call_info_for_decl): Update.
(walk_ssa_copies): Break out from ...
(get_polymorphic_call_info): ... here; set speculative context
before giving up.
* ipa-prop.c (ipa_write_indirect_edge_info, ipa_read_indirect_edge_info):
Stream speculative context.
* ipa-utils.h (ipa_polymorphic_call_context): Add speculative info
(SPECULATIVE_OFFSET, SPECULATIVE_OUTER_TYPE,
SPECULATIVE_MAYBE_DERIVED_TYPE).
(possible_polymorphic_call_targets overriders): Update.
(dump_possible_polymorphic_call_targets overriders): Update.
(dump_possible_polymorphic_call_target_p overriders): Update.

From-SVN: r213152

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-devirt.c
gcc/ipa-prop.c
gcc/ipa-utils.h

index 8f1a133261e85aeec008396d7350680f05a3b5b4..484a5e18101a4a079e5ab2c9c73c214dd177a43b 100644 (file)
@@ -1,3 +1,28 @@
+2014-07-28  Jan Hubicka  <hubicka@ucw.cz>
+
+       * cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.
+       * cgraph.h (cgraph_indirect_call_info): Add speculative data.
+       * gimple-fold.c (fold_gimple_assign): Fix check for virtual
+       call.
+       * ipa-devirt.c (ipa_dummy_polymorphic_call_context): Update
+       (contains_type_p): Forward declare.
+       (polymorphic_call_target_hasher::hash): Hash speculative info.
+       (polymorphic_call_target_hasher::equal): Compare speculative info.
+       (get_class_context): Handle speuclation.
+       (contains_type_p): Update.
+       (get_polymorphic_call_info_for_decl): Update.
+       (walk_ssa_copies): Break out from ...
+       (get_polymorphic_call_info): ... here; set speculative context
+       before giving up.
+       * ipa-prop.c (ipa_write_indirect_edge_info, ipa_read_indirect_edge_info):
+       Stream speculative context.
+       * ipa-utils.h (ipa_polymorphic_call_context): Add speculative info
+       (SPECULATIVE_OFFSET, SPECULATIVE_OUTER_TYPE,
+       SPECULATIVE_MAYBE_DERIVED_TYPE).
+       (possible_polymorphic_call_targets overriders): Update.
+       (dump_possible_polymorphic_call_targets overriders): Update.
+       (dump_possible_polymorphic_call_target_p overriders): Update.
+
 2014-07-28  Jan Hubicka  <hubicka@ucw.cz>
 
        * gimple-fold.c (fold_gimple_assign): Fix condition guarding
index a5d07496f0a7a6fb7ec574cc7c2a94d760570db7..52f9985694a0d50331eeb75d7cca1a790590899d 100644 (file)
@@ -973,10 +973,15 @@ cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags,
       edge->indirect_info->otr_token = otr_token;
       edge->indirect_info->otr_type = otr_type;
       edge->indirect_info->outer_type = context.outer_type;
+      edge->indirect_info->speculative_outer_type
+        = context.speculative_outer_type;
       edge->indirect_info->offset = context.offset;
+      edge->indirect_info->speculative_offset = context.speculative_offset;
       edge->indirect_info->maybe_in_construction
         = context.maybe_in_construction;
       edge->indirect_info->maybe_derived_type = context.maybe_derived_type;
+      edge->indirect_info->speculative_maybe_derived_type
+        = context.speculative_maybe_derived_type;
     }
 
   edge->next_callee = indirect_calls;
@@ -3043,12 +3048,9 @@ cgraph_node::get_body (void)
   data = lto_get_section_data (file_data, LTO_section_function_body,
                               name, &len);
   if (!data)
-    {
-       debug ();
     fatal_error ("%s: section %s is missing",
                 file_data->file_name,
                 name);
-    }
 
   gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
 
index f8f76c42d6ca039809a96d7de353f4af888fef4f..d8651e2f6f390730bdb7814cd07e8bcc4423fb85 100644 (file)
@@ -1243,11 +1243,11 @@ struct GTY(()) cgraph_indirect_call_info
      was actually used in the polymorphic resides within a larger structure.
      If agg_contents is set, the field contains the offset within the aggregate
      from which the address to call was loaded.  */
-  HOST_WIDE_INT offset;
+  HOST_WIDE_INT offset, speculative_offset;
   /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set).  */
   HOST_WIDE_INT otr_token;
   /* Type of the object from OBJ_TYPE_REF_OBJECT. */
-  tree otr_type, outer_type;
+  tree otr_type, outer_type, speculative_outer_type;
   /* Index of the parameter that is called.  */
   int param_index;
   /* ECF flags determined from the caller.  */
@@ -1270,6 +1270,7 @@ struct GTY(()) cgraph_indirect_call_info
   unsigned by_ref : 1;
   unsigned int maybe_in_construction : 1;
   unsigned int maybe_derived_type : 1;
+  unsigned int speculative_maybe_derived_type : 1;
 };
 
 struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
index 127d58d775d2dd8a2f71b27adfbc7e51c614d8fc..4b5b2a659c0f60b1b46fa3fcd497c4b129265d72 100644 (file)
@@ -141,7 +141,7 @@ static bool odr_violation_reported = false;
 /* Dummy polymorphic call context.  */
 
 const ipa_polymorphic_call_context ipa_dummy_polymorphic_call_context
-   = {0, NULL, false, true};
+   = {0, 0, NULL, NULL, false, true, true};
 
 /* Pointer set of all call targets appearing in the cache.  */
 static pointer_set_t *cached_polymorphic_call_targets;
@@ -175,6 +175,8 @@ struct GTY(()) odr_type_d
   bool odr_violated;
 };
 
+static bool contains_type_p (tree, HOST_WIDE_INT, tree);
+
 
 /* Return true if BINFO corresponds to a type with virtual methods. 
 
@@ -1641,8 +1643,16 @@ polymorphic_call_target_hasher::hash (const value_type *odr_query)
   hash = iterative_hash_hashval_t (TYPE_UID (odr_query->context.outer_type),
                                   hash);
   hash = iterative_hash_host_wide_int (odr_query->context.offset, hash);
+  if (odr_query->context.speculative_outer_type)
+    {
+      hash = iterative_hash_hashval_t
+              (TYPE_UID (odr_query->context.speculative_outer_type), hash);
+      hash = iterative_hash_host_wide_int (odr_query->context.speculative_offset,
+                                          hash);
+    }
   return iterative_hash_hashval_t
-           (((int)odr_query->context.maybe_in_construction << 1)
+           (((int)odr_query->context.maybe_in_construction << 2)
+            | ((int)odr_query->context.speculative_maybe_derived_type << 1)
             | (int)odr_query->context.maybe_derived_type, hash);
 }
 
@@ -1654,10 +1664,14 @@ polymorphic_call_target_hasher::equal (const value_type *t1,
 {
   return (t1->type == t2->type && t1->otr_token == t2->otr_token
          && t1->context.offset == t2->context.offset
+         && t1->context.speculative_offset == t2->context.speculative_offset
          && t1->context.outer_type == t2->context.outer_type
+         && t1->context.speculative_outer_type == t2->context.speculative_outer_type
          && t1->context.maybe_in_construction
              == t2->context.maybe_in_construction
-         && t1->context.maybe_derived_type == t2->context.maybe_derived_type);
+         && t1->context.maybe_derived_type == t2->context.maybe_derived_type
+         && (t1->context.speculative_maybe_derived_type
+             == t2->context.speculative_maybe_derived_type));
 }
 
 /* Remove entry in polymorphic call target cache hash.  */
@@ -1750,9 +1764,42 @@ get_class_context (ipa_polymorphic_call_context *context,
 {
   tree type = context->outer_type;
   HOST_WIDE_INT offset = context->offset;
-
+  bool speculative = false;
+  bool speculation_valid = false;
+  bool valid = false;
+
+ if (!context->outer_type)
+   {
+     context->outer_type = expected_type;
+     context->offset = offset;
+   }
+  /* See if speculative type seem to be derrived from outer_type.
+     Then speculation is valid only if it really is a derivate and derived types
+     are allowed.  
+
+     The test does not really look for derivate, but also accepts the case where
+     outer_type is a field of speculative_outer_type.  In this case eiter
+     MAYBE_DERIVED_TYPE is false and we have full non-speculative information or
+     the loop bellow will correctly update SPECULATIVE_OUTER_TYPE
+     and SPECULATIVE_MAYBE_DERIVED_TYPE.  */
+  if (context->speculative_outer_type
+      && context->speculative_offset >= context->offset
+      && contains_type_p (context->speculative_outer_type,
+                         context->offset - context->speculative_offset,
+                         context->outer_type))
+    speculation_valid = context->maybe_derived_type;
+  else
+    {
+      context->speculative_outer_type = NULL;
+      context->speculative_offset = 0;
+      context->speculative_maybe_derived_type = false;
+    }
+                              
   /* Find the sub-object the constant actually refers to and mark whether it is
-     an artificial one (as opposed to a user-defined one).  */
+     an artificial one (as opposed to a user-defined one).
+
+     This loop is performed twice; first time for outer_type and second time
+     for speculative_outer_type.  The second iteration has SPECULATIVE set.  */
   while (true)
     {
       HOST_WIDE_INT pos, size;
@@ -1762,12 +1809,51 @@ get_class_context (ipa_polymorphic_call_context *context,
       if (TREE_CODE (type) == TREE_CODE (expected_type)
          && types_same_for_odr (type, expected_type))
        {
-         /* Type can not contain itself on an non-zero offset.  In that case
-            just give up.  */
-         if (offset != 0)
-           goto give_up;
-         gcc_assert (offset == 0);
-         return true;
+         if (speculative)
+           {
+             gcc_assert (speculation_valid);
+             gcc_assert (valid);
+
+             /* If we did not match the offset, just give up on speculation.  */
+             if (offset != 0
+                 || (types_same_for_odr (context->speculative_outer_type,
+                                         context->outer_type)
+                     && (context->maybe_derived_type
+                         == context->speculative_maybe_derived_type)))
+               {
+                 context->speculative_outer_type = NULL;
+                 context->speculative_offset = 0;
+               }
+             return true;
+           }
+         else
+           {
+             /* Type can not contain itself on an non-zero offset.  In that case
+                just give up.  */
+             if (offset != 0)
+               {
+                 valid = false;
+                 goto give_up;
+               }
+             valid = true;
+             /* If speculation is not valid or we determined type precisely,
+                we are done.  */
+             if (!speculation_valid
+                 || !context->maybe_derived_type)
+               {
+                 context->speculative_outer_type = NULL;
+                 context->speculative_offset = 0;
+                 return true;
+               }
+             /* Otherwise look into speculation now.  */
+             else
+               {
+                 speculative = true;
+                 type = context->speculative_outer_type;
+                 offset = context->speculative_offset;
+                 continue;
+               }
+           }
        }
 
       /* Walk fields and find corresponding on at OFFSET.  */
@@ -1792,11 +1878,20 @@ get_class_context (ipa_polymorphic_call_context *context,
          /* DECL_ARTIFICIAL represents a basetype.  */
          if (!DECL_ARTIFICIAL (fld))
            {
-             context->outer_type = type;
-             context->offset = offset;
-             /* As soon as we se an field containing the type,
-                we know we are not looking for derivations.  */
-             context->maybe_derived_type = false;
+             if (!speculative)
+               {
+                 context->outer_type = type;
+                 context->offset = offset;
+                 /* As soon as we se an field containing the type,
+                    we know we are not looking for derivations.  */
+                 context->maybe_derived_type = false;
+               }
+             else
+               {
+                 context->speculative_outer_type = type;
+                 context->speculative_offset = offset;
+                 context->speculative_maybe_derived_type = false;
+               }
            }
        }
       else if (TREE_CODE (type) == ARRAY_TYPE)
@@ -1809,9 +1904,18 @@ get_class_context (ipa_polymorphic_call_context *context,
            goto give_up;
          offset = offset % tree_to_shwi (TYPE_SIZE (subtype));
          type = subtype;
-         context->outer_type = type;
-         context->offset = offset;
-         context->maybe_derived_type = false;
+         if (!speculative)
+           {
+             context->outer_type = type;
+             context->offset = offset;
+             context->maybe_derived_type = false;
+           }
+         else
+           {
+             context->speculative_outer_type = type;
+             context->speculative_offset = offset;
+             context->speculative_maybe_derived_type = false;
+           }
        }
       /* Give up on anything else.  */
       else
@@ -1821,6 +1925,11 @@ get_class_context (ipa_polymorphic_call_context *context,
   /* If we failed to find subtype we look for, give up and fall back to the
      most generic query.  */
 give_up:
+  context->speculative_outer_type = NULL;
+  context->speculative_offset = 0;
+  context->speculative_maybe_derived_type = false;
+  if (valid)
+    return true;
   context->outer_type = expected_type;
   context->offset = 0;
   context->maybe_derived_type = true;
@@ -1831,7 +1940,8 @@ give_up:
   if ((TREE_CODE (type) != RECORD_TYPE
        || !TYPE_BINFO (type)
        || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
-      && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+      && (!TYPE_SIZE (type)
+         || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
          || (offset + tree_to_uhwi (TYPE_SIZE (expected_type)) <=
              tree_to_uhwi (TYPE_SIZE (type)))))
     return true;
@@ -1844,9 +1954,9 @@ static bool
 contains_type_p (tree outer_type, HOST_WIDE_INT offset,
                 tree otr_type)
 {
-  ipa_polymorphic_call_context context = {offset,
+  ipa_polymorphic_call_context context = {offset, 0,
                                          TYPE_MAIN_VARIANT (outer_type),
-                                         false, true};
+                                         NULL, false, true, false};
   return get_class_context (&context, otr_type);
 }
 
@@ -2054,6 +2164,9 @@ get_polymorphic_call_info_for_decl (ipa_polymorphic_call_context *context,
 
   context->outer_type = TYPE_MAIN_VARIANT (TREE_TYPE (base));
   context->offset = offset;
+  context->speculative_outer_type = NULL;
+  context->speculative_offset = 0;
+  context->speculative_maybe_derived_type = true;
   /* Make very conservative assumption that all objects
      may be in construction. 
      TODO: ipa-prop already contains code to tell better. 
@@ -2093,6 +2206,26 @@ get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *context,
   return true;
 }
 
+/* See if OP is SSA name initialized as a copy or by single assignment.
+   If so, walk the SSA graph up.  */
+
+static tree
+walk_ssa_copies (tree op)
+{
+  STRIP_NOPS (op);
+  while (TREE_CODE (op) == SSA_NAME
+        && !SSA_NAME_IS_DEFAULT_DEF (op)
+        && SSA_NAME_DEF_STMT (op)
+        && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
+    {
+      if (gimple_assign_load_p (SSA_NAME_DEF_STMT (op)))
+       return op;
+      op = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op));
+      STRIP_NOPS (op);
+    }
+  return op;
+}
+
 /* Given REF call in FNDECL, determine class of the polymorphic
    call (OTR_TYPE), its token (OTR_TOKEN) and CONTEXT.
    CALL is optional argument giving the actual statement (usually call) where
@@ -2112,6 +2245,9 @@ get_polymorphic_call_info (tree fndecl,
   *otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
 
   /* Set up basic info in case we find nothing interesting in the analysis.  */
+  context->speculative_outer_type = NULL;
+  context->speculative_offset = 0;
+  context->speculative_maybe_derived_type = true;
   context->outer_type = TYPE_MAIN_VARIANT (*otr_type);
   context->offset = 0;
   base_pointer = OBJ_TYPE_REF_OBJECT (ref);
@@ -2121,15 +2257,8 @@ get_polymorphic_call_info (tree fndecl,
   /* Walk SSA for outer object.  */
   do 
     {
-      if (TREE_CODE (base_pointer) == SSA_NAME
-         && !SSA_NAME_IS_DEFAULT_DEF (base_pointer)
-         && SSA_NAME_DEF_STMT (base_pointer)
-         && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
-       {
-         base_pointer = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (base_pointer));
-         STRIP_NOPS (base_pointer);
-       }
-      else if (TREE_CODE (base_pointer) == ADDR_EXPR)
+      base_pointer = walk_ssa_copies (base_pointer);
+      if (TREE_CODE (base_pointer) == ADDR_EXPR)
        {
          HOST_WIDE_INT size, max_size;
          HOST_WIDE_INT offset2;
@@ -2175,7 +2304,7 @@ get_polymorphic_call_info (tree fndecl,
                                                     context->outer_type,
                                                     call,
                                                     current_function_decl);
-                 return NULL;
+                 return base_pointer;
                }
              else
                break;
@@ -2259,6 +2388,35 @@ get_polymorphic_call_info (tree fndecl,
           return base_pointer;
        }
     }
+
+  tree base_type = TREE_TYPE (base_pointer);
+
+  if (TREE_CODE (base_pointer) == SSA_NAME
+      && SSA_NAME_IS_DEFAULT_DEF (base_pointer)
+      && TREE_CODE (SSA_NAME_VAR (base_pointer)) != PARM_DECL)
+    {
+      /* Use OTR_TOKEN = INT_MAX as a marker of probably type inconsistent
+        code sequences; we arrange the calls to be builtin_unreachable
+        later.  */
+      *otr_token = INT_MAX;
+      return base_pointer;
+    }
+  if (TREE_CODE (base_pointer) == SSA_NAME
+      && SSA_NAME_DEF_STMT (base_pointer)
+      && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer)))
+    base_type = TREE_TYPE (gimple_assign_rhs1
+                           (SSA_NAME_DEF_STMT (base_pointer)));
+  if (POINTER_TYPE_P (base_type)
+      && contains_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)),
+                         context->offset,
+                         *otr_type))
+    {
+      context->speculative_outer_type = TYPE_MAIN_VARIANT
+                                         (TREE_TYPE (base_type));
+      context->speculative_offset = context->offset;
+      context->speculative_maybe_derived_type = true;
+    }
   /* TODO: There are multiple ways to derive a type.  For instance
      if BASE_POINTER is passed to an constructor call prior our refernece.
      We do not make this type of flow sensitive analysis yet.  */
index 9c65076440b7d8c9462f41262ddca0e28b7380e4..576e59acc20099556770f707d6de95791d99eb78 100644 (file)
@@ -4693,6 +4693,7 @@ ipa_write_indirect_edge_info (struct output_block *ob,
   bp_pack_value (&bp, ii->by_ref, 1);
   bp_pack_value (&bp, ii->maybe_in_construction, 1);
   bp_pack_value (&bp, ii->maybe_derived_type, 1);
+  bp_pack_value (&bp, ii->speculative_maybe_derived_type, 1);
   streamer_write_bitpack (&bp);
 
   if (ii->polymorphic)
@@ -4700,6 +4701,9 @@ ipa_write_indirect_edge_info (struct output_block *ob,
       streamer_write_hwi (ob, ii->otr_token);
       stream_write_tree (ob, ii->otr_type, true);
       stream_write_tree (ob, ii->outer_type, true);
+      stream_write_tree (ob, ii->speculative_outer_type, true);
+      if (ii->speculative_outer_type)
+        streamer_write_hwi (ob, ii->speculative_offset);
     }
 }
 
@@ -4723,11 +4727,15 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
   ii->by_ref = bp_unpack_value (&bp, 1);
   ii->maybe_in_construction = bp_unpack_value (&bp, 1);
   ii->maybe_derived_type = bp_unpack_value (&bp, 1);
+  ii->speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
   if (ii->polymorphic)
     {
       ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
       ii->otr_type = stream_read_tree (ib, data_in);
       ii->outer_type = stream_read_tree (ib, data_in);
+      ii->speculative_outer_type = stream_read_tree (ib, data_in);
+      if (ii->speculative_outer_type)
+        ii->speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
     }
 }
 
index bb2e0d50d6be0aa2a1bb382a800b34714b41c803..12543048289a295c142a507ba519b38f0f79f59d 100644 (file)
@@ -38,13 +38,19 @@ struct ipa_dfs_info {
    type inheritance graph.  */
 struct ipa_polymorphic_call_context {
   /* The called object appears in an object of type OUTER_TYPE
-     at offset OFFSET.  */
+     at offset OFFSET.  When information is not 100% reliable, we
+     use SPECULATIVE_OUTER_TYPE and SPECULATIVE_OFFSET. */
   HOST_WIDE_INT offset;
+  HOST_WIDE_INT speculative_offset;
   tree outer_type;
+  tree speculative_outer_type;
   /* True if outer object may be in construction or destruction.  */
   bool maybe_in_construction;
   /* True if outer object may be of derived type.  */
   bool maybe_derived_type;
+  /* True if speculative outer object may be of derived type.  We always
+     speculate that construction does not happen.  */
+  bool speculative_maybe_derived_type;
 };
 
 /* Context representing "I know nothing".  */
@@ -89,6 +95,7 @@ tree get_polymorphic_call_info (tree, tree, tree *,
                                HOST_WIDE_INT *,
                                ipa_polymorphic_call_context *,
                                gimple call = NULL);
+bool get_dynamic_type (tree, ipa_polymorphic_call_context *, tree, gimple);
 bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *,
                                               tree, tree, HOST_WIDE_INT);
 bool decl_maybe_in_construction_p (tree, tree, gimple, tree);
@@ -114,9 +121,12 @@ possible_polymorphic_call_targets (struct cgraph_edge *e,
 {
   gcc_checking_assert (e->indirect_info->polymorphic);
   ipa_polymorphic_call_context context = {e->indirect_info->offset,
+                                         e->indirect_info->speculative_offset,
                                          e->indirect_info->outer_type,
+                                         e->indirect_info->speculative_outer_type,
                                          e->indirect_info->maybe_in_construction,
-                                         e->indirect_info->maybe_derived_type};
+                                         e->indirect_info->maybe_derived_type,
+                                         e->indirect_info->speculative_maybe_derived_type};
   return possible_polymorphic_call_targets (e->indirect_info->otr_type,
                                            e->indirect_info->otr_token,
                                            context,
@@ -153,9 +163,12 @@ dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e)
 {
   gcc_checking_assert (e->indirect_info->polymorphic);
   ipa_polymorphic_call_context context = {e->indirect_info->offset,
+                                         e->indirect_info->speculative_offset,
                                          e->indirect_info->outer_type,
+                                         e->indirect_info->speculative_outer_type,
                                          e->indirect_info->maybe_in_construction,
-                                         e->indirect_info->maybe_derived_type};
+                                         e->indirect_info->maybe_derived_type,
+                                         e->indirect_info->speculative_maybe_derived_type};
   dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type,
                                          e->indirect_info->otr_token,
                                          context);
@@ -168,10 +181,11 @@ inline bool
 possible_polymorphic_call_target_p (struct cgraph_edge *e,
                                    struct cgraph_node *n)
 {
-  ipa_polymorphic_call_context context = {e->indirect_info->offset,
-                                         e->indirect_info->outer_type,
+  ipa_polymorphic_call_context context = {e->indirect_info->offset, 0,
+                                         e->indirect_info->outer_type, NULL,
                                          e->indirect_info->maybe_in_construction,
-                                         e->indirect_info->maybe_derived_type};
+                                         e->indirect_info->maybe_derived_type,
+                                         false};
   return possible_polymorphic_call_target_p (e->indirect_info->otr_type,
                                             e->indirect_info->otr_token,
                                             context, n);