LCOV - code coverage report
Current view: top level - gcc - ipa-prop.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 99.5 % 217 216
Test Date: 2025-06-21 16:26:05 Functions: 97.8 % 46 45
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Interprocedural analyses.
       2                 :             :    Copyright (C) 2005-2025 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #ifndef IPA_PROP_H
      21                 :             : #define IPA_PROP_H
      22                 :             : 
      23                 :             : /* The following definitions and interfaces are used by
      24                 :             :    interprocedural analyses or parameters.  */
      25                 :             : 
      26                 :             : #define IPA_UNDESCRIBED_USE -1
      27                 :             : 
      28                 :             : /* Index identifying an actualargument or a formal parameter may have only this
      29                 :             :    many bits.  */
      30                 :             : 
      31                 :             : #define IPA_PROP_ARG_INDEX_LIMIT_BITS 16
      32                 :             : 
      33                 :             : /* ipa-prop.cc stuff (ipa-cp, indirect inlining):  */
      34                 :             : 
      35                 :             : /* A jump function for a callsite represents the values passed as actual
      36                 :             :    arguments of the callsite.  They were originally proposed in a paper called
      37                 :             :    "Interprocedural Constant Propagation", by David Callahan, Keith D Cooper,
      38                 :             :    Ken Kennedy, Linda Torczon in Comp86, pg 152-161.  There are three main
      39                 :             :    types of values :
      40                 :             : 
      41                 :             :    Pass-through - the caller's formal parameter is passed as an actual
      42                 :             :                   argument, possibly one simple operation performed on it.
      43                 :             :    Constant     - a constant (is_gimple_ip_invariant)is passed as an actual
      44                 :             :                   argument.
      45                 :             :    Unknown      - neither of the above.
      46                 :             : 
      47                 :             :    IPA_JF_LOAD_AGG is a compound pass-through jump function, in which primary
      48                 :             :    operation on formal parameter is memory dereference that loads a value from
      49                 :             :    a part of an aggregate, which is represented or pointed to by the formal
      50                 :             :    parameter.  Moreover, an additional unary/binary operation can be applied on
      51                 :             :    the loaded value, and final result is passed as actual argument of callee
      52                 :             :    (e.g. *(param_1(D) + 4) op 24 ).  It is meant to describe usage of aggregate
      53                 :             :    parameter or by-reference parameter referenced in argument passing, commonly
      54                 :             :    found in C++ and Fortran.
      55                 :             : 
      56                 :             :    IPA_JF_ANCESTOR is a special pass-through jump function, which means that
      57                 :             :    the result is an address of a part of the object pointed to by the formal
      58                 :             :    parameter to which the function refers.  It is mainly intended to represent
      59                 :             :    getting addresses of ancestor fields in C++
      60                 :             :    (e.g. &this_1(D)->D.1766.D.1756).  Note that if the original pointer is
      61                 :             :    NULL, ancestor jump function must behave like a simple pass-through.
      62                 :             : 
      63                 :             :    Other pass-through functions can either simply pass on an unchanged formal
      64                 :             :    parameter or can apply one simple binary operation to it (such jump
      65                 :             :    functions are called polynomial).
      66                 :             : 
      67                 :             :    Jump functions are computed in ipa-prop.cc by function
      68                 :             :    update_call_notes_after_inlining.  Some information can be lost and jump
      69                 :             :    functions degraded accordingly when inlining, see
      70                 :             :    update_call_notes_after_inlining in the same file.  */
      71                 :             : 
      72                 :             : enum jump_func_type
      73                 :             : {
      74                 :             :   IPA_JF_UNKNOWN = 0,  /* newly allocated and zeroed jump functions default */
      75                 :             :   IPA_JF_CONST,             /* represented by field costant */
      76                 :             :   IPA_JF_PASS_THROUGH,      /* represented by field pass_through */
      77                 :             :   IPA_JF_LOAD_AGG,          /* represented by field load_agg */
      78                 :             :   IPA_JF_ANCESTOR           /* represented by field ancestor */
      79                 :             : };
      80                 :             : 
      81                 :             : struct ipa_cst_ref_desc;
      82                 :             : 
      83                 :             : /* Structure holding data required to describe a constant jump function.  */
      84                 :             : struct GTY(()) ipa_constant_data
      85                 :             : {
      86                 :             :   /* The value of the constant.  */
      87                 :             :   tree value;
      88                 :             :   /* Pointer to the structure that describes the reference.  */
      89                 :             :   struct ipa_cst_ref_desc GTY((skip)) *rdesc;
      90                 :             : };
      91                 :             : 
      92                 :             : /* Structure holding data required to describe a pass-through jump function.  */
      93                 :             : 
      94                 :             : struct GTY(()) ipa_pass_through_data
      95                 :             : {
      96                 :             :   /* If an operation is to be performed on the original parameter, this is the
      97                 :             :      second (constant) operand.  */
      98                 :             :   tree operand;
      99                 :             :   /* The result type of the operation.  In case of no operation (represented by
     100                 :             :      NOP_EXPR) it should be NULL_TREE.  */
     101                 :             :   tree op_type;
     102                 :             :   /* Number of the caller's formal parameter being passed.  */
     103                 :             :   int formal_id;
     104                 :             :   /* Operation that is performed on the argument before it is passed on.
     105                 :             :      Special values which have other meaning than in normal contexts:
     106                 :             :        - NOP_EXPR means no operation, not even type conversion.
     107                 :             :        - ASSERT_EXPR means that only the value in operand is allowed to pass
     108                 :             :          through (without any change), for all other values the result is
     109                 :             :          unknown.
     110                 :             :      Otherwise operation must be a simple binary or unary arithmetic operation
     111                 :             :      where the caller's parameter is the first operand and (for binary
     112                 :             :      operations) the operand field from this structure is the second one.  */
     113                 :             :   enum tree_code operation;
     114                 :             :   /* When the passed value is a pointer, it is set to true only when we are
     115                 :             :      certain that no write to the object it points to has occurred since the
     116                 :             :      caller functions started execution, except for changes noted in the
     117                 :             :      aggregate part of the jump function (see description of
     118                 :             :      ipa_agg_jump_function).  The flag is used only when the operation is
     119                 :             :      NOP_EXPR.  */
     120                 :             :   unsigned agg_preserved : 1;
     121                 :             :   /* Set when the edge has already been used to decrement an appropriate
     122                 :             :      reference description counter and should not be decremented again.  */
     123                 :             :   unsigned refdesc_decremented : 1;
     124                 :             : };
     125                 :             : 
     126                 :             : /* Structure holding data required to describe a load-value-from-aggregate
     127                 :             :    jump function.  */
     128                 :             : 
     129                 :             : struct GTY(()) ipa_load_agg_data
     130                 :             : {
     131                 :             :   /* Inherit from pass through jump function, describing unary/binary
     132                 :             :      operation on the value loaded from aggregate that is represented or
     133                 :             :      pointed to by the formal parameter, specified by formal_id in this
     134                 :             :      pass_through jump function data structure.  */
     135                 :             :   struct ipa_pass_through_data pass_through;
     136                 :             :   /* Type of the value loaded from the aggregate.  */
     137                 :             :   tree type;
     138                 :             :   /* Offset at which the value is located within the aggregate.  */
     139                 :             :   HOST_WIDE_INT offset;
     140                 :             :   /* True if loaded by reference (the aggregate is pointed to by the formal
     141                 :             :      parameter) or false if loaded by value (the aggregate is represented
     142                 :             :      by the formal parameter).  */
     143                 :             :   bool by_ref;
     144                 :             : };
     145                 :             : 
     146                 :             : /* Structure holding data required to describe an ancestor pass-through
     147                 :             :    jump function.  */
     148                 :             : 
     149                 :             : struct GTY(()) ipa_ancestor_jf_data
     150                 :             : {
     151                 :             :   /* Offset of the field representing the ancestor.  */
     152                 :             :   HOST_WIDE_INT offset;
     153                 :             :   /* Number of the caller's formal parameter being passed.  */
     154                 :             :   int formal_id;
     155                 :             :   /* Flag with the same meaning like agg_preserve in ipa_pass_through_data.  */
     156                 :             :   unsigned agg_preserved : 1;
     157                 :             :   /* When set, the operation should not have any effect on NULL pointers.  */
     158                 :             :   unsigned keep_null : 1;
     159                 :             : };
     160                 :             : 
     161                 :             : /* A jump function for an aggregate part at a given offset, which describes how
     162                 :             :    it content value is generated.  All unlisted positions are assumed to have a
     163                 :             :    value defined in an unknown way.  */
     164                 :             : 
     165                 :             : struct GTY(()) ipa_agg_jf_item
     166                 :             : {
     167                 :             :   /* The offset for the aggregate part.  */
     168                 :             :   HOST_WIDE_INT offset;
     169                 :             : 
     170                 :             :   /* Data type of the aggregate part.  */
     171                 :             :   tree type;
     172                 :             : 
     173                 :             :   /* Jump function type.  */
     174                 :             :   enum jump_func_type jftype;
     175                 :             : 
     176                 :             :   /* Represents a value of jump function. constant represents the actual constant
     177                 :             :      in constant jump function content.  pass_through is used only in simple pass
     178                 :             :      through jump function context.  load_agg is for load-value-from-aggregate
     179                 :             :      jump function context.  */
     180                 :             :   union jump_func_agg_value
     181                 :             :   {
     182                 :             :     tree GTY ((tag ("IPA_JF_CONST"))) constant;
     183                 :             :     struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
     184                 :             :     struct ipa_load_agg_data GTY ((tag ("IPA_JF_LOAD_AGG"))) load_agg;
     185                 :             :   } GTY ((desc ("%1.jftype"))) value;
     186                 :             : };
     187                 :             : 
     188                 :             : /* Jump functions describing a set of aggregate contents.  */
     189                 :             : 
     190                 :             : struct GTY(()) ipa_agg_jump_function
     191                 :             : {
     192                 :             :   /* Description of the individual jump function item.  */
     193                 :             :   vec<ipa_agg_jf_item, va_gc> *items;
     194                 :             :   /* True if the data was passed by reference (as opposed to by value).  */
     195                 :             :   bool by_ref;
     196                 :             : };
     197                 :             : 
     198                 :             : class ipcp_transformation;
     199                 :             : class ipa_auto_call_arg_values;
     200                 :             : class ipa_call_arg_values;
     201                 :             : 
     202                 :             : /* Element of a vector describing aggregate values for a number of arguments in
     203                 :             :    a particular context, be it a call or the aggregate constants that a node is
     204                 :             :    specialized for.  */
     205                 :             : 
     206                 :             : struct GTY(()) ipa_argagg_value
     207                 :             : {
     208                 :             :   /* The constant value.  In the contexts where the list of known values is
     209                 :             :      being pruned, NULL means a variable value.  */
     210                 :             :   tree value;
     211                 :             :   /* Unit offset within the aggregate.  */
     212                 :             :   unsigned unit_offset;
     213                 :             :   /* Index of the parameter, as it was in the original function (i.e. needs
     214                 :             :      remapping after parameter modification is carried out as part of clone
     215                 :             :      materialization).  */
     216                 :             :   unsigned index : IPA_PROP_ARG_INDEX_LIMIT_BITS;
     217                 :             :   /* Whether the value was passed by reference.  */
     218                 :             :   unsigned by_ref : 1;
     219                 :             :   /* Set if the value should not be used after materialization in
     220                 :             :      value_numbering.  It is kept around just so that clone materialization can
     221                 :             :      distinguish a combined IPA-CP and IPA-SRA from a deleted argument.  */
     222                 :             :   unsigned killed : 1;
     223                 :             : };
     224                 :             : 
     225                 :             : /* A view into a sorted list of aggregate values in a particular context, be it
     226                 :             :    a call or the aggregate constants that a node is specialized for.  The
     227                 :             :    actual data is stored in the vector this has been constructed from.  */
     228                 :             : 
     229                 :             : class ipa_argagg_value_list
     230                 :             : {
     231                 :             : public:
     232                 :             :   ipa_argagg_value_list () = delete;
     233                 :        2976 :   ipa_argagg_value_list (const vec<ipa_argagg_value, va_gc> *values)
     234                 :        5890 :     : m_elts (values)
     235                 :             :   {}
     236                 :        3825 :   ipa_argagg_value_list (const vec<ipa_argagg_value> *values)
     237                 :        7650 :     : m_elts (*values)
     238                 :             :   {}
     239                 :             :   ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals);
     240                 :             :   ipa_argagg_value_list (const ipa_call_arg_values *gavals);
     241                 :             :   ipa_argagg_value_list (const ipcp_transformation *tinfo);
     242                 :             : 
     243                 :             :   /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is
     244                 :             :      passed by reference or not according to BY_REF, or NULL_TREE
     245                 :             :      otherwise.  */
     246                 :             : 
     247                 :             :   tree get_value (int index, unsigned unit_offset, bool by_ref) const;
     248                 :             : 
     249                 :             :   /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, not
     250                 :             :      performing any check of whether value is passed by reference.  Return
     251                 :             :      NULL_TREE if there is no such constant.  */
     252                 :             : 
     253                 :             :   tree get_value (int index, unsigned unit_offset) const;
     254                 :             : 
     255                 :             :   /* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
     256                 :             :      NULL if there is no such constant.  */
     257                 :             : 
     258                 :             :   const ipa_argagg_value *get_elt (int index, unsigned unit_offset) const;
     259                 :             : 
     260                 :             : 
     261                 :             :   /* Return the first item describing a constant stored for parameter with
     262                 :             :      INDEX, regardless of offset or reference, or NULL if there is no such
     263                 :             :      constant.  */
     264                 :             : 
     265                 :             :   const ipa_argagg_value *get_elt_for_index (int index) const;
     266                 :             : 
     267                 :             :   /* Return true if there is an aggregate constant referring to a value passed
     268                 :             :      in or by parameter with INDEX (at any offset, whether by reference or
     269                 :             :      not).  */
     270                 :             : 
     271                 :      137191 :   bool value_for_index_p (int index) const
     272                 :             :   {
     273                 :      137191 :     return !!get_elt_for_index (index);
     274                 :             :   }
     275                 :             : 
     276                 :             :   /* Return true if all elements present in OTHER are also present in this
     277                 :             :      list.  */
     278                 :             : 
     279                 :             :   bool superset_of_p (const ipa_argagg_value_list &other) const;
     280                 :             : 
     281                 :             :   /* Push all items in this list that describe parameter SRC_INDEX into RES as
     282                 :             :      ones describing DST_INDEX while subtracting UNIT_DELTA from their unit
     283                 :             :      offsets but skip those which would end up with a negative offset.  */
     284                 :             : 
     285                 :             :   void push_adjusted_values (unsigned src_index, unsigned dest_index,
     286                 :             :                              unsigned unit_delta,
     287                 :             :                              vec<ipa_argagg_value> *res) const;
     288                 :             : 
     289                 :             :   /* Dump aggregate constants to FILE.  */
     290                 :             : 
     291                 :             :   void dump (FILE *f);
     292                 :             : 
     293                 :             :   /* Dump aggregate constants to stderr.  */
     294                 :             : 
     295                 :             :   void DEBUG_FUNCTION debug ();
     296                 :             : 
     297                 :             :   /* Array slice pointing to the actual storage.  */
     298                 :             : 
     299                 :             :   array_slice<const ipa_argagg_value> m_elts;
     300                 :             : };
     301                 :             : 
     302                 :             : /* Info about value ranges.  */
     303                 :             : 
     304                 :             : class GTY(()) ipa_vr
     305                 :             : {
     306                 :             : public:
     307                 :             :   ipa_vr ();
     308                 :             :   ipa_vr (const vrange &);
     309                 :             :   void set_unknown ();
     310                 :     9633659 :   bool known_p () const { return m_storage != NULL; }
     311                 :     9184823 :   tree type () const { return m_type; }
     312                 :             :   void get_vrange (value_range &) const;
     313                 :             :   bool equal_p (const vrange &) const;
     314                 :             :   bool equal_p (const ipa_vr &) const;
     315                 :             :   const vrange_storage *storage () const { return m_storage; }
     316                 :             :   void streamer_read (lto_input_block *, class data_in *);
     317                 :             :   void streamer_write (output_block *) const;
     318                 :             :   void dump (FILE *) const;
     319                 :             : 
     320                 :             : private:
     321                 :             :   friend void gt_pch_nx (struct ipa_vr &);
     322                 :             :   friend void gt_ggc_mx (struct ipa_vr &);
     323                 :             :   friend void gt_pch_nx (struct ipa_vr *, gt_pointer_operator, void *);
     324                 :             :   friend void gt_ggc_mx_ipa_vr (void *);
     325                 :             :   friend void gt_pch_nx_ipa_vr (void*);
     326                 :             :   friend void gt_pch_p_6ipa_vr(void*, void*, gt_pointer_operator, void*);
     327                 :             : 
     328                 :             :   vrange_storage *m_storage;
     329                 :             :   tree m_type;
     330                 :             : };
     331                 :             : 
     332                 :             : /* A jump function for a callsite represents the values passed as actual
     333                 :             :    arguments of the callsite. See enum jump_func_type for the various
     334                 :             :    types of jump functions supported.  */
     335                 :             : struct GTY (()) ipa_jump_func
     336                 :             : {
     337                 :             :   /* Aggregate jump function description.  See struct ipa_agg_jump_function
     338                 :             :      and its description.  */
     339                 :             :   struct ipa_agg_jump_function agg;
     340                 :             : 
     341                 :             :   /* Information about value range, containing valid data only when vr_known is
     342                 :             :      true.  The pointed to structure is shared betweed different jump
     343                 :             :      functions.  Use ipa_set_jfunc_vr to set this field.  */
     344                 :             :   ipa_vr *m_vr;
     345                 :             : 
     346                 :             :   enum jump_func_type type;
     347                 :             :   /* Represents a value of a jump function.  pass_through is used only in jump
     348                 :             :      function context.  constant represents the actual constant in constant jump
     349                 :             :      functions and member_cst holds constant c++ member functions.  */
     350                 :             :   union jump_func_value
     351                 :             :   {
     352                 :             :     struct ipa_constant_data GTY ((tag ("IPA_JF_CONST"))) constant;
     353                 :             :     struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
     354                 :             :     struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
     355                 :             :   } GTY ((desc ("%1.type"))) value;
     356                 :             : };
     357                 :             : 
     358                 :             : 
     359                 :             : /* Return the constant stored in a constant jump functin JFUNC.  */
     360                 :             : 
     361                 :             : inline tree
     362                 :     4624140 : ipa_get_jf_constant (struct ipa_jump_func *jfunc)
     363                 :             : {
     364                 :     4624140 :   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
     365                 :     4624140 :   return jfunc->value.constant.value;
     366                 :             : }
     367                 :             : 
     368                 :             : inline struct ipa_cst_ref_desc *
     369                 :     1498358 : ipa_get_jf_constant_rdesc (struct ipa_jump_func *jfunc)
     370                 :             : {
     371                 :     1498358 :   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
     372                 :     1498358 :   return jfunc->value.constant.rdesc;
     373                 :             : }
     374                 :             : 
     375                 :             : /* Make JFUNC not participate in any further reference counting.  */
     376                 :             : 
     377                 :             : inline void
     378                 :         387 : ipa_zap_jf_refdesc (ipa_jump_func *jfunc)
     379                 :             : {
     380                 :         387 :   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
     381                 :         387 :   jfunc->value.constant.rdesc = NULL;
     382                 :         387 : }
     383                 :             : 
     384                 :             : /* Return the operand of a pass through jmp function JFUNC.  */
     385                 :             : 
     386                 :             : inline tree
     387                 :       87741 : ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
     388                 :             : {
     389                 :       87741 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     390                 :       87741 :   return jfunc->value.pass_through.operand;
     391                 :             : }
     392                 :             : 
     393                 :             : /* Return the type of the operation in a non-NOP pass through jmp function
     394                 :             :    JFUNC.  */
     395                 :             : 
     396                 :             : inline tree
     397                 :        7066 : ipa_get_jf_pass_through_op_type (struct ipa_jump_func *jfunc)
     398                 :             : {
     399                 :        7066 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH
     400                 :             :                        && jfunc->value.pass_through.operation != NOP_EXPR);
     401                 :             : 
     402                 :        7066 :   return jfunc->value.pass_through.op_type;
     403                 :             : }
     404                 :             : 
     405                 :             : /* Return the number of the caller's formal parameter that a pass through jump
     406                 :             :    function JFUNC refers to.  */
     407                 :             : 
     408                 :             : inline int
     409                 :     6271931 : ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
     410                 :             : {
     411                 :     6271931 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     412                 :     6271931 :   return jfunc->value.pass_through.formal_id;
     413                 :             : }
     414                 :             : 
     415                 :             : /* Return operation of a pass through jump function JFUNC.  */
     416                 :             : 
     417                 :             : inline enum tree_code
     418                 :     2356646 : ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
     419                 :             : {
     420                 :     2356646 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     421                 :     2356646 :   return jfunc->value.pass_through.operation;
     422                 :             : }
     423                 :             : 
     424                 :             : /* Return the agg_preserved flag of a pass through jump function JFUNC.  */
     425                 :             : 
     426                 :             : inline bool
     427                 :     2237244 : ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
     428                 :             : {
     429                 :     2237244 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     430                 :     2237244 :   return jfunc->value.pass_through.agg_preserved;
     431                 :             : }
     432                 :             : 
     433                 :             : /* Return the refdesc_decremented flag of a pass through jump function
     434                 :             :    JFUNC.  */
     435                 :             : 
     436                 :             : inline bool
     437                 :      471748 : ipa_get_jf_pass_through_refdesc_decremented (struct ipa_jump_func *jfunc)
     438                 :             : {
     439                 :      471748 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     440                 :      471748 :   return jfunc->value.pass_through.refdesc_decremented;
     441                 :             : }
     442                 :             : 
     443                 :             : /* Set the refdesc_decremented flag of a pass through jump function JFUNC to
     444                 :             :    VALUE.  */
     445                 :             : 
     446                 :             : inline void
     447                 :          16 : ipa_set_jf_pass_through_refdesc_decremented (ipa_jump_func *jfunc, bool value)
     448                 :             : {
     449                 :          16 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     450                 :          16 :   jfunc->value.pass_through.refdesc_decremented = value;
     451                 :          16 : }
     452                 :             : 
     453                 :             : /* Return true if pass through jump function JFUNC preserves type
     454                 :             :    information.  */
     455                 :             : 
     456                 :             : inline bool
     457                 :      259675 : ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
     458                 :             : {
     459                 :      259675 :   gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
     460                 :      259675 :   return jfunc->value.pass_through.agg_preserved;
     461                 :             : }
     462                 :             : 
     463                 :             : /* Return the offset of an ancestor jump function JFUNC.  */
     464                 :             : 
     465                 :             : inline HOST_WIDE_INT
     466                 :      236742 : ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
     467                 :             : {
     468                 :      236742 :   gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
     469                 :      236742 :   return jfunc->value.ancestor.offset;
     470                 :             : }
     471                 :             : 
     472                 :             : /* Return the number of the caller's formal parameter that an ancestor jump
     473                 :             :    function JFUNC refers to.  */
     474                 :             : 
     475                 :             : inline int
     476                 :     1158295 : ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
     477                 :             : {
     478                 :     1158295 :   gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
     479                 :     1158295 :   return jfunc->value.ancestor.formal_id;
     480                 :             : }
     481                 :             : 
     482                 :             : /* Return the agg_preserved flag of an ancestor jump function JFUNC.  */
     483                 :             : 
     484                 :             : inline bool
     485                 :      274263 : ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
     486                 :             : {
     487                 :      274263 :   gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
     488                 :      274263 :   return jfunc->value.ancestor.agg_preserved;
     489                 :             : }
     490                 :             : 
     491                 :             : /* Return true if ancestor jump function JFUNC presrves type information.  */
     492                 :             : 
     493                 :             : inline bool
     494                 :       55699 : ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
     495                 :             : {
     496                 :       55699 :   gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
     497                 :       55699 :   return jfunc->value.ancestor.agg_preserved;
     498                 :             : }
     499                 :             : 
     500                 :             : /* Return if jfunc represents an operation whether we first check the formal
     501                 :             :    parameter for non-NULLness unless it does not matter because the offset is
     502                 :             :    zero anyway.  */
     503                 :             : 
     504                 :             : inline bool
     505                 :       26334 : ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc)
     506                 :             : {
     507                 :       26334 :   gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
     508                 :       26334 :   return jfunc->value.ancestor.keep_null;
     509                 :             : }
     510                 :             : 
     511                 :             : /* Class for allocating a bundle of various potentially known properties about
     512                 :             :    actual arguments of a particular call on stack for the usual case and on
     513                 :             :    heap only if there are unusually many arguments.  The data is deallocated
     514                 :             :    when the instance of this class goes out of scope or is otherwise
     515                 :             :    destructed.  */
     516                 :             : 
     517                 :    23478238 : class ipa_auto_call_arg_values
     518                 :             : {
     519                 :             : public:
     520                 :             :   /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
     521                 :             :      return its element at INDEX, otherwise return NULL.  */
     522                 :    52835938 :   tree safe_sval_at (int index)
     523                 :             :   {
     524                 :    52835938 :     if ((unsigned) index < m_known_vals.length ())
     525                 :    32865783 :       return m_known_vals[index];
     526                 :             :     return NULL;
     527                 :             :   }
     528                 :             : 
     529                 :             :   /* Vector describing known values of parameters.  */
     530                 :             :   auto_vec<tree, 32> m_known_vals;
     531                 :             : 
     532                 :             :   /* Vector describing known polymorphic call contexts.  */
     533                 :             :   auto_vec<ipa_polymorphic_call_context, 32> m_known_contexts;
     534                 :             : 
     535                 :             :   /* Vector describing known aggregate values.  */
     536                 :             :   auto_vec<ipa_argagg_value, 32> m_known_aggs;
     537                 :             : 
     538                 :             :   /* Vector describing known value ranges of arguments.  */
     539                 :             :   auto_vec<value_range, 32> m_known_value_ranges;
     540                 :             : };
     541                 :             : 
     542                 :             : inline
     543                 :    26797339 : ipa_argagg_value_list
     544                 :    26797339 : ::ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals)
     545                 :    53594678 :   : m_elts (aavals->m_known_aggs)
     546                 :             : {}
     547                 :             : 
     548                 :             : /* Class bundling the various potentially known properties about actual
     549                 :             :    arguments of a particular call.  This variant does not deallocate the
     550                 :             :    bundled data in any way as the vectors can either be pointing to vectors in
     551                 :             :    ipa_auto_call_arg_values or be allocated independently.  */
     552                 :             : 
     553                 :             : class ipa_call_arg_values
     554                 :             : {
     555                 :             : public:
     556                 :             :   /* Default constructor, setting the vectors to empty ones.  */
     557                 :     1176984 :   ipa_call_arg_values ()
     558                 :           0 :   {}
     559                 :             : 
     560                 :             :   /* Construct this general variant of the bundle from the variant which uses
     561                 :             :      auto_vecs to hold the vectors.  This means that vectors of objects
     562                 :             :      constructed with this constructor should not be changed because if they
     563                 :             :      get reallocated, the member vectors and the underlying auto_vecs would get
     564                 :             :      out of sync.  */
     565                 :    18991843 :   ipa_call_arg_values (ipa_auto_call_arg_values *aavals)
     566                 :    18991843 :     : m_known_vals (aavals->m_known_vals.to_vec_legacy ()),
     567                 :    18991843 :       m_known_contexts (aavals->m_known_contexts.to_vec_legacy ()),
     568                 :    18991843 :       m_known_aggs (aavals->m_known_aggs.to_vec_legacy ()),
     569                 :    18991843 :       m_known_value_ranges (aavals->m_known_value_ranges.to_vec_legacy ())
     570                 :             :   {}
     571                 :             : 
     572                 :             :   /* If m_known_vals (vector of known "scalar" values) is sufficiantly long,
     573                 :             :      return its element at INDEX, otherwise return NULL.  */
     574                 :      154245 :   tree safe_sval_at (int index)
     575                 :             :   {
     576                 :      154245 :     if ((unsigned) index < m_known_vals.length ())
     577                 :       93776 :       return m_known_vals[index];
     578                 :             :     return NULL;
     579                 :             :   }
     580                 :             : 
     581                 :             :   /* Vector describing known values of parameters.  */
     582                 :             :   vec<tree> m_known_vals = vNULL;
     583                 :             : 
     584                 :             :   /* Vector describing known polymorphic call contexts.  */
     585                 :             :   vec<ipa_polymorphic_call_context> m_known_contexts = vNULL;
     586                 :             : 
     587                 :             :   /* Vector describing known aggregate values.  */
     588                 :             :   vec<ipa_argagg_value> m_known_aggs = vNULL;
     589                 :             : 
     590                 :             :   /* Vector describing known value ranges of arguments.  */
     591                 :             :   vec<value_range> m_known_value_ranges = vNULL;
     592                 :             : };
     593                 :             : 
     594                 :             : inline
     595                 :     2487769 : ipa_argagg_value_list
     596                 :     2487769 : ::ipa_argagg_value_list (const ipa_call_arg_values *gavals)
     597                 :     3102207 :   : m_elts (gavals->m_known_aggs)
     598                 :             : {}
     599                 :             : 
     600                 :             : /* Summary describing a single formal parameter.  */
     601                 :             : 
     602                 :             : struct GTY(()) ipa_param_descriptor
     603                 :             : {
     604                 :             :   /* In analysis and modification phase, this is the PARAM_DECL of this
     605                 :             :      parameter, in IPA LTO phase, this is the type of the described
     606                 :             :      parameter or NULL if not known.  Do not read this field directly but
     607                 :             :      through ipa_get_param and ipa_get_type as appropriate.  */
     608                 :             :   tree decl_or_type;
     609                 :             :   /* If all uses of the parameter are described by ipa-prop structures, this
     610                 :             :      says how many there are.  If any use could not be described by means of
     611                 :             :      ipa-prop structures (which include flag dereferenced below), this is
     612                 :             :      IPA_UNDESCRIBED_USE.  */
     613                 :             :   int controlled_uses;
     614                 :             :   unsigned int move_cost : 27;
     615                 :             :   /* The parameter is used.  */
     616                 :             :   unsigned used : 1;
     617                 :             :   unsigned used_by_ipa_predicates : 1;
     618                 :             :   unsigned used_by_indirect_call : 1;
     619                 :             :   unsigned used_by_polymorphic_call : 1;
     620                 :             :   /* Set to true when in addition to being used in call statements, the
     621                 :             :      parameter has also been used for loads (but not for writes, does not
     622                 :             :      escape, etc.).  This allows us to identify parameters p which are only
     623                 :             :      used as *p, and so when we propagate a constant to them, we can generate a
     624                 :             :      LOAD and not ADDR reference to them.  */
     625                 :             :   unsigned load_dereferenced : 1;
     626                 :             : };
     627                 :             : 
     628                 :             : /* ipa_node_params stores information related to formal parameters of functions
     629                 :             :    and some other information for interprocedural passes that operate on
     630                 :             :    parameters (such as ipa-cp).  */
     631                 :             : 
     632                 :             : class GTY((for_user)) ipa_node_params
     633                 :             : {
     634                 :             : public:
     635                 :             :   /* Default constructor.  */
     636                 :             :   ipa_node_params ();
     637                 :             : 
     638                 :             :   /* Default destructor.  */
     639                 :             :   ~ipa_node_params ();
     640                 :             : 
     641                 :             :   /* Information about individual formal parameters that are gathered when
     642                 :             :      summaries are generated. */
     643                 :             :   vec<ipa_param_descriptor, va_gc> *descriptors;
     644                 :             :   /* Pointer to an array of structures describing individual formal
     645                 :             :      parameters.  */
     646                 :             :   vec<ipcp_param_lattices> GTY((skip)) lattices;
     647                 :             :   /* Only for versioned nodes this field would not be NULL,
     648                 :             :      it points to the node that IPA cp cloned from.  */
     649                 :             :   struct cgraph_node * GTY((skip)) ipcp_orig_node;
     650                 :             :   /* If this node is an ipa-cp clone, these are the known constants that
     651                 :             :      describe what it has been specialized for.  */
     652                 :             :   vec<tree> GTY((skip)) known_csts;
     653                 :             :   /* If this node is an ipa-cp clone, these are the known polymorphic contexts
     654                 :             :      that describe what it has been specialized for.  */
     655                 :             :   vec<ipa_polymorphic_call_context> GTY((skip)) known_contexts;
     656                 :             :   /* Whether the param uses analysis and jump function computation has already
     657                 :             :      been performed.  */
     658                 :             :   unsigned analysis_done : 1;
     659                 :             :   /* Whether the function is enqueued in ipa-cp propagation stack.  */
     660                 :             :   unsigned node_enqueued : 1;
     661                 :             :   /* Whether we should create a specialized version based on values that are
     662                 :             :      known to be constant in all contexts.  */
     663                 :             :   unsigned do_clone_for_all_contexts : 1;
     664                 :             :   /* Set if this is an IPA-CP clone for all contexts.  */
     665                 :             :   unsigned is_all_contexts_clone : 1;
     666                 :             :   /* Node has been completely replaced by clones and will be removed after
     667                 :             :      ipa-cp is finished.  */
     668                 :             :   unsigned node_dead : 1;
     669                 :             :   /* Node is involved in a recursion, potentionally indirect.  */
     670                 :             :   unsigned node_within_scc : 1;
     671                 :             :   /* Node contains only direct recursion.  */
     672                 :             :   unsigned node_is_self_scc : 1;
     673                 :             :   /* Node is calling a private function called only once.  */
     674                 :             :   unsigned node_calling_single_call : 1;
     675                 :             :   /* False when there is something makes versioning impossible.  */
     676                 :             :   unsigned versionable : 1;
     677                 :             : };
     678                 :             : 
     679                 :             : inline
     680                 :     7084081 : ipa_node_params::ipa_node_params ()
     681                 :     7084081 : : descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL),
     682                 :     7084081 :   known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
     683                 :     7084081 :   node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
     684                 :     7084081 :   node_dead (0), node_within_scc (0), node_is_self_scc (0),
     685                 :     7084081 :   node_calling_single_call (0), versionable (0)
     686                 :             : {
     687                 :             : }
     688                 :             : 
     689                 :             : inline
     690                 :     7084080 : ipa_node_params::~ipa_node_params ()
     691                 :             : {
     692                 :     7084080 :   vec_free (descriptors);
     693                 :     7084080 :   lattices.release ();
     694                 :     7084080 :   known_csts.release ();
     695                 :     7084080 :   known_contexts.release ();
     696                 :     7084080 : }
     697                 :             : 
     698                 :             : /* Intermediate information that we get from alias analysis about a particular
     699                 :             :    parameter in a particular basic_block.  When a parameter or the memory it
     700                 :             :    references is marked modified, we use that information in all dominated
     701                 :             :    blocks without consulting alias analysis oracle.  */
     702                 :             : 
     703                 :             : struct ipa_param_aa_status
     704                 :             : {
     705                 :             :   /* Set when this structure contains meaningful information.  If not, the
     706                 :             :      structure describing a dominating BB should be used instead.  */
     707                 :             :   bool valid;
     708                 :             : 
     709                 :             :   /* Whether we have seen something which might have modified the data in
     710                 :             :      question.  PARM is for the parameter itself, REF is for data it points to
     711                 :             :      but using the alias type of individual accesses and PT is the same thing
     712                 :             :      but for computing aggregate pass-through functions using a very inclusive
     713                 :             :      ao_ref.  */
     714                 :             :   bool parm_modified, ref_modified, pt_modified;
     715                 :             : };
     716                 :             : 
     717                 :             : /* Information related to a given BB that used only when looking at function
     718                 :             :    body.  */
     719                 :             : 
     720                 :             : struct ipa_bb_info
     721                 :             : {
     722                 :             :   /* Call graph edges going out of this BB.  */
     723                 :             :   vec<cgraph_edge *> cg_edges;
     724                 :             :   /* Alias analysis statuses of each formal parameter at this bb.  */
     725                 :             :   vec<ipa_param_aa_status> param_aa_statuses;
     726                 :             : };
     727                 :             : 
     728                 :             : /* Structure with global information that is only used when looking at function
     729                 :             :    body. */
     730                 :             : 
     731                 :             : struct ipa_func_body_info
     732                 :             : {
     733                 :             :   /* The node that is being analyzed.  */
     734                 :             :   cgraph_node *node;
     735                 :             : 
     736                 :             :   /* Its info.  */
     737                 :             :   class ipa_node_params *info;
     738                 :             : 
     739                 :             :   /* Information about individual BBs. */
     740                 :             :   vec<ipa_bb_info> bb_infos;
     741                 :             : 
     742                 :             :   /* Number of parameters.  */
     743                 :             :   int param_count;
     744                 :             : 
     745                 :             :   /* Number of statements we are still allowed to walked by when analyzing this
     746                 :             :      function.  */
     747                 :             :   unsigned int aa_walk_budget;
     748                 :             : };
     749                 :             : 
     750                 :             : /* ipa_node_params access functions.  Please use these to access fields that
     751                 :             :    are or will be shared among various passes.  */
     752                 :             : 
     753                 :             : /* Return the number of formal parameters. */
     754                 :             : 
     755                 :             : inline int
     756                 :    77468066 : ipa_get_param_count (class ipa_node_params *info)
     757                 :             : {
     758                 :   149865363 :   return vec_safe_length (info->descriptors);
     759                 :             : }
     760                 :             : 
     761                 :             : /* Return the parameter declaration in DESCRIPTORS at index I and assert it is
     762                 :             :    indeed a PARM_DECL.  */
     763                 :             : 
     764                 :             : inline tree
     765                 :     2469025 : ipa_get_param (const vec<ipa_param_descriptor, va_gc> &descriptors, int i)
     766                 :             : {
     767                 :     2469025 :   tree t = descriptors[i].decl_or_type;
     768                 :     2469025 :   gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
     769                 :     2469025 :   return t;
     770                 :             : }
     771                 :             : 
     772                 :             : /* Return the declaration of Ith formal parameter of the function corresponding
     773                 :             :    to INFO.  Note there is no setter function as this array is built just once
     774                 :             :    using ipa_initialize_node_params.  This function should not be called in
     775                 :             :    WPA.  */
     776                 :             : 
     777                 :             : inline tree
     778                 :     2469025 : ipa_get_param (class ipa_node_params *info, int i)
     779                 :             : {
     780                 :     2469025 :   gcc_checking_assert (info->descriptors);
     781                 :     2469025 :   return ipa_get_param (*info->descriptors, i);
     782                 :             : }
     783                 :             : 
     784                 :             : /* Return the type of Ith formal parameter of the function corresponding
     785                 :             :    to INFO if it is known or NULL if not.  */
     786                 :             : 
     787                 :             : inline tree
     788                 :    24629544 : ipa_get_type (class ipa_node_params *info, int i)
     789                 :             : {
     790                 :    24629544 :   if (vec_safe_length (info->descriptors) <= (unsigned) i)
     791                 :             :     return NULL;
     792                 :    24392452 :   tree t = (*info->descriptors)[i].decl_or_type;
     793                 :    24392452 :   if (!t)
     794                 :             :     return NULL;
     795                 :    24392452 :   if (TYPE_P (t))
     796                 :             :     return t;
     797                 :    22946286 :   gcc_checking_assert (TREE_CODE (t) == PARM_DECL);
     798                 :    22946286 :   return TREE_TYPE (t);
     799                 :             : }
     800                 :             : 
     801                 :             : /* Return the move cost of Ith formal parameter of the function corresponding
     802                 :             :    to INFO.  */
     803                 :             : 
     804                 :             : inline int
     805                 :      315093 : ipa_get_param_move_cost (class ipa_node_params *info, int i)
     806                 :             : {
     807                 :      315093 :   gcc_checking_assert (info->descriptors);
     808                 :      315093 :   return (*info->descriptors)[i].move_cost;
     809                 :             : }
     810                 :             : 
     811                 :             : /* Set the used flag corresponding to the Ith formal parameter of the function
     812                 :             :    associated with INFO to VAL.  */
     813                 :             : 
     814                 :             : inline void
     815                 :     2544678 : ipa_set_param_used (class ipa_node_params *info, int i, bool val)
     816                 :             : {
     817                 :     2544678 :   gcc_checking_assert (info->descriptors);
     818                 :     2544678 :   (*info->descriptors)[i].used = val;
     819                 :     2544678 : }
     820                 :             : 
     821                 :             : /* Set the used_by_ipa_predicates flag corresponding to the Ith formal
     822                 :             :    parameter of the function associated with INFO to VAL.  */
     823                 :             : 
     824                 :             : inline void
     825                 :     7771342 : ipa_set_param_used_by_ipa_predicates (class ipa_node_params *info, int i, bool val)
     826                 :             : {
     827                 :     7771342 :   gcc_checking_assert (info->descriptors);
     828                 :     7771342 :   (*info->descriptors)[i].used_by_ipa_predicates = val;
     829                 :     7771342 : }
     830                 :             : 
     831                 :             : /* Set the used_by_indirect_call flag corresponding to the Ith formal
     832                 :             :    parameter of the function associated with INFO to VAL.  */
     833                 :             : 
     834                 :             : inline void
     835                 :       21984 : ipa_set_param_used_by_indirect_call (class ipa_node_params *info, int i, bool val)
     836                 :             : {
     837                 :       21984 :   gcc_checking_assert (info->descriptors);
     838                 :       21984 :   (*info->descriptors)[i].used_by_indirect_call = val;
     839                 :       21984 : }
     840                 :             : 
     841                 :             : /* Set the .used_by_polymorphic_call flag corresponding to the Ith formal
     842                 :             :    parameter of the function associated with INFO to VAL.  */
     843                 :             : 
     844                 :             : inline void
     845                 :       13900 : ipa_set_param_used_by_polymorphic_call (class ipa_node_params *info, int i, bool val)
     846                 :             : {
     847                 :       13900 :   gcc_checking_assert (info->descriptors);
     848                 :       13900 :   (*info->descriptors)[i].used_by_polymorphic_call = val;
     849                 :       13900 : }
     850                 :             : 
     851                 :             : /* Return how many uses described by ipa-prop a parameter has or
     852                 :             :    IPA_UNDESCRIBED_USE if there is a use that is not described by these
     853                 :             :    structures.  */
     854                 :             : inline int
     855                 :     1177140 : ipa_get_controlled_uses (class ipa_node_params *info, int i)
     856                 :             : {
     857                 :             :   /* FIXME: introducing speculation causes out of bounds access here.  */
     858                 :     1177140 :   if (vec_safe_length (info->descriptors) > (unsigned)i)
     859                 :     1177131 :     return (*info->descriptors)[i].controlled_uses;
     860                 :             :   return IPA_UNDESCRIBED_USE;
     861                 :             : }
     862                 :             : 
     863                 :             : /* Set the controlled counter of a given parameter.  */
     864                 :             : 
     865                 :             : inline void
     866                 :     2892941 : ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
     867                 :             : {
     868                 :     2892941 :   gcc_checking_assert (info->descriptors);
     869                 :     2892941 :   (*info->descriptors)[i].controlled_uses = val;
     870                 :     2892941 : }
     871                 :             : 
     872                 :             : /* Assuming a parameter does not have IPA_UNDESCRIBED_USE controlled uses,
     873                 :             :    return flag which indicates it has been dereferenced but only in a load.  */
     874                 :             : inline int
     875                 :      224777 : ipa_get_param_load_dereferenced (class ipa_node_params *info, int i)
     876                 :             : {
     877                 :      224777 :   gcc_assert (ipa_get_controlled_uses (info, i) != IPA_UNDESCRIBED_USE);
     878                 :      224777 :   return (*info->descriptors)[i].load_dereferenced;
     879                 :             : }
     880                 :             : 
     881                 :             : /* Set the load_dereferenced flag of a given parameter.  */
     882                 :             : 
     883                 :             : inline void
     884                 :     2657520 : ipa_set_param_load_dereferenced (class ipa_node_params *info, int i, bool val)
     885                 :             : {
     886                 :     2657520 :   gcc_checking_assert (info->descriptors);
     887                 :     2657520 :   (*info->descriptors)[i].load_dereferenced = val;
     888                 :     2657520 : }
     889                 :             : 
     890                 :             : /* Return the used flag corresponding to the Ith formal parameter of the
     891                 :             :    function associated with INFO.  */
     892                 :             : 
     893                 :             : inline bool
     894                 :     9544390 : ipa_is_param_used (class ipa_node_params *info, int i)
     895                 :             : {
     896                 :     9544390 :   gcc_checking_assert (info->descriptors);
     897                 :     9544390 :   return (*info->descriptors)[i].used;
     898                 :             : }
     899                 :             : 
     900                 :             : /* Return the used_by_ipa_predicates flag corresponding to the Ith formal
     901                 :             :    parameter of the function associated with INFO.  */
     902                 :             : 
     903                 :             : inline bool
     904                 :    45698913 : ipa_is_param_used_by_ipa_predicates (class ipa_node_params *info, int i)
     905                 :             : {
     906                 :    45698913 :   gcc_checking_assert (info->descriptors);
     907                 :    45698913 :   return (*info->descriptors)[i].used_by_ipa_predicates;
     908                 :             : }
     909                 :             : 
     910                 :             : /* Return the used_by_indirect_call flag corresponding to the Ith formal
     911                 :             :    parameter of the function associated with INFO.  */
     912                 :             : 
     913                 :             : inline bool
     914                 :    47793321 : ipa_is_param_used_by_indirect_call (class ipa_node_params *info, int i)
     915                 :             : {
     916                 :    47793321 :   gcc_checking_assert (info->descriptors);
     917                 :    47793321 :   return (*info->descriptors)[i].used_by_indirect_call;
     918                 :             : }
     919                 :             : 
     920                 :             : /* Return the used_by_polymorphic_call flag corresponding to the Ith formal
     921                 :             :    parameter of the function associated with INFO.  */
     922                 :             : 
     923                 :             : inline bool
     924                 :    38195444 : ipa_is_param_used_by_polymorphic_call (class ipa_node_params *info, int i)
     925                 :             : {
     926                 :    38195444 :   gcc_checking_assert (info->descriptors);
     927                 :    38195444 :   return (*info->descriptors)[i].used_by_polymorphic_call;
     928                 :             : }
     929                 :             : 
     930                 :             : /* GTY-marked structure used to map DECL_UIDs of APRAMs to their indices in
     931                 :             :    their DECL_ARGUMENTs chain.  */
     932                 :             : struct GTY(()) ipa_uid_to_idx_map_elt
     933                 :             : {
     934                 :             :   /* DECL_UID of the PARAM.  */
     935                 :             :   unsigned uid;
     936                 :             :   /* Its index in the DECL_ARGUMETs chain.  */
     937                 :             :   unsigned index;
     938                 :             : };
     939                 :             : 
     940                 :             : /* Structure holding information for the transformation phase of IPA-CP.  */
     941                 :             : 
     942                 :             : struct GTY(()) ipcp_transformation
     943                 :             : {
     944                 :             :   /* Default constructor.  */
     945                 :      130739 :   ipcp_transformation ()
     946                 :      130739 :     : m_agg_values (nullptr), m_vr (nullptr), m_uid_to_idx (nullptr)
     947                 :             :   { }
     948                 :             : 
     949                 :             :   /* Default destructor.  */
     950                 :      130719 :   ~ipcp_transformation ()
     951                 :             :   {
     952                 :      130719 :     vec_free (m_agg_values);
     953                 :      130719 :     vec_free (m_vr);
     954                 :      130719 :   }
     955                 :             : 
     956                 :             :   /* Given PARAM which must be a parameter of function FNDECL described by
     957                 :             :      THIS, return its index in the DECL_ARGUMENTS chain, using a pre-computed
     958                 :             :      DECL_UID-sorted vector if available (which is pre-computed only if there
     959                 :             :      are many parameters).  Can return -1 if param is static chain not
     960                 :             :      represented among DECL_ARGUMENTS. */
     961                 :             : 
     962                 :             :   int get_param_index (const_tree fndecl, const_tree param) const;
     963                 :             : 
     964                 :             :   /* Assuming THIS describes FNDECL and it has sufficiently many parameters to
     965                 :             :      justify the overhead, create a DECL_UID-sorted vector to speed up mapping
     966                 :             :      from parameters to their indices in DECL_ARGUMENTS chain.  */
     967                 :             : 
     968                 :             :   void maybe_create_parm_idx_map (tree fndecl);
     969                 :             : 
     970                 :             :   /* Remove all elements in m_agg_values on which PREDICATE returns true.  */
     971                 :             : 
     972                 :             :   template<typename pred_function>
     973                 :        9268 :   void remove_argaggs_if (pred_function &&predicate)
     974                 :             :   {
     975                 :        9268 :     unsigned ts_len = vec_safe_length (m_agg_values);
     976                 :        3951 :     if (ts_len == 0)
     977                 :             :       return;
     978                 :             : 
     979                 :             :     bool removed_item = false;
     980                 :             :     unsigned dst_index = 0;
     981                 :             : 
     982                 :       22683 :     for (unsigned i = 0; i < ts_len; i++)
     983                 :             :       {
     984                 :       18732 :         ipa_argagg_value *v = &(*m_agg_values)[i];
     985                 :       18732 :         if (!predicate (*v))
     986                 :             :           {
     987                 :       18615 :             if (removed_item)
     988                 :          22 :               (*m_agg_values)[dst_index] = *v;
     989                 :       18615 :             dst_index++;
     990                 :             :           }
     991                 :             :         else
     992                 :             :           removed_item = true;
     993                 :             :       }
     994                 :        3951 :     if (dst_index == 0)
     995                 :             :       {
     996                 :          35 :         ggc_free (m_agg_values);
     997                 :          35 :         m_agg_values = NULL;
     998                 :             :       }
     999                 :        3916 :     else if (removed_item)
    1000                 :          22 :       m_agg_values->truncate (dst_index);
    1001                 :             :   }
    1002                 :             : 
    1003                 :             :   /* Known aggregate values.  */
    1004                 :             :   vec<ipa_argagg_value, va_gc>  *m_agg_values;
    1005                 :             :   /* Value range information.  */
    1006                 :             :   vec<ipa_vr, va_gc> *m_vr;
    1007                 :             :   /* If there are many parameters, this is a vector sorted by their DECL_UIDs
    1008                 :             :      to map them to their indices in the DECL_ARGUMENT chain.  */
    1009                 :             :   vec<ipa_uid_to_idx_map_elt, va_gc> *m_uid_to_idx;
    1010                 :             : };
    1011                 :             : 
    1012                 :             : inline
    1013                 :       54213 : ipa_argagg_value_list::ipa_argagg_value_list (const ipcp_transformation *tinfo)
    1014                 :      108426 :   : m_elts (tinfo->m_agg_values)
    1015                 :             : {}
    1016                 :             : 
    1017                 :             : void ipa_set_node_agg_value_chain (struct cgraph_node *node,
    1018                 :             :                                    vec<ipa_argagg_value, va_gc> *aggs);
    1019                 :             : void ipcp_transformation_initialize (void);
    1020                 :             : void ipcp_free_transformation_sum (void);
    1021                 :             : 
    1022                 :             : /* ipa_edge_args stores information related to a callsite and particularly its
    1023                 :             :    arguments.  It can be accessed by the IPA_EDGE_REF macro.  */
    1024                 :             : 
    1025                 :             : class GTY((for_user)) ipa_edge_args
    1026                 :             : {
    1027                 :             :  public:
    1028                 :             : 
    1029                 :             :   /* Default constructor.  */
    1030                 :     4282530 :   ipa_edge_args () : jump_functions (NULL), polymorphic_call_contexts (NULL)
    1031                 :             :     {}
    1032                 :             : 
    1033                 :             :   /* Destructor.  */
    1034                 :     4282530 :   ~ipa_edge_args ()
    1035                 :             :     {
    1036                 :     4282530 :       unsigned int i;
    1037                 :     4282530 :       ipa_jump_func *jf;
    1038                 :    13507508 :       FOR_EACH_VEC_SAFE_ELT (jump_functions, i, jf)
    1039                 :     9645378 :         vec_free (jf->agg.items);
    1040                 :     4282530 :       vec_free (jump_functions);
    1041                 :     4282530 :       vec_free (polymorphic_call_contexts);
    1042                 :     4282530 :     }
    1043                 :             : 
    1044                 :             :   /* Vectors of the callsite's jump function and polymorphic context
    1045                 :             :      information of each parameter.  */
    1046                 :             :   vec<ipa_jump_func, va_gc> *jump_functions;
    1047                 :             :   vec<ipa_polymorphic_call_context, va_gc> *polymorphic_call_contexts;
    1048                 :             : };
    1049                 :             : 
    1050                 :             : /* ipa_edge_args access functions.  Please use these to access fields that
    1051                 :             :    are or will be shared among various passes.  */
    1052                 :             : 
    1053                 :             : /* Return the number of actual arguments. */
    1054                 :             : 
    1055                 :             : inline int
    1056                 :    23740053 : ipa_get_cs_argument_count (class ipa_edge_args *args)
    1057                 :             : {
    1058                 :    46272421 :   return vec_safe_length (args->jump_functions);
    1059                 :             : }
    1060                 :             : 
    1061                 :             : /* Returns a pointer to the jump function for the ith argument.  Please note
    1062                 :             :    there is no setter function as jump functions are all set up in
    1063                 :             :    ipa_compute_jump_functions. */
    1064                 :             : 
    1065                 :             : inline struct ipa_jump_func *
    1066                 :    51100420 : ipa_get_ith_jump_func (class ipa_edge_args *args, int i)
    1067                 :             : {
    1068                 :    48496129 :   return &(*args->jump_functions)[i];
    1069                 :             : }
    1070                 :             : 
    1071                 :             : /* Returns a pointer to the polymorphic call context for the ith argument.
    1072                 :             :    NULL if contexts are not computed.  */
    1073                 :             : inline class ipa_polymorphic_call_context *
    1074                 :     7819776 : ipa_get_ith_polymorhic_call_context (class ipa_edge_args *args, int i)
    1075                 :             : {
    1076                 :     7817148 :   if (!args->polymorphic_call_contexts)
    1077                 :             :     return NULL;
    1078                 :     3841793 :   return &(*args->polymorphic_call_contexts)[i];
    1079                 :             : }
    1080                 :             : 
    1081                 :             : /* Function summary for ipa_node_params.  */
    1082                 :             : class GTY((user)) ipa_node_params_t: public function_summary <ipa_node_params *>
    1083                 :             : {
    1084                 :             : public:
    1085                 :     5172748 :   ipa_node_params_t (symbol_table *table, bool ggc):
    1086                 :     5172748 :     function_summary<ipa_node_params *> (table, ggc)
    1087                 :             :   {
    1088                 :     5172748 :     disable_insertion_hook ();
    1089                 :     5172748 :   }
    1090                 :             : 
    1091                 :             :   /* Hook that is called by summary when a node is duplicated.  */
    1092                 :             :   void duplicate (cgraph_node *node,
    1093                 :             :                   cgraph_node *node2,
    1094                 :             :                   ipa_node_params *data,
    1095                 :             :                   ipa_node_params *data2) final override;
    1096                 :             : };
    1097                 :             : 
    1098                 :             : /* Summary to manange ipa_edge_args structures.  */
    1099                 :             : 
    1100                 :             : class GTY((user)) ipa_edge_args_sum_t : public call_summary <ipa_edge_args *>
    1101                 :             : {
    1102                 :             :  public:
    1103                 :      241829 :   ipa_edge_args_sum_t (symbol_table *table, bool ggc)
    1104                 :      241829 :     : call_summary<ipa_edge_args *> (table, ggc) { }
    1105                 :             : 
    1106                 :      848755 :   void remove (cgraph_edge *edge)
    1107                 :             :   {
    1108                 :      848755 :     call_summary <ipa_edge_args *>::remove (edge);
    1109                 :      848755 :   }
    1110                 :             : 
    1111                 :             :   /* Hook that is called by summary when an edge is removed.  */
    1112                 :             :   void remove (cgraph_edge *cs, ipa_edge_args *args) final override;
    1113                 :             :   /* Hook that is called by summary when an edge is duplicated.  */
    1114                 :             :   void duplicate (cgraph_edge *src,
    1115                 :             :                   cgraph_edge *dst,
    1116                 :             :                   ipa_edge_args *old_args,
    1117                 :             :                   ipa_edge_args *new_args) final override;
    1118                 :             : };
    1119                 :             : 
    1120                 :             : /* Function summary where the parameter infos are actually stored. */
    1121                 :             : extern GTY(()) ipa_node_params_t * ipa_node_params_sum;
    1122                 :             : /* Call summary to store information about edges such as jump functions.  */
    1123                 :             : extern GTY(()) ipa_edge_args_sum_t *ipa_edge_args_sum;
    1124                 :             : 
    1125                 :             : /* Function summary for IPA-CP transformation.  */
    1126                 :             : class ipcp_transformation_t
    1127                 :             : : public function_summary<ipcp_transformation *>
    1128                 :             : {
    1129                 :             : public:
    1130                 :       18957 :   ipcp_transformation_t (symbol_table *table, bool ggc):
    1131                 :       37914 :     function_summary<ipcp_transformation *> (table, ggc) {}
    1132                 :             : 
    1133                 :       18948 :   ~ipcp_transformation_t () {}
    1134                 :             : 
    1135                 :       18957 :   static ipcp_transformation_t *create_ggc (symbol_table *symtab)
    1136                 :             :   {
    1137                 :       18957 :     ipcp_transformation_t *summary
    1138                 :       18957 :       = new (ggc_alloc_no_dtor <ipcp_transformation_t> ())
    1139                 :       18957 :       ipcp_transformation_t (symtab, true);
    1140                 :       18957 :     return summary;
    1141                 :             :   }
    1142                 :             :   /* Hook that is called by summary when a node is duplicated.  */
    1143                 :             :   void duplicate (cgraph_node *node,
    1144                 :             :                   cgraph_node *node2,
    1145                 :             :                   ipcp_transformation *data,
    1146                 :             :                   ipcp_transformation *data2) final override;
    1147                 :             : };
    1148                 :             : 
    1149                 :             : /* Function summary where the IPA CP transformations are actually stored.  */
    1150                 :             : extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum;
    1151                 :             : 
    1152                 :             : /* Creating and freeing ipa_node_params and ipa_edge_args.  */
    1153                 :             : void ipa_create_all_node_params (void);
    1154                 :             : void ipa_create_all_edge_args (void);
    1155                 :             : void ipa_check_create_edge_args (void);
    1156                 :             : void ipa_free_all_node_params (void);
    1157                 :             : void ipa_free_all_edge_args (void);
    1158                 :             : void ipa_free_all_structures_after_ipa_cp (void);
    1159                 :             : void ipa_free_all_structures_after_iinln (void);
    1160                 :             : 
    1161                 :             : void ipa_register_cgraph_hooks (void);
    1162                 :             : int count_formal_params (tree fndecl);
    1163                 :             : 
    1164                 :             : /* This function ensures the array of node param infos is big enough to
    1165                 :             :    accommodate a structure for all nodes and reallocates it if not.  */
    1166                 :             : 
    1167                 :             : inline void
    1168                 :     8093138 : ipa_check_create_node_params (void)
    1169                 :             : {
    1170                 :     8093138 :   if (!ipa_node_params_sum)
    1171                 :     5172748 :     ipa_node_params_sum
    1172                 :    10345496 :       = (new (ggc_alloc_no_dtor <ipa_node_params_t> ())
    1173                 :     5172748 :          ipa_node_params_t (symtab, true));
    1174                 :     8093138 : }
    1175                 :             : 
    1176                 :             : /* Returns true if edge summary contains a record for EDGE.  The main purpose
    1177                 :             :    of this function is that debug dumping function can check info availability
    1178                 :             :    without causing allocations.  */
    1179                 :             : 
    1180                 :             : inline bool
    1181                 :        1156 : ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
    1182                 :             : {
    1183                 :        1156 :   return ipa_edge_args_sum->exists (edge);
    1184                 :             : }
    1185                 :             : 
    1186                 :             : inline ipcp_transformation *
    1187                 :    18067505 : ipcp_get_transformation_summary (cgraph_node *node)
    1188                 :             : {
    1189                 :    18067505 :   if (ipcp_transformation_sum == NULL)
    1190                 :             :     return NULL;
    1191                 :             : 
    1192                 :     6541214 :   return ipcp_transformation_sum->get (node);
    1193                 :             : }
    1194                 :             : 
    1195                 :             : /* Function formal parameters related computations.  */
    1196                 :             : void ipa_initialize_node_params (struct cgraph_node *node);
    1197                 :             : void ipa_print_constant_value (FILE *f, tree val);
    1198                 :             : bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
    1199                 :             :                                         vec<cgraph_edge *> *new_edges);
    1200                 :             : 
    1201                 :             : /* Indirect edge processing and target discovery.  */
    1202                 :             : tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
    1203                 :             :                                    ipa_call_arg_values *avals,
    1204                 :             :                                    bool *speculative);
    1205                 :             : struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
    1206                 :             :                                                     bool speculative = false);
    1207                 :             : tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
    1208                 :             : 
    1209                 :             : 
    1210                 :             : /* Functions related to both.  */
    1211                 :             : void ipa_analyze_node (struct cgraph_node *);
    1212                 :             : 
    1213                 :             : /* Aggregate jump function related functions.  */
    1214                 :             : tree ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset,
    1215                 :             :                                  bool by_ref);
    1216                 :             : bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
    1217                 :             :                              vec<ipa_param_descriptor, va_gc> *descriptors,
    1218                 :             :                              gimple *stmt, tree op, int *index_p,
    1219                 :             :                              HOST_WIDE_INT *offset_p, poly_int64 *size_p,
    1220                 :             :                              bool *by_ref, bool *guaranteed_unmodified = NULL);
    1221                 :             : 
    1222                 :             : /* Debugging interface.  */
    1223                 :             : void ipa_print_node_params (FILE *, struct cgraph_node *node);
    1224                 :             : void ipa_print_all_params (FILE *);
    1225                 :             : void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
    1226                 :             : void ipa_print_all_jump_functions (FILE * f);
    1227                 :             : void ipcp_verify_propagated_values (void);
    1228                 :             : 
    1229                 :             : template <typename value>
    1230                 :             : class ipcp_value;
    1231                 :             : 
    1232                 :             : extern object_allocator<ipcp_value<tree> > ipcp_cst_values_pool;
    1233                 :             : extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
    1234                 :             :   ipcp_poly_ctx_values_pool;
    1235                 :             : 
    1236                 :             : template <typename valtype>
    1237                 :             : struct ipcp_value_source;
    1238                 :             : 
    1239                 :             : extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;
    1240                 :             : 
    1241                 :             : struct ipcp_agg_lattice;
    1242                 :             : 
    1243                 :             : extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;
    1244                 :             : 
    1245                 :             : void ipa_prop_write_jump_functions (void);
    1246                 :             : void ipa_prop_read_jump_functions (void);
    1247                 :             : void ipcp_write_transformation_summaries (void);
    1248                 :             : void ipcp_read_transformation_summaries (void);
    1249                 :             : int ipa_get_param_decl_index (class ipa_node_params *, tree);
    1250                 :             : tree ipa_value_from_jfunc (class ipa_node_params *info,
    1251                 :             :                            struct ipa_jump_func *jfunc, tree type);
    1252                 :             : tree ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
    1253                 :             :                                const ipa_agg_jf_item *item);
    1254                 :             : unsigned int ipcp_transform_function (struct cgraph_node *node);
    1255                 :             : ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
    1256                 :             :                                                      cgraph_edge *,
    1257                 :             :                                                      int,
    1258                 :             :                                                      ipa_jump_func *);
    1259                 :             : void ipa_value_range_from_jfunc (vrange &, ipa_node_params *, cgraph_edge *,
    1260                 :             :                                  ipa_jump_func *, tree);
    1261                 :             : void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
    1262                 :             :                                      ipa_agg_jump_function *agg_jfunc,
    1263                 :             :                                      unsigned dst_index,
    1264                 :             :                                      vec<ipa_argagg_value> *res);
    1265                 :             : void ipa_dump_param (FILE *, class ipa_node_params *info, int i);
    1266                 :             : void ipa_dump_jump_function (FILE *f, ipa_jump_func *jfunc,
    1267                 :             :                              class ipa_polymorphic_call_context *ctx = NULL);
    1268                 :             : void ipa_release_body_info (struct ipa_func_body_info *);
    1269                 :             : tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
    1270                 :             : bool ipcp_get_parm_bits (tree, tree *, widest_int *);
    1271                 :             : tree ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
    1272                 :             :                                HOST_WIDE_INT bit_offset,
    1273                 :             :                                HOST_WIDE_INT bit_size);
    1274                 :             : bool unadjusted_ptr_and_unit_offset (tree op, tree *ret,
    1275                 :             :                                      poly_int64 *offset_ret);
    1276                 :             : void ipa_get_range_from_ip_invariant (vrange &r, tree val, cgraph_node *node);
    1277                 :             : void ipa_prop_cc_finalize (void);
    1278                 :             : 
    1279                 :             : /* From tree-sra.cc:  */
    1280                 :             : tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,
    1281                 :             :                            gimple_stmt_iterator *, bool);
    1282                 :             : 
    1283                 :             : /* In ipa-cp.cc  */
    1284                 :             : void ipa_cp_cc_finalize (void);
    1285                 :             : bool ipa_return_value_range (value_range &range, tree decl);
    1286                 :             : void ipa_record_return_value_range (value_range val);
    1287                 :             : bool ipa_jump_functions_equivalent_p (ipa_jump_func *jf1, ipa_jump_func *jf2);
    1288                 :             : 
    1289                 :             : 
    1290                 :             : #endif /* IPA_PROP_H */
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.