]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ipa-prop.h
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / ipa-prop.h
index 24a69c18f6e5142b93faaec0630056438612015b..42842d9466a3c26dff80d1fd00d910601c2cea6e 100644 (file)
@@ -1,5 +1,5 @@
 /* Interprocedural analyses.
-   Copyright (C) 2005-2019 Free Software Foundation, Inc.
+   Copyright (C) 2005-2021 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -39,6 +39,15 @@ along with GCC; see the file COPYING3.  If not see
                   argument.
    Unknown      - neither of the above.
 
+   IPA_JF_LOAD_AGG is a compound pass-through jump function, in which primary
+   operation on formal parameter is memory dereference that loads a value from
+   a part of an aggregate, which is represented or pointed to by the formal
+   parameter.  Moreover, an additional unary/binary operation can be applied on
+   the loaded value, and final result is passed as actual argument of callee
+   (e.g. *(param_1(D) + 4) op 24 ).  It is meant to describe usage of aggregate
+   parameter or by-reference parameter referenced in argument passing, commonly
+   found in C++ and Fortran.
+
    IPA_JF_ANCESTOR is a special pass-through jump function, which means that
    the result is an address of a part of the object pointed to by the formal
    parameter to which the function refers.  It is mainly intended to represent
@@ -60,6 +69,7 @@ enum jump_func_type
   IPA_JF_UNKNOWN = 0,  /* newly allocated and zeroed jump functions default */
   IPA_JF_CONST,             /* represented by field costant */
   IPA_JF_PASS_THROUGH,     /* represented by field pass_through */
+  IPA_JF_LOAD_AGG,         /* represented by field load_agg */
   IPA_JF_ANCESTOR          /* represented by field ancestor */
 };
 
@@ -84,9 +94,14 @@ struct GTY(()) ipa_pass_through_data
   /* Number of the caller's formal parameter being passed.  */
   int formal_id;
   /* Operation that is performed on the argument before it is passed on.
-     NOP_EXPR means no operation.  Otherwise oper must be a simple binary
-     arithmetic operation where the caller's parameter is the first operand and
-     operand field from this structure is the second one.  */
+     Special values which have other meaning than in normal contexts:
+       - NOP_EXPR means no operation, not even type conversion.
+       - ASSERT_EXPR means that only the value in operand is allowed to pass
+         through (without any change), for all other values the result is
+         unknown.
+     Otherwise operation must be a simple binary or unary arithmetic operation
+     where the caller's parameter is the first operand and (for binary
+     operations) the operand field from this structure is the second one.  */
   enum tree_code operation;
   /* When the passed value is a pointer, it is set to true only when we are
      certain that no write to the object it points to has occurred since the
@@ -97,6 +112,26 @@ struct GTY(()) ipa_pass_through_data
   unsigned agg_preserved : 1;
 };
 
+/* Structure holding data required to describe a load-value-from-aggregate
+   jump function.  */
+
+struct GTY(()) ipa_load_agg_data
+{
+  /* Inherit from pass through jump function, describing unary/binary
+     operation on the value loaded from aggregate that is represented or
+     pointed to by the formal parameter, specified by formal_id in this
+     pass_through jump function data structure.  */
+  struct ipa_pass_through_data pass_through;
+  /* Type of the value loaded from the aggregate.  */
+  tree type;
+  /* Offset at which the value is located within the aggregate.  */
+  HOST_WIDE_INT offset;
+  /* True if loaded by reference (the aggregate is pointed to by the formal
+     parameter) or false if loaded by value (the aggregate is represented
+     by the formal parameter).  */
+  bool by_ref;
+};
+
 /* Structure holding data required to describe an ancestor pass-through
    jump function.  */
 
@@ -110,38 +145,141 @@ struct GTY(()) ipa_ancestor_jf_data
   unsigned agg_preserved : 1;
 };
 
-/* An element in an aggegate part of a jump function describing a known value
-   at a given offset.  When it is part of a pass-through jump function with
-   agg_preserved set or an ancestor jump function with agg_preserved set, all
-   unlisted positions are assumed to be preserved but the value can be a type
-   node, which means that the particular piece (starting at offset and having
-   the size of the type) is clobbered with an unknown value.  When
-   agg_preserved is false or the type of the containing jump function is
-   different, all unlisted parts are assumed to be unknown and all values must
-   fulfill is_gimple_ip_invariant.  */
+/* A jump function for an aggregate part at a given offset, which describes how
+   it content value is generated.  All unlisted positions are assumed to have a
+   value defined in an unknown way.  */
 
 struct GTY(()) ipa_agg_jf_item
 {
-  /* The offset at which the known value is located within the aggregate.  */
+  /* The offset for the aggregate part.  */
   HOST_WIDE_INT offset;
 
-  /* The known constant or type if this is a clobber.  */
-  tree value;
-};
+  /* Data type of the aggregate part.  */
+  tree type;
+
+  /* Jump function type.  */
+  enum jump_func_type jftype;
 
+  /* Represents a value of jump function. constant represents the actual constant
+     in constant jump function content.  pass_through is used only in simple pass
+     through jump function context.  load_agg is for load-value-from-aggregate
+     jump function context.  */
+  union jump_func_agg_value
+  {
+    tree GTY ((tag ("IPA_JF_CONST"))) constant;
+    struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
+    struct ipa_load_agg_data GTY ((tag ("IPA_JF_LOAD_AGG"))) load_agg;
+  } GTY ((desc ("%1.jftype"))) value;
+};
 
-/* Aggregate jump function - i.e. description of contents of aggregates passed
-   either by reference or value.  */
+/* Jump functions describing a set of aggregate contents.  */
 
 struct GTY(()) ipa_agg_jump_function
 {
-  /* Description of the individual items.  */
+  /* Description of the individual jump function item.  */
   vec<ipa_agg_jf_item, va_gc> *items;
-  /* True if the data was passed by reference (as opposed to by value). */
+  /* True if the data was passed by reference (as opposed to by value).  */
   bool by_ref;
 };
 
-typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
+/* An element in an aggregate part describing a known value at a given offset.
+   All unlisted positions are assumed to be unknown and all listed values must
+   fulfill is_gimple_ip_invariant.  */
+
+struct ipa_agg_value
+{
+  /* The offset at which the known value is located within the aggregate.  */
+  HOST_WIDE_INT offset;
+
+  /* The known constant.  */
+  tree value;
+
+  /* Return true if OTHER describes same agg value.  */
+  bool equal_to (const ipa_agg_value &other);
+};
+
+/* Structure describing a set of known offset/value for aggregate.  */
+
+struct ipa_agg_value_set
+{
+  /* Description of the individual item.  */
+  vec<ipa_agg_value> items;
+  /* True if the data was passed by reference (as opposed to by value).  */
+  bool by_ref;
+
+  /* Return true if OTHER describes same agg values.  */
+  bool equal_to (const ipa_agg_value_set &other)
+  {
+    if (by_ref != other.by_ref)
+      return false;
+    if (items.length () != other.items.length ())
+      return false;
+    for (unsigned int i = 0; i < items.length (); i++)
+      if (!items[i].equal_to (other.items[i]))
+       return false;
+    return true;
+  }
+
+  /* Return true if there is any value for aggregate.  */
+  bool is_empty () const
+  {
+    return items.is_empty ();
+  }
+
+  ipa_agg_value_set copy () const
+  {
+    ipa_agg_value_set new_copy;
+
+    new_copy.items = items.copy ();
+    new_copy.by_ref = by_ref;
+
+    return new_copy;
+  }
+
+  void release ()
+  {
+    items.release ();
+  }
+};
+
+/* Return copy of a vec<ipa_agg_value_set>.  */
+
+static inline vec<ipa_agg_value_set>
+ipa_copy_agg_values (const vec<ipa_agg_value_set> &aggs)
+{
+  vec<ipa_agg_value_set> aggs_copy = vNULL;
+
+  if (!aggs.is_empty ())
+    {
+      ipa_agg_value_set *agg;
+      int i;
+
+      aggs_copy.reserve_exact (aggs.length ());
+
+      FOR_EACH_VEC_ELT (aggs, i, agg)
+       aggs_copy.quick_push (agg->copy ());
+    }
+
+  return aggs_copy;
+}
+
+/* For vec<ipa_agg_value_set>, DO NOT call release(), use below function
+   instead.  Because ipa_agg_value_set contains a field of vector type, we
+   should release this child vector in each element before reclaiming the
+   whole vector.  */
+
+static inline void
+ipa_release_agg_values (vec<ipa_agg_value_set> &aggs,
+                       bool release_vector = true)
+{
+  ipa_agg_value_set *agg;
+  int i;
+
+  FOR_EACH_VEC_ELT (aggs, i, agg)
+    agg->release ();
+  if (release_vector)
+    aggs.release ();
+}
 
 /* Information about zero/non-zero bits.  */
 class GTY(()) ipa_bits
@@ -173,8 +311,8 @@ public:
    types of jump functions supported.  */
 struct GTY (()) ipa_jump_func
 {
-  /* Aggregate contants description.  See struct ipa_agg_jump_function and its
-     description.  */
+  /* Aggregate jump function description.  See struct ipa_agg_jump_function
+     and its description.  */
   struct ipa_agg_jump_function agg;
 
   /* Information about zero/non-zero bits.  The pointed to structure is shared
@@ -185,7 +323,7 @@ struct GTY (()) ipa_jump_func
   /* Information about value range, containing valid data only when vr_known is
      true.  The pointed to structure is shared betweed different jump
      functions.  Use ipa_set_jfunc_vr to set this field.  */
-  class value_range_base *m_vr;
+  value_range *m_vr;
 
   enum jump_func_type type;
   /* Represents a value of a jump function.  pass_through is used only in jump
@@ -300,22 +438,133 @@ ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
   return jfunc->value.ancestor.agg_preserved;
 }
 
+/* Class for allocating a bundle of various potentially known properties about
+   actual arguments of a particular call on stack for the usual case and on
+   heap only if there are unusually many arguments.  The data is deallocated
+   when the instance of this class goes out of scope or is otherwise
+   destructed.  */
+
+class ipa_auto_call_arg_values
+{
+public:
+  ~ipa_auto_call_arg_values ();
+
+  /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
+     return its element at INDEX, otherwise return NULL.  */
+  tree safe_sval_at (int index)
+  {
+    /* TODO: Assert non-negative index here and test.  */
+    if ((unsigned) index < m_known_vals.length ())
+      return m_known_vals[index];
+    return NULL;
+  }
+
+  /* If m_known_aggs is sufficiantly long, return the pointer rto its element
+     at INDEX, otherwise return NULL.  */
+  ipa_agg_value_set *safe_aggval_at (int index)
+  {
+    /* TODO: Assert non-negative index here and test.  */
+    if ((unsigned) index < m_known_aggs.length ())
+      return &m_known_aggs[index];
+    return NULL;
+  }
+
+  /* Vector describing known values of parameters.  */
+  auto_vec<tree, 32> m_known_vals;
+
+  /* Vector describing known polymorphic call contexts.  */
+  auto_vec<ipa_polymorphic_call_context, 32> m_known_contexts;
+
+  /* Vector describing known aggregate values.  */
+  auto_vec<ipa_agg_value_set, 32> m_known_aggs;
+
+  /* Vector describing known value ranges of arguments.  */
+  auto_vec<value_range, 32> m_known_value_ranges;
+};
+
+/* Class bundling the various potentially known properties about actual
+   arguments of a particular call.  This variant does not deallocate the
+   bundled data in any way.  */
+
+class ipa_call_arg_values
+{
+public:
+  /* Default constructor, setting the vectors to empty ones.  */
+  ipa_call_arg_values ()
+  {}
+
+  /* Construct this general variant of the bundle from the variant which uses
+     auto_vecs to hold the vectors.  This means that vectors of objects
+     constructed with this constructor should not be changed because if they
+     get reallocated, the member vectors and the underlying auto_vecs would get
+     out of sync.  */
+  ipa_call_arg_values (ipa_auto_call_arg_values *aavals)
+    : m_known_vals (aavals->m_known_vals.to_vec_legacy ()),
+      m_known_contexts (aavals->m_known_contexts.to_vec_legacy ()),
+      m_known_aggs (aavals->m_known_aggs.to_vec_legacy ()),
+      m_known_value_ranges (aavals->m_known_value_ranges.to_vec_legacy ())
+  {}
+
+  /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
+     return its element at INDEX, otherwise return NULL.  */
+  tree safe_sval_at (int index)
+  {
+    /* TODO: Assert non-negative index here and test.  */
+    if ((unsigned) index < m_known_vals.length ())
+      return m_known_vals[index];
+    return NULL;
+  }
+
+  /* If m_known_aggs is sufficiantly long, return the pointer rto its element
+     at INDEX, otherwise return NULL.  */
+  ipa_agg_value_set *safe_aggval_at (int index)
+  {
+    /* TODO: Assert non-negative index here and test.  */
+    if ((unsigned) index < m_known_aggs.length ())
+      return &m_known_aggs[index];
+    return NULL;
+  }
+
+  /* Vector describing known values of parameters.  */
+  vec<tree> m_known_vals = vNULL;
+
+  /* Vector describing known polymorphic call contexts.  */
+  vec<ipa_polymorphic_call_context> m_known_contexts = vNULL;
+
+  /* Vector describing known aggregate values.  */
+  vec<ipa_agg_value_set> m_known_aggs = vNULL;
+
+  /* Vector describing known value ranges of arguments.  */
+  vec<value_range> m_known_value_ranges = vNULL;
+};
+
+
 /* Summary describing a single formal parameter.  */
 
 struct GTY(()) ipa_param_descriptor
 {
   /* In analysis and modification phase, this is the PARAM_DECL of this
-     parameter, in IPA LTO phase, this is the type of the the described
+     parameter, in IPA LTO phase, this is the type of the described
      parameter or NULL if not known.  Do not read this field directly but
      through ipa_get_param and ipa_get_type as appropriate.  */
   tree decl_or_type;
   /* If all uses of the parameter are described by ipa-prop structures, this
      says how many there are.  If any use could not be described by means of
-     ipa-prop structures, this is IPA_UNDESCRIBED_USE.  */
+     ipa-prop structures (which include flag dereferenced below), this is
+     IPA_UNDESCRIBED_USE.  */
   int controlled_uses;
-  unsigned int move_cost : 31;
+  unsigned int move_cost : 27;
   /* The parameter is used.  */
   unsigned used : 1;
+  unsigned used_by_ipa_predicates : 1;
+  unsigned used_by_indirect_call : 1;
+  unsigned used_by_polymorphic_call : 1;
+  /* Set to true when in addition to being used in call statements, the
+     parameter has also been used for loads (but not for writes, does not
+     escape, etc.).  This allows us to identify parameters p which are only
+     used as *p, and so when we propagate a constant to them, we can generate a
+     LOAD and not ADDR reference to them.  */
+  unsigned load_dereferenced : 1;
 };
 
 /* ipa_node_params stores information related to formal parameters of functions
@@ -361,6 +610,8 @@ public:
   unsigned node_dead : 1;
   /* Node is involved in a recursion, potentionally indirect.  */
   unsigned node_within_scc : 1;
+  /* Node contains only direct recursion.  */
+  unsigned node_is_self_scc : 1;
   /* Node is calling a private function called only once.  */
   unsigned node_calling_single_call : 1;
   /* False when there is something makes versioning impossible.  */
@@ -381,6 +632,7 @@ inline
 ipa_node_params::~ipa_node_params ()
 {
   free (lattices);
+  vec_free (descriptors);
   known_csts.release ();
   known_contexts.release ();
 }
@@ -457,7 +709,6 @@ static inline tree
 ipa_get_param (class ipa_node_params *info, int i)
 {
   gcc_checking_assert (info->descriptors);
-  gcc_checking_assert (!flag_wpa);
   tree t = (*info->descriptors)[i].decl_or_type;
   gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
   return t;
@@ -500,6 +751,36 @@ ipa_set_param_used (class ipa_node_params *info, int i, bool val)
   (*info->descriptors)[i].used = val;
 }
 
+/* Set the used_by_ipa_predicates flag corresponding to the Ith formal
+   parameter of the function associated with INFO to VAL.  */
+
+static inline void
+ipa_set_param_used_by_ipa_predicates (class ipa_node_params *info, int i, bool val)
+{
+  gcc_checking_assert (info->descriptors);
+  (*info->descriptors)[i].used_by_ipa_predicates = val;
+}
+
+/* Set the used_by_indirect_call flag corresponding to the Ith formal
+   parameter of the function associated with INFO to VAL.  */
+
+static inline void
+ipa_set_param_used_by_indirect_call (class ipa_node_params *info, int i, bool val)
+{
+  gcc_checking_assert (info->descriptors);
+  (*info->descriptors)[i].used_by_indirect_call = val;
+}
+
+/* Set the .used_by_polymorphic_call flag corresponding to the Ith formal
+   parameter of the function associated with INFO to VAL.  */
+
+static inline void
+ipa_set_param_used_by_polymorphic_call (class ipa_node_params *info, int i, bool val)
+{
+  gcc_checking_assert (info->descriptors);
+  (*info->descriptors)[i].used_by_polymorphic_call = val;
+}
+
 /* Return how many uses described by ipa-prop a parameter has or
    IPA_UNDESCRIBED_USE if there is a use that is not described by these
    structures.  */
@@ -521,6 +802,24 @@ ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
   (*info->descriptors)[i].controlled_uses = val;
 }
 
+/* Assuming a parameter does not have IPA_UNDESCRIBED_USE controlled uses,
+   return flag which indicates it has been dereferenced but only in a load.  */
+static inline int
+ipa_get_param_load_dereferenced (class ipa_node_params *info, int i)
+{
+  gcc_assert (ipa_get_controlled_uses (info, i) != IPA_UNDESCRIBED_USE);
+  return (*info->descriptors)[i].load_dereferenced;
+}
+
+/* Set the load_dereferenced flag of a given parameter.  */
+
+static inline void
+ipa_set_param_load_dereferenced (class ipa_node_params *info, int i, bool val)
+{
+  gcc_checking_assert (info->descriptors);
+  (*info->descriptors)[i].load_dereferenced = val;
+}
+
 /* Return the used flag corresponding to the Ith formal parameter of the
    function associated with INFO.  */
 
@@ -531,6 +830,36 @@ ipa_is_param_used (class ipa_node_params *info, int i)
   return (*info->descriptors)[i].used;
 }
 
+/* Return the used_by_ipa_predicates flag corresponding to the Ith formal
+   parameter of the function associated with INFO.  */
+
+static inline bool
+ipa_is_param_used_by_ipa_predicates (class ipa_node_params *info, int i)
+{
+  gcc_checking_assert (info->descriptors);
+  return (*info->descriptors)[i].used_by_ipa_predicates;
+}
+
+/* Return the used_by_indirect_call flag corresponding to the Ith formal
+   parameter of the function associated with INFO.  */
+
+static inline bool
+ipa_is_param_used_by_indirect_call (class ipa_node_params *info, int i)
+{
+  gcc_checking_assert (info->descriptors);
+  return (*info->descriptors)[i].used_by_indirect_call;
+}
+
+/* Return the used_by_polymorphic_call flag corresponding to the Ith formal
+   parameter of the function associated with INFO.  */
+
+static inline bool
+ipa_is_param_used_by_polymorphic_call (class ipa_node_params *info, int i)
+{
+  gcc_checking_assert (info->descriptors);
+  return (*info->descriptors)[i].used_by_polymorphic_call;
+}
+
 /* Information about replacements done in aggregates for a given node (each
    node has its linked list).  */
 struct GTY(()) ipa_agg_replacement_value
@@ -541,7 +870,7 @@ struct GTY(()) ipa_agg_replacement_value
   HOST_WIDE_INT offset;
   /* The constant value.  */
   tree value;
-  /* The paramter index.  */
+  /* The parameter index.  */
   int index;
   /* Whether the value was passed by reference.  */
   bool by_ref;
@@ -557,6 +886,25 @@ struct GTY(()) ipcp_transformation
   vec<ipa_bits *, va_gc> *bits;
   /* Value range information.  */
   vec<ipa_vr, va_gc> *m_vr;
+
+  /* Default constructor.  */
+  ipcp_transformation ()
+  : agg_values (NULL), bits (NULL), m_vr (NULL)
+  { }
+
+  /* Default destructor.  */
+  ~ipcp_transformation ()
+  {
+    ipa_agg_replacement_value *agg = agg_values;
+    while (agg)
+      {
+       ipa_agg_replacement_value *next = agg->next;
+       ggc_free (agg);
+       agg = next;
+      }
+    vec_free (bits);
+    vec_free (m_vr);
+  }
 };
 
 void ipa_set_node_agg_value_chain (struct cgraph_node *node,
@@ -578,6 +926,10 @@ class GTY((for_user)) ipa_edge_args
   /* Destructor.  */
   ~ipa_edge_args ()
     {
+      unsigned int i;
+      ipa_jump_func *jf;
+      FOR_EACH_VEC_SAFE_ELT (jump_functions, i, jf)
+       vec_free (jf->agg.items);
       vec_free (jump_functions);
       vec_free (polymorphic_call_contexts);
     }
@@ -624,7 +976,10 @@ class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *>
 {
 public:
   ipa_node_params_t (symbol_table *table, bool ggc):
-    function_summary<ipa_node_params *> (table, ggc) { }
+    function_summary<ipa_node_params *> (table, ggc)
+  {
+    disable_insertion_hook ();
+  }
 
   /* Hook that is called by summary when a node is duplicated.  */
   virtual void duplicate (cgraph_node *node,
@@ -641,6 +996,11 @@ class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
   ipa_edge_args_sum_t (symbol_table *table, bool ggc)
     : call_summary<ipa_edge_args *> (table, ggc) { }
 
+  void remove (cgraph_edge *edge)
+  {
+    call_summary <ipa_edge_args *>::remove (edge);
+  }
+
   /* Hook that is called by summary when an edge is removed.  */
   virtual void remove (cgraph_edge *cs, ipa_edge_args *args);
   /* Hook that is called by summary when an edge is duplicated.  */
@@ -668,23 +1028,20 @@ public:
   static ipcp_transformation_t *create_ggc (symbol_table *symtab)
   {
     ipcp_transformation_t *summary
-      = new (ggc_cleared_alloc <ipcp_transformation_t> ())
+      = new (ggc_alloc_no_dtor <ipcp_transformation_t> ())
       ipcp_transformation_t (symtab, true);
     return summary;
   }
+  /* Hook that is called by summary when a node is duplicated.  */
+  virtual void duplicate (cgraph_node *node,
+                         cgraph_node *node2,
+                         ipcp_transformation *data,
+                         ipcp_transformation *data2);
 };
 
 /* Function summary where the IPA CP transformations are actually stored.  */
 extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum;
 
-/* Return the associated parameter/argument info corresponding to the given
-   node/edge.  */
-#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get_create (NODE))
-#define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get_create (EDGE))
-/* This macro checks validity of index returned by
-   ipa_get_param_decl_index function.  */
-#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
-
 /* Creating and freeing ipa_node_params and ipa_edge_args.  */
 void ipa_create_all_node_params (void);
 void ipa_create_all_edge_args (void);
@@ -705,7 +1062,7 @@ ipa_check_create_node_params (void)
 {
   if (!ipa_node_params_sum)
     ipa_node_params_sum
-      = (new (ggc_cleared_alloc <ipa_node_params_t> ())
+      = (new (ggc_alloc_no_dtor <ipa_node_params_t> ())
         ipa_node_params_t (symtab, true));
 }
 
@@ -742,12 +1099,13 @@ void ipa_initialize_node_params (struct cgraph_node *node);
 bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
                                        vec<cgraph_edge *> *new_edges);
 
-/* Indirect edge and binfo processing.  */
+/* Indirect edge processing and target discovery.  */
+tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
+                                  ipa_call_arg_values *avals,
+                                  bool *speculative);
 tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
-                                  vec<tree> ,
-                                  vec<ipa_polymorphic_call_context>,
-                                  vec<ipa_agg_jump_function_p>,
-                                  bool *);
+                                  ipa_auto_call_arg_values *avals,
+                                  bool *speculative);
 struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
                                                    bool speculative = false);
 tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
@@ -759,7 +1117,7 @@ ipa_bits *ipa_get_ipa_bits_for_value (const widest_int &value,
 void ipa_analyze_node (struct cgraph_node *);
 
 /* Aggregate jump function related functions.  */
-tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar,
+tree ipa_find_agg_cst_for_param (const ipa_agg_value_set *agg, tree scalar,
                                 HOST_WIDE_INT offset, bool by_ref,
                                 bool *from_global_constant = NULL);
 bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
@@ -805,9 +1163,17 @@ ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
                                                     cgraph_edge *,
                                                     int,
                                                     ipa_jump_func *);
+value_range ipa_value_range_from_jfunc (ipa_node_params *, cgraph_edge *,
+                                       ipa_jump_func *, tree);
+ipa_agg_value_set ipa_agg_value_set_from_jfunc (ipa_node_params *,
+                                               cgraph_node *,
+                                               ipa_agg_jump_function *);
 void ipa_dump_param (FILE *, class ipa_node_params *info, int i);
 void ipa_release_body_info (struct ipa_func_body_info *);
 tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
+bool ipcp_get_parm_bits (tree, tree *, widest_int *);
+bool unadjusted_ptr_and_unit_offset (tree op, tree *ret,
+                                    poly_int64 *offset_ret);
 
 /* From tree-sra.c:  */
 tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,