/* Interprocedural analyses.
   Copyright (C) 2005-2023 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef IPA_PROP_H
#define IPA_PROP_H

/* The following definitions and interfaces are used by
   interprocedural analyses or parameters.  */

#define IPA_UNDESCRIBED_USE -1

/* Index identifying an actualargument or a formal parameter may have only this
   many bits.  */

#define IPA_PROP_ARG_INDEX_LIMIT_BITS 16

/* ipa-prop.cc stuff (ipa-cp, indirect inlining):  */

/* A jump function for a callsite represents the values passed as actual
   arguments of the callsite.  They were originally proposed in a paper called
   "Interprocedural Constant Propagation", by David Callahan, Keith D Cooper,
   Ken Kennedy, Linda Torczon in Comp86, pg 152-161.  There are three main
   types of values :

   Pass-through - the caller's formal parameter is passed as an actual
                  argument, possibly one simple operation performed on it.
   Constant     - a constant (is_gimple_ip_invariant)is passed as an actual
                  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
   getting addresses of ancestor fields in C++
   (e.g. &this_1(D)->D.1766.D.1756).  Note that if the original pointer is
   NULL, ancestor jump function must behave like a simple pass-through.

   Other pass-through functions can either simply pass on an unchanged formal
   parameter or can apply one simple binary operation to it (such jump
   functions are called polynomial).

   Jump functions are computed in ipa-prop.cc by function
   update_call_notes_after_inlining.  Some information can be lost and jump
   functions degraded accordingly when inlining, see
   update_call_notes_after_inlining in the same file.  */

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 */
};

struct ipa_cst_ref_desc;

/* Structure holding data required to describe a constant jump function.  */
struct GTY(()) ipa_constant_data
{
  /* The value of the constant.  */
  tree value;
  /* Pointer to the structure that describes the reference.  */
  struct ipa_cst_ref_desc GTY((skip)) *rdesc;
};

/* Structure holding data required to describe a pass-through jump function.  */

struct GTY(()) ipa_pass_through_data
{
  /* If an operation is to be performed on the original parameter, this is the
     second (constant) operand.  */
  tree operand;
  /* Number of the caller's formal parameter being passed.  */
  int formal_id;
  /* Operation that is performed on the argument before it is passed on.
     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
     caller functions started execution, except for changes noted in the
     aggregate part of the jump function (see description of
     ipa_agg_jump_function).  The flag is used only when the operation is
     NOP_EXPR.  */
  unsigned agg_preserved : 1;
  /* Set when the edge has already been used to decrement an appropriate
     reference description counter and should not be decremented again.  */
  unsigned refdesc_decremented : 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.  */

struct GTY(()) ipa_ancestor_jf_data
{
  /* Offset of the field representing the ancestor.  */
  HOST_WIDE_INT offset;
  /* Number of the caller's formal parameter being passed.  */
  int formal_id;
  /* Flag with the same meaning like agg_preserve in ipa_pass_through_data.  */
  unsigned agg_preserved : 1;
  /* When set, the operation should not have any effect on NULL pointers.  */
  unsigned keep_null : 1;
};

/* 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 for the aggregate part.  */
  HOST_WIDE_INT offset;

  /* 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;
};

/* Jump functions describing a set of aggregate contents.  */

struct GTY(()) ipa_agg_jump_function
{
  /* 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).  */
  bool by_ref;
};

class ipcp_transformation;
class ipa_auto_call_arg_values;
class ipa_call_arg_values;

/* Element of a vector describing aggregate values for a number of arguments in
   a particular context, be it a call or the aggregate constants that a node is
   specialized for.  */

struct GTY(()) ipa_argagg_value
{
  /* The constant value.  In the contexts where the list of known values is
     being pruned, NULL means a variable value.  */
  tree value;
  /* Unit offset within the aggregate.  */
  unsigned unit_offset;
  /* Index of the parameter, as it was in the original function (i.e. needs
     remapping after parameter modification is carried out as part of clone
     materialization).  */
  unsigned index : IPA_PROP_ARG_INDEX_LIMIT_BITS;
  /* Whether the value was passed by reference.  */
  unsigned by_ref : 1;
};

/* A view into a sorted list of aggregate values in a particular context, be it
   a call or the aggregate constants that a node is specialized for.  The
   actual data is stored in the vector this has been constructed from.  */

class ipa_argagg_value_list
{
public:
  ipa_argagg_value_list () = delete;
  ipa_argagg_value_list (const vec<ipa_argagg_value, va_gc> *values)
    : m_elts (values)
  {}
  ipa_argagg_value_list (const vec<ipa_argagg_value> *values)
    : m_elts (*values)
  {}
  ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals);
  ipa_argagg_value_list (const ipa_call_arg_values *gavals);
  ipa_argagg_value_list (const ipcp_transformation *tinfo);

  /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is
     passed by reference or not according to BY_REF, or NULL_TREE
     otherwise.  */

  tree get_value (int index, unsigned unit_offset, bool by_ref) const;

  /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, not
     performing any check of whether value is passed by reference.  Return
     NULL_TREE if there is no such constant.  */

  tree get_value (int index, unsigned unit_offset) const;

  /* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
     NULL if there is no such constant.  */

  const ipa_argagg_value *get_elt (int index, unsigned unit_offset) const;


  /* Return the first item describing a constant stored for parameter with
     INDEX, regardless of offset or reference, or NULL if there is no such
     constant.  */

  const ipa_argagg_value *get_elt_for_index (int index) const;

  /* Return true if there is an aggregate constant referring to a value passed
     in or by parameter with INDEX (at any offset, whether by reference or
     not).  */

  bool value_for_index_p (int index) const
  {
    return !!get_elt_for_index (index);
  }

  /* Return true if all elements present in OTHER are also present in this
     list.  */

  bool superset_of_p (const ipa_argagg_value_list &other) const;

  /* Push all items in this list that describe parameter SRC_INDEX into RES as
     ones describing DST_INDEX while subtracting UNIT_DELTA from their unit
     offsets but skip those which would end up with a negative offset.  */

  void push_adjusted_values (unsigned src_index, unsigned dest_index,
			     unsigned unit_delta,
			     vec<ipa_argagg_value> *res) const;

  /* Dump aggregate constants to FILE.  */

  void dump (FILE *f);

  /* Dump aggregate constants to stderr.  */

  void DEBUG_FUNCTION debug ();

  /* Array slice pointing to the actual storage.  */

  array_slice<const ipa_argagg_value> m_elts;
};

/* Information about zero/non-zero bits.  */
class GTY(()) ipa_bits
{
public:
  /* The propagated value.  */
  widest_int value;
  /* Mask corresponding to the value.
     Similar to ccp_lattice_t, if xth bit of mask is 0,
     implies xth bit of value is constant.  */
  widest_int mask;
};

/* Info about value ranges.  */

class GTY(()) ipa_vr
{
public:
  ipa_vr ();
  ipa_vr (const vrange &);
  void set_unknown ();
  bool known_p () const { return m_storage != NULL; }
  tree type () const { return m_type; }
  void get_vrange (Value_Range &) const;
  bool equal_p (const vrange &) const;
  const vrange_storage *storage () const { return m_storage; }
  void streamer_read (lto_input_block *, data_in *);
  void streamer_write (output_block *) const;
  void dump (FILE *) const;

private:
  friend void gt_pch_nx (struct ipa_vr &);
  friend void gt_ggc_mx (struct ipa_vr &);
  friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);

  vrange_storage *m_storage;
  tree m_type;
};

/* A jump function for a callsite represents the values passed as actual
   arguments of the callsite. See enum jump_func_type for the various
   types of jump functions supported.  */
struct GTY (()) ipa_jump_func
{
  /* 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
     betweed different jump functions.  Use ipa_set_jfunc_bits to set this
     field.  */
  class ipa_bits *bits;

  /* 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.  */
  value_range *m_vr;

  enum jump_func_type type;
  /* Represents a value of a jump function.  pass_through is used only in jump
     function context.  constant represents the actual constant in constant jump
     functions and member_cst holds constant c++ member functions.  */
  union jump_func_value
  {
    struct ipa_constant_data GTY ((tag ("IPA_JF_CONST"))) constant;
    struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
    struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
  } GTY ((desc ("%1.type"))) value;
};


/* Return the constant stored in a constant jump functin JFUNC.  */

inline tree
ipa_get_jf_constant (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_CONST);
  return jfunc->value.constant.value;
}

inline struct ipa_cst_ref_desc *
ipa_get_jf_constant_rdesc (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_CONST);
  return jfunc->value.constant.rdesc;
}

/* Make JFUNC not participate in any further reference counting.  */

inline void
ipa_zap_jf_refdesc (ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_CONST);
  jfunc->value.constant.rdesc = NULL;
}

/* Return the operand of a pass through jmp function JFUNC.  */

inline tree
ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.operand;
}

/* Return the number of the caller's formal parameter that a pass through jump
   function JFUNC refers to.  */

inline int
ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.formal_id;
}

/* Return operation of a pass through jump function JFUNC.  */

inline enum tree_code
ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.operation;
}

/* Return the agg_preserved flag of a pass through jump function JFUNC.  */

inline bool
ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.agg_preserved;
}

/* Return the refdesc_decremented flag of a pass through jump function
   JFUNC.  */

inline bool
ipa_get_jf_pass_through_refdesc_decremented (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.refdesc_decremented;
}

/* Set the refdesc_decremented flag of a pass through jump function JFUNC to
   VALUE.  */

inline void
ipa_set_jf_pass_through_refdesc_decremented (ipa_jump_func *jfunc, bool value)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  jfunc->value.pass_through.refdesc_decremented = value;
}

/* Return true if pass through jump function JFUNC preserves type
   information.  */

inline bool
ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
  return jfunc->value.pass_through.agg_preserved;
}

/* Return the offset of an ancestor jump function JFUNC.  */

inline HOST_WIDE_INT
ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
  return jfunc->value.ancestor.offset;
}

/* Return the number of the caller's formal parameter that an ancestor jump
   function JFUNC refers to.  */

inline int
ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
  return jfunc->value.ancestor.formal_id;
}

/* Return the agg_preserved flag of an ancestor jump function JFUNC.  */

inline bool
ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
  return jfunc->value.ancestor.agg_preserved;
}

/* Return true if ancestor jump function JFUNC presrves type information.  */

inline bool
ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
  return jfunc->value.ancestor.agg_preserved;
}

/* Return if jfunc represents an operation whether we first check the formal
   parameter for non-NULLness unless it does not matter because the offset is
   zero anyway.  */

inline bool
ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc)
{
  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
  return jfunc->value.ancestor.keep_null;
}

/* 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:
  /* 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)
  {
    if ((unsigned) index < m_known_vals.length ())
      return m_known_vals[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_argagg_value, 32> m_known_aggs;

  /* Vector describing known value ranges of arguments.  */
  auto_vec<Value_Range, 32> m_known_value_ranges;
};

inline
ipa_argagg_value_list
::ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals)
  : m_elts (aavals->m_known_aggs)
{}

/* 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 as the vectors can either be pointing to vectors in
   ipa_auto_call_arg_values or be allocated independently.  */

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)
  {
    if ((unsigned) index < m_known_vals.length ())
      return m_known_vals[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_argagg_value> m_known_aggs = vNULL;

  /* Vector describing known value ranges of arguments.  */
  vec<Value_Range> m_known_value_ranges = vNULL;
};

inline
ipa_argagg_value_list
::ipa_argagg_value_list (const ipa_call_arg_values *gavals)
  : m_elts (gavals->m_known_aggs)
{}

/* 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 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 (which include flag dereferenced below), this is
     IPA_UNDESCRIBED_USE.  */
  int controlled_uses;
  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
   and some other information for interprocedural passes that operate on
   parameters (such as ipa-cp).  */

class GTY((for_user)) ipa_node_params
{
public:
  /* Default constructor.  */
  ipa_node_params ();

  /* Default destructor.  */
  ~ipa_node_params ();

  /* Information about individual formal parameters that are gathered when
     summaries are generated. */
  vec<ipa_param_descriptor, va_gc> *descriptors;
  /* Pointer to an array of structures describing individual formal
     parameters.  */
  class ipcp_param_lattices * GTY((skip)) lattices;
  /* Only for versioned nodes this field would not be NULL,
     it points to the node that IPA cp cloned from.  */
  struct cgraph_node * GTY((skip)) ipcp_orig_node;
  /* If this node is an ipa-cp clone, these are the known constants that
     describe what it has been specialized for.  */
  vec<tree> GTY((skip)) known_csts;
  /* If this node is an ipa-cp clone, these are the known polymorphic contexts
     that describe what it has been specialized for.  */
  vec<ipa_polymorphic_call_context> GTY((skip)) known_contexts;
  /* Whether the param uses analysis and jump function computation has already
     been performed.  */
  unsigned analysis_done : 1;
  /* Whether the function is enqueued in ipa-cp propagation stack.  */
  unsigned node_enqueued : 1;
  /* Whether we should create a specialized version based on values that are
     known to be constant in all contexts.  */
  unsigned do_clone_for_all_contexts : 1;
  /* Set if this is an IPA-CP clone for all contexts.  */
  unsigned is_all_contexts_clone : 1;
  /* Node has been completely replaced by clones and will be removed after
     ipa-cp is finished.  */
  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.  */
  unsigned versionable : 1;
};

inline
ipa_node_params::ipa_node_params ()
: descriptors (NULL), lattices (NULL), ipcp_orig_node (NULL),
  known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
  node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
  node_dead (0), node_within_scc (0), node_is_self_scc (0),
  node_calling_single_call (0), versionable (0)
{
}

inline
ipa_node_params::~ipa_node_params ()
{
  free (lattices);
  vec_free (descriptors);
  known_csts.release ();
  known_contexts.release ();
}

/* Intermediate information that we get from alias analysis about a particular
   parameter in a particular basic_block.  When a parameter or the memory it
   references is marked modified, we use that information in all dominated
   blocks without consulting alias analysis oracle.  */

struct ipa_param_aa_status
{
  /* Set when this structure contains meaningful information.  If not, the
     structure describing a dominating BB should be used instead.  */
  bool valid;

  /* Whether we have seen something which might have modified the data in
     question.  PARM is for the parameter itself, REF is for data it points to
     but using the alias type of individual accesses and PT is the same thing
     but for computing aggregate pass-through functions using a very inclusive
     ao_ref.  */
  bool parm_modified, ref_modified, pt_modified;
};

/* Information related to a given BB that used only when looking at function
   body.  */

struct ipa_bb_info
{
  /* Call graph edges going out of this BB.  */
  vec<cgraph_edge *> cg_edges;
  /* Alias analysis statuses of each formal parameter at this bb.  */
  vec<ipa_param_aa_status> param_aa_statuses;
};

/* Structure with global information that is only used when looking at function
   body. */

struct ipa_func_body_info
{
  /* The node that is being analyzed.  */
  cgraph_node *node;

  /* Its info.  */
  class ipa_node_params *info;

  /* Information about individual BBs. */
  vec<ipa_bb_info> bb_infos;

  /* Number of parameters.  */
  int param_count;

  /* Number of statements we are still allowed to walked by when analyzing this
     function.  */
  unsigned int aa_walk_budget;
};

/* ipa_node_params access functions.  Please use these to access fields that
   are or will be shared among various passes.  */

/* Return the number of formal parameters. */

inline int
ipa_get_param_count (class ipa_node_params *info)
{
  return vec_safe_length (info->descriptors);
}

/* Return the parameter declaration in DESCRIPTORS at index I and assert it is
   indeed a PARM_DECL.  */

inline tree
ipa_get_param (const vec<ipa_param_descriptor, va_gc> &descriptors, int i)
{
  tree t = descriptors[i].decl_or_type;
  gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
  return t;
}

/* Return the declaration of Ith formal parameter of the function corresponding
   to INFO.  Note there is no setter function as this array is built just once
   using ipa_initialize_node_params.  This function should not be called in
   WPA.  */

inline tree
ipa_get_param (class ipa_node_params *info, int i)
{
  gcc_checking_assert (info->descriptors);
  return ipa_get_param (*info->descriptors, i);
}

/* Return the type of Ith formal parameter of the function corresponding
   to INFO if it is known or NULL if not.  */

inline tree
ipa_get_type (class ipa_node_params *info, int i)
{
  if (vec_safe_length (info->descriptors) <= (unsigned) i)
    return NULL;
  tree t = (*info->descriptors)[i].decl_or_type;
  if (!t)
    return NULL;
  if (TYPE_P (t))
    return t;
  gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
  return TREE_TYPE (t);
}

/* Return the move cost of Ith formal parameter of the function corresponding
   to INFO.  */

inline int
ipa_get_param_move_cost (class ipa_node_params *info, int i)
{
  gcc_checking_assert (info->descriptors);
  return (*info->descriptors)[i].move_cost;
}

/* Set the used flag corresponding to the Ith formal parameter of the function
   associated with INFO to VAL.  */

inline void
ipa_set_param_used (class ipa_node_params *info, int i, bool val)
{
  gcc_checking_assert (info->descriptors);
  (*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.  */

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.  */

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.  */

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.  */
inline int
ipa_get_controlled_uses (class ipa_node_params *info, int i)
{
  /* FIXME: introducing speculation causes out of bounds access here.  */
  if (vec_safe_length (info->descriptors) > (unsigned)i)
    return (*info->descriptors)[i].controlled_uses;
  return IPA_UNDESCRIBED_USE;
}

/* Set the controlled counter of a given parameter.  */

inline void
ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
{
  gcc_checking_assert (info->descriptors);
  (*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.  */
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.  */

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.  */

inline bool
ipa_is_param_used (class ipa_node_params *info, int i)
{
  gcc_checking_assert (info->descriptors);
  return (*info->descriptors)[i].used;
}

/* Return the used_by_ipa_predicates flag corresponding to the Ith formal
   parameter of the function associated with INFO.  */

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.  */

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.  */

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;
}

/* GTY-marked structure used to map DECL_UIDs of APRAMs to their indices in
   their DECL_ARGUMENTs chain.  */
struct GTY(()) ipa_uid_to_idx_map_elt
{
  /* DECL_UID of the PARAM.  */
  unsigned uid;
  /* Its index in the DECL_ARGUMETs chain.  */
  unsigned index;
};

/* Structure holding information for the transformation phase of IPA-CP.  */

struct GTY(()) ipcp_transformation
{
  /* Default constructor.  */
  ipcp_transformation ()
    : m_agg_values (nullptr), bits (nullptr), m_vr (nullptr),
    m_uid_to_idx (nullptr)
  { }

  /* Default destructor.  */
  ~ipcp_transformation ()
  {
    vec_free (m_agg_values);
    vec_free (bits);
    vec_free (m_vr);
  }

  /* Given PARAM which must be a parameter of function FNDECL described by
     THIS, return its index in the DECL_ARGUMENTS chain, using a pre-computed
     DECL_UID-sorted vector if available (which is pre-computed only if there
     are many parameters).  Can return -1 if param is static chain not
     represented among DECL_ARGUMENTS. */

  int get_param_index (const_tree fndecl, const_tree param) const;

  /* Assuming THIS describes FNDECL and it has sufficiently many parameters to
     justify the overhead, create a DECL_UID-sorted vector to speed up mapping
     from parameters to their indices in DECL_ARGUMENTS chain.  */

  void maybe_create_parm_idx_map (tree fndecl);

  /* Known aggregate values.  */
  vec<ipa_argagg_value, va_gc>  *m_agg_values;
  /* Known bits information.  */
  vec<ipa_bits *, va_gc> *bits;
  /* Value range information.  */
  vec<ipa_vr, va_gc> *m_vr;
  /* If there are many parameters, this is a vector sorted by their DECL_UIDs
     to map them to their indices in the DECL_ARGUMENT chain.  */
  vec<ipa_uid_to_idx_map_elt, va_gc> *m_uid_to_idx;
};

inline
ipa_argagg_value_list::ipa_argagg_value_list (const ipcp_transformation *tinfo)
  : m_elts (tinfo->m_agg_values)
{}

void ipa_set_node_agg_value_chain (struct cgraph_node *node,
				   vec<ipa_argagg_value, va_gc> *aggs);
void ipcp_transformation_initialize (void);
void ipcp_free_transformation_sum (void);

/* ipa_edge_args stores information related to a callsite and particularly its
   arguments.  It can be accessed by the IPA_EDGE_REF macro.  */

class GTY((for_user)) ipa_edge_args
{
 public:

  /* Default constructor.  */
  ipa_edge_args () : jump_functions (NULL), polymorphic_call_contexts (NULL)
    {}

  /* 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);
    }

  /* Vectors of the callsite's jump function and polymorphic context
     information of each parameter.  */
  vec<ipa_jump_func, va_gc> *jump_functions;
  vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts;
};

/* ipa_edge_args access functions.  Please use these to access fields that
   are or will be shared among various passes.  */

/* Return the number of actual arguments. */

inline int
ipa_get_cs_argument_count (class ipa_edge_args *args)
{
  return vec_safe_length (args->jump_functions);
}

/* Returns a pointer to the jump function for the ith argument.  Please note
   there is no setter function as jump functions are all set up in
   ipa_compute_jump_functions. */

inline struct ipa_jump_func *
ipa_get_ith_jump_func (class ipa_edge_args *args, int i)
{
  return &(*args->jump_functions)[i];
}

/* Returns a pointer to the polymorphic call context for the ith argument.
   NULL if contexts are not computed.  */
inline class ipa_polymorphic_call_context *
ipa_get_ith_polymorhic_call_context (class ipa_edge_args *args, int i)
{
  if (!args->polymorphic_call_contexts)
    return NULL;
  return &(*args->polymorphic_call_contexts)[i];
}

/* Function summary for ipa_node_params.  */
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)
  {
    disable_insertion_hook ();
  }

  /* Hook that is called by summary when a node is duplicated.  */
  void duplicate (cgraph_node *node,
		  cgraph_node *node2,
		  ipa_node_params *data,
		  ipa_node_params *data2) final override;
};

/* Summary to manange ipa_edge_args structures.  */

class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
{
 public:
  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.  */
  void remove (cgraph_edge *cs, ipa_edge_args *args) final override;
  /* Hook that is called by summary when an edge is duplicated.  */
  void duplicate (cgraph_edge *src,
		  cgraph_edge *dst,
		  ipa_edge_args *old_args,
		  ipa_edge_args *new_args) final override;
};

/* Function summary where the parameter infos are actually stored. */
extern GTY(()) ipa_node_params_t * ipa_node_params_sum;
/* Call summary to store information about edges such as jump functions.  */
extern GTY(()) ipa_edge_args_sum_t *ipa_edge_args_sum;

/* Function summary for IPA-CP transformation.  */
class ipcp_transformation_t
: public function_summary<ipcp_transformation *>
{
public:
  ipcp_transformation_t (symbol_table *table, bool ggc):
    function_summary<ipcp_transformation *> (table, ggc) {}

  ~ipcp_transformation_t () {}

  static ipcp_transformation_t *create_ggc (symbol_table *symtab)
  {
    ipcp_transformation_t *summary
      = 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.  */
  void duplicate (cgraph_node *node,
		  cgraph_node *node2,
		  ipcp_transformation *data,
		  ipcp_transformation *data2) final override;
};

/* Function summary where the IPA CP transformations are actually stored.  */
extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum;

/* Creating and freeing ipa_node_params and ipa_edge_args.  */
void ipa_create_all_node_params (void);
void ipa_create_all_edge_args (void);
void ipa_check_create_edge_args (void);
void ipa_free_all_node_params (void);
void ipa_free_all_edge_args (void);
void ipa_free_all_structures_after_ipa_cp (void);
void ipa_free_all_structures_after_iinln (void);

void ipa_register_cgraph_hooks (void);
int count_formal_params (tree fndecl);

/* This function ensures the array of node param infos is big enough to
   accommodate a structure for all nodes and reallocates it if not.  */

inline void
ipa_check_create_node_params (void)
{
  if (!ipa_node_params_sum)
    ipa_node_params_sum
      = (new (ggc_alloc_no_dtor <ipa_node_params_t> ())
	 ipa_node_params_t (symtab, true));
}

/* Returns true if edge summary contains a record for EDGE.  The main purpose
   of this function is that debug dumping function can check info availability
   without causing allocations.  */

inline bool
ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
{
  return ipa_edge_args_sum->exists (edge);
}

inline ipcp_transformation *
ipcp_get_transformation_summary (cgraph_node *node)
{
  if (ipcp_transformation_sum == NULL)
    return NULL;

  return ipcp_transformation_sum->get (node);
}

/* Function formal parameters related computations.  */
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 processing and target discovery.  */
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
				   ipa_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);
ipa_bits *ipa_get_ipa_bits_for_value (const widest_int &value,
				      const widest_int &mask);


/* Functions related to both.  */
void ipa_analyze_node (struct cgraph_node *);

/* Aggregate jump function related functions.  */
tree ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset,
				 bool by_ref);
bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
			     vec<ipa_param_descriptor, va_gc> *descriptors,
			     gimple *stmt, tree op, int *index_p,
			     HOST_WIDE_INT *offset_p, poly_int64 *size_p,
			     bool *by_ref, bool *guaranteed_unmodified = NULL);

/* Debugging interface.  */
void ipa_print_node_params (FILE *, struct cgraph_node *node);
void ipa_print_all_params (FILE *);
void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
void ipa_print_all_jump_functions (FILE * f);
void ipcp_verify_propagated_values (void);

template <typename value>
class ipcp_value;

extern object_allocator<ipcp_value<tree> > ipcp_cst_values_pool;
extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
  ipcp_poly_ctx_values_pool;

template <typename valtype>
struct ipcp_value_source;

extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;

struct ipcp_agg_lattice;

extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;

void ipa_prop_write_jump_functions (void);
void ipa_prop_read_jump_functions (void);
void ipcp_write_transformation_summaries (void);
void ipcp_read_transformation_summaries (void);
int ipa_get_param_decl_index (class ipa_node_params *, tree);
tree ipa_value_from_jfunc (class ipa_node_params *info,
			   struct ipa_jump_func *jfunc, tree type);
tree ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
			       const ipa_agg_jf_item *item);
unsigned int ipcp_transform_function (struct cgraph_node *node);
ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
						     cgraph_edge *,
						     int,
						     ipa_jump_func *);
void ipa_value_range_from_jfunc (vrange &, ipa_node_params *, cgraph_edge *,
				 ipa_jump_func *, tree);
void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
				     ipa_agg_jump_function *agg_jfunc,
				     unsigned dst_index,
				     vec<ipa_argagg_value> *res);
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.cc:  */
tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,
			   gimple_stmt_iterator *, bool);

/* In ipa-cp.cc  */
void ipa_cp_cc_finalize (void);

/* Set R to the range of [VAL, VAL] while normalizing addresses to
   non-zero.  */

inline void
ipa_range_set_and_normalize (vrange &r, tree val)
{
  if (TREE_CODE (val) == ADDR_EXPR)
    r.set_nonzero (TREE_TYPE (val));
  else
    r.set (val, val);
}

#endif /* IPA_PROP_H */
