LCOV - code coverage report
Current view: top level - gcc - ipa-param-manipulation.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 728 902 80.7 %
Date: 2020-03-28 11:57:23 Functions: 35 41 85.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Manipulation of formal and actual parameters of functions and function
       2                 :            :    calls.
       3                 :            :    Copyright (C) 2017-2020 Free Software Foundation, Inc.
       4                 :            : 
       5                 :            : This file is part of GCC.
       6                 :            : 
       7                 :            : GCC is free software; you can redistribute it and/or modify it under
       8                 :            : the terms of the GNU General Public License as published by the Free
       9                 :            : Software Foundation; either version 3, or (at your option) any later
      10                 :            : version.
      11                 :            : 
      12                 :            : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :            : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :            : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :            : for more details.
      16                 :            : 
      17                 :            : You should have received a copy of the GNU General Public License
      18                 :            : along with GCC; see the file COPYING3.  If not see
      19                 :            : <http://www.gnu.org/licenses/>.  */
      20                 :            : 
      21                 :            : #include "config.h"
      22                 :            : #include "system.h"
      23                 :            : #include "coretypes.h"
      24                 :            : #include "backend.h"
      25                 :            : #include "tree.h"
      26                 :            : #include "gimple.h"
      27                 :            : #include "ssa.h"
      28                 :            : #include "cgraph.h"
      29                 :            : #include "fold-const.h"
      30                 :            : #include "tree-eh.h"
      31                 :            : #include "stor-layout.h"
      32                 :            : #include "gimplify.h"
      33                 :            : #include "gimple-iterator.h"
      34                 :            : #include "gimplify-me.h"
      35                 :            : #include "tree-cfg.h"
      36                 :            : #include "tree-dfa.h"
      37                 :            : #include "ipa-param-manipulation.h"
      38                 :            : #include "print-tree.h"
      39                 :            : #include "gimple-pretty-print.h"
      40                 :            : #include "builtins.h"
      41                 :            : #include "tree-ssa.h"
      42                 :            : #include "tree-inline.h"
      43                 :            : 
      44                 :            : 
      45                 :            : /* Actual prefixes of different newly synthetized parameters.  Keep in sync
      46                 :            :    with IPA_PARAM_PREFIX_* defines.  */
      47                 :            : 
      48                 :            : static const char *ipa_param_prefixes[IPA_PARAM_PREFIX_COUNT]
      49                 :            :   = {"SYNTH",
      50                 :            :      "ISRA",
      51                 :            :      "simd",
      52                 :            :      "mask"};
      53                 :            : 
      54                 :            : /* Names of parameters for dumping.  Keep in sync with enum ipa_parm_op.  */
      55                 :            : 
      56                 :            : static const char *ipa_param_op_names[IPA_PARAM_PREFIX_COUNT]
      57                 :            :   = {"IPA_PARAM_OP_UNDEFINED",
      58                 :            :      "IPA_PARAM_OP_COPY",
      59                 :            :      "IPA_PARAM_OP_NEW",
      60                 :            :      "IPA_PARAM_OP_SPLIT"};
      61                 :            : 
      62                 :            : /* Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
      63                 :            :    FNDECL.  The function should not be called during LTO WPA phase except for
      64                 :            :    thunks (or functions with bodies streamed in). */
      65                 :            : 
      66                 :            : void
      67                 :     115240 : push_function_arg_decls (vec<tree> *args, tree fndecl)
      68                 :            : {
      69                 :     115240 :   int count;
      70                 :     115240 :   tree parm;
      71                 :            : 
      72                 :            :   /* Safety check that we do not attempt to use the function in WPA, except
      73                 :            :      when the function is a thunk and then we have DECL_ARGUMENTS or when we
      74                 :            :      have already explicitely loaded its body.  */
      75                 :     115241 :   gcc_assert (!flag_wpa
      76                 :            :               || DECL_ARGUMENTS (fndecl)
      77                 :            :               || gimple_has_body_p (fndecl));
      78                 :     115240 :   count = 0;
      79                 :     396160 :   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
      80                 :     280920 :     count++;
      81                 :            : 
      82                 :     115240 :   args->reserve_exact (count);
      83                 :     396160 :   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
      84                 :     280920 :     args->quick_push (parm);
      85                 :     115240 : }
      86                 :            : 
      87                 :            : /* Fill an empty vector TYPES with trees representing formal parameters of
      88                 :            :    function type FNTYPE.  */
      89                 :            : 
      90                 :            : void
      91                 :     200577 : push_function_arg_types (vec<tree> *types, tree fntype)
      92                 :            : {
      93                 :     200577 :   int count = 0;
      94                 :     200577 :   tree t;
      95                 :            : 
      96                 :    1031750 :   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
      97                 :     723140 :     count++;
      98                 :            : 
      99                 :     200577 :   types->reserve_exact (count);
     100                 :    1031750 :   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
     101                 :     723140 :     types->quick_push (TREE_VALUE (t));
     102                 :     200577 : }
     103                 :            : 
     104                 :            : /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
     105                 :            :    friendly way, assuming they are meant to be applied to FNDECL.  */
     106                 :            : 
     107                 :            : void
     108                 :          1 : ipa_dump_adjusted_parameters (FILE *f,
     109                 :            :                               vec<ipa_adjusted_param, va_gc> *adj_params)
     110                 :            : {
     111                 :          1 :   unsigned i, len = vec_safe_length (adj_params);
     112                 :          1 :   bool first = true;
     113                 :            : 
     114                 :          1 :   fprintf (f, "    IPA adjusted parameters: ");
     115                 :          3 :   for (i = 0; i < len; i++)
     116                 :            :     {
     117                 :          2 :       struct ipa_adjusted_param *apm;
     118                 :          2 :       apm = &(*adj_params)[i];
     119                 :            : 
     120                 :          2 :       if (!first)
     121                 :          1 :         fprintf (f, "                             ");
     122                 :            :       else
     123                 :            :         first = false;
     124                 :            : 
     125                 :          2 :       fprintf (f, "%i. %s %s", i, ipa_param_op_names[apm->op],
     126                 :          2 :                apm->prev_clone_adjustment ? "prev_clone_adjustment " : "");
     127                 :          2 :       switch (apm->op)
     128                 :            :         {
     129                 :            :         case IPA_PARAM_OP_UNDEFINED:
     130                 :            :           break;
     131                 :            : 
     132                 :          0 :         case IPA_PARAM_OP_COPY:
     133                 :          0 :           fprintf (f, ", base_index: %u", apm->base_index);
     134                 :          0 :           fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
     135                 :          0 :           break;
     136                 :            : 
     137                 :          2 :         case IPA_PARAM_OP_SPLIT:
     138                 :          2 :           fprintf (f, ", offset: %u", apm->unit_offset);
     139                 :            :           /* fall-through */
     140                 :          2 :         case IPA_PARAM_OP_NEW:
     141                 :          2 :           fprintf (f, ", base_index: %u", apm->base_index);
     142                 :          2 :           fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
     143                 :          2 :           print_node_brief (f, ", type: ", apm->type, 0);
     144                 :          2 :           print_node_brief (f, ", alias type: ", apm->alias_ptr_type, 0);
     145                 :          2 :           fprintf (f, " prefix: %s",
     146                 :          2 :                    ipa_param_prefixes[apm->param_prefix_index]);
     147                 :          2 :           if (apm->reverse)
     148                 :          0 :             fprintf (f, ", reverse-sso");
     149                 :            :           break;
     150                 :            :         }
     151                 :          2 :       fprintf (f, "\n");
     152                 :            :     }
     153                 :          1 : }
     154                 :            : 
     155                 :            : /* Fill NEW_TYPES with types of a function after its current OTYPES have been
     156                 :            :    modified as described in ADJ_PARAMS.  When USE_PREV_INDICES is true, use
     157                 :            :    prev_clone_index from ADJ_PARAMS as opposed to base_index when the parameter
     158                 :            :    is false.  */
     159                 :            : 
     160                 :            : static void
     161                 :     197917 : fill_vector_of_new_param_types (vec<tree> *new_types, vec<tree> *otypes,
     162                 :            :                                 vec<ipa_adjusted_param, va_gc> *adj_params,
     163                 :            :                                 bool use_prev_indices)
     164                 :            : {
     165                 :     197917 :   unsigned adj_len = vec_safe_length (adj_params);
     166                 :     197917 :   new_types->reserve_exact (adj_len);
     167                 :     595939 :   for (unsigned i = 0; i < adj_len ; i++)
     168                 :            :     {
     169                 :     398022 :       ipa_adjusted_param *apm = &(*adj_params)[i];
     170                 :     398022 :       if (apm->op == IPA_PARAM_OP_COPY)
     171                 :            :         {
     172                 :     635028 :           unsigned index
     173                 :     317514 :             = use_prev_indices ? apm->prev_clone_index : apm->base_index;
     174                 :            :           /* The following needs to be handled gracefully because of type
     175                 :            :              mismatches.  This happens with LTO but apparently also in Fortran
     176                 :            :              with -fcoarray=lib -O2 -lcaf_single -latomic.  */
     177                 :     635028 :           if (index >= otypes->length ())
     178                 :          0 :             continue;
     179                 :     715536 :           new_types->quick_push ((*otypes)[index]);
     180                 :            :         }
     181                 :      80508 :       else if (apm->op == IPA_PARAM_OP_NEW
     182                 :      80508 :                || apm->op == IPA_PARAM_OP_SPLIT)
     183                 :            :         {
     184                 :      80508 :           tree ntype = apm->type;
     185                 :      80508 :           if (is_gimple_reg_type (ntype)
     186                 :      80508 :               && TYPE_MODE (ntype) != BLKmode)
     187                 :            :             {
     188                 :      80158 :               unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ntype));
     189                 :      80158 :               if (TYPE_ALIGN (ntype) != malign)
     190                 :       1013 :                 ntype = build_aligned_type (ntype, malign);
     191                 :            :             }
     192                 :      80508 :           new_types->quick_push (ntype);
     193                 :            :         }
     194                 :            :       else
     195                 :          0 :         gcc_unreachable ();
     196                 :            :     }
     197                 :     197917 : }
     198                 :            : 
     199                 :            : /* Build and return a function type just like ORIG_TYPE but with parameter
     200                 :            :    types given in NEW_PARAM_TYPES - which can be NULL if, but only if,
     201                 :            :    ORIG_TYPE itself has NULL TREE_ARG_TYPEs.  If METHOD2FUNC is true, also make
     202                 :            :    it a FUNCTION_TYPE instead of FUNCTION_TYPE.  */
     203                 :            : 
     204                 :            : static tree
     205                 :     120064 : build_adjusted_function_type (tree orig_type, vec<tree> *new_param_types,
     206                 :            :                               bool method2func, bool skip_return)
     207                 :            : {
     208                 :     120064 :   tree new_arg_types = NULL;
     209                 :     188789 :   if (TYPE_ARG_TYPES (orig_type))
     210                 :            :     {
     211                 :     119790 :       gcc_checking_assert (new_param_types);
     212                 :     188515 :       bool last_parm_void = (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type)))
     213                 :     119790 :                              == void_type_node);
     214                 :     119790 :       unsigned len = new_param_types->length ();
     215                 :     363140 :       for (unsigned i = 0; i < len; i++)
     216                 :     243350 :         new_arg_types = tree_cons (NULL_TREE, (*new_param_types)[i],
     217                 :            :                                    new_arg_types);
     218                 :            : 
     219                 :     119790 :       tree new_reversed = nreverse (new_arg_types);
     220                 :     119790 :       if (last_parm_void)
     221                 :            :         {
     222                 :     119789 :           if (new_reversed)
     223                 :     102848 :             TREE_CHAIN (new_arg_types) = void_list_node;
     224                 :            :           else
     225                 :      16941 :             new_reversed = void_list_node;
     226                 :            :         }
     227                 :            :       new_arg_types = new_reversed;
     228                 :            :     }
     229                 :            : 
     230                 :            :   /* Use build_distinct_type_copy to preserve as much as possible from original
     231                 :            :      type (debug info, attribute lists etc.).  The one exception is
     232                 :            :      METHOD_TYPEs which must have THIS argument and when we are asked to remove
     233                 :            :      it, we need to build new FUNCTION_TYPE instead.  */
     234                 :     120064 :   tree new_type = NULL;
     235                 :     120064 :   if (method2func)
     236                 :            :     {
     237                 :      30664 :       tree ret_type;
     238                 :      30664 :       if (skip_return)
     239                 :       3998 :         ret_type = void_type_node;
     240                 :            :       else
     241                 :      26666 :         ret_type = TREE_TYPE (orig_type);
     242                 :            : 
     243                 :      30664 :       new_type
     244                 :      30664 :         = build_distinct_type_copy (build_function_type (ret_type,
     245                 :            :                                                          new_arg_types));
     246                 :      30664 :       TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
     247                 :            :     }
     248                 :            :   else
     249                 :            :     {
     250                 :      89400 :       new_type = build_distinct_type_copy (orig_type);
     251                 :      89400 :       TYPE_ARG_TYPES (new_type) = new_arg_types;
     252                 :      89400 :       if (skip_return)
     253                 :      29161 :         TREE_TYPE (new_type) = void_type_node;
     254                 :            :     }
     255                 :            : 
     256                 :     120064 :   return new_type;
     257                 :            : }
     258                 :            : 
     259                 :            : /* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
     260                 :            :    is none.  */
     261                 :            : 
     262                 :            : int
     263                 :      34908 : ipa_param_adjustments::get_max_base_index ()
     264                 :            : {
     265                 :      34908 :   unsigned adj_len = vec_safe_length (m_adj_params);
     266                 :      34908 :   int max_index = -1;
     267                 :      65067 :   for (unsigned i = 0; i < adj_len ; i++)
     268                 :            :     {
     269                 :      30159 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     270                 :      30159 :       if (apm->op == IPA_PARAM_OP_COPY
     271                 :      28980 :           && max_index < apm->base_index)
     272                 :            :         max_index = apm->base_index;
     273                 :            :     }
     274                 :      34908 :   return max_index;
     275                 :            : }
     276                 :            : 
     277                 :            : 
     278                 :            : /* Fill SURVIVING_PARAMS with an array of bools where each one says whether a
     279                 :            :    parameter that originally was at that position still survives in the given
     280                 :            :    clone or is removed/replaced.  If the final array is smaller than an index
     281                 :            :    of an original parameter, that parameter also did not survive.  That a
     282                 :            :    parameter survives does not mean it has the same index as before.  */
     283                 :            : 
     284                 :            : void
     285                 :      25954 : ipa_param_adjustments::get_surviving_params (vec<bool> *surviving_params)
     286                 :            : {
     287                 :      25954 :   unsigned adj_len = vec_safe_length (m_adj_params);
     288                 :      25954 :   int max_index = get_max_base_index ();
     289                 :            : 
     290                 :      25954 :   if (max_index < 0)
     291                 :            :     return;
     292                 :       9074 :   surviving_params->reserve_exact (max_index + 1);
     293                 :       9074 :   surviving_params->quick_grow_cleared (max_index + 1);
     294                 :      25310 :   for (unsigned i = 0; i < adj_len ; i++)
     295                 :            :     {
     296                 :      16236 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     297                 :      16236 :       if (apm->op == IPA_PARAM_OP_COPY)
     298                 :      16236 :         (*surviving_params)[apm->base_index] = true;
     299                 :            :     }
     300                 :            : }
     301                 :            : 
     302                 :            : /* Fill NEW_INDICES with new indices of each surviving parameter or -1 for
     303                 :            :    those which do not survive.  Any parameter outside of lenght of the vector
     304                 :            :    does not survive.  There is currently no support for a parameter to be
     305                 :            :    copied to two distinct new parameters.  */
     306                 :            : 
     307                 :            : void
     308                 :       8954 : ipa_param_adjustments::get_updated_indices (vec<int> *new_indices)
     309                 :            : {
     310                 :       8954 :   unsigned adj_len = vec_safe_length (m_adj_params);
     311                 :       8954 :   int max_index = get_max_base_index ();
     312                 :            : 
     313                 :       8954 :   if (max_index < 0)
     314                 :            :     return;
     315                 :       6827 :   unsigned res_len = max_index + 1;
     316                 :       6827 :   new_indices->reserve_exact (res_len);
     317                 :      22730 :   for (unsigned i = 0; i < res_len ; i++)
     318                 :      15903 :     new_indices->quick_push (-1);
     319                 :      20365 :   for (unsigned i = 0; i < adj_len ; i++)
     320                 :            :     {
     321                 :      13538 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     322                 :      13538 :       if (apm->op == IPA_PARAM_OP_COPY)
     323                 :      12744 :         (*new_indices)[apm->base_index] = i;
     324                 :            :     }
     325                 :            : }
     326                 :            : 
     327                 :            : /* Return the original index for the given new parameter index.  Return a
     328                 :            :    negative number if not available.  */
     329                 :            : 
     330                 :            : int
     331                 :       8270 : ipa_param_adjustments::get_original_index (int newidx)
     332                 :            : {
     333                 :       8270 :   const ipa_adjusted_param *adj = &(*m_adj_params)[newidx];
     334                 :       8270 :   if (adj->op != IPA_PARAM_OP_COPY)
     335                 :            :     return -1;
     336                 :       7902 :   return adj->base_index;
     337                 :            : }
     338                 :            : 
     339                 :            : /* Return true if the first parameter (assuming there was one) survives the
     340                 :            :    transformation intact and remains the first one.  */
     341                 :            : 
     342                 :            : bool
     343                 :     107577 : ipa_param_adjustments::first_param_intact_p ()
     344                 :            : {
     345                 :     107577 :   return (!vec_safe_is_empty (m_adj_params)
     346                 :      98830 :           && (*m_adj_params)[0].op == IPA_PARAM_OP_COPY
     347                 :      81802 :           && (*m_adj_params)[0].base_index == 0);
     348                 :            : }
     349                 :            : 
     350                 :            : /* Return true if we have to change what has formerly been a method into a
     351                 :            :    function.  */
     352                 :            : 
     353                 :            : bool
     354                 :     195161 : ipa_param_adjustments::method2func_p (tree orig_type)
     355                 :            : {
     356                 :     195161 :   return ((TREE_CODE (orig_type) == METHOD_TYPE) && !first_param_intact_p ());
     357                 :            : }
     358                 :            : 
     359                 :            : /* Given function type OLD_TYPE, return a new type derived from it after
     360                 :            :    performing all atored modifications.  TYPE_ORIGINAL_P should be true when
     361                 :            :    OLD_TYPE refers to the type before any IPA transformations, as opposed to a
     362                 :            :    type that can be an intermediate one in between various IPA
     363                 :            :    transformations.  */
     364                 :            : 
     365                 :            : tree
     366                 :     116619 : ipa_param_adjustments::build_new_function_type (tree old_type,
     367                 :            :                                                 bool type_original_p)
     368                 :            : {
     369                 :     116619 :   auto_vec<tree,16> new_param_types, *new_param_types_p;
     370                 :     116619 :   if (prototype_p (old_type))
     371                 :            :     {
     372                 :     232722 :       auto_vec<tree, 16> otypes;
     373                 :     116361 :       push_function_arg_types (&otypes, old_type);
     374                 :     116361 :       fill_vector_of_new_param_types (&new_param_types, &otypes, m_adj_params,
     375                 :     116361 :                                       !type_original_p);
     376                 :     116361 :       new_param_types_p = &new_param_types;
     377                 :            :     }
     378                 :            :   else
     379                 :            :     new_param_types_p = NULL;
     380                 :            : 
     381                 :     116619 :   return build_adjusted_function_type (old_type, new_param_types_p,
     382                 :     116619 :                                        method2func_p (old_type), m_skip_return);
     383                 :            : }
     384                 :            : 
     385                 :            : /* Build variant of function decl ORIG_DECL which has no return value if
     386                 :            :    M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
     387                 :            :    this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
     388                 :            :    DECL_ARGUMENTS list are not processed now, since they are linked by
     389                 :            :    TREE_CHAIN directly and not accessible in LTO during WPA.  The caller is
     390                 :            :    responsible for eliminating them when clones are properly materialized.  */
     391                 :            : 
     392                 :            : tree
     393                 :      78542 : ipa_param_adjustments::adjust_decl (tree orig_decl)
     394                 :            : {
     395                 :      78542 :   tree new_decl = copy_node (orig_decl);
     396                 :      78542 :   tree orig_type = TREE_TYPE (orig_decl);
     397                 :      78542 :   if (prototype_p (orig_type)
     398                 :      78801 :       || (m_skip_return && !VOID_TYPE_P (TREE_TYPE (orig_type))))
     399                 :            :     {
     400                 :      78483 :       tree new_type = build_new_function_type (orig_type, false);
     401                 :      78483 :       TREE_TYPE (new_decl) = new_type;
     402                 :            :     }
     403                 :      78542 :   if (method2func_p (orig_type))
     404                 :      16902 :     DECL_VINDEX (new_decl) = NULL_TREE;
     405                 :            : 
     406                 :            :   /* When signature changes, we need to clear builtin info.  */
     407                 :      78542 :   if (fndecl_built_in_p (new_decl))
     408                 :         96 :     set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);
     409                 :            : 
     410                 :      78542 :   DECL_VIRTUAL_P (new_decl) = 0;
     411                 :      78542 :   DECL_LANG_SPECIFIC (new_decl) = NULL;
     412                 :            : 
     413                 :            :   /* Drop MALLOC attribute for a void function.  */
     414                 :      78542 :   if (m_skip_return)
     415                 :      23628 :     DECL_IS_MALLOC (new_decl) = 0;
     416                 :            : 
     417                 :      78542 :   return new_decl;
     418                 :            : }
     419                 :            : 
     420                 :            : /* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
     421                 :            :    transformations.  Return true if EXPR has an interesting form and fill in
     422                 :            :    *BASE_P and *UNIT_OFFSET_P with the appropriate info.  */
     423                 :            : 
     424                 :            : static bool
     425                 :    1634440 : isra_get_ref_base_and_offset (tree expr, tree *base_p, unsigned *unit_offset_p)
     426                 :            : {
     427                 :    1634440 :   HOST_WIDE_INT offset, size;
     428                 :    1634440 :   bool reverse;
     429                 :    1634440 :   tree base
     430                 :    1634440 :     = get_ref_base_and_extent_hwi (expr, &offset, &size, &reverse);
     431                 :    1634440 :   if (!base || size < 0)
     432                 :            :     return false;
     433                 :            : 
     434                 :    1623910 :   if ((offset % BITS_PER_UNIT) != 0)
     435                 :            :     return false;
     436                 :            : 
     437                 :    1623730 :   if (TREE_CODE (base) == MEM_REF)
     438                 :            :     {
     439                 :     239100 :       poly_int64 plmoff = mem_ref_offset (base).force_shwi ();
     440                 :     239100 :       HOST_WIDE_INT moff;
     441                 :     239100 :       bool is_cst = plmoff.is_constant (&moff);
     442                 :     239100 :       if (!is_cst)
     443                 :            :         return false;
     444                 :     239100 :       offset += moff * BITS_PER_UNIT;
     445                 :     239100 :       base = TREE_OPERAND (base, 0);
     446                 :            :     }
     447                 :            : 
     448                 :    1623730 :   if (offset < 0 || (offset / BITS_PER_UNIT) > UINT_MAX)
     449                 :            :     return false;
     450                 :            : 
     451                 :    1618340 :   *base_p = base;
     452                 :    1618340 :   *unit_offset_p = offset / BITS_PER_UNIT;
     453                 :    1618340 :   return true;
     454                 :            : }
     455                 :            : 
     456                 :            : /* Return true if EXPR describes a transitive split (i.e. one that happened for
     457                 :            :    both the caller and the callee) as recorded in PERFORMED_SPLITS.  In that
     458                 :            :    case, store index of the respective record in PERFORMED_SPLITS into
     459                 :            :    *SM_IDX_P and the unit offset from all handled components in EXPR into
     460                 :            :    *UNIT_OFFSET_P.  */
     461                 :            : 
     462                 :            : static bool
     463                 :      81320 : transitive_split_p (vec<ipa_param_performed_split, va_gc> *performed_splits,
     464                 :            :                     tree expr, unsigned *sm_idx_p, unsigned *unit_offset_p)
     465                 :            : {
     466                 :      81320 :   tree base;
     467                 :      81320 :   if (!isra_get_ref_base_and_offset (expr, &base, unit_offset_p))
     468                 :            :     return false;
     469                 :            : 
     470                 :      81320 :   if (TREE_CODE (base) == SSA_NAME)
     471                 :            :     {
     472                 :      42631 :       base = SSA_NAME_VAR (base);
     473                 :      42631 :       if (!base)
     474                 :            :         return false;
     475                 :            :     }
     476                 :            : 
     477                 :      49747 :   unsigned len = vec_safe_length (performed_splits);
     478                 :     465965 :   for (unsigned i = 0 ; i < len; i++)
     479                 :            :     {
     480                 :     417757 :       ipa_param_performed_split *sm = &(*performed_splits)[i];
     481                 :     417757 :       if (sm->dummy_decl == base)
     482                 :            :         {
     483                 :       1539 :           *sm_idx_p = i;
     484                 :       1539 :           return true;
     485                 :            :         }
     486                 :            :     }
     487                 :            :   return false;
     488                 :            : }
     489                 :            : 
     490                 :            : /* Structure to hold declarations representing transitive IPA-SRA splits.  In
     491                 :            :    essence, if we need to pass UNIT_OFFSET of a parameter which originally has
     492                 :            :    number BASE_INDEX, we should pass down REPL.  */
     493                 :            : 
     494                 :            : struct transitive_split_map
     495                 :            : {
     496                 :            :   tree repl;
     497                 :            :   unsigned base_index;
     498                 :            :   unsigned unit_offset;
     499                 :            : };
     500                 :            : 
     501                 :            : /* If call STMT contains any parameters representing transitive splits as
     502                 :            :    described by PERFORMED_SPLITS, return the number of extra parameters that
     503                 :            :    were addded during clone materialization and fill in INDEX_MAP with adjusted
     504                 :            :    indices of corresponding original parameters and TRANS_MAP with description
     505                 :            :    of all transitive replacement descriptions.  Otherwise return zero. */
     506                 :            : 
     507                 :            : static unsigned
     508                 :      29818 : init_transitive_splits (vec<ipa_param_performed_split, va_gc> *performed_splits,
     509                 :            :                         gcall *stmt, vec <unsigned> *index_map,
     510                 :            :                         auto_vec <transitive_split_map> *trans_map)
     511                 :            : {
     512                 :      29818 :   unsigned phony_arguments = 0;
     513                 :      29818 :   unsigned stmt_idx = 0, base_index = 0;
     514                 :      29818 :   unsigned nargs = gimple_call_num_args (stmt);
     515                 :     111138 :   while (stmt_idx < nargs)
     516                 :            :     {
     517                 :      81320 :       unsigned unit_offset_delta;
     518                 :      81320 :       tree base_arg = gimple_call_arg (stmt, stmt_idx);
     519                 :            : 
     520                 :      81320 :       if (phony_arguments > 0)
     521                 :        932 :         index_map->safe_push (stmt_idx);
     522                 :            : 
     523                 :      81320 :       unsigned sm_idx;
     524                 :      81320 :       stmt_idx++;
     525                 :      81320 :       if (transitive_split_p (performed_splits, base_arg, &sm_idx,
     526                 :            :                               &unit_offset_delta))
     527                 :            :         {
     528                 :       1539 :           if (phony_arguments == 0)
     529                 :            :             /* We have optimistically avoided constructing index_map do far but
     530                 :            :                now it is clear it will be necessary, so let's create the easy
     531                 :            :                bit we skipped until now.  */
     532                 :       3720 :             for (unsigned k = 0; k < stmt_idx; k++)
     533                 :       2377 :               index_map->safe_push (k);
     534                 :            : 
     535                 :       1539 :           tree dummy = (*performed_splits)[sm_idx].dummy_decl;
     536                 :       4681 :           for (unsigned j = sm_idx; j < performed_splits->length (); j++)
     537                 :            :             {
     538                 :       3489 :               ipa_param_performed_split *caller_split
     539                 :       3489 :                 = &(*performed_splits)[j];
     540                 :       3489 :               if (caller_split->dummy_decl != dummy)
     541                 :            :                 break;
     542                 :            : 
     543                 :       3142 :               tree arg = gimple_call_arg (stmt, stmt_idx);
     544                 :       3142 :               struct transitive_split_map tsm;
     545                 :       3142 :               tsm.repl = arg;
     546                 :       3142 :               tsm.base_index = base_index;
     547                 :       3142 :               if (caller_split->unit_offset >= unit_offset_delta)
     548                 :            :                 {
     549                 :       3141 :                   tsm.unit_offset
     550                 :       3141 :                     = (caller_split->unit_offset - unit_offset_delta);
     551                 :       3141 :                   trans_map->safe_push (tsm);
     552                 :            :                 }
     553                 :            : 
     554                 :       3142 :               phony_arguments++;
     555                 :       3142 :               stmt_idx++;
     556                 :            :             }
     557                 :            :         }
     558                 :      81320 :       base_index++;
     559                 :            :     }
     560                 :      29818 :   return phony_arguments;
     561                 :            : }
     562                 :            : 
     563                 :            : /* Modify actual arguments of a function call in statement STMT, assuming it
     564                 :            :    calls CALLEE_DECL.  CALLER_ADJ must be the description of parameter
     565                 :            :    adjustments of the caller or NULL if there are none.  Return the new
     566                 :            :    statement that replaced the old one.  When invoked, cfun and
     567                 :            :    current_function_decl have to be set to the caller.  */
     568                 :            : 
     569                 :            : gcall *
     570                 :     184098 : ipa_param_adjustments::modify_call (gcall *stmt,
     571                 :            :                                     vec<ipa_param_performed_split,
     572                 :            :                                         va_gc> *performed_splits,
     573                 :            :                                     tree callee_decl, bool update_references)
     574                 :            : {
     575                 :     184098 :   unsigned len = vec_safe_length (m_adj_params);
     576                 :     184098 :   auto_vec<tree, 16> vargs (len);
     577                 :     184098 :   tree old_decl = gimple_call_fndecl (stmt);
     578                 :     184098 :   unsigned old_nargs = gimple_call_num_args (stmt);
     579                 :     368196 :   auto_vec<bool, 16> kept (old_nargs);
     580                 :     184098 :   kept.quick_grow_cleared (old_nargs);
     581                 :            : 
     582                 :     368196 :   auto_vec <unsigned, 16> index_map;
     583                 :     368196 :   auto_vec <transitive_split_map> trans_map;
     584                 :     184098 :   bool transitive_remapping = false;
     585                 :            : 
     586                 :     184098 :   if (performed_splits)
     587                 :            :     {
     588                 :      29818 :       unsigned removed = init_transitive_splits (performed_splits,
     589                 :            :                                                  stmt, &index_map, &trans_map);
     590                 :      29818 :       if (removed > 0)
     591                 :            :         {
     592                 :       1343 :           transitive_remapping = true;
     593                 :       1343 :           old_nargs -= removed;
     594                 :            :         }
     595                 :            :     }
     596                 :            : 
     597                 :     184098 :   cgraph_node *current_node = cgraph_node::get (current_function_decl);
     598                 :     184098 :   if (update_references)
     599                 :          0 :     current_node->remove_stmt_references (stmt);
     600                 :            : 
     601                 :     184098 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
     602                 :     184098 :   gimple_stmt_iterator prev_gsi = gsi;
     603                 :     184098 :   gsi_prev (&prev_gsi);
     604                 :     595686 :   for (unsigned i = 0; i < len; i++)
     605                 :            :     {
     606                 :     411588 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     607                 :     411588 :       if (apm->op == IPA_PARAM_OP_COPY)
     608                 :            :         {
     609                 :     330766 :           unsigned index = apm->base_index;
     610                 :     330766 :           if (index >= old_nargs)
     611                 :            :             /* Can happen if the original call has argument mismatch,
     612                 :            :                ignore.  */
     613                 :          0 :             continue;
     614                 :     330766 :           if (transitive_remapping)
     615                 :        758 :             index = index_map[apm->base_index];
     616                 :            : 
     617                 :     330766 :           tree arg = gimple_call_arg (stmt, index);
     618                 :            : 
     619                 :     330766 :           vargs.quick_push (arg);
     620                 :     330766 :           kept[index] = true;
     621                 :     330766 :           continue;
     622                 :            :         }
     623                 :            : 
     624                 :            :       /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
     625                 :            :          If we ever want to support it during WPA IPA stage, we'll need a
     626                 :            :          mechanism to call into the IPA passes that introduced them.  Currently
     627                 :            :          we simply mandate that IPA infrastructure understands all argument
     628                 :            :          modifications.  Remember, edge redirection/modification is done only
     629                 :            :          once, not in steps for each pass modifying the callee like clone
     630                 :            :          materialization.  */
     631                 :      80822 :       gcc_assert (apm->op == IPA_PARAM_OP_SPLIT);
     632                 :            : 
     633                 :            :       /* We have to handle transitive changes differently using the maps we
     634                 :            :          have created before.  So look into them first.  */
     635                 :      87350 :       tree repl = NULL_TREE;
     636                 :      98768 :       for (unsigned j = 0; j < trans_map.length (); j++)
     637                 :       9520 :         if (trans_map[j].base_index == apm->base_index
     638                 :       9520 :             && trans_map[j].unit_offset == apm->unit_offset)
     639                 :            :           {
     640                 :       2992 :             repl = trans_map[j].repl;
     641                 :       2992 :             break;
     642                 :            :           }
     643                 :      80822 :       if (repl)
     644                 :            :         {
     645                 :       2992 :           vargs.quick_push (repl);
     646                 :       2992 :           continue;
     647                 :            :         }
     648                 :            : 
     649                 :      77830 :       unsigned index = apm->base_index;
     650                 :      77830 :       if (index >= old_nargs)
     651                 :            :         /* Can happen if the original call has argument mismatch, ignore.  */
     652                 :          1 :         continue;
     653                 :      77829 :       if (transitive_remapping)
     654                 :       1898 :         index = index_map[apm->base_index];
     655                 :      77829 :       tree base = gimple_call_arg (stmt, index);
     656                 :            : 
     657                 :            :       /* We create a new parameter out of the value of the old one, we can
     658                 :            :          do the following kind of transformations:
     659                 :            : 
     660                 :            :          - A scalar passed by reference, potentially as a part of a larger
     661                 :            :          aggregate, is converted to a scalar passed by value.
     662                 :            : 
     663                 :            :          - A part of an aggregate is passed instead of the whole aggregate.  */
     664                 :            : 
     665                 :      77829 :       location_t loc = gimple_location (stmt);
     666                 :      77829 :       tree off;
     667                 :      77829 :       bool deref_base = false;
     668                 :      77829 :       unsigned int deref_align = 0;
     669                 :      77829 :       if (TREE_CODE (base) != ADDR_EXPR
     670                 :     127994 :           && is_gimple_reg_type (TREE_TYPE (base)))
     671                 :            :         {
     672                 :            :           /* Detect type mismatches in calls in invalid programs and make a
     673                 :            :              poor attempt to gracefully convert them so that we don't ICE.  */
     674                 :      28957 :           if (!POINTER_TYPE_P (TREE_TYPE (base)))
     675                 :          1 :             base = force_value_to_type (ptr_type_node, base);
     676                 :            : 
     677                 :      28957 :           off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
     678                 :            :         }
     679                 :            :       else
     680                 :            :         {
     681                 :      48872 :           bool addrof;
     682                 :      48872 :           if (TREE_CODE (base) == ADDR_EXPR)
     683                 :            :             {
     684                 :      27664 :               base = TREE_OPERAND (base, 0);
     685                 :      27664 :               addrof = true;
     686                 :            :             }
     687                 :            :           else
     688                 :            :             addrof = false;
     689                 :            : 
     690                 :      48872 :           tree prev_base = base;
     691                 :      48872 :           poly_int64 base_offset;
     692                 :      48872 :           base = get_addr_base_and_unit_offset (base, &base_offset);
     693                 :            : 
     694                 :            :           /* Aggregate arguments can have non-invariant addresses.  */
     695                 :      48872 :           if (!base)
     696                 :            :             {
     697                 :          0 :               base = build_fold_addr_expr (prev_base);
     698                 :          0 :               off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
     699                 :            :             }
     700                 :      48872 :           else if (TREE_CODE (base) == MEM_REF)
     701                 :            :             {
     702                 :       3819 :               if (!addrof)
     703                 :            :                 {
     704                 :       3819 :                   deref_base = true;
     705                 :       3819 :                   deref_align = TYPE_ALIGN (TREE_TYPE (base));
     706                 :            :                 }
     707                 :       7638 :               off = build_int_cst (apm->alias_ptr_type,
     708                 :       3819 :                                    base_offset + apm->unit_offset);
     709                 :       3819 :               off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
     710                 :            :                                      off);
     711                 :       3819 :               base = TREE_OPERAND (base, 0);
     712                 :            :             }
     713                 :            :           else
     714                 :            :             {
     715                 :      90106 :               off = build_int_cst (apm->alias_ptr_type,
     716                 :      45053 :                                    base_offset + apm->unit_offset);
     717                 :      45053 :               base = build_fold_addr_expr (base);
     718                 :            :             }
     719                 :            :         }
     720                 :            : 
     721                 :      77829 :       tree type = apm->type;
     722                 :      77829 :       unsigned int align;
     723                 :      77829 :       unsigned HOST_WIDE_INT misalign;
     724                 :            : 
     725                 :      77829 :       if (deref_base)
     726                 :            :         {
     727                 :       3819 :           align = deref_align;
     728                 :       3819 :           misalign = 0;
     729                 :            :         }
     730                 :            :       else
     731                 :            :         {
     732                 :      74010 :           get_pointer_alignment_1 (base, &align, &misalign);
     733                 :            :           /* All users must make sure that we can be optimistic when it
     734                 :            :              comes to alignment in this case (by inspecting the final users
     735                 :            :              of these new parameters).  */
     736                 :      74010 :           if (TYPE_ALIGN (type) > align)
     737                 :      28634 :             align = TYPE_ALIGN (type);
     738                 :            :         }
     739                 :      77829 :       misalign
     740                 :      77829 :         += (offset_int::from (wi::to_wide (off), SIGNED).to_short_addr ()
     741                 :      77829 :             * BITS_PER_UNIT);
     742                 :      77829 :       misalign = misalign & (align - 1);
     743                 :      77829 :       if (misalign != 0)
     744                 :       1144 :         align = least_bit_hwi (misalign);
     745                 :      77829 :       if (align < TYPE_ALIGN (type))
     746                 :          0 :         type = build_aligned_type (type, align);
     747                 :      77829 :       base = force_gimple_operand_gsi (&gsi, base,
     748                 :            :                                        true, NULL, true, GSI_SAME_STMT);
     749                 :      77829 :       tree expr = fold_build2_loc (loc, MEM_REF, type, base, off);
     750                 :      77829 :       REF_REVERSE_STORAGE_ORDER (expr) = apm->reverse;
     751                 :            :       /* If expr is not a valid gimple call argument emit
     752                 :            :          a load into a temporary.  */
     753                 :      77829 :       if (is_gimple_reg_type (TREE_TYPE (expr)))
     754                 :            :         {
     755                 :      77552 :           gimple *tem = gimple_build_assign (NULL_TREE, expr);
     756                 :      77552 :           if (gimple_in_ssa_p (cfun))
     757                 :            :             {
     758                 :     155104 :               gimple_set_vuse (tem, gimple_vuse (stmt));
     759                 :      77552 :               expr = make_ssa_name (TREE_TYPE (expr), tem);
     760                 :            :             }
     761                 :            :           else
     762                 :          0 :             expr = create_tmp_reg (TREE_TYPE (expr));
     763                 :      77552 :           gimple_assign_set_lhs (tem, expr);
     764                 :      77552 :           gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
     765                 :            :         }
     766                 :      77829 :       vargs.quick_push (expr);
     767                 :            :     }
     768                 :            : 
     769                 :     184098 :   if (m_always_copy_start >= 0)
     770                 :     184099 :     for (unsigned i = m_always_copy_start; i < old_nargs; i++)
     771                 :          1 :       vargs.safe_push (gimple_call_arg (stmt, i));
     772                 :            : 
     773                 :            :   /* For optimized away parameters, add on the caller side
     774                 :            :      before the call
     775                 :            :      DEBUG D#X => parm_Y(D)
     776                 :            :      stmts and associate D#X with parm in decl_debug_args_lookup
     777                 :            :      vector to say for debug info that if parameter parm had been passed,
     778                 :            :      it would have value parm_Y(D).  */
     779                 :     184098 :   if (MAY_HAVE_DEBUG_BIND_STMTS && old_decl && callee_decl)
     780                 :            :     {
     781                 :     169010 :       vec<tree, va_gc> **debug_args = NULL;
     782                 :     169010 :       unsigned i = 0;
     783                 :     582993 :       for (tree old_parm = DECL_ARGUMENTS (old_decl);
     784                 :     582993 :            old_parm && i < old_nargs && ((int) i) < m_always_copy_start;
     785                 :     413983 :            old_parm = DECL_CHAIN (old_parm), i++)
     786                 :            :         {
     787                 :     413983 :           if (!is_gimple_reg (old_parm) || kept[i])
     788                 :     320645 :             continue;
     789                 :      93357 :           tree origin = DECL_ORIGIN (old_parm);
     790                 :      93357 :           tree arg = gimple_call_arg (stmt, i);
     791                 :            : 
     792                 :      93357 :           if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
     793                 :            :             {
     794                 :        364 :               if (!fold_convertible_p (TREE_TYPE (origin), arg))
     795                 :         19 :                 continue;
     796                 :        345 :               tree rhs1;
     797                 :        345 :               if (TREE_CODE (arg) == SSA_NAME
     798                 :        152 :                   && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg))
     799                 :         28 :                   && (rhs1
     800                 :         28 :                       = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg)))
     801                 :        373 :                   && useless_type_conversion_p (TREE_TYPE (origin),
     802                 :         28 :                                                 TREE_TYPE (rhs1)))
     803                 :            :                 arg = rhs1;
     804                 :            :               else
     805                 :        634 :                 arg = fold_convert_loc (gimple_location (stmt),
     806                 :        317 :                                         TREE_TYPE (origin), arg);
     807                 :            :             }
     808                 :      93338 :           if (debug_args == NULL)
     809                 :      77050 :             debug_args = decl_debug_args_insert (callee_decl);
     810                 :      93338 :           unsigned int ix;
     811                 :      93338 :           tree ddecl = NULL_TREE;
     812                 :     118462 :           for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
     813                 :      97326 :             if (ddecl == origin)
     814                 :            :               {
     815                 :      79026 :                 ddecl = (**debug_args)[ix + 1];
     816                 :      79026 :                 break;
     817                 :            :               }
     818                 :      93338 :           if (ddecl == NULL)
     819                 :            :             {
     820                 :      14312 :               ddecl = make_node (DEBUG_EXPR_DECL);
     821                 :      14312 :               DECL_ARTIFICIAL (ddecl) = 1;
     822                 :      14312 :               TREE_TYPE (ddecl) = TREE_TYPE (origin);
     823                 :      14312 :               SET_DECL_MODE (ddecl, DECL_MODE (origin));
     824                 :            : 
     825                 :      14312 :               vec_safe_push (*debug_args, origin);
     826                 :      14312 :               vec_safe_push (*debug_args, ddecl);
     827                 :            :             }
     828                 :      93338 :           gimple *def_temp = gimple_build_debug_bind (ddecl,
     829                 :            :                                                       unshare_expr (arg), stmt);
     830                 :      93338 :           gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
     831                 :            :         }
     832                 :            :     }
     833                 :            : 
     834                 :     184098 :   if (dump_file && (dump_flags & TDF_DETAILS))
     835                 :            :     {
     836                 :         10 :       fprintf (dump_file, "replacing stmt:");
     837                 :         10 :       print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
     838                 :            :     }
     839                 :            : 
     840                 :     184098 :   gcall *new_stmt = gimple_build_call_vec (callee_decl, vargs);
     841                 :            : 
     842                 :     184098 :   if (tree lhs = gimple_call_lhs (stmt))
     843                 :            :     {
     844                 :      68101 :       if (!m_skip_return)
     845                 :      61237 :         gimple_call_set_lhs (new_stmt, lhs);
     846                 :       6864 :       else if (TREE_CODE (lhs) == SSA_NAME)
     847                 :            :         {
     848                 :            :           /* LHS should now by a default-def SSA.  Unfortunately default-def
     849                 :            :              SSA_NAMEs need a backing variable (or at least some code examining
     850                 :            :              SSAs assumes it is non-NULL).  So we either have to re-use the
     851                 :            :              decl we have at hand or introdice a new one.  */
     852                 :       6864 :           tree repl = create_tmp_var (TREE_TYPE (lhs), "removed_return");
     853                 :       6864 :           repl = get_or_create_ssa_default_def (cfun, repl);
     854                 :       6864 :           SSA_NAME_IS_DEFAULT_DEF (repl) = true;
     855                 :       6864 :           imm_use_iterator ui;
     856                 :       6864 :           use_operand_p use_p;
     857                 :       6864 :           gimple *using_stmt;
     858                 :       8565 :           FOR_EACH_IMM_USE_STMT (using_stmt, ui, lhs)
     859                 :            :             {
     860                 :       5103 :               FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
     861                 :            :                 {
     862                 :       1701 :                   SET_USE (use_p, repl);
     863                 :            :                 }
     864                 :       3402 :               update_stmt (using_stmt);
     865                 :            :             }
     866                 :            :         }
     867                 :            :     }
     868                 :            : 
     869                 :     362846 :   gimple_set_block (new_stmt, gimple_block (stmt));
     870                 :     362846 :   if (gimple_has_location (stmt))
     871                 :     173030 :     gimple_set_location (new_stmt, gimple_location (stmt));
     872                 :     184098 :   gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
     873                 :     184098 :   gimple_call_copy_flags (new_stmt, stmt);
     874                 :     184098 :   if (gimple_in_ssa_p (cfun))
     875                 :     184098 :     gimple_move_vops (new_stmt, stmt);
     876                 :            : 
     877                 :     184098 :   if (dump_file && (dump_flags & TDF_DETAILS))
     878                 :            :     {
     879                 :         10 :       fprintf (dump_file, "with stmt:");
     880                 :         10 :       print_gimple_stmt (dump_file, new_stmt, 0);
     881                 :         10 :       fprintf (dump_file, "\n");
     882                 :            :     }
     883                 :     184098 :   gsi_replace (&gsi, new_stmt, true);
     884                 :     184098 :   if (update_references)
     885                 :          0 :     do
     886                 :            :       {
     887                 :          0 :         current_node->record_stmt_references (gsi_stmt (gsi));
     888                 :          0 :         gsi_prev (&gsi);
     889                 :            :       }
     890                 :          0 :     while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
     891                 :     184098 :   return new_stmt;
     892                 :            : }
     893                 :            : 
     894                 :            : /* Dump information contained in the object in textual form to F.  */
     895                 :            : 
     896                 :            : void
     897                 :          1 : ipa_param_adjustments::dump (FILE *f)
     898                 :            : {
     899                 :          1 :   fprintf (f, "    m_always_copy_start: %i\n", m_always_copy_start);
     900                 :          1 :   ipa_dump_adjusted_parameters (f, m_adj_params);
     901                 :          1 :   if (m_skip_return)
     902                 :          1 :     fprintf (f, "     Will SKIP return.\n");
     903                 :          1 : }
     904                 :            : 
     905                 :            : /* Dump information contained in the object in textual form to stderr.  */
     906                 :            : 
     907                 :            : void
     908                 :          0 : ipa_param_adjustments::debug ()
     909                 :            : {
     910                 :          0 :   dump (stderr);
     911                 :          0 : }
     912                 :            : 
     913                 :            : /* Register that REPLACEMENT should replace parameter described in APM and
     914                 :            :    optionally as DUMMY to mark transitive splits across calls.  */
     915                 :            : 
     916                 :            : void
     917                 :      32517 : ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
     918                 :            :                                                   tree replacement,
     919                 :            :                                                   tree dummy)
     920                 :            : {
     921                 :      32517 :   gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT
     922                 :            :                        || apm->op == IPA_PARAM_OP_NEW);
     923                 :      32517 :   gcc_checking_assert (!apm->prev_clone_adjustment);
     924                 :      32517 :   ipa_param_body_replacement psr;
     925                 :      32517 :   psr.base = m_oparms[apm->prev_clone_index];
     926                 :      32517 :   psr.repl = replacement;
     927                 :      32517 :   psr.dummy = dummy;
     928                 :      32517 :   psr.unit_offset = apm->unit_offset;
     929                 :      32517 :   m_replacements.safe_push (psr);
     930                 :      32517 : }
     931                 :            : 
     932                 :            : /* Copy or not, as appropriate given m_id and decl context, a pre-existing
     933                 :            :    PARM_DECL T so that it can be included in the parameters of the modified
     934                 :            :    function.  */
     935                 :            : 
     936                 :            : tree
     937                 :     129921 : ipa_param_body_adjustments::carry_over_param (tree t)
     938                 :            : {
     939                 :     129921 :   tree new_parm;
     940                 :     129921 :   if (m_id)
     941                 :            :     {
     942                 :     126164 :       new_parm = remap_decl (t, m_id);
     943                 :     126164 :       if (TREE_CODE (new_parm) != PARM_DECL)
     944                 :          0 :         new_parm = m_id->copy_decl (t, m_id);
     945                 :            :     }
     946                 :       3757 :   else if (DECL_CONTEXT (t) != m_fndecl)
     947                 :            :     {
     948                 :         47 :       new_parm = copy_node (t);
     949                 :         47 :       DECL_CONTEXT (new_parm) = m_fndecl;
     950                 :            :     }
     951                 :            :   else
     952                 :            :     new_parm = t;
     953                 :     129921 :   return new_parm;
     954                 :            : }
     955                 :            : 
     956                 :            : /* Common initialization performed by all ipa_param_body_adjustments
     957                 :            :    constructors.  OLD_FNDECL is the declaration we take original arguments
     958                 :            :    from, (it may be the same as M_FNDECL).  VARS, if non-NULL, is a pointer to
     959                 :            :    a chained list of new local variables.  TREE_MAP is the IPA-CP produced
     960                 :            :    mapping of trees to constants.
     961                 :            : 
     962                 :            :    The function is rather long but it really onlu initializes all data members
     963                 :            :    of the class.  It creates new param DECLs, finds their new types,   */
     964                 :            : 
     965                 :            : void
     966                 :      81556 : ipa_param_body_adjustments::common_initialization (tree old_fndecl,
     967                 :            :                                                    tree *vars,
     968                 :            :                                                    vec<ipa_replace_map *,
     969                 :            :                                                        va_gc> *tree_map)
     970                 :            : {
     971                 :      81556 :   push_function_arg_decls (&m_oparms, old_fndecl);
     972                 :     149137 :   auto_vec<tree,16> otypes;
     973                 :     120942 :   if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl)) != NULL_TREE)
     974                 :      81246 :     push_function_arg_types (&otypes, TREE_TYPE (old_fndecl));
     975                 :            :   else
     976                 :            :     {
     977                 :        620 :       auto_vec<tree,16> oparms;
     978                 :        310 :       push_function_arg_decls (&oparms, old_fndecl);
     979                 :        310 :       unsigned ocount = oparms.length ();
     980                 :        310 :       otypes.reserve_exact (ocount);
     981                 :        520 :       for (unsigned i = 0; i < ocount; i++)
     982                 :        210 :         otypes.quick_push (TREE_TYPE (oparms[i]));
     983                 :            :     }
     984                 :      81556 :   fill_vector_of_new_param_types (&m_new_types, &otypes, m_adj_params, true);
     985                 :            : 
     986                 :     149137 :   auto_vec<bool, 16> kept;
     987                 :     163112 :   kept.reserve_exact (m_oparms.length ());
     988                 :     163112 :   kept.quick_grow_cleared (m_oparms.length ());
     989                 :     149137 :   auto_vec<tree, 16> isra_dummy_decls;
     990                 :     163112 :   isra_dummy_decls.reserve_exact (m_oparms.length ());
     991                 :     163112 :   isra_dummy_decls.quick_grow_cleared (m_oparms.length ());
     992                 :            : 
     993                 :      81556 :   unsigned adj_len = vec_safe_length (m_adj_params);
     994                 :      81556 :   m_method2func = ((TREE_CODE (TREE_TYPE (m_fndecl)) == METHOD_TYPE)
     995                 :      81556 :                    && (adj_len == 0
     996                 :      22547 :                        || (*m_adj_params)[0].op != IPA_PARAM_OP_COPY
     997                 :      22419 :                        || (*m_adj_params)[0].base_index != 0));
     998                 :            : 
     999                 :            :   /* The main job of the this function is to go over the vector of adjusted
    1000                 :            :      parameters and create declarations or find corresponding old ones and push
    1001                 :            :      them to m_new_decls.  For IPA-SRA replacements it also creates
    1002                 :            :      corresponding m_id->dst_node->clone.performed_splits entries.  */
    1003                 :            : 
    1004                 :      81556 :   m_new_decls.reserve_exact (adj_len);
    1005                 :     247053 :   for (unsigned i = 0; i < adj_len ; i++)
    1006                 :            :     {
    1007                 :     165497 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
    1008                 :     165497 :       unsigned prev_index = apm->prev_clone_index;
    1009                 :     165497 :       tree new_parm;
    1010                 :     165497 :       if (apm->op == IPA_PARAM_OP_COPY
    1011                 :      35576 :           || apm->prev_clone_adjustment)
    1012                 :            :         {
    1013                 :     129921 :           kept[prev_index] = true;
    1014                 :     129921 :           new_parm = carry_over_param (m_oparms[prev_index]);
    1015                 :     295418 :           m_new_decls.quick_push (new_parm);
    1016                 :            :         }
    1017                 :      35576 :       else if (apm->op == IPA_PARAM_OP_NEW
    1018                 :      35576 :                || apm->op == IPA_PARAM_OP_SPLIT)
    1019                 :            :         {
    1020                 :      35576 :           tree new_type = m_new_types[i];
    1021                 :      35576 :           gcc_checking_assert (new_type);
    1022                 :      35576 :           new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
    1023                 :            :                                  new_type);
    1024                 :      35576 :           const char *prefix = ipa_param_prefixes[apm->param_prefix_index];
    1025                 :      35576 :           DECL_NAME (new_parm) = create_tmp_var_name (prefix);
    1026                 :      35576 :           DECL_ARTIFICIAL (new_parm) = 1;
    1027                 :      35576 :           DECL_ARG_TYPE (new_parm) = new_type;
    1028                 :      35576 :           DECL_CONTEXT (new_parm) = m_fndecl;
    1029                 :      35576 :           TREE_USED (new_parm) = 1;
    1030                 :      35576 :           DECL_IGNORED_P (new_parm) = 1;
    1031                 :            :           /* We assume all newly created arguments are not addressable.  */
    1032                 :      35576 :           if (TREE_CODE (new_type) == COMPLEX_TYPE
    1033                 :      35576 :               || TREE_CODE (new_type) == VECTOR_TYPE)
    1034                 :       6902 :             DECL_GIMPLE_REG_P (new_parm) = 1;
    1035                 :      35576 :           layout_decl (new_parm, 0);
    1036                 :      35576 :           m_new_decls.quick_push (new_parm);
    1037                 :            : 
    1038                 :      35576 :           if (apm->op == IPA_PARAM_OP_SPLIT)
    1039                 :            :             {
    1040                 :      28440 :               m_split_modifications_p = true;
    1041                 :            : 
    1042                 :      28440 :               if (m_id)
    1043                 :            :                 {
    1044                 :      28440 :                   tree dummy_decl;
    1045                 :      28440 :                   if (!isra_dummy_decls[prev_index])
    1046                 :            :                     {
    1047                 :      16584 :                       dummy_decl = copy_decl_to_var (m_oparms[prev_index],
    1048                 :            :                                                      m_id);
    1049                 :            :                       /* Any attempt to remap this dummy in this particular
    1050                 :            :                          instance of clone materialization should yield
    1051                 :            :                          itself.  */
    1052                 :      16584 :                       insert_decl_map (m_id, dummy_decl, dummy_decl);
    1053                 :            : 
    1054                 :      16584 :                       DECL_CHAIN (dummy_decl) = *vars;
    1055                 :      16584 :                       *vars = dummy_decl;
    1056                 :      16584 :                       isra_dummy_decls[prev_index] = dummy_decl;
    1057                 :            :                     }
    1058                 :            :                   else
    1059                 :      28440 :                     dummy_decl = isra_dummy_decls[prev_index];
    1060                 :            : 
    1061                 :      28440 :                   register_replacement (apm, new_parm, dummy_decl);
    1062                 :      28440 :                   ipa_param_performed_split ps;
    1063                 :      28440 :                   ps.dummy_decl = dummy_decl;
    1064                 :      28440 :                   ps.unit_offset = apm->unit_offset;
    1065                 :      28440 :                   vec_safe_push (m_id->dst_node->clone.performed_splits, ps);
    1066                 :            :                 }
    1067                 :            :               else
    1068                 :          0 :                 register_replacement (apm, new_parm);
    1069                 :            :             }
    1070                 :            :         }
    1071                 :            :       else
    1072                 :          0 :         gcc_unreachable ();
    1073                 :            :     }
    1074                 :            : 
    1075                 :            : 
    1076                 :            :   /* As part of body modifications, we will also have to replace remaining uses
    1077                 :            :      of remaining uses of removed PARM_DECLs (which do not however use the
    1078                 :            :      initial value) with their VAR_DECL copies.
    1079                 :            : 
    1080                 :            :      We do this differently with and without m_id.  With m_id, we rely on its
    1081                 :            :      mapping and create a replacement straight away.  Without it, we have our
    1082                 :            :      own mechanism for which we have to populate m_removed_decls vector.  Just
    1083                 :            :      don't mix them, that is why you should not call
    1084                 :            :      replace_removed_params_ssa_names or perform_cfun_body_modifications when
    1085                 :            :      you construct with ID not equal to NULL.  */
    1086                 :            : 
    1087                 :      81556 :   unsigned op_len = m_oparms.length ();
    1088                 :     297433 :   for (unsigned i = 0; i < op_len; i++)
    1089                 :     215877 :     if (!kept[i])
    1090                 :            :       {
    1091                 :      85956 :         if (m_id)
    1092                 :            :           {
    1093                 :     297687 :             if (!m_id->decl_map->get (m_oparms[i]))
    1094                 :            :               {
    1095                 :            :                 /* TODO: Perhaps at least aggregate-type params could re-use
    1096                 :            :                    their isra_dummy_decl here?  */
    1097                 :      60331 :                 tree var = copy_decl_to_var (m_oparms[i], m_id);
    1098                 :      60331 :                 insert_decl_map (m_id, m_oparms[i], var);
    1099                 :            :                 /* Declare this new variable.  */
    1100                 :      60331 :                 DECL_CHAIN (var) = *vars;
    1101                 :      60331 :                 *vars = var;
    1102                 :            :               }
    1103                 :            :           }
    1104                 :            :         else
    1105                 :            :           {
    1106                 :       4146 :             m_removed_decls.safe_push (m_oparms[i]);
    1107                 :       8292 :             m_removed_map.put (m_oparms[i], m_removed_decls.length () - 1);
    1108                 :            :           }
    1109                 :            :       }
    1110                 :            : 
    1111                 :      81556 :   if (!MAY_HAVE_DEBUG_STMTS)
    1112                 :      27950 :     return;
    1113                 :            : 
    1114                 :            :   /* Finally, when generating debug info, we fill vector m_reset_debug_decls
    1115                 :            :     with removed parameters declarations.  We do this in order to re-map their
    1116                 :            :     debug bind statements and create debug decls for them.  */
    1117                 :            : 
    1118                 :      67581 :   if (tree_map)
    1119                 :            :     {
    1120                 :            :       /* Do not output debuginfo for parameter declarations as if they vanished
    1121                 :            :          when they were in fact replaced by a constant.  */
    1122                 :      15754 :       auto_vec <int, 16> index_mapping;
    1123                 :       7877 :       bool need_remap = false;
    1124                 :            : 
    1125                 :       7877 :       if (m_id && m_id->src_node->clone.param_adjustments)
    1126                 :            :         {
    1127                 :          0 :           ipa_param_adjustments *prev_adjustments
    1128                 :            :             = m_id->src_node->clone.param_adjustments;
    1129                 :          0 :           prev_adjustments->get_updated_indices (&index_mapping);
    1130                 :          0 :           need_remap = true;
    1131                 :            :         }
    1132                 :            : 
    1133                 :      22555 :       for (unsigned i = 0; i < tree_map->length (); i++)
    1134                 :            :         {
    1135                 :      14678 :           int parm_num = (*tree_map)[i]->parm_num;
    1136                 :      14678 :           gcc_assert (parm_num >= 0);
    1137                 :      14678 :           if (need_remap)
    1138                 :          0 :             parm_num = index_mapping[parm_num];
    1139                 :      14678 :           kept[parm_num] = true;
    1140                 :            :         }
    1141                 :            :     }
    1142                 :            : 
    1143                 :     249140 :   for (unsigned i = 0; i < op_len; i++)
    1144                 :     181559 :     if (!kept[i] && is_gimple_reg (m_oparms[i]))
    1145                 :      37590 :       m_reset_debug_decls.safe_push (m_oparms[i]);
    1146                 :            : }
    1147                 :            : 
    1148                 :            : /* Constructor of ipa_param_body_adjustments from a simple list of
    1149                 :            :    modifications to parameters listed in ADJ_PARAMS which will prepare ground
    1150                 :            :    for modification of parameters of fndecl.  Return value of the function will
    1151                 :            :    not be removed and the object will assume it does not run as a part of
    1152                 :            :    tree-function_versioning.  */
    1153                 :            : 
    1154                 :       3404 : ipa_param_body_adjustments
    1155                 :            : ::ipa_param_body_adjustments (vec<ipa_adjusted_param, va_gc> *adj_params,
    1156                 :       3404 :                               tree fndecl)
    1157                 :            :   : m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
    1158                 :            :     m_split_modifications_p (false), m_fndecl (fndecl), m_id (NULL),
    1159                 :            :     m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
    1160                 :       3404 :     m_removed_decls (), m_removed_map (), m_method2func (false)
    1161                 :            : {
    1162                 :       3404 :   common_initialization (fndecl, NULL, NULL);
    1163                 :       3404 : }
    1164                 :            : 
    1165                 :            : /* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
    1166                 :            :    ADJUSTMENTS which will prepare ground for modification of parameters of
    1167                 :            :    fndecl.  The object will assume it does not run as a part of
    1168                 :            :    tree-function_versioning.  */
    1169                 :            : 
    1170                 :         41 : ipa_param_body_adjustments
    1171                 :            : ::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
    1172                 :         41 :                               tree fndecl)
    1173                 :         41 :   : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    1174                 :            :     m_reset_debug_decls (), m_split_modifications_p (false), m_fndecl (fndecl),
    1175                 :            :     m_id (NULL), m_oparms (), m_new_decls (), m_new_types (),
    1176                 :            :     m_replacements (), m_removed_decls (), m_removed_map (),
    1177                 :         41 :     m_method2func (false)
    1178                 :            : {
    1179                 :         41 :   common_initialization (fndecl, NULL, NULL);
    1180                 :         41 : }
    1181                 :            : 
    1182                 :            : /* Constructor of ipa_param_body_adjustments which sets it up as a part of
    1183                 :            :    running tree_function_versioning.  Planned modifications to the function are
    1184                 :            :    in ADJUSTMENTS.  FNDECL designates the new function clone which is being
    1185                 :            :    modified.  OLD_FNDECL is the function of which FNDECL is a clone (and which
    1186                 :            :    at the time of invocation still share DECL_ARGUMENTS).  ID is the
    1187                 :            :    copy_body_data structure driving the wholy body copying process.  VARS is a
    1188                 :            :    pointer to the head of the list of new local variables, TREE_MAP is the map
    1189                 :            :    that drives tree substitution in the cloning process.  */
    1190                 :            : 
    1191                 :      78111 : ipa_param_body_adjustments
    1192                 :            : ::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
    1193                 :            :                               tree fndecl, tree old_fndecl,
    1194                 :            :                               copy_body_data *id, tree *vars,
    1195                 :      78111 :                               vec<ipa_replace_map *, va_gc> *tree_map)
    1196                 :      78111 :   : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    1197                 :            :     m_reset_debug_decls (), m_split_modifications_p (false), m_fndecl (fndecl),
    1198                 :            :     m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
    1199                 :      78111 :     m_removed_decls (), m_removed_map (), m_method2func (false)
    1200                 :            : {
    1201                 :      78111 :   common_initialization (old_fndecl, vars, tree_map);
    1202                 :      78111 : }
    1203                 :            : 
    1204                 :            : /* Chain new param decls up and return them.  */
    1205                 :            : 
    1206                 :            : tree
    1207                 :      81556 : ipa_param_body_adjustments::get_new_param_chain ()
    1208                 :            : {
    1209                 :      81556 :   tree result;
    1210                 :      81556 :   tree *link = &result;
    1211                 :            : 
    1212                 :      81556 :   unsigned len = vec_safe_length (m_adj_params);
    1213                 :     247053 :   for (unsigned i = 0; i < len; i++)
    1214                 :            :     {
    1215                 :     165497 :       tree new_decl = m_new_decls[i];
    1216                 :     165497 :       *link = new_decl;
    1217                 :     165497 :       link = &DECL_CHAIN (new_decl);
    1218                 :            :     }
    1219                 :      81556 :   *link = NULL_TREE;
    1220                 :      81556 :   return result;
    1221                 :            : }
    1222                 :            : 
    1223                 :            : /* Modify the function parameters FNDECL and its type according to the plan in
    1224                 :            :    ADJUSTMENTS.  This function needs to be called when the decl has not already
    1225                 :            :    been processed with ipa_param_adjustments::adjust_decl, otherwise just
    1226                 :            :    seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough.  */
    1227                 :            : 
    1228                 :            : void
    1229                 :       3445 : ipa_param_body_adjustments::modify_formal_parameters ()
    1230                 :            : {
    1231                 :       3445 :   tree orig_type = TREE_TYPE (m_fndecl);
    1232                 :       3445 :   DECL_ARGUMENTS (m_fndecl) = get_new_param_chain ();
    1233                 :            : 
    1234                 :            :   /* When signature changes, we need to clear builtin info.  */
    1235                 :       3445 :   if (fndecl_built_in_p (m_fndecl))
    1236                 :          0 :     set_decl_built_in_function (m_fndecl, NOT_BUILT_IN, 0);
    1237                 :            : 
    1238                 :            :   /* At this point, removing return value is only implemented when going
    1239                 :            :      through tree_function_versioning, not when modifying function body
    1240                 :            :      directly.  */
    1241                 :       3445 :   gcc_assert (!m_adjustments || !m_adjustments->m_skip_return);
    1242                 :       6890 :   tree new_type = build_adjusted_function_type (orig_type, &m_new_types,
    1243                 :       3445 :                                                 m_method2func, false);
    1244                 :            : 
    1245                 :       3445 :   TREE_TYPE (m_fndecl) = new_type;
    1246                 :       3445 :   DECL_VIRTUAL_P (m_fndecl) = 0;
    1247                 :       3445 :   DECL_LANG_SPECIFIC (m_fndecl) = NULL;
    1248                 :       3445 :   if (m_method2func)
    1249                 :        128 :     DECL_VINDEX (m_fndecl) = NULL_TREE;
    1250                 :       3445 : }
    1251                 :            : 
    1252                 :            : /* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
    1253                 :            :    structures.  */
    1254                 :            : 
    1255                 :            : ipa_param_body_replacement *
    1256                 :     268959 : ipa_param_body_adjustments::lookup_replacement_1 (tree base,
    1257                 :            :                                                   unsigned unit_offset)
    1258                 :            : {
    1259                 :     268959 :   unsigned int len = m_replacements.length ();
    1260                 :     344284 :   for (unsigned i = 0; i < len; i++)
    1261                 :            :     {
    1262                 :     108948 :       ipa_param_body_replacement *pbr = &m_replacements[i];
    1263                 :            : 
    1264                 :     108948 :       if (pbr->base == base
    1265                 :      45877 :           && (pbr->unit_offset == unit_offset))
    1266                 :      33623 :         return pbr;
    1267                 :            :     }
    1268                 :            :   return NULL;
    1269                 :            : }
    1270                 :            : 
    1271                 :            : /* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
    1272                 :            :    and return it, assuming it is known it does not hold value by reference or
    1273                 :            :    in reverse storage order.  */
    1274                 :            : 
    1275                 :            : tree
    1276                 :       3619 : ipa_param_body_adjustments::lookup_replacement (tree base, unsigned unit_offset)
    1277                 :            : {
    1278                 :       3619 :   ipa_param_body_replacement *pbr = lookup_replacement_1 (base, unit_offset);
    1279                 :       3619 :   if (!pbr)
    1280                 :            :     return NULL;
    1281                 :       3619 :   return pbr->repl;
    1282                 :            : }
    1283                 :            : 
    1284                 :            : /* If T is an SSA_NAME, return NULL if it is not a default def or
    1285                 :            :    return its base variable if it is.  If IGNORE_DEFAULT_DEF is true,
    1286                 :            :    the base variable is always returned, regardless if it is a default
    1287                 :            :    def.  Return T if it is not an SSA_NAME.  */
    1288                 :            : 
    1289                 :            : static tree
    1290                 :    1470960 : get_ssa_base_param (tree t, bool ignore_default_def)
    1291                 :            : {
    1292                 :          0 :   if (TREE_CODE (t) == SSA_NAME)
    1293                 :            :     {
    1294                 :     873751 :       if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
    1295                 :     231614 :         return SSA_NAME_VAR (t);
    1296                 :            :       else
    1297                 :            :         return NULL_TREE;
    1298                 :            :     }
    1299                 :            :   return t;
    1300                 :            : }
    1301                 :            : 
    1302                 :            : /* Given an expression, return the structure describing how it should be
    1303                 :            :    replaced if it accesses a part of a split parameter or NULL otherwise.
    1304                 :            : 
    1305                 :            :    Do not free the result, it will be deallocated when the object is destroyed.
    1306                 :            : 
    1307                 :            :    If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
    1308                 :            :    which are default definitions, if set, consider all SSA_NAMEs of
    1309                 :            :    PARM_DECLs.  */
    1310                 :            : 
    1311                 :            : ipa_param_body_replacement *
    1312                 :    1487060 : ipa_param_body_adjustments::get_expr_replacement (tree expr,
    1313                 :            :                                                   bool ignore_default_def)
    1314                 :            : {
    1315                 :    1487060 :   tree base;
    1316                 :    1487060 :   unsigned unit_offset;
    1317                 :            : 
    1318                 :    1487060 :   if (!isra_get_ref_base_and_offset (expr, &base, &unit_offset))
    1319                 :            :     return NULL;
    1320                 :            : 
    1321                 :    1470960 :   base = get_ssa_base_param (base, ignore_default_def);
    1322                 :    1470960 :   if (!base || TREE_CODE (base) != PARM_DECL)
    1323                 :            :     return NULL;
    1324                 :     264504 :   return lookup_replacement_1 (base, unit_offset);
    1325                 :            : }
    1326                 :            : 
    1327                 :            : /* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
    1328                 :            :    (which includes it being split or replaced), return a new variable that
    1329                 :            :    should be used for any SSA names that will remain in the function that
    1330                 :            :    previously belonged to OLD_DECL.  */
    1331                 :            : 
    1332                 :            : tree
    1333                 :       7337 : ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl)
    1334                 :            : {
    1335                 :       7337 :   unsigned *idx = m_removed_map.get (old_decl);
    1336                 :       4003 :   if (!idx)
    1337                 :            :     return NULL;
    1338                 :            : 
    1339                 :       4003 :   tree repl;
    1340                 :       4003 :   if (TREE_CODE (m_removed_decls[*idx]) == PARM_DECL)
    1341                 :            :     {
    1342                 :       3619 :       gcc_assert (m_removed_decls[*idx] == old_decl);
    1343                 :       3619 :       repl = copy_var_decl (old_decl, DECL_NAME (old_decl),
    1344                 :       3619 :                             TREE_TYPE (old_decl));
    1345                 :       3619 :       m_removed_decls[*idx] = repl;
    1346                 :            :     }
    1347                 :            :   else
    1348                 :       7337 :     repl = m_removed_decls[*idx];
    1349                 :            :   return repl;
    1350                 :            : }
    1351                 :            : 
    1352                 :            : /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
    1353                 :            :    parameter which is to be removed because its value is not used, create a new
    1354                 :            :    SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
    1355                 :            :    original with it and return it.  If there is no need to re-map, return NULL.
    1356                 :            :    ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments.  */
    1357                 :            : 
    1358                 :            : tree
    1359                 :          0 : ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name,
    1360                 :            :                                                               gimple *stmt)
    1361                 :            : {
    1362                 :          0 :   gcc_assert (!m_id);
    1363                 :          0 :   if (TREE_CODE (old_name) != SSA_NAME)
    1364                 :            :     return NULL;
    1365                 :            : 
    1366                 :          0 :   tree decl = SSA_NAME_VAR (old_name);
    1367                 :          0 :   if (decl == NULL_TREE
    1368                 :          0 :       || TREE_CODE (decl) != PARM_DECL)
    1369                 :            :     return NULL;
    1370                 :            : 
    1371                 :          0 :   tree repl = get_replacement_ssa_base (decl);
    1372                 :          0 :   if (!repl)
    1373                 :            :     return NULL;
    1374                 :            : 
    1375                 :          0 :   tree new_name = make_ssa_name (repl, stmt);
    1376                 :          0 :   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
    1377                 :          0 :     = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
    1378                 :            : 
    1379                 :          0 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1380                 :            :     {
    1381                 :          0 :       fprintf (dump_file, "replacing an SSA name of a removed param ");
    1382                 :          0 :       print_generic_expr (dump_file, old_name);
    1383                 :          0 :       fprintf (dump_file, " with ");
    1384                 :          0 :       print_generic_expr (dump_file, new_name);
    1385                 :          0 :       fprintf (dump_file, "\n");
    1386                 :            :     }
    1387                 :            : 
    1388                 :          0 :   replace_uses_by (old_name, new_name);
    1389                 :          0 :   return new_name;
    1390                 :            : }
    1391                 :            : 
    1392                 :            : /* If the expression *EXPR_P should be replaced, do so.  CONVERT specifies
    1393                 :            :    whether the function should care about type incompatibility of the current
    1394                 :            :    and new expressions.  If it is false, the function will leave
    1395                 :            :    incompatibility issues to the caller - note that when the function
    1396                 :            :    encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
    1397                 :            :    their bases instead of the expressions themselves and then also performs any
    1398                 :            :    necessary conversions.  */
    1399                 :            : 
    1400                 :            : bool
    1401                 :    1484540 : ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert)
    1402                 :            : {
    1403                 :    1484540 :   tree expr = *expr_p;
    1404                 :            : 
    1405                 :    1484540 :   if (TREE_CODE (expr) == BIT_FIELD_REF
    1406                 :    1484540 :       || TREE_CODE (expr) == IMAGPART_EXPR
    1407                 :    1484040 :       || TREE_CODE (expr) == REALPART_EXPR)
    1408                 :            :     {
    1409                 :        614 :       expr_p = &TREE_OPERAND (expr, 0);
    1410                 :        614 :       expr = *expr_p;
    1411                 :        614 :       convert = true;
    1412                 :            :     }
    1413                 :            : 
    1414                 :    1484540 :   ipa_param_body_replacement *pbr = get_expr_replacement (expr, false);
    1415                 :    1484540 :   if (!pbr)
    1416                 :            :     return false;
    1417                 :            : 
    1418                 :      27523 :   tree repl = pbr->repl;
    1419                 :      27523 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1420                 :            :     {
    1421                 :          0 :       fprintf (dump_file, "About to replace expr ");
    1422                 :          0 :       print_generic_expr (dump_file, expr);
    1423                 :          0 :       fprintf (dump_file, " with ");
    1424                 :          0 :       print_generic_expr (dump_file, repl);
    1425                 :          0 :       fprintf (dump_file, "\n");
    1426                 :            :     }
    1427                 :            : 
    1428                 :      27638 :   if (convert && !useless_type_conversion_p (TREE_TYPE (expr),
    1429                 :        115 :                                              TREE_TYPE (repl)))
    1430                 :            :     {
    1431                 :          0 :       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), repl);
    1432                 :          0 :       *expr_p = vce;
    1433                 :            :     }
    1434                 :            :   else
    1435                 :      27523 :     *expr_p = repl;
    1436                 :            :   return true;
    1437                 :            : }
    1438                 :            : 
    1439                 :            : /* If the assignment statement STMT contains any expressions that need to
    1440                 :            :    replaced with a different one as noted by ADJUSTMENTS, do so.  Handle any
    1441                 :            :    potential type incompatibilities.  If any conversion sttements have to be
    1442                 :            :    pre-pended to STMT, they will be added to EXTRA_STMTS.  Return true iff the
    1443                 :            :    statement was modified.  */
    1444                 :            : 
    1445                 :            : bool
    1446                 :     742727 : ipa_param_body_adjustments::modify_assignment (gimple *stmt,
    1447                 :            :                                                gimple_seq *extra_stmts)
    1448                 :            : {
    1449                 :     742727 :   tree *lhs_p, *rhs_p;
    1450                 :     742727 :   bool any;
    1451                 :            : 
    1452                 :     742727 :   if (!gimple_assign_single_p (stmt))
    1453                 :            :     return false;
    1454                 :            : 
    1455                 :     491885 :   rhs_p = gimple_assign_rhs1_ptr (stmt);
    1456                 :     491885 :   lhs_p = gimple_assign_lhs_ptr (stmt);
    1457                 :            : 
    1458                 :     491885 :   any = modify_expression (lhs_p, false);
    1459                 :     491885 :   any |= modify_expression (rhs_p, false);
    1460                 :     491885 :   if (any
    1461                 :     491885 :       && !useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
    1462                 :            :     {
    1463                 :          0 :       if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
    1464                 :            :         {
    1465                 :            :           /* V_C_Es of constructors can cause trouble (PR 42714).  */
    1466                 :          0 :           if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
    1467                 :          0 :             *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
    1468                 :            :           else
    1469                 :          0 :             *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
    1470                 :            :                                         NULL);
    1471                 :            :         }
    1472                 :            :       else
    1473                 :            :         {
    1474                 :          0 :           tree new_rhs = fold_build1_loc (gimple_location (stmt),
    1475                 :          0 :                                           VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
    1476                 :            :                                           *rhs_p);
    1477                 :          0 :           tree tmp = force_gimple_operand (new_rhs, extra_stmts, true,
    1478                 :            :                                            NULL_TREE);
    1479                 :          0 :           gimple_assign_set_rhs1 (stmt, tmp);
    1480                 :            :         }
    1481                 :          0 :       return true;
    1482                 :            :     }
    1483                 :            : 
    1484                 :            :   return any;
    1485                 :            : }
    1486                 :            : 
    1487                 :            : /* Data passed to remap_split_decl_to_dummy through walk_tree.  */
    1488                 :            : 
    1489                 :            : struct simple_tree_swap_info
    1490                 :            : {
    1491                 :            :   /* Change FROM to TO.  */
    1492                 :            :   tree from, to;
    1493                 :            :   /* And set DONE to true when doing so.  */
    1494                 :            :   bool done;
    1495                 :            : };
    1496                 :            : 
    1497                 :            : /* Simple remapper to remap a split parameter to the same expression based on a
    1498                 :            :    special dummy decl so that edge redirections can detect transitive splitting
    1499                 :            :    and finish them.  */
    1500                 :            : 
    1501                 :            : static tree
    1502                 :       1059 : remap_split_decl_to_dummy (tree *tp, int *walk_subtrees, void *data)
    1503                 :            : {
    1504                 :       1059 :   tree t = *tp;
    1505                 :            : 
    1506                 :       1059 :   if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
    1507                 :            :     {
    1508                 :       1058 :       struct simple_tree_swap_info *swapinfo
    1509                 :            :         = (struct simple_tree_swap_info *) data;
    1510                 :       1058 :       if (t == swapinfo->from
    1511                 :       1058 :           || (TREE_CODE (t) == SSA_NAME
    1512                 :        472 :               && SSA_NAME_VAR (t) == swapinfo->from))
    1513                 :            :         {
    1514                 :       1057 :           *tp = swapinfo->to;
    1515                 :       1057 :           swapinfo->done = true;
    1516                 :            :         }
    1517                 :       1058 :       *walk_subtrees = 0;
    1518                 :            :     }
    1519                 :          1 :   else if (TYPE_P (t))
    1520                 :          0 :       *walk_subtrees = 0;
    1521                 :            :   else
    1522                 :          1 :     *walk_subtrees = 1;
    1523                 :       1059 :   return NULL_TREE;
    1524                 :            : }
    1525                 :            : 
    1526                 :            : 
    1527                 :            : /* If the call statement pointed at by STMT_P contains any expressions that
    1528                 :            :    need to replaced with a different one as noted by ADJUSTMENTS, do so.  f the
    1529                 :            :    statement needs to be rebuilt, do so.  Return true if any modifications have
    1530                 :            :    been performed.
    1531                 :            : 
    1532                 :            :    If the method is invoked as a part of IPA clone materialization and if any
    1533                 :            :    parameter split is transitive, i.e. it applies to the functin that is being
    1534                 :            :    modified and also to the callee of the statement, replace the parameter
    1535                 :            :    passed to old callee with an equivalent expression based on a dummy decl
    1536                 :            :    followed by PARM_DECLs representing the actual replacements.  The actual
    1537                 :            :    replacements will be then converted into SSA_NAMEs and then
    1538                 :            :    ipa_param_adjustments::modify_call will find the appropriate ones and leave
    1539                 :            :    only those in the call.  */
    1540                 :            : 
    1541                 :            : bool
    1542                 :     200561 : ipa_param_body_adjustments::modify_call_stmt (gcall **stmt_p)
    1543                 :            : {
    1544                 :     200561 :   gcall *stmt = *stmt_p;
    1545                 :     200561 :   auto_vec <unsigned, 4> pass_through_args;
    1546                 :     200561 :   auto_vec <unsigned, 4> pass_through_pbr_indices;
    1547                 :            : 
    1548                 :     200561 :   if (m_split_modifications_p && m_id)
    1549                 :            :     {
    1550                 :      98701 :       for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
    1551                 :            :         {
    1552                 :      66059 :           tree t = gimple_call_arg (stmt, i);
    1553                 :      66059 :           gcc_assert (TREE_CODE (t) != BIT_FIELD_REF
    1554                 :            :                       && TREE_CODE (t) != IMAGPART_EXPR
    1555                 :            :                       && TREE_CODE (t) != REALPART_EXPR);
    1556                 :            : 
    1557                 :      66059 :           tree base;
    1558                 :      66059 :           unsigned unit_offset;
    1559                 :      66059 :           if (!isra_get_ref_base_and_offset (t, &base, &unit_offset))
    1560                 :      64949 :             continue;
    1561                 :            : 
    1562                 :      66059 :           bool by_ref = false;
    1563                 :      66059 :           if (TREE_CODE (base) == SSA_NAME)
    1564                 :            :             {
    1565                 :      37110 :               if (!SSA_NAME_IS_DEFAULT_DEF (base))
    1566                 :      31005 :                 continue;
    1567                 :       6105 :               base = SSA_NAME_VAR (base);
    1568                 :       6105 :               gcc_checking_assert (base);
    1569                 :            :               by_ref = true;
    1570                 :            :             }
    1571                 :      35054 :           if (TREE_CODE (base) != PARM_DECL)
    1572                 :      27960 :             continue;
    1573                 :            : 
    1574                 :       7094 :           bool base_among_replacements = false;
    1575                 :       7094 :           unsigned j, repl_list_len = m_replacements.length ();
    1576                 :      19230 :           for (j = 0; j < repl_list_len; j++)
    1577                 :            :             {
    1578                 :      13246 :               ipa_param_body_replacement *pbr = &m_replacements[j];
    1579                 :      13246 :               if (pbr->base == base)
    1580                 :            :                 {
    1581                 :            :                   base_among_replacements = true;
    1582                 :            :                   break;
    1583                 :            :                 }
    1584                 :            :             }
    1585                 :       7094 :           if (!base_among_replacements)
    1586                 :       5984 :             continue;
    1587                 :            : 
    1588                 :            :           /* We still have to distinguish between an end-use that we have to
    1589                 :            :              transform now and a pass-through, which happens in the following
    1590                 :            :              two cases.  */
    1591                 :            : 
    1592                 :            :           /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
    1593                 :            :              &MEM_REF[ssa_name + offset], we will also have to detect that case
    1594                 :            :              here.    */
    1595                 :            : 
    1596                 :       1110 :           if (TREE_CODE (t) == SSA_NAME
    1597                 :        236 :               && SSA_NAME_IS_DEFAULT_DEF (t)
    1598                 :        236 :               && SSA_NAME_VAR (t)
    1599                 :       1346 :               && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL)
    1600                 :            :             {
    1601                 :            :               /* This must be a by_reference pass-through.  */
    1602                 :        236 :               gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
    1603                 :        236 :               pass_through_args.safe_push (i);
    1604                 :        236 :               pass_through_pbr_indices.safe_push (j);
    1605                 :            :             }
    1606                 :       1710 :           else if (!by_ref && AGGREGATE_TYPE_P (TREE_TYPE (t)))
    1607                 :            :             {
    1608                 :            :               /* Currently IPA-SRA guarantees the aggregate access type
    1609                 :            :                  exactly matches in this case.  So if it does not match, it is
    1610                 :            :                  a pass-through argument that will be sorted out at edge
    1611                 :            :                  redirection time.  */
    1612                 :        836 :               ipa_param_body_replacement *pbr
    1613                 :        836 :                 = lookup_replacement_1 (base, unit_offset);
    1614                 :            : 
    1615                 :        836 :               if (!pbr
    1616                 :       1669 :                   || (TYPE_MAIN_VARIANT (TREE_TYPE (t))
    1617                 :        833 :                       != TYPE_MAIN_VARIANT (TREE_TYPE (pbr->repl))))
    1618                 :            :                 {
    1619                 :        821 :                   pass_through_args.safe_push (i);
    1620                 :        821 :                   pass_through_pbr_indices.safe_push (j);
    1621                 :            :                 }
    1622                 :            :             }
    1623                 :            :         }
    1624                 :            :     }
    1625                 :            : 
    1626                 :     200561 :   unsigned nargs = gimple_call_num_args (stmt);
    1627                 :     200561 :   if (!pass_through_args.is_empty ())
    1628                 :            :     {
    1629                 :       1874 :       auto_vec<tree, 16> vargs;
    1630                 :        937 :       unsigned pt_idx = 0;
    1631                 :       3298 :       for (unsigned i = 0; i < nargs; i++)
    1632                 :            :         {
    1633                 :       2361 :           if (pt_idx < pass_through_args.length ()
    1634                 :       2361 :               && i == pass_through_args[pt_idx])
    1635                 :            :             {
    1636                 :       1057 :               unsigned j = pass_through_pbr_indices[pt_idx];
    1637                 :       1057 :               pt_idx++;
    1638                 :       1057 :               tree base = m_replacements[j].base;
    1639                 :            : 
    1640                 :            :               /* Map base will get mapped to the special transitive-isra marker
    1641                 :            :                  dummy decl. */
    1642                 :       1057 :               struct simple_tree_swap_info swapinfo;
    1643                 :       1057 :               swapinfo.from = base;
    1644                 :       1057 :               swapinfo.to = m_replacements[j].dummy;
    1645                 :       1057 :               swapinfo.done = false;
    1646                 :       1057 :               tree arg = gimple_call_arg (stmt, i);
    1647                 :       1057 :               walk_tree (&arg, remap_split_decl_to_dummy, &swapinfo, NULL);
    1648                 :       1057 :               gcc_assert (swapinfo.done);
    1649                 :       1057 :               vargs.safe_push (arg);
    1650                 :            :               /* Now let's push all replacements pertaining to this parameter
    1651                 :            :                  so that all gimple register ones get correct SSA_NAMES.  Edge
    1652                 :            :                  redirection will weed out the dummy argument as well as all
    1653                 :            :                  unused replacements later.  */
    1654                 :       2114 :               unsigned int repl_list_len = m_replacements.length ();
    1655                 :       3296 :               for (; j < repl_list_len; j++)
    1656                 :            :                 {
    1657                 :       2505 :                   if (m_replacements[j].base != base)
    1658                 :            :                     break;
    1659                 :       2239 :                   vargs.safe_push (m_replacements[j].repl);
    1660                 :            :                 }
    1661                 :            :             }
    1662                 :            :           else
    1663                 :            :             {
    1664                 :       1304 :               tree t = gimple_call_arg (stmt, i);
    1665                 :       1304 :               modify_expression (&t, true);
    1666                 :       1304 :               vargs.safe_push (t);
    1667                 :            :             }
    1668                 :            :         }
    1669                 :        937 :       gcall *new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs);
    1670                 :        937 :       gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
    1671                 :        937 :       gimple_call_copy_flags (new_stmt, stmt);
    1672                 :        937 :       if (tree lhs = gimple_call_lhs (stmt))
    1673                 :            :         {
    1674                 :        849 :           modify_expression (&lhs, false);
    1675                 :        849 :           gimple_call_set_lhs (new_stmt, lhs);
    1676                 :            :         }
    1677                 :        937 :       *stmt_p = new_stmt;
    1678                 :        937 :       return true;
    1679                 :            :     }
    1680                 :            : 
    1681                 :            :   /* Otherwise, no need to rebuild the statement, let's just modify arguments
    1682                 :            :      and the LHS if/as appropriate.  */
    1683                 :            :   bool modified = false;
    1684                 :     599452 :   for (unsigned i = 0; i < nargs; i++)
    1685                 :            :     {
    1686                 :     399828 :       tree *t = gimple_call_arg_ptr (stmt, i);
    1687                 :     399828 :       modified |= modify_expression (t, true);
    1688                 :            :     }
    1689                 :            : 
    1690                 :     199624 :   if (gimple_call_lhs (stmt))
    1691                 :            :     {
    1692                 :      69348 :       tree *t = gimple_call_lhs_ptr (stmt);
    1693                 :      69348 :       modified |= modify_expression (t, false);
    1694                 :            :     }
    1695                 :            : 
    1696                 :            :   return modified;
    1697                 :            : }
    1698                 :            : 
    1699                 :            : /* If the statement STMT contains any expressions that need to replaced with a
    1700                 :            :    different one as noted by ADJUSTMENTS, do so.  Handle any potential type
    1701                 :            :    incompatibilities.  If any conversion sttements have to be pre-pended to
    1702                 :            :    STMT, they will be added to EXTRA_STMTS.  Return true iff the statement was
    1703                 :            :    modified.  */
    1704                 :            : 
    1705                 :            : bool
    1706                 :    1203040 : ipa_param_body_adjustments::modify_gimple_stmt (gimple **stmt,
    1707                 :            :                                                 gimple_seq *extra_stmts)
    1708                 :            : {
    1709                 :    1203040 :   bool modified = false;
    1710                 :    1203040 :   tree *t;
    1711                 :            : 
    1712                 :    1203040 :   switch (gimple_code (*stmt))
    1713                 :            :     {
    1714                 :      71237 :     case GIMPLE_RETURN:
    1715                 :      71237 :       t = gimple_return_retval_ptr (as_a <greturn *> (*stmt));
    1716                 :      71237 :       if (m_adjustments && m_adjustments->m_skip_return)
    1717                 :      16742 :         *t = NULL_TREE;
    1718                 :      54495 :       else if (*t != NULL_TREE)
    1719                 :      27197 :         modified |= modify_expression (t, true);
    1720                 :            :       break;
    1721                 :            : 
    1722                 :     742727 :     case GIMPLE_ASSIGN:
    1723                 :     742727 :       modified |= modify_assignment (*stmt, extra_stmts);
    1724                 :     742727 :       break;
    1725                 :            : 
    1726                 :     200561 :     case GIMPLE_CALL:
    1727                 :     200561 :       modified |= modify_call_stmt ((gcall **) stmt);
    1728                 :     200561 :       break;
    1729                 :            : 
    1730                 :       1311 :     case GIMPLE_ASM:
    1731                 :       1311 :       {
    1732                 :       1311 :         gasm *asm_stmt = as_a <gasm *> (*stmt);
    1733                 :       2499 :         for (unsigned i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
    1734                 :            :           {
    1735                 :       1188 :             t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
    1736                 :       1188 :             modified |= modify_expression (t, true);
    1737                 :            :           }
    1738                 :       2365 :         for (unsigned i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
    1739                 :            :           {
    1740                 :       1054 :             t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
    1741                 :       1054 :             modified |= modify_expression (t, false);
    1742                 :            :           }
    1743                 :            :       }
    1744                 :            :       break;
    1745                 :            : 
    1746                 :            :     default:
    1747                 :            :       break;
    1748                 :            :     }
    1749                 :    1203040 :   return modified;
    1750                 :            : }
    1751                 :            : 
    1752                 :            : 
    1753                 :            : /* Traverse body of the current function and perform the requested adjustments
    1754                 :            :    on its statements.  Return true iff the CFG has been changed.  */
    1755                 :            : 
    1756                 :            : bool
    1757                 :          0 : ipa_param_body_adjustments::modify_cfun_body ()
    1758                 :            : {
    1759                 :          0 :   bool cfg_changed = false;
    1760                 :          0 :   basic_block bb;
    1761                 :            : 
    1762                 :          0 :   FOR_EACH_BB_FN (bb, cfun)
    1763                 :            :     {
    1764                 :          0 :       gimple_stmt_iterator gsi;
    1765                 :            : 
    1766                 :          0 :       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1767                 :            :         {
    1768                 :          0 :           gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
    1769                 :          0 :           tree new_lhs, old_lhs = gimple_phi_result (phi);
    1770                 :          0 :           new_lhs = replace_removed_params_ssa_names (old_lhs, phi);
    1771                 :          0 :           if (new_lhs)
    1772                 :            :             {
    1773                 :          0 :               gimple_phi_set_result (phi, new_lhs);
    1774                 :          0 :               release_ssa_name (old_lhs);
    1775                 :            :             }
    1776                 :            :         }
    1777                 :            : 
    1778                 :          0 :       gsi = gsi_start_bb (bb);
    1779                 :          0 :       while (!gsi_end_p (gsi))
    1780                 :            :         {
    1781                 :          0 :           gimple *stmt = gsi_stmt (gsi);
    1782                 :          0 :           gimple *stmt_copy = stmt;
    1783                 :          0 :           gimple_seq extra_stmts = NULL;
    1784                 :          0 :           bool modified = modify_gimple_stmt (&stmt, &extra_stmts);
    1785                 :          0 :           if (stmt != stmt_copy)
    1786                 :            :             {
    1787                 :          0 :               gcc_checking_assert (modified);
    1788                 :          0 :               gsi_replace (&gsi, stmt, false);
    1789                 :            :             }
    1790                 :          0 :           if (!gimple_seq_empty_p (extra_stmts))
    1791                 :          0 :             gsi_insert_seq_before (&gsi, extra_stmts, GSI_SAME_STMT);
    1792                 :            : 
    1793                 :          0 :           def_operand_p defp;
    1794                 :          0 :           ssa_op_iter iter;
    1795                 :          0 :           FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
    1796                 :            :             {
    1797                 :          0 :               tree old_def = DEF_FROM_PTR (defp);
    1798                 :          0 :               if (tree new_def = replace_removed_params_ssa_names (old_def,
    1799                 :            :                                                                    stmt))
    1800                 :            :                 {
    1801                 :          0 :                   SET_DEF (defp, new_def);
    1802                 :          0 :                   release_ssa_name (old_def);
    1803                 :          0 :                   modified = true;
    1804                 :            :                 }
    1805                 :            :             }
    1806                 :            : 
    1807                 :          0 :           if (modified)
    1808                 :            :             {
    1809                 :          0 :               update_stmt (stmt);
    1810                 :          0 :               if (maybe_clean_eh_stmt (stmt)
    1811                 :          0 :                   && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
    1812                 :            :                 cfg_changed = true;
    1813                 :            :             }
    1814                 :          0 :           gsi_next (&gsi);
    1815                 :            :         }
    1816                 :            :     }
    1817                 :            : 
    1818                 :          0 :   return cfg_changed;
    1819                 :            : }
    1820                 :            : 
    1821                 :            : /* Call gimple_debug_bind_reset_value on all debug statements describing
    1822                 :            :    gimple register parameters that are being removed or replaced.  */
    1823                 :            : 
    1824                 :            : void
    1825                 :          0 : ipa_param_body_adjustments::reset_debug_stmts ()
    1826                 :            : {
    1827                 :          0 :   int i, len;
    1828                 :          0 :   gimple_stmt_iterator *gsip = NULL, gsi;
    1829                 :            : 
    1830                 :          0 :   if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    1831                 :            :     {
    1832                 :          0 :       gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
    1833                 :          0 :       gsip = &gsi;
    1834                 :            :     }
    1835                 :          0 :   len = m_reset_debug_decls.length ();
    1836                 :          0 :   for (i = 0; i < len; i++)
    1837                 :            :     {
    1838                 :          0 :       imm_use_iterator ui;
    1839                 :          0 :       gimple *stmt;
    1840                 :          0 :       gdebug *def_temp;
    1841                 :          0 :       tree name, vexpr, copy = NULL_TREE;
    1842                 :          0 :       use_operand_p use_p;
    1843                 :          0 :       tree decl = m_reset_debug_decls[i];
    1844                 :            : 
    1845                 :          0 :       gcc_checking_assert (is_gimple_reg (decl));
    1846                 :          0 :       name = ssa_default_def (cfun, decl);
    1847                 :          0 :       vexpr = NULL;
    1848                 :          0 :       if (name)
    1849                 :          0 :         FOR_EACH_IMM_USE_STMT (stmt, ui, name)
    1850                 :            :           {
    1851                 :          0 :             if (gimple_clobber_p (stmt))
    1852                 :            :               {
    1853                 :          0 :                 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
    1854                 :          0 :                 unlink_stmt_vdef (stmt);
    1855                 :          0 :                 gsi_remove (&cgsi, true);
    1856                 :          0 :                 release_defs (stmt);
    1857                 :          0 :                 continue;
    1858                 :            :               }
    1859                 :            :             /* All other users must have been removed by function body
    1860                 :            :                modification.  */
    1861                 :          0 :             gcc_assert (is_gimple_debug (stmt));
    1862                 :          0 :             if (vexpr == NULL && gsip != NULL)
    1863                 :            :               {
    1864                 :          0 :                 vexpr = make_node (DEBUG_EXPR_DECL);
    1865                 :          0 :                 def_temp = gimple_build_debug_source_bind (vexpr, decl, NULL);
    1866                 :          0 :                 DECL_ARTIFICIAL (vexpr) = 1;
    1867                 :          0 :                 TREE_TYPE (vexpr) = TREE_TYPE (name);
    1868                 :          0 :                 SET_DECL_MODE (vexpr, DECL_MODE (decl));
    1869                 :          0 :                 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
    1870                 :            :               }
    1871                 :          0 :             if (vexpr)
    1872                 :            :               {
    1873                 :          0 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
    1874                 :          0 :                   SET_USE (use_p, vexpr);
    1875                 :            :               }
    1876                 :            :             else
    1877                 :          0 :               gimple_debug_bind_reset_value (stmt);
    1878                 :          0 :             update_stmt (stmt);
    1879                 :            :           }
    1880                 :            :       /* Create a VAR_DECL for debug info purposes.  */
    1881                 :          0 :       if (!DECL_IGNORED_P (decl))
    1882                 :            :         {
    1883                 :          0 :           copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
    1884                 :          0 :                              VAR_DECL, DECL_NAME (decl),
    1885                 :          0 :                              TREE_TYPE (decl));
    1886                 :          0 :           if (DECL_PT_UID_SET_P (decl))
    1887                 :          0 :             SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
    1888                 :          0 :           TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
    1889                 :          0 :           TREE_READONLY (copy) = TREE_READONLY (decl);
    1890                 :          0 :           TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
    1891                 :          0 :           DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
    1892                 :          0 :           DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
    1893                 :          0 :           DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
    1894                 :          0 :           DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
    1895                 :          0 :           DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
    1896                 :          0 :           SET_DECL_RTL (copy, 0);
    1897                 :          0 :           TREE_USED (copy) = 1;
    1898                 :          0 :           DECL_CONTEXT (copy) = current_function_decl;
    1899                 :          0 :           add_local_decl (cfun, copy);
    1900                 :          0 :           DECL_CHAIN (copy)
    1901                 :          0 :             = BLOCK_VARS (DECL_INITIAL (current_function_decl));
    1902                 :          0 :           BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
    1903                 :            :         }
    1904                 :          0 :       if (gsip != NULL && copy && target_for_debug_bind (decl))
    1905                 :            :         {
    1906                 :          0 :           gcc_assert (TREE_CODE (decl) == PARM_DECL);
    1907                 :          0 :           if (vexpr)
    1908                 :          0 :             def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
    1909                 :            :           else
    1910                 :          0 :             def_temp = gimple_build_debug_source_bind (copy, decl,
    1911                 :            :                                                        NULL);
    1912                 :          0 :           gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
    1913                 :            :         }
    1914                 :            :     }
    1915                 :          0 : }
    1916                 :            : 
    1917                 :            : /* Perform all necessary body changes to change signature, body and debug info
    1918                 :            :    of fun according to adjustments passed at construction.  Return true if CFG
    1919                 :            :    was changed in any way.  The main entry point for modification of standalone
    1920                 :            :    functions that is not part of IPA clone materialization.  */
    1921                 :            : 
    1922                 :            : bool
    1923                 :          0 : ipa_param_body_adjustments::perform_cfun_body_modifications ()
    1924                 :            : {
    1925                 :          0 :   bool cfg_changed;
    1926                 :          0 :   modify_formal_parameters ();
    1927                 :          0 :   cfg_changed = modify_cfun_body ();
    1928                 :          0 :   reset_debug_stmts ();
    1929                 :            : 
    1930                 :          0 :   return cfg_changed;
    1931                 :            : }
    1932                 :            : 

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.