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