LCOV - code coverage report
Current view: top level - gcc - ipa-param-manipulation.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.8 % 1275 1069
Test Date: 2025-04-26 15:52:03 Functions: 91.7 % 60 55
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-2025 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                 :             : #define INCLUDE_ALGORITHM
      22                 :             : #include "config.h"
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "backend.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "gimple.h"
      28                 :             : #include "ssa.h"
      29                 :             : #include "cgraph.h"
      30                 :             : #include "fold-const.h"
      31                 :             : #include "tree-eh.h"
      32                 :             : #include "stor-layout.h"
      33                 :             : #include "gimplify.h"
      34                 :             : #include "gimple-iterator.h"
      35                 :             : #include "gimplify-me.h"
      36                 :             : #include "tree-cfg.h"
      37                 :             : #include "tree-dfa.h"
      38                 :             : #include "ipa-param-manipulation.h"
      39                 :             : #include "print-tree.h"
      40                 :             : #include "gimple-pretty-print.h"
      41                 :             : #include "builtins.h"
      42                 :             : #include "tree-ssa.h"
      43                 :             : #include "tree-inline.h"
      44                 :             : #include "alloc-pool.h"
      45                 :             : #include "symbol-summary.h"
      46                 :             : #include "symtab-clones.h"
      47                 :             : #include "tree-phinodes.h"
      48                 :             : #include "cfgexpand.h"
      49                 :             : #include "attribs.h"
      50                 :             : #include "sreal.h"
      51                 :             : #include "ipa-cp.h"
      52                 :             : #include "ipa-prop.h"
      53                 :             : 
      54                 :             : /* Actual prefixes of different newly synthetized parameters.  Keep in sync
      55                 :             :    with IPA_PARAM_PREFIX_* defines.  */
      56                 :             : 
      57                 :             : static const char *ipa_param_prefixes[IPA_PARAM_PREFIX_COUNT]
      58                 :             :   = {"SYNTH",
      59                 :             :      "ISRA",
      60                 :             :      "simd",
      61                 :             :      "mask"};
      62                 :             : 
      63                 :             : /* Names of parameters for dumping.  Keep in sync with enum ipa_parm_op.  */
      64                 :             : 
      65                 :             : static const char *ipa_param_op_names[IPA_PARAM_PREFIX_COUNT]
      66                 :             :   = {"IPA_PARAM_OP_UNDEFINED",
      67                 :             :      "IPA_PARAM_OP_COPY",
      68                 :             :      "IPA_PARAM_OP_NEW",
      69                 :             :      "IPA_PARAM_OP_SPLIT"};
      70                 :             : 
      71                 :             : /* Structure to hold declarations representing pass-through IPA-SRA splits.  In
      72                 :             :    essence, it tells new index for a combination of original index and
      73                 :             :    offset.  */
      74                 :             : 
      75                 :             : struct pass_through_split_map
      76                 :             : {
      77                 :             :   /* Original argument index.  */
      78                 :             :   unsigned base_index;
      79                 :             :   /* Offset of the split part in the original argument.  */
      80                 :             :   unsigned unit_offset;
      81                 :             :   /* Index of the split part in the call statement - where clone
      82                 :             :      materialization put it.  */
      83                 :             :   int new_index;
      84                 :             : };
      85                 :             : 
      86                 :             : /* Information about some call statements that needs to be conveyed from clone
      87                 :             :    materialization to edge redirection. */
      88                 :             : 
      89                 :       52954 : class ipa_edge_modification_info
      90                 :             : {
      91                 :             :  public:
      92                 :       52954 :   ipa_edge_modification_info ()
      93                 :       52954 :     {}
      94                 :             : 
      95                 :             :   /* Mapping of original argument indices to where those arguments sit in the
      96                 :             :      call statement now or to a negative index if they were removed.  */
      97                 :             :   auto_vec<int> index_map;
      98                 :             :   /* Information about ISRA replacements put into the call statement at the
      99                 :             :      clone materialization stages.  */
     100                 :             :   auto_vec<pass_through_split_map> pass_through_map;
     101                 :             :   /* Necessary adjustment to ipa_param_adjustments::m_always_copy_start when
     102                 :             :      redirecting the call.  */
     103                 :             :   int always_copy_delta = 0;
     104                 :             : };
     105                 :             : 
     106                 :             : /* Class for storing and retrieving summaries about cal statement
     107                 :             :    modifications.  */
     108                 :             : 
     109                 :             : class ipa_edge_modification_sum
     110                 :             :   : public call_summary <ipa_edge_modification_info *>
     111                 :             : {
     112                 :             :  public:
     113                 :        2312 :   ipa_edge_modification_sum (symbol_table *table)
     114                 :        4624 :     : call_summary<ipa_edge_modification_info *> (table)
     115                 :             :   {
     116                 :             :   }
     117                 :             : 
     118                 :             :   /* Hook that is called by summary when an edge is duplicated.  */
     119                 :             : 
     120                 :       24410 :   void duplicate (cgraph_edge *,
     121                 :             :                   cgraph_edge *,
     122                 :             :                   ipa_edge_modification_info *old_info,
     123                 :             :                   ipa_edge_modification_info *new_info) final override
     124                 :             :   {
     125                 :       24410 :     new_info->index_map.safe_splice (old_info->index_map);
     126                 :       24410 :     new_info->pass_through_map.safe_splice (old_info->pass_through_map);
     127                 :       24410 :     new_info->always_copy_delta = old_info->always_copy_delta;
     128                 :       24410 :   }
     129                 :             : };
     130                 :             : 
     131                 :             : /* Call summary to store information about edges which have had their arguments
     132                 :             :    partially modified already.  */
     133                 :             : 
     134                 :             : static ipa_edge_modification_sum *ipa_edge_modifications;
     135                 :             : 
     136                 :             : /* Fail compilation if CS has any summary associated with it in
     137                 :             :    ipa_edge_modifications.  */
     138                 :             : 
     139                 :             : DEBUG_FUNCTION void
     140                 :      286709 : ipa_verify_edge_has_no_modifications (cgraph_edge *cs)
     141                 :             : {
     142                 :      286709 :   gcc_assert (!ipa_edge_modifications || !ipa_edge_modifications->get (cs));
     143                 :      286709 : }
     144                 :             : 
     145                 :             : /* Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
     146                 :             :    FNDECL.  The function should not be called during LTO WPA phase except for
     147                 :             :    thunks (or functions with bodies streamed in). */
     148                 :             : 
     149                 :             : void
     150                 :      172347 : push_function_arg_decls (vec<tree> *args, tree fndecl)
     151                 :             : {
     152                 :      172347 :   int count;
     153                 :      172347 :   tree parm;
     154                 :             : 
     155                 :             :   /* Safety check that we do not attempt to use the function in WPA, except
     156                 :             :      when the function is a thunk and then we have DECL_ARGUMENTS or when we
     157                 :             :      have already explicitely loaded its body.  */
     158                 :      172348 :   gcc_assert (!flag_wpa
     159                 :             :               || DECL_ARGUMENTS (fndecl)
     160                 :             :               || gimple_has_body_p (fndecl));
     161                 :      172347 :   count = 0;
     162                 :      611315 :   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
     163                 :      438968 :     count++;
     164                 :             : 
     165                 :      172347 :   args->reserve_exact (count);
     166                 :      611315 :   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
     167                 :      438968 :     args->quick_push (parm);
     168                 :      172347 : }
     169                 :             : 
     170                 :             : /* Fill an empty vector TYPES with trees representing formal parameters of
     171                 :             :    function type FNTYPE.  */
     172                 :             : 
     173                 :             : void
     174                 :      391592 : push_function_arg_types (vec<tree> *types, tree fntype)
     175                 :             : {
     176                 :      391592 :   int count = 0;
     177                 :      391592 :   tree t;
     178                 :             : 
     179                 :     1790365 :   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
     180                 :     1398773 :     count++;
     181                 :             : 
     182                 :      391592 :   types->reserve_exact (count);
     183                 :     1790365 :   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
     184                 :     1398773 :     types->quick_push (TREE_VALUE (t));
     185                 :      391592 : }
     186                 :             : 
     187                 :             : /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
     188                 :             :    friendly way, assuming they are meant to be applied to FNDECL.  */
     189                 :             : 
     190                 :             : void
     191                 :           9 : ipa_dump_adjusted_parameters (FILE *f,
     192                 :             :                               vec<ipa_adjusted_param, va_gc> *adj_params)
     193                 :             : {
     194                 :           9 :   unsigned i, len = vec_safe_length (adj_params);
     195                 :          17 :   bool first = true;
     196                 :             : 
     197                 :           8 :   if (!len)
     198                 :             :     return;
     199                 :             : 
     200                 :           8 :   fprintf (f, "    IPA adjusted parameters: ");
     201                 :          29 :   for (i = 0; i < len; i++)
     202                 :             :     {
     203                 :          21 :       struct ipa_adjusted_param *apm;
     204                 :          21 :       apm = &(*adj_params)[i];
     205                 :             : 
     206                 :          21 :       if (!first)
     207                 :          13 :         fprintf (f, "                             ");
     208                 :             :       else
     209                 :             :         first = false;
     210                 :             : 
     211                 :          21 :       fprintf (f, "%i. %s %s", i, ipa_param_op_names[apm->op],
     212                 :          21 :                apm->prev_clone_adjustment ? "prev_clone_adjustment " : "");
     213                 :          21 :       switch (apm->op)
     214                 :             :         {
     215                 :             :         case IPA_PARAM_OP_UNDEFINED:
     216                 :             :           break;
     217                 :             : 
     218                 :           8 :         case IPA_PARAM_OP_COPY:
     219                 :           8 :           fprintf (f, ", base_index: %u", apm->base_index);
     220                 :           8 :           fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
     221                 :           8 :           break;
     222                 :             : 
     223                 :          13 :         case IPA_PARAM_OP_SPLIT:
     224                 :          13 :           fprintf (f, ", offset: %u", apm->unit_offset);
     225                 :             :           /* fall-through */
     226                 :          13 :         case IPA_PARAM_OP_NEW:
     227                 :          13 :           fprintf (f, ", base_index: %u", apm->base_index);
     228                 :          13 :           fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
     229                 :          13 :           print_node_brief (f, ", type: ", apm->type, 0);
     230                 :          13 :           print_node_brief (f, ", alias type: ", apm->alias_ptr_type, 0);
     231                 :          13 :           fprintf (f, " prefix: %s",
     232                 :          13 :                    ipa_param_prefixes[apm->param_prefix_index]);
     233                 :          13 :           if (apm->reverse)
     234                 :           0 :             fprintf (f, ", reverse");
     235                 :             :           break;
     236                 :             :         }
     237                 :          21 :       fprintf (f, "\n");
     238                 :             :     }
     239                 :             : }
     240                 :             : 
     241                 :             : /* Fill NEW_TYPES with types of a function after its current OTYPES have been
     242                 :             :    modified as described in ADJ_PARAMS.  When USE_PREV_INDICES is true, use
     243                 :             :    prev_clone_index from ADJ_PARAMS as opposed to base_index when the parameter
     244                 :             :    is false.  */
     245                 :             : 
     246                 :             : static void
     247                 :      387128 : fill_vector_of_new_param_types (vec<tree> *new_types, vec<tree> *otypes,
     248                 :             :                                 vec<ipa_adjusted_param, va_gc> *adj_params,
     249                 :             :                                 bool use_prev_indices)
     250                 :             : {
     251                 :      387128 :   unsigned adj_len = vec_safe_length (adj_params);
     252                 :      387128 :   new_types->reserve_exact (adj_len);
     253                 :     1193378 :   for (unsigned i = 0; i < adj_len ; i++)
     254                 :             :     {
     255                 :      806250 :       ipa_adjusted_param *apm = &(*adj_params)[i];
     256                 :      806250 :       if (apm->op == IPA_PARAM_OP_COPY)
     257                 :             :         {
     258                 :     1158084 :           unsigned index
     259                 :      579042 :             = use_prev_indices ? apm->prev_clone_index : apm->base_index;
     260                 :             :           /* The following needs to be handled gracefully because of type
     261                 :             :              mismatches.  This happens with LTO but apparently also in Fortran
     262                 :             :              with -fcoarray=lib -O2 -lcaf_single -latomic.  */
     263                 :      579042 :           if (index >= otypes->length ())
     264                 :           0 :             continue;
     265                 :      579042 :           new_types->quick_push ((*otypes)[index]);
     266                 :             :         }
     267                 :      227208 :       else if (apm->op == IPA_PARAM_OP_NEW
     268                 :      227208 :                || apm->op == IPA_PARAM_OP_SPLIT)
     269                 :             :         {
     270                 :      227208 :           tree ntype = apm->type;
     271                 :      227208 :           if (is_gimple_reg_type (ntype)
     272                 :      227208 :               && TYPE_MODE (ntype) != BLKmode)
     273                 :             :             {
     274                 :      225544 :               unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ntype));
     275                 :      225544 :               if (TYPE_ALIGN (ntype) != malign)
     276                 :        2685 :                 ntype = build_aligned_type (ntype, malign);
     277                 :             :             }
     278                 :      227208 :           new_types->quick_push (ntype);
     279                 :             :         }
     280                 :             :       else
     281                 :           0 :         gcc_unreachable ();
     282                 :             :     }
     283                 :      387128 : }
     284                 :             : 
     285                 :             : /* Return false if given attribute should prevent type adjustments.  */
     286                 :             : 
     287                 :             : bool
     288                 :      377779 : ipa_param_adjustments::type_attribute_allowed_p (tree name)
     289                 :             : {
     290                 :      609357 :   if ((is_attribute_p ("fn spec", name) && flag_ipa_modref)
     291                 :      171074 :       || is_attribute_p ("access", name)
     292                 :      157878 :       || is_attribute_p ("returns_nonnull", name)
     293                 :      156560 :       || is_attribute_p ("assume_aligned", name)
     294                 :      156560 :       || is_attribute_p ("nocf_check", name)
     295                 :      534314 :       || is_attribute_p ("warn_unused_result", name))
     296                 :             :     return true;
     297                 :             :   return false;
     298                 :             : }
     299                 :             : 
     300                 :             : /* Return true if attribute should be dropped if parameter changed.  */
     301                 :             : 
     302                 :             : static bool
     303                 :        4479 : drop_type_attribute_if_params_changed_p (tree name)
     304                 :             : {
     305                 :        4479 :   if (is_attribute_p ("fn spec", name)
     306                 :        4479 :       || is_attribute_p ("access", name))
     307                 :             :     return true;
     308                 :             :   return false;
     309                 :             : }
     310                 :             : 
     311                 :             : /* Build and return a function type just like ORIG_TYPE but with parameter
     312                 :             :    types given in NEW_PARAM_TYPES - which can be NULL if, but only if,
     313                 :             :    ORIG_TYPE itself has NULL TREE_ARG_TYPEs.  If METHOD2FUNC is true, also make
     314                 :             :    it a FUNCTION_TYPE instead of FUNCTION_TYPE.
     315                 :             :    If ARG_MODIFIED is true drop attributes that are no longer up to date.  */
     316                 :             : 
     317                 :             : static tree
     318                 :      244163 : build_adjusted_function_type (tree orig_type, vec<tree> *new_param_types,
     319                 :             :                               bool method2func, bool skip_return,
     320                 :             :                               bool args_modified)
     321                 :             : {
     322                 :      244163 :   tree new_arg_types = NULL;
     323                 :      244163 :   if (TYPE_ARG_TYPES (orig_type))
     324                 :             :     {
     325                 :      244037 :       gcc_checking_assert (new_param_types);
     326                 :      244037 :       bool last_parm_void = (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type)))
     327                 :      244037 :                              == void_type_node);
     328                 :      244037 :       unsigned len = new_param_types->length ();
     329                 :      755942 :       for (unsigned i = 0; i < len; i++)
     330                 :      511905 :         new_arg_types = tree_cons (NULL_TREE, (*new_param_types)[i],
     331                 :             :                                    new_arg_types);
     332                 :             : 
     333                 :      244037 :       tree new_reversed = nreverse (new_arg_types);
     334                 :      244037 :       if (last_parm_void)
     335                 :             :         {
     336                 :      244028 :           if (new_reversed)
     337                 :      220980 :             TREE_CHAIN (new_arg_types) = void_list_node;
     338                 :             :           else
     339                 :       23048 :             new_reversed = void_list_node;
     340                 :             :         }
     341                 :             :       new_arg_types = new_reversed;
     342                 :             :     }
     343                 :             : 
     344                 :             :   /* Use build_distinct_type_copy to preserve as much as possible from original
     345                 :             :      type (debug info, attribute lists etc.).  The one exception is
     346                 :             :      METHOD_TYPEs which must have THIS argument and when we are asked to remove
     347                 :             :      it, we need to build new FUNCTION_TYPE instead.  */
     348                 :      244163 :   tree new_type = NULL;
     349                 :      244163 :   if (method2func)
     350                 :             :     {
     351                 :       94690 :       tree ret_type;
     352                 :       94690 :       if (skip_return)
     353                 :       12821 :         ret_type = void_type_node;
     354                 :             :       else
     355                 :       81869 :         ret_type = TREE_TYPE (orig_type);
     356                 :             : 
     357                 :       94690 :       new_type
     358                 :       94690 :         = build_distinct_type_copy (build_function_type (ret_type,
     359                 :             :                                                          new_arg_types));
     360                 :       94690 :       TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
     361                 :             :     }
     362                 :             :   else
     363                 :             :     {
     364                 :      149473 :       new_type = build_distinct_type_copy (orig_type);
     365                 :      149473 :       TYPE_ARG_TYPES (new_type) = new_arg_types;
     366                 :      149473 :       if (skip_return)
     367                 :       57646 :         TREE_TYPE (new_type) = void_type_node;
     368                 :             :     }
     369                 :      244163 :   if (args_modified && TYPE_ATTRIBUTES (new_type))
     370                 :             :     {
     371                 :        4479 :       tree t = TYPE_ATTRIBUTES (new_type);
     372                 :        4479 :       tree *last = &TYPE_ATTRIBUTES (new_type);
     373                 :        4479 :       TYPE_ATTRIBUTES (new_type) = NULL;
     374                 :        8958 :       for (;t; t = TREE_CHAIN (t))
     375                 :        4479 :         if (!drop_type_attribute_if_params_changed_p
     376                 :        4479 :                 (get_attribute_name (t)))
     377                 :             :           {
     378                 :          12 :             *last = copy_node (t);
     379                 :          12 :             TREE_CHAIN (*last) = NULL;
     380                 :          12 :             last = &TREE_CHAIN (*last);
     381                 :             :           }
     382                 :             :     }
     383                 :             : 
     384                 :      244163 :   return new_type;
     385                 :             : }
     386                 :             : 
     387                 :             : /* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
     388                 :             :    is none.  */
     389                 :             : 
     390                 :             : int
     391                 :       40466 : ipa_param_adjustments::get_max_base_index ()
     392                 :             : {
     393                 :       40466 :   unsigned adj_len = vec_safe_length (m_adj_params);
     394                 :       40466 :   int max_index = -1;
     395                 :       94667 :   for (unsigned i = 0; i < adj_len ; i++)
     396                 :             :     {
     397                 :       54201 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     398                 :       54201 :       if (apm->op == IPA_PARAM_OP_COPY
     399                 :       48831 :           && max_index < apm->base_index)
     400                 :       54201 :         max_index = apm->base_index;
     401                 :             :     }
     402                 :       40466 :   return max_index;
     403                 :             : }
     404                 :             : 
     405                 :             : 
     406                 :             : /* Fill SURVIVING_PARAMS with an array of bools where each one says whether a
     407                 :             :    parameter that originally was at that position still survives in the given
     408                 :             :    clone or is removed/replaced.  If the final array is smaller than an index
     409                 :             :    of an original parameter, that parameter also did not survive.  That a
     410                 :             :    parameter survives does not mean it has the same index as before.  */
     411                 :             : 
     412                 :             : void
     413                 :       25898 : ipa_param_adjustments::get_surviving_params (vec<bool> *surviving_params)
     414                 :             : {
     415                 :       25898 :   unsigned adj_len = vec_safe_length (m_adj_params);
     416                 :       25898 :   int max_index = get_max_base_index ();
     417                 :             : 
     418                 :       25898 :   if (max_index < 0)
     419                 :             :     return;
     420                 :       14962 :   surviving_params->reserve_exact (max_index + 1);
     421                 :       14962 :   surviving_params->quick_grow_cleared (max_index + 1);
     422                 :       42382 :   for (unsigned i = 0; i < adj_len ; i++)
     423                 :             :     {
     424                 :       27420 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     425                 :       27420 :       if (apm->op == IPA_PARAM_OP_COPY)
     426                 :       27420 :         (*surviving_params)[apm->base_index] = true;
     427                 :             :     }
     428                 :             : }
     429                 :             : 
     430                 :             : /* Fill NEW_INDICES with new indices of each surviving parameter or -1 for
     431                 :             :    those which do not survive.  Any parameter outside of lenght of the vector
     432                 :             :    does not survive.  There is currently no support for a parameter to be
     433                 :             :    copied to two distinct new parameters.  */
     434                 :             : 
     435                 :             : void
     436                 :       14568 : ipa_param_adjustments::get_updated_indices (vec<int> *new_indices)
     437                 :             : {
     438                 :       14568 :   unsigned adj_len = vec_safe_length (m_adj_params);
     439                 :       14568 :   int max_index = get_max_base_index ();
     440                 :             : 
     441                 :       14568 :   if (max_index < 0)
     442                 :             :     return;
     443                 :       10984 :   unsigned res_len = max_index + 1;
     444                 :       10984 :   new_indices->reserve_exact (res_len);
     445                 :       38510 :   for (unsigned i = 0; i < res_len ; i++)
     446                 :       27526 :     new_indices->quick_push (-1);
     447                 :       35715 :   for (unsigned i = 0; i < adj_len ; i++)
     448                 :             :     {
     449                 :       24731 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     450                 :       24731 :       if (apm->op == IPA_PARAM_OP_COPY)
     451                 :       21411 :         (*new_indices)[apm->base_index] = i;
     452                 :             :     }
     453                 :             : }
     454                 :             : 
     455                 :             : /* Return the original index for the given new parameter index.  Return a
     456                 :             :    negative number if not available.  */
     457                 :             : 
     458                 :             : int
     459                 :      595126 : ipa_param_adjustments::get_original_index (int newidx)
     460                 :             : {
     461                 :      595126 :   const ipa_adjusted_param *adj = &(*m_adj_params)[newidx];
     462                 :      595126 :   if (adj->op != IPA_PARAM_OP_COPY)
     463                 :             :     return -1;
     464                 :      461486 :   return adj->base_index;
     465                 :             : }
     466                 :             : 
     467                 :             : /* Return true if the first parameter (assuming there was one) survives the
     468                 :             :    transformation intact and remains the first one.  */
     469                 :             : 
     470                 :             : bool
     471                 :      252678 : ipa_param_adjustments::first_param_intact_p ()
     472                 :             : {
     473                 :      252678 :   return (!vec_safe_is_empty (m_adj_params)
     474                 :      235499 :           && (*m_adj_params)[0].op == IPA_PARAM_OP_COPY
     475                 :      163178 :           && (*m_adj_params)[0].base_index == 0);
     476                 :             : }
     477                 :             : 
     478                 :             : /* Return true if we have to change what has formerly been a method into a
     479                 :             :    function.  */
     480                 :             : 
     481                 :             : bool
     482                 :      383579 : ipa_param_adjustments::method2func_p (tree orig_type)
     483                 :             : {
     484                 :      383579 :   return ((TREE_CODE (orig_type) == METHOD_TYPE) && !first_param_intact_p ());
     485                 :             : }
     486                 :             : 
     487                 :             : /* Given function type OLD_TYPE, return a new type derived from it after
     488                 :             :    performing all atored modifications.  TYPE_ORIGINAL_P should be true when
     489                 :             :    OLD_TYPE refers to the type before any IPA transformations, as opposed to a
     490                 :             :    type that can be an intermediate one in between various IPA
     491                 :             :    transformations.  */
     492                 :             : 
     493                 :             : tree
     494                 :      239703 : ipa_param_adjustments::build_new_function_type (tree old_type,
     495                 :             :                                                 bool type_original_p)
     496                 :             : {
     497                 :      239703 :   auto_vec<tree,16> new_param_types, *new_param_types_p;
     498                 :      239703 :   if (prototype_p (old_type))
     499                 :             :     {
     500                 :      239641 :       auto_vec<tree, 16> otypes;
     501                 :      239641 :       push_function_arg_types (&otypes, old_type);
     502                 :      239641 :       fill_vector_of_new_param_types (&new_param_types, &otypes, m_adj_params,
     503                 :      239641 :                                       !type_original_p);
     504                 :      239641 :       new_param_types_p = &new_param_types;
     505                 :      239641 :     }
     506                 :             :   else
     507                 :             :     new_param_types_p = NULL;
     508                 :             : 
     509                 :             :   /* Check if any params type cares about are modified.  In this case will
     510                 :             :      need to drop some type attributes.  */
     511                 :      239703 :   bool modified = false;
     512                 :      239703 :   size_t index = 0;
     513                 :      239703 :   if (m_adj_params)
     514                 :      216954 :     for (tree t = TYPE_ARG_TYPES (old_type);
     515                 :      646254 :          t && (int)index < m_always_copy_start && !modified;
     516                 :      429300 :          t = TREE_CHAIN (t), index++)
     517                 :      429300 :       if (index >= m_adj_params->length ()
     518                 :      429300 :           || get_original_index (index) != (int)index)
     519                 :             :         modified = true;
     520                 :             : 
     521                 :             : 
     522                 :      239703 :   return build_adjusted_function_type (old_type, new_param_types_p,
     523                 :      239703 :                                        method2func_p (old_type), m_skip_return,
     524                 :      239703 :                                        modified);
     525                 :      239703 : }
     526                 :             : 
     527                 :             : /* Build variant of function decl ORIG_DECL which has no return value if
     528                 :             :    M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
     529                 :             :    this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
     530                 :             :    DECL_ARGUMENTS list are not processed now, since they are linked by
     531                 :             :    TREE_CHAIN directly and not accessible in LTO during WPA.  The caller is
     532                 :             :    responsible for eliminating them when clones are properly materialized.  */
     533                 :             : 
     534                 :             : tree
     535                 :      143876 : ipa_param_adjustments::adjust_decl (tree orig_decl)
     536                 :             : {
     537                 :      143876 :   tree new_decl = copy_node (orig_decl);
     538                 :      143876 :   tree orig_type = TREE_TYPE (orig_decl);
     539                 :      143876 :   if (prototype_p (orig_type)
     540                 :      143876 :       || (m_skip_return && !VOID_TYPE_P (TREE_TYPE (orig_type))))
     541                 :             :     {
     542                 :      143816 :       tree new_type = build_new_function_type (orig_type, false);
     543                 :      143816 :       TREE_TYPE (new_decl) = new_type;
     544                 :             :     }
     545                 :      143876 :   if (method2func_p (orig_type))
     546                 :       45966 :     DECL_VINDEX (new_decl) = NULL_TREE;
     547                 :             : 
     548                 :             :   /* When signature changes, we need to clear builtin info.  */
     549                 :      143876 :   if (fndecl_built_in_p (new_decl))
     550                 :          97 :     set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);
     551                 :             : 
     552                 :      143876 :   DECL_VIRTUAL_P (new_decl) = 0;
     553                 :      143876 :   DECL_LANG_SPECIFIC (new_decl) = NULL;
     554                 :             : 
     555                 :             :   /* Drop MALLOC attribute for a void function.  */
     556                 :      143876 :   if (m_skip_return)
     557                 :       44877 :     DECL_IS_MALLOC (new_decl) = 0;
     558                 :             : 
     559                 :      143876 :   return new_decl;
     560                 :             : }
     561                 :             : 
     562                 :             : /* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
     563                 :             :    transformations.  Return true if EXPR has an interesting form and fill in
     564                 :             :    *BASE_P and *UNIT_OFFSET_P with the appropriate info.  */
     565                 :             : 
     566                 :             : static bool
     567                 :     1188728 : isra_get_ref_base_and_offset (tree expr, tree *base_p, unsigned *unit_offset_p)
     568                 :             : {
     569                 :     1188728 :   HOST_WIDE_INT offset, size;
     570                 :     1188728 :   bool reverse;
     571                 :     1188728 :   tree base
     572                 :     1188728 :     = get_ref_base_and_extent_hwi (expr, &offset, &size, &reverse);
     573                 :     1188728 :   if (!base || size < 0)
     574                 :             :     return false;
     575                 :             : 
     576                 :     1183934 :   if ((offset % BITS_PER_UNIT) != 0)
     577                 :             :     return false;
     578                 :             : 
     579                 :     1183201 :   if (TREE_CODE (base) == MEM_REF)
     580                 :             :     {
     581                 :      181892 :       poly_int64 plmoff = mem_ref_offset (base).force_shwi ();
     582                 :      181892 :       HOST_WIDE_INT moff;
     583                 :      181892 :       bool is_cst = plmoff.is_constant (&moff);
     584                 :      181892 :       if (!is_cst)
     585                 :             :         return false;
     586                 :      181892 :       offset += moff * BITS_PER_UNIT;
     587                 :      181892 :       base = TREE_OPERAND (base, 0);
     588                 :             :     }
     589                 :             : 
     590                 :     1183201 :   if (offset < 0 || (offset / BITS_PER_UNIT) > UINT_MAX)
     591                 :             :     return false;
     592                 :             : 
     593                 :     1183023 :   *base_p = base;
     594                 :     1183023 :   *unit_offset_p = offset / BITS_PER_UNIT;
     595                 :     1183023 :   return true;
     596                 :             : }
     597                 :             : 
     598                 :             : /* Remove all statements that use NAME directly or indirectly.  KILLED_SSAS
     599                 :             :    contains the SSA_NAMEs that are already being or have been processed and new
     600                 :             :    ones need to be added to it.  The function only has to process situations
     601                 :             :    handled by ssa_name_only_returned_p in ipa-sra.cc with the exception that it
     602                 :             :    can assume it must never reach a use in a return statement.  */
     603                 :             : 
     604                 :             : static void
     605                 :       11880 : purge_all_uses (tree name, hash_set <tree> *killed_ssas)
     606                 :             : {
     607                 :       11880 :   imm_use_iterator imm_iter;
     608                 :       11880 :   gimple *stmt;
     609                 :       11880 :   auto_vec <tree, 4> worklist;
     610                 :             : 
     611                 :       11880 :   worklist.safe_push (name);
     612                 :       50265 :   while (!worklist.is_empty ())
     613                 :             :     {
     614                 :       14625 :       tree cur_name = worklist.pop ();
     615                 :       32055 :       FOR_EACH_IMM_USE_STMT (stmt, imm_iter, cur_name)
     616                 :             :         {
     617                 :        2805 :           if (gimple_debug_bind_p (stmt))
     618                 :             :             {
     619                 :             :               /* When runing within tree-inline, we will never end up here but
     620                 :             :                  adding the SSAs to killed_ssas will do the trick in this case
     621                 :             :                  and the respective debug statements will get reset. */
     622                 :          60 :               gimple_debug_bind_reset_value (stmt);
     623                 :          60 :               update_stmt (stmt);
     624                 :          60 :               continue;
     625                 :             :             }
     626                 :             : 
     627                 :        2745 :           tree lhs = NULL_TREE;
     628                 :        2745 :           if (is_gimple_assign (stmt))
     629                 :         741 :             lhs = gimple_assign_lhs (stmt);
     630                 :        2004 :           else if (gimple_code (stmt) == GIMPLE_PHI)
     631                 :        2004 :             lhs = gimple_phi_result (stmt);
     632                 :        3486 :           gcc_assert (lhs
     633                 :             :                       && (TREE_CODE (lhs) == SSA_NAME)
     634                 :             :                       && !gimple_vdef (stmt));
     635                 :        2745 :           if (!killed_ssas->add (lhs))
     636                 :             :             {
     637                 :        2745 :               worklist.safe_push (lhs);
     638                 :        2745 :               gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
     639                 :        2745 :               gsi_remove (&gsi, true);
     640                 :             :             }
     641                 :       14625 :         }
     642                 :             :     }
     643                 :       11880 : }
     644                 :             : 
     645                 :             : /* Modify actual arguments of a function call in statement currently belonging
     646                 :             :    to CS, and make it call CS->callee->decl.  Return the new statement that
     647                 :             :    replaced the old one.  When invoked, cfun and current_function_decl have to
     648                 :             :    be set to the caller.  When called from within tree-inline, KILLED_SSAs has
     649                 :             :    to contain the pointer to killed_new_ssa_names within the copy_body_data
     650                 :             :    structure and SSAs discovered to be useless (if LHS is removed) will be
     651                 :             :    added to it, otherwise it needs to be NULL.  */
     652                 :             : 
     653                 :             : gcall *
     654                 :      438410 : ipa_param_adjustments::modify_call (cgraph_edge *cs,
     655                 :             :                                     bool update_references,
     656                 :             :                                     hash_set <tree> *killed_ssas)
     657                 :             : {
     658                 :      438410 :   gcall *stmt = cs->call_stmt;
     659                 :      438410 :   tree callee_decl = cs->callee->decl;
     660                 :             : 
     661                 :     1121433 :   ipa_edge_modification_info *mod_info
     662                 :      438410 :     = ipa_edge_modifications ? ipa_edge_modifications->get (cs) : NULL;
     663                 :      244613 :   if (mod_info && symtab->dump_file)
     664                 :             :     {
     665                 :           0 :       fprintf (symtab->dump_file, "Information about pre-exiting "
     666                 :             :                "modifications.\n  Index map:");
     667                 :           0 :       unsigned idx_len = mod_info->index_map.length ();
     668                 :           0 :       for (unsigned i = 0; i < idx_len; i++)
     669                 :           0 :         fprintf (symtab->dump_file, " %i", mod_info->index_map[i]);
     670                 :           0 :       fprintf (symtab->dump_file, "\n  Pass-through split map: ");
     671                 :           0 :       unsigned ptm_len = mod_info->pass_through_map.length ();
     672                 :           0 :       for (unsigned i = 0; i < ptm_len; i++)
     673                 :           0 :         fprintf (symtab->dump_file,
     674                 :             :                  " (base_index: %u, offset: %u, new_index: %i)",
     675                 :           0 :                  mod_info->pass_through_map[i].base_index,
     676                 :           0 :                  mod_info->pass_through_map[i].unit_offset,
     677                 :           0 :                  mod_info->pass_through_map[i].new_index);
     678                 :           0 :       fprintf (symtab->dump_file, "\n  Always-copy delta: %i\n",
     679                 :             :                mod_info->always_copy_delta);
     680                 :             :     }
     681                 :             : 
     682                 :      438410 :   unsigned len = vec_safe_length (m_adj_params);
     683                 :      438410 :   auto_vec<tree, 16> vargs (len);
     684                 :      438410 :   unsigned old_nargs = gimple_call_num_args (stmt);
     685                 :      438410 :   unsigned orig_nargs = mod_info ? mod_info->index_map.length () : old_nargs;
     686                 :      438410 :   auto_vec<bool, 16> kept (old_nargs);
     687                 :      438410 :   kept.quick_grow_cleared (old_nargs);
     688                 :             : 
     689                 :      438410 :   cgraph_node *current_node = cgraph_node::get (current_function_decl);
     690                 :      438410 :   if (update_references)
     691                 :           0 :     current_node->remove_stmt_references (stmt);
     692                 :             : 
     693                 :      438410 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
     694                 :      438410 :   gimple_stmt_iterator prev_gsi = gsi;
     695                 :      438410 :   gsi_prev (&prev_gsi);
     696                 :     1427768 :   for (unsigned i = 0; i < len; i++)
     697                 :             :     {
     698                 :      989358 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
     699                 :      989358 :       if (apm->op == IPA_PARAM_OP_COPY)
     700                 :             :         {
     701                 :      682679 :           int index = apm->base_index;
     702                 :      682679 :           if ((unsigned) index >= orig_nargs)
     703                 :             :             /* Can happen if the original call has argument mismatch,
     704                 :             :                ignore.  */
     705                 :           0 :             continue;
     706                 :      682679 :           if (mod_info)
     707                 :             :             {
     708                 :       36372 :               index = mod_info->index_map[apm->base_index];
     709                 :       36372 :               gcc_assert (index >= 0);
     710                 :             :             }
     711                 :             : 
     712                 :      682679 :           tree arg = gimple_call_arg (stmt, index);
     713                 :             : 
     714                 :      682679 :           vargs.quick_push (arg);
     715                 :      682679 :           kept[index] = true;
     716                 :      682679 :           continue;
     717                 :      682679 :         }
     718                 :             : 
     719                 :             :       /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
     720                 :             :          If we ever want to support it during WPA IPA stage, we'll need a
     721                 :             :          mechanism to call into the IPA passes that introduced them.  Currently
     722                 :             :          we simply mandate that IPA infrastructure understands all argument
     723                 :             :          modifications.  Remember, edge redirection/modification is done only
     724                 :             :          once, not in steps for each pass modifying the callee like clone
     725                 :             :          materialization.  */
     726                 :      306679 :       gcc_assert (apm->op == IPA_PARAM_OP_SPLIT);
     727                 :             : 
     728                 :             :       /* We have to handle pass-through changes differently using the map
     729                 :             :          clone materialziation might have left behind.  */
     730                 :      306679 :       tree repl = NULL_TREE;
     731                 :      306679 :       unsigned ptm_len = mod_info ? mod_info->pass_through_map.length () : 0;
     732                 :      330030 :       for (unsigned j = 0; j < ptm_len; j++)
     733                 :       41945 :         if (mod_info->pass_through_map[j].base_index == apm->base_index
     734                 :       41945 :             && mod_info->pass_through_map[j].unit_offset == apm->unit_offset)
     735                 :             :           {
     736                 :       18594 :             int repl_idx = mod_info->pass_through_map[j].new_index;
     737                 :       18594 :             gcc_assert (repl_idx >= 0);
     738                 :       18594 :             repl = gimple_call_arg (stmt, repl_idx);
     739                 :       18594 :             break;
     740                 :             :           }
     741                 :      306679 :       if (repl)
     742                 :             :         {
     743                 :       18594 :           if (!useless_type_conversion_p(apm->type, repl->typed.type))
     744                 :             :             {
     745                 :           0 :               repl = force_value_to_type (apm->type, repl);
     746                 :           0 :               repl = force_gimple_operand_gsi (&gsi, repl,
     747                 :             :                                                true, NULL, true, GSI_SAME_STMT);
     748                 :             :             }
     749                 :       18594 :           vargs.quick_push (repl);
     750                 :       18594 :           continue;
     751                 :             :         }
     752                 :             : 
     753                 :      288085 :       int index = apm->base_index;
     754                 :      288085 :       if ((unsigned) index >= orig_nargs)
     755                 :             :         /* Can happen if the original call has argument mismatch, ignore.  */
     756                 :           1 :         continue;
     757                 :      288084 :       if (mod_info)
     758                 :             :         {
     759                 :        4310 :           index = mod_info->index_map[apm->base_index];
     760                 :        4310 :           gcc_assert (index >= 0);
     761                 :             :         }
     762                 :      288084 :       tree base = gimple_call_arg (stmt, index);
     763                 :             : 
     764                 :             :       /* We create a new parameter out of the value of the old one, we can
     765                 :             :          do the following kind of transformations:
     766                 :             : 
     767                 :             :          - A scalar passed by reference, potentially as a part of a larger
     768                 :             :          aggregate, is converted to a scalar passed by value.
     769                 :             : 
     770                 :             :          - A part of an aggregate is passed instead of the whole aggregate.  */
     771                 :             : 
     772                 :      288084 :       location_t loc = gimple_location (stmt);
     773                 :      288084 :       tree off;
     774                 :      288084 :       bool deref_base = false;
     775                 :      288084 :       unsigned int deref_align = 0;
     776                 :      288084 :       if (TREE_CODE (base) != ADDR_EXPR
     777                 :      288084 :           && is_gimple_reg_type (TREE_TYPE (base)))
     778                 :             :         {
     779                 :             :           /* Detect type mismatches in calls in invalid programs and make a
     780                 :             :              poor attempt to gracefully convert them so that we don't ICE.  */
     781                 :       78732 :           if (!POINTER_TYPE_P (TREE_TYPE (base)))
     782                 :          11 :             base = force_value_to_type (ptr_type_node, base);
     783                 :             : 
     784                 :       78732 :           off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
     785                 :             :         }
     786                 :             :       else
     787                 :             :         {
     788                 :      209352 :           bool addrof;
     789                 :      209352 :           if (TREE_CODE (base) == ADDR_EXPR)
     790                 :             :             {
     791                 :      170810 :               base = TREE_OPERAND (base, 0);
     792                 :      170810 :               addrof = true;
     793                 :             :             }
     794                 :             :           else
     795                 :             :             addrof = false;
     796                 :             : 
     797                 :      209352 :           tree prev_base = base;
     798                 :      209352 :           poly_int64 base_offset;
     799                 :      209352 :           base = get_addr_base_and_unit_offset (base, &base_offset);
     800                 :             : 
     801                 :             :           /* Aggregate arguments can have non-invariant addresses.  */
     802                 :      209352 :           if (!base)
     803                 :             :             {
     804                 :           0 :               base = build_fold_addr_expr (prev_base);
     805                 :           0 :               off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
     806                 :             :             }
     807                 :      209352 :           else if (TREE_CODE (base) == MEM_REF)
     808                 :             :             {
     809                 :        4856 :               if (!addrof)
     810                 :             :                 {
     811                 :        4856 :                   deref_base = true;
     812                 :        4856 :                   deref_align = TYPE_ALIGN (TREE_TYPE (base));
     813                 :             :                 }
     814                 :        9712 :               off = build_int_cst (apm->alias_ptr_type,
     815                 :        4856 :                                    base_offset + apm->unit_offset);
     816                 :        4856 :               off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
     817                 :             :                                      off);
     818                 :        4856 :               base = TREE_OPERAND (base, 0);
     819                 :             :             }
     820                 :             :           else
     821                 :             :             {
     822                 :      408992 :               off = build_int_cst (apm->alias_ptr_type,
     823                 :      204496 :                                    base_offset + apm->unit_offset);
     824                 :      204496 :               base = build_fold_addr_expr (base);
     825                 :             :             }
     826                 :             :         }
     827                 :             : 
     828                 :      288084 :       tree type = apm->type;
     829                 :      288084 :       unsigned int align;
     830                 :      288084 :       unsigned HOST_WIDE_INT misalign;
     831                 :             : 
     832                 :      288084 :       if (deref_base)
     833                 :             :         {
     834                 :        4856 :           align = deref_align;
     835                 :        4856 :           misalign = 0;
     836                 :             :         }
     837                 :             :       else
     838                 :             :         {
     839                 :      283228 :           get_pointer_alignment_1 (base, &align, &misalign);
     840                 :             :           /* All users must make sure that we can be optimistic when it
     841                 :             :              comes to alignment in this case (by inspecting the final users
     842                 :             :              of these new parameters).  */
     843                 :      283228 :           if (TYPE_ALIGN (type) > align)
     844                 :       77341 :             align = TYPE_ALIGN (type);
     845                 :             :         }
     846                 :      288084 :       misalign
     847                 :      576168 :         += (offset_int::from (wi::to_wide (off), SIGNED).to_short_addr ()
     848                 :      288084 :             * BITS_PER_UNIT);
     849                 :      288084 :       misalign = misalign & (align - 1);
     850                 :      288084 :       if (misalign != 0)
     851                 :        2934 :         align = least_bit_hwi (misalign);
     852                 :      288084 :       if (align < TYPE_ALIGN (type))
     853                 :           0 :         type = build_aligned_type (type, align);
     854                 :      288084 :       base = force_gimple_operand_gsi (&gsi, base,
     855                 :             :                                        true, NULL, true, GSI_SAME_STMT);
     856                 :      288084 :       tree expr = fold_build2_loc (loc, MEM_REF, type, base, off);
     857                 :      288084 :       REF_REVERSE_STORAGE_ORDER (expr) = apm->reverse;
     858                 :             :       /* If expr is not a valid gimple call argument emit
     859                 :             :          a load into a temporary.  */
     860                 :      288084 :       if (is_gimple_reg_type (TREE_TYPE (expr)))
     861                 :             :         {
     862                 :      286346 :           gimple *tem = gimple_build_assign (NULL_TREE, expr);
     863                 :      286346 :           if (gimple_in_ssa_p (cfun))
     864                 :             :             {
     865                 :      572692 :               gimple_set_vuse (tem, gimple_vuse (stmt));
     866                 :      286346 :               expr = make_ssa_name (TREE_TYPE (expr), tem);
     867                 :             :             }
     868                 :             :           else
     869                 :           0 :             expr = create_tmp_reg (TREE_TYPE (expr));
     870                 :      286346 :           gimple_assign_set_lhs (tem, expr);
     871                 :      286346 :           gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
     872                 :             :         }
     873                 :      288084 :       vargs.quick_push (expr);
     874                 :             :     }
     875                 :             : 
     876                 :      438410 :   if (m_always_copy_start >= 0)
     877                 :             :     {
     878                 :      438410 :       int always_copy_start = m_always_copy_start;
     879                 :      438410 :       if (mod_info)
     880                 :             :         {
     881                 :       28509 :           always_copy_start += mod_info->always_copy_delta;
     882                 :       28509 :           gcc_assert (always_copy_start >= 0);
     883                 :             :         }
     884                 :      438417 :       for (unsigned i = always_copy_start; i < old_nargs; i++)
     885                 :           7 :         vargs.safe_push (gimple_call_arg (stmt, i));
     886                 :             :     }
     887                 :             : 
     888                 :             :   /* For optimized away parameters, add on the caller side
     889                 :             :      before the call
     890                 :             :      DEBUG D#X => parm_Y(D)
     891                 :             :      stmts and associate D#X with parm in decl_debug_args_lookup
     892                 :             :      vector to say for debug info that if parameter parm had been passed,
     893                 :             :      it would have value parm_Y(D).  */
     894                 :      438410 :   tree old_decl = gimple_call_fndecl (stmt);
     895                 :      438410 :   if (MAY_HAVE_DEBUG_BIND_STMTS && old_decl && callee_decl)
     896                 :             :     {
     897                 :      401075 :       vec<tree, va_gc> **debug_args = NULL;
     898                 :      401075 :       unsigned i = 0;
     899                 :      401075 :       cgraph_node *callee_node = cgraph_node::get (callee_decl);
     900                 :             : 
     901                 :             :       /* FIXME: we don't seem to be able to insert debug args before clone
     902                 :             :          is materialized.  Materializing them early leads to extra memory
     903                 :             :          use.  */
     904                 :      401075 :       if (callee_node->clone_of)
     905                 :           0 :         callee_node->get_untransformed_body ();
     906                 :      401075 :       for (tree old_parm = DECL_ARGUMENTS (old_decl);
     907                 :     1264251 :            old_parm && i < old_nargs && ((int) i) < m_always_copy_start;
     908                 :      863176 :            old_parm = DECL_CHAIN (old_parm), i++)
     909                 :             :         {
     910                 :     1563521 :           if (!is_gimple_reg (old_parm) || kept[i])
     911                 :      673380 :             continue;
     912                 :      193681 :           tree arg;
     913                 :      193681 :           if (mod_info)
     914                 :             :             {
     915                 :        8147 :               if (mod_info->index_map[i] < 0)
     916                 :        3884 :                 continue;
     917                 :        4263 :               arg = gimple_call_arg (stmt, mod_info->index_map[i]);
     918                 :             :             }
     919                 :             :           else
     920                 :      185534 :             arg = gimple_call_arg (stmt, i);
     921                 :             : 
     922                 :      189797 :           tree origin = DECL_ORIGIN (old_parm);
     923                 :      189797 :           if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
     924                 :             :             {
     925                 :         859 :               if (!fold_convertible_p (TREE_TYPE (origin), arg))
     926                 :           1 :                 continue;
     927                 :         858 :               tree rhs1;
     928                 :         858 :               if (TREE_CODE (arg) == SSA_NAME
     929                 :         572 :                   && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg))
     930                 :         569 :                   && (rhs1
     931                 :         569 :                       = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg)))
     932                 :        1427 :                   && useless_type_conversion_p (TREE_TYPE (origin),
     933                 :         569 :                                                 TREE_TYPE (rhs1)))
     934                 :             :                 arg = rhs1;
     935                 :             :               else
     936                 :         289 :                 arg = fold_convert_loc (gimple_location (stmt),
     937                 :         289 :                                         TREE_TYPE (origin), arg);
     938                 :             :             }
     939                 :      189796 :           if (debug_args == NULL)
     940                 :      150549 :             debug_args = decl_debug_args_insert (callee_decl);
     941                 :      189796 :           unsigned int ix;
     942                 :      189796 :           tree ddecl = NULL_TREE;
     943                 :      243655 :           for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
     944                 :      238460 :             if (ddecl == origin)
     945                 :             :               {
     946                 :      184601 :                 ddecl = (**debug_args)[ix + 1];
     947                 :      184601 :                 break;
     948                 :             :               }
     949                 :      189796 :           if (ddecl == NULL)
     950                 :             :             {
     951                 :        5195 :               ddecl = build_debug_expr_decl (TREE_TYPE (origin));
     952                 :             :               /* FIXME: Is setting the mode really necessary? */
     953                 :        5195 :               SET_DECL_MODE (ddecl, DECL_MODE (origin));
     954                 :             : 
     955                 :        5195 :               vec_safe_push (*debug_args, origin);
     956                 :        5195 :               vec_safe_push (*debug_args, ddecl);
     957                 :             :             }
     958                 :      189796 :           gimple *def_temp = gimple_build_debug_bind (ddecl,
     959                 :             :                                                       unshare_expr (arg), stmt);
     960                 :      189796 :           gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
     961                 :             :         }
     962                 :             :     }
     963                 :             : 
     964                 :      438410 :   if (dump_file && (dump_flags & TDF_DETAILS))
     965                 :             :     {
     966                 :          10 :       fprintf (dump_file, "replacing stmt:");
     967                 :          10 :       print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
     968                 :             :     }
     969                 :             : 
     970                 :      438410 :   gcall *new_stmt = gimple_build_call_vec (callee_decl, vargs);
     971                 :             : 
     972                 :      438410 :   hash_set <tree> *ssas_to_remove = NULL;
     973                 :      438410 :   if (tree lhs = gimple_call_lhs (stmt))
     974                 :             :     {
     975                 :      164651 :       if (!m_skip_return)
     976                 :      152771 :         gimple_call_set_lhs (new_stmt, lhs);
     977                 :       11880 :       else if (TREE_CODE (lhs) == SSA_NAME)
     978                 :             :         {
     979                 :       11880 :           if (!killed_ssas)
     980                 :             :             {
     981                 :         641 :               ssas_to_remove = new hash_set<tree> (8);
     982                 :         641 :               killed_ssas = ssas_to_remove;
     983                 :             :             }
     984                 :       11880 :           killed_ssas->add (lhs);
     985                 :       11880 :           purge_all_uses (lhs, killed_ssas);
     986                 :             :         }
     987                 :             :     }
     988                 :             : 
     989                 :      438410 :   gimple_set_block (new_stmt, gimple_block (stmt));
     990                 :      438410 :   if (gimple_has_location (stmt))
     991                 :      743087 :     gimple_set_location (new_stmt, gimple_location (stmt));
     992                 :      438410 :   gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
     993                 :      438410 :   gimple_call_copy_flags (new_stmt, stmt);
     994                 :      438410 :   if (gimple_in_ssa_p (cfun))
     995                 :      438410 :     gimple_move_vops (new_stmt, stmt);
     996                 :             : 
     997                 :      438410 :   if (dump_file && (dump_flags & TDF_DETAILS))
     998                 :             :     {
     999                 :          10 :       fprintf (dump_file, "with stmt:");
    1000                 :          10 :       print_gimple_stmt (dump_file, new_stmt, 0);
    1001                 :          10 :       fprintf (dump_file, "\n");
    1002                 :             :     }
    1003                 :      438410 :   gsi_replace (&gsi, new_stmt, true);
    1004                 :      438410 :   if (ssas_to_remove)
    1005                 :             :     {
    1006                 :         641 :       ipa_release_ssas_in_hash (ssas_to_remove);
    1007                 :         641 :       delete ssas_to_remove;
    1008                 :             :     }
    1009                 :      438410 :   if (update_references)
    1010                 :           0 :     do
    1011                 :             :       {
    1012                 :           0 :         current_node->record_stmt_references (gsi_stmt (gsi));
    1013                 :           0 :         gsi_prev (&gsi);
    1014                 :             :       }
    1015                 :           0 :     while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
    1016                 :             : 
    1017                 :      438410 :   if (mod_info)
    1018                 :       28509 :     ipa_edge_modifications->remove (cs);
    1019                 :      438410 :   return new_stmt;
    1020                 :      438410 : }
    1021                 :             : 
    1022                 :             : /* Dump information contained in the object in textual form to F.  */
    1023                 :             : 
    1024                 :             : void
    1025                 :           9 : ipa_param_adjustments::dump (FILE *f)
    1026                 :             : {
    1027                 :           9 :   fprintf (f, "    m_always_copy_start: %i\n", m_always_copy_start);
    1028                 :           9 :   ipa_dump_adjusted_parameters (f, m_adj_params);
    1029                 :           9 :   if (m_skip_return)
    1030                 :           5 :     fprintf (f, "    Will SKIP return.\n");
    1031                 :           9 : }
    1032                 :             : 
    1033                 :             : /* Dump information contained in the object in textual form to stderr.  */
    1034                 :             : 
    1035                 :             : void
    1036                 :           0 : ipa_param_adjustments::debug ()
    1037                 :             : {
    1038                 :           0 :   dump (stderr);
    1039                 :           0 : }
    1040                 :             : 
    1041                 :             : /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET.  */
    1042                 :             : 
    1043                 :             : void
    1044                 :       91778 : ipa_param_body_adjustments::register_replacement (tree base,
    1045                 :             :                                                   unsigned unit_offset,
    1046                 :             :                                                   tree replacement)
    1047                 :             : {
    1048                 :       91778 :   ipa_param_body_replacement psr;
    1049                 :       91778 :   psr.base = base;
    1050                 :       91778 :   psr.repl = replacement;
    1051                 :       91778 :   psr.dummy = NULL_TREE;
    1052                 :       91778 :   psr.unit_offset = unit_offset;
    1053                 :       91778 :   m_replacements.safe_push (psr);
    1054                 :       91778 :   m_sorted_replacements_p = false;
    1055                 :       91778 : }
    1056                 :             : 
    1057                 :             : /* Register that REPLACEMENT should replace parameter described in APM.  */
    1058                 :             : 
    1059                 :             : void
    1060                 :       81036 : ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
    1061                 :             :                                                   tree replacement)
    1062                 :             : {
    1063                 :       81036 :   gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT
    1064                 :             :                        || apm->op == IPA_PARAM_OP_NEW);
    1065                 :       81036 :   gcc_checking_assert (!apm->prev_clone_adjustment);
    1066                 :       81036 :   register_replacement (m_oparms[apm->prev_clone_index], apm->unit_offset,
    1067                 :             :                         replacement);
    1068                 :       81036 : }
    1069                 :             : 
    1070                 :             : /* Comparator for sorting and searching
    1071                 :             :    ipa_param_body_adjustments::m_replacements.  */
    1072                 :             : 
    1073                 :             : static int
    1074                 :     1551787 : compare_param_body_replacement (const void *va, const void *vb)
    1075                 :             : {
    1076                 :     1551787 :   const ipa_param_body_replacement *a = (const ipa_param_body_replacement *) va;
    1077                 :     1551787 :   const ipa_param_body_replacement *b = (const ipa_param_body_replacement *) vb;
    1078                 :             : 
    1079                 :     1551787 :   if (DECL_UID (a->base) < DECL_UID (b->base))
    1080                 :             :     return -1;
    1081                 :     1279476 :   if (DECL_UID (a->base) > DECL_UID (b->base))
    1082                 :             :     return 1;
    1083                 :      967859 :   if (a->unit_offset < b->unit_offset)
    1084                 :             :     return -1;
    1085                 :      536446 :   if (a->unit_offset > b->unit_offset)
    1086                 :      448195 :     return 1;
    1087                 :             :   return 0;
    1088                 :             : }
    1089                 :             : 
    1090                 :             : /* Sort m_replacements and set m_sorted_replacements_p to true.  */
    1091                 :             : 
    1092                 :             : void
    1093                 :      161450 : ipa_param_body_adjustments::sort_replacements ()
    1094                 :             : {
    1095                 :      161450 :   if (m_sorted_replacements_p)
    1096                 :             :     return;
    1097                 :       50960 :   m_replacements.qsort (compare_param_body_replacement);
    1098                 :       50960 :   m_sorted_replacements_p = true;
    1099                 :             : }
    1100                 :             : 
    1101                 :             : /* Copy or not, as appropriate given m_id and decl context, a pre-existing
    1102                 :             :    PARM_DECL T so that it can be included in the parameters of the modified
    1103                 :             :    function.  */
    1104                 :             : 
    1105                 :             : tree
    1106                 :      221090 : ipa_param_body_adjustments::carry_over_param (tree t)
    1107                 :             : {
    1108                 :      221090 :   tree new_parm;
    1109                 :      221090 :   if (m_id)
    1110                 :             :     {
    1111                 :      217162 :       new_parm = remap_decl (t, m_id);
    1112                 :      217162 :       if (TREE_CODE (new_parm) != PARM_DECL)
    1113                 :           0 :         new_parm = m_id->copy_decl (t, m_id);
    1114                 :             :     }
    1115                 :        3928 :   else if (DECL_CONTEXT (t) != m_fndecl)
    1116                 :             :     {
    1117                 :          30 :       new_parm = copy_node (t);
    1118                 :          30 :       DECL_CONTEXT (new_parm) = m_fndecl;
    1119                 :             :     }
    1120                 :             :   else
    1121                 :             :     new_parm = t;
    1122                 :      221090 :   return new_parm;
    1123                 :             : }
    1124                 :             : 
    1125                 :             : /* If DECL is a gimple register that has a default definition SSA name and that
    1126                 :             :    has some uses, return the default definition, otherwise return NULL_TREE.  */
    1127                 :             : 
    1128                 :             : tree
    1129                 :      139452 : ipa_param_body_adjustments::get_ddef_if_exists_and_is_used (tree decl)
    1130                 :             : {
    1131                 :      139452 :  if (!is_gimple_reg (decl))
    1132                 :             :     return NULL_TREE;
    1133                 :      116157 :   tree ddef = ssa_default_def (m_id->src_cfun, decl);
    1134                 :      116157 :   if (!ddef || has_zero_uses (ddef))
    1135                 :             :     return NULL_TREE;
    1136                 :             :   return ddef;
    1137                 :             : }
    1138                 :             : 
    1139                 :             : /* Populate m_dead_stmts given that DEAD_PARAM is going to be removed without
    1140                 :             :    any replacement or splitting.  REPL is the replacement VAR_SECL to base any
    1141                 :             :    remaining uses of a removed parameter on.  Push all removed SSA names that
    1142                 :             :    are used within debug statements to DEBUGSTACK.  */
    1143                 :             : 
    1144                 :             : void
    1145                 :       98962 : ipa_param_body_adjustments::mark_dead_statements (tree dead_param,
    1146                 :             :                                                   vec<tree> *debugstack)
    1147                 :             : {
    1148                 :             :   /* Current IPA analyses which remove unused parameters never remove a
    1149                 :             :      non-gimple register ones which have any use except as parameters in other
    1150                 :             :      calls, so we can safely leve them as they are.  */
    1151                 :       98962 :   tree parm_ddef = get_ddef_if_exists_and_is_used (dead_param);
    1152                 :       98962 :   if (!parm_ddef)
    1153                 :       69277 :     return;
    1154                 :             : 
    1155                 :       34263 :   auto_vec<tree, 4> stack;
    1156                 :       34263 :   hash_set<tree> used_in_debug;
    1157                 :       34263 :   m_dead_ssas.add (parm_ddef);
    1158                 :       34263 :   stack.safe_push (parm_ddef);
    1159                 :      104659 :   while (!stack.is_empty ())
    1160                 :             :     {
    1161                 :       36133 :       imm_use_iterator imm_iter;
    1162                 :       36133 :       use_operand_p use_p;
    1163                 :       36133 :       tree t = stack.pop ();
    1164                 :             : 
    1165                 :       36133 :       insert_decl_map (m_id, t, error_mark_node);
    1166                 :      136354 :       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, t)
    1167                 :             :         {
    1168                 :      100221 :           gimple *stmt = USE_STMT (use_p);
    1169                 :             : 
    1170                 :             :           /* Calls containing dead arguments cannot be deleted,
    1171                 :             :              modify_call_stmt will instead remove just the argument later on.
    1172                 :             :              If isra_track_scalar_value_uses in ipa-sra.cc is extended to look
    1173                 :             :              through const functions, we will need to do so here too.  */
    1174                 :      100221 :           if (is_gimple_call (stmt)
    1175                 :      100221 :               || (m_id->blocks_to_copy
    1176                 :       70320 :                   && !bitmap_bit_p (m_id->blocks_to_copy,
    1177                 :       70320 :                                     gimple_bb (stmt)->index)))
    1178                 :       90391 :             continue;
    1179                 :             : 
    1180                 :        9830 :           if (is_gimple_debug (stmt))
    1181                 :             :             {
    1182                 :        7433 :               m_dead_stmts.add (stmt);
    1183                 :        7433 :               gcc_assert (gimple_debug_bind_p (stmt));
    1184                 :        7433 :               if (!used_in_debug.contains (t))
    1185                 :             :                 {
    1186                 :        3273 :                   used_in_debug.add (t);
    1187                 :        3273 :                   debugstack->safe_push (t);
    1188                 :             :                 }
    1189                 :             :             }
    1190                 :        2397 :           else if (gimple_code (stmt) == GIMPLE_PHI)
    1191                 :             :             {
    1192                 :         409 :               gphi *phi = as_a <gphi *> (stmt);
    1193                 :         409 :               int ix = PHI_ARG_INDEX_FROM_USE (use_p);
    1194                 :             : 
    1195                 :         409 :               if (!m_id->blocks_to_copy
    1196                 :         440 :                   || bitmap_bit_p (m_id->blocks_to_copy,
    1197                 :          31 :                                    gimple_phi_arg_edge (phi, ix)->src->index))
    1198                 :             :                 {
    1199                 :         378 :                   m_dead_stmts.add (phi);
    1200                 :         378 :                   tree res = gimple_phi_result (phi);
    1201                 :         378 :                   if (!m_dead_ssas.add (res))
    1202                 :         262 :                     stack.safe_push (res);
    1203                 :             :                 }
    1204                 :             :             }
    1205                 :        1988 :           else if (is_gimple_assign (stmt))
    1206                 :             :             {
    1207                 :        1896 :               m_dead_stmts.add (stmt);
    1208                 :        1896 :               if (!gimple_clobber_p (stmt))
    1209                 :             :                 {
    1210                 :        1866 :                   tree lhs = gimple_assign_lhs (stmt);
    1211                 :        1866 :                   gcc_assert (TREE_CODE (lhs) == SSA_NAME);
    1212                 :        1866 :                   if (!m_dead_ssas.add (lhs))
    1213                 :        1608 :                     stack.safe_push (lhs);
    1214                 :             :                 }
    1215                 :             :             }
    1216                 :          92 :           else if (gimple_code (stmt) == GIMPLE_RETURN)
    1217                 :          92 :             gcc_assert (m_adjustments && m_adjustments->m_skip_return);
    1218                 :             :           else
    1219                 :             :             /* IPA-SRA does not analyze other types of statements.  */
    1220                 :           0 :             gcc_unreachable ();
    1221                 :             :         }
    1222                 :             :     }
    1223                 :             : 
    1224                 :       34263 :   if (!MAY_HAVE_DEBUG_STMTS)
    1225                 :             :     {
    1226                 :        4578 :       gcc_assert (debugstack->is_empty ());
    1227                 :        4578 :       return;
    1228                 :             :     }
    1229                 :             : 
    1230                 :       29685 :   tree dp_ddecl = build_debug_expr_decl (TREE_TYPE (dead_param));
    1231                 :             :   /* FIXME: Is setting the mode really necessary? */
    1232                 :       29685 :   SET_DECL_MODE (dp_ddecl, DECL_MODE (dead_param));
    1233                 :       29685 :   m_dead_ssa_debug_equiv.put (parm_ddef, dp_ddecl);
    1234                 :       34263 : }
    1235                 :             : 
    1236                 :             : /* Put all clobbers of of dereference of default definition of PARAM into
    1237                 :             :    m_dead_stmts.  If there are returns among uses of the default definition of
    1238                 :             :    PARAM, verify they will be stripped off the return value.  */
    1239                 :             : 
    1240                 :             : void
    1241                 :       47346 : ipa_param_body_adjustments::mark_clobbers_dead (tree param)
    1242                 :             : {
    1243                 :       47346 :   if (!is_gimple_reg (param))
    1244                 :        6856 :     return;
    1245                 :       40490 :   tree ddef = get_ddef_if_exists_and_is_used (param);
    1246                 :       40490 :   if (!ddef)
    1247                 :             :     return;
    1248                 :             : 
    1249                 :       40490 :  imm_use_iterator imm_iter;
    1250                 :       40490 :  use_operand_p use_p;
    1251                 :      178346 :  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ddef)
    1252                 :             :    {
    1253                 :      137856 :      gimple *stmt = USE_STMT (use_p);
    1254                 :      137856 :      if (gimple_clobber_p (stmt))
    1255                 :         302 :        m_dead_stmts.add (stmt);
    1256                 :      137554 :      else if (gimple_code (stmt) == GIMPLE_RETURN)
    1257                 :         170 :        gcc_assert (m_adjustments && m_adjustments->m_skip_return);
    1258                 :             :    }
    1259                 :             : }
    1260                 :             : 
    1261                 :             : /* Callback to walk_tree.  If REMAP is an SSA_NAME that is present in hash_map
    1262                 :             :    passed in DATA, replace it with unshared version of what it was mapped to.
    1263                 :             :    If an SSA argument would be remapped to NULL, the whole operation needs to
    1264                 :             :    abort which is signaled by returning error_mark_node.  */
    1265                 :             : 
    1266                 :             : static tree
    1267                 :       15178 : replace_with_mapped_expr (tree *remap, int *walk_subtrees, void *data)
    1268                 :             : {
    1269                 :       15178 :   if (TYPE_P (*remap))
    1270                 :             :     {
    1271                 :           0 :       *walk_subtrees = 0;
    1272                 :           0 :       return 0;
    1273                 :             :     }
    1274                 :       15178 :   if (TREE_CODE (*remap) != SSA_NAME)
    1275                 :             :     return 0;
    1276                 :             : 
    1277                 :        2736 :   *walk_subtrees = 0;
    1278                 :             : 
    1279                 :        2736 :   hash_map<tree, tree> *equivs = (hash_map<tree, tree> *) data;
    1280                 :        2736 :   if (tree *p = equivs->get (*remap))
    1281                 :             :     {
    1282                 :        2641 :       if (!*p)
    1283                 :           1 :         return error_mark_node;
    1284                 :        2640 :       *remap = unshare_expr (*p);
    1285                 :             :     }
    1286                 :             :   return 0;
    1287                 :             : }
    1288                 :             : 
    1289                 :             : /* Replace all occurances of SSAs in m_dead_ssa_debug_equiv in t with what they
    1290                 :             :    are mapped to.  */
    1291                 :             : 
    1292                 :             : void
    1293                 :        8224 : ipa_param_body_adjustments::remap_with_debug_expressions (tree *t)
    1294                 :             : {
    1295                 :             :   /* If *t is an SSA_NAME which should have its debug statements reset, it is
    1296                 :             :      mapped to NULL in the hash_map.
    1297                 :             : 
    1298                 :             :      It is perhaps simpler to handle the SSA_NAME cases directly and only
    1299                 :             :      invoke walk_tree on more complex expressions.  When
    1300                 :             :      remap_with_debug_expressions is called from tree-inline.cc, a to-be-reset
    1301                 :             :      SSA_NAME can be an operand to such expressions and the entire debug
    1302                 :             :      variable we are remapping should be reset.  This is signaled by walk_tree
    1303                 :             :      returning error_mark_node and done by setting *t to NULL.  */
    1304                 :        8224 :   if (TREE_CODE (*t) == SSA_NAME)
    1305                 :             :     {
    1306                 :        5641 :       if (tree *p = m_dead_ssa_debug_equiv.get (*t))
    1307                 :        5641 :         *t = *p;
    1308                 :             :     }
    1309                 :        2583 :   else if (walk_tree (t, replace_with_mapped_expr,
    1310                 :        2583 :                       &m_dead_ssa_debug_equiv, NULL) == error_mark_node)
    1311                 :           1 :     *t = NULL_TREE;
    1312                 :        8224 : }
    1313                 :             : 
    1314                 :             : /* For an SSA_NAME DEAD_SSA which is about to be DCEd because it is based on a
    1315                 :             :    useless parameter, prepare an expression that should represent it in
    1316                 :             :    debug_binds in the cloned function and add a mapping from DEAD_SSA to
    1317                 :             :    m_dead_ssa_debug_equiv.  That mapping is to NULL when the associated
    1318                 :             :    debug_statement has to be reset instead.  In such case return false,
    1319                 :             :    ottherwise return true.  If DEAD_SSA comes from a basic block which is not
    1320                 :             :    about to be copied, ignore it and return true.  */
    1321                 :             : 
    1322                 :             : bool
    1323                 :        4380 : ipa_param_body_adjustments::prepare_debug_expressions (tree dead_ssa)
    1324                 :             : {
    1325                 :        4380 :   gcc_checking_assert (m_dead_ssas.contains (dead_ssa));
    1326                 :        4380 :   if (tree *d = m_dead_ssa_debug_equiv.get (dead_ssa))
    1327                 :        3206 :     return (*d != NULL_TREE);
    1328                 :             : 
    1329                 :        1174 :   gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (dead_ssa));
    1330                 :        1174 :   gimple *def = SSA_NAME_DEF_STMT (dead_ssa);
    1331                 :        1174 :   if (m_id->blocks_to_copy
    1332                 :        1174 :       && !bitmap_bit_p (m_id->blocks_to_copy, gimple_bb (def)->index))
    1333                 :             :     return true;
    1334                 :             : 
    1335                 :        1174 :   if (gimple_code (def) == GIMPLE_PHI)
    1336                 :             :     {
    1337                 :             :       /* In theory, we could ignore all SSAs coming from BBs not in
    1338                 :             :          m_id->blocks_to_copy but at the time of the writing this code that
    1339                 :             :          should never really be the case because only fnsplit uses that bitmap,
    1340                 :             :          so don't bother.  */
    1341                 :         185 :       tree value = degenerate_phi_result (as_a <gphi *> (def));
    1342                 :         185 :       if (!value
    1343                 :         185 :           || (m_dead_ssas.contains (value)
    1344                 :           0 :               && !prepare_debug_expressions (value)))
    1345                 :             :         {
    1346                 :         185 :           m_dead_ssa_debug_equiv.put (dead_ssa, NULL_TREE);
    1347                 :         185 :           return false;
    1348                 :             :         }
    1349                 :             : 
    1350                 :           0 :       gcc_assert (TREE_CODE (value) == SSA_NAME);
    1351                 :           0 :       tree *d = m_dead_ssa_debug_equiv.get (value);
    1352                 :           0 :       m_dead_ssa_debug_equiv.put (dead_ssa, *d);
    1353                 :           0 :       return true;
    1354                 :             :     }
    1355                 :             : 
    1356                 :         989 :   bool lost = false;
    1357                 :         989 :   use_operand_p use_p;
    1358                 :         989 :   ssa_op_iter oi;
    1359                 :        2007 :   FOR_EACH_PHI_OR_STMT_USE (use_p, def, oi, SSA_OP_USE)
    1360                 :             :     {
    1361                 :        1216 :       tree use = USE_FROM_PTR (use_p);
    1362                 :        1216 :       if (m_dead_ssas.contains (use)
    1363                 :        1216 :           && !prepare_debug_expressions (use))
    1364                 :             :         {
    1365                 :         198 :           lost = true;
    1366                 :         198 :           break;
    1367                 :             :         }
    1368                 :             :     }
    1369                 :             : 
    1370                 :         989 :   if (lost)
    1371                 :             :     {
    1372                 :         198 :       m_dead_ssa_debug_equiv.put (dead_ssa, NULL_TREE);
    1373                 :         198 :       return false;
    1374                 :             :     }
    1375                 :             : 
    1376                 :         791 :   if (is_gimple_assign (def))
    1377                 :             :     {
    1378                 :         791 :       gcc_assert (!gimple_clobber_p (def));
    1379                 :         791 :       if (gimple_assign_copy_p (def)
    1380                 :         791 :           && TREE_CODE (gimple_assign_rhs1 (def)) == SSA_NAME)
    1381                 :             :         {
    1382                 :           0 :           tree d = *m_dead_ssa_debug_equiv.get (gimple_assign_rhs1 (def));
    1383                 :           0 :           gcc_assert (d);
    1384                 :           0 :           m_dead_ssa_debug_equiv.put (dead_ssa, d);
    1385                 :           0 :           return true;
    1386                 :             :         }
    1387                 :             : 
    1388                 :         791 :       tree val
    1389                 :         791 :         = unshare_expr_without_location (gimple_assign_rhs_to_tree (def));
    1390                 :         791 :       remap_with_debug_expressions (&val);
    1391                 :             : 
    1392                 :         791 :       tree vexpr = build_debug_expr_decl (TREE_TYPE (val));
    1393                 :         791 :       m_dead_stmt_debug_equiv.put (def, val);
    1394                 :         791 :       m_dead_ssa_debug_equiv.put (dead_ssa, vexpr);
    1395                 :         791 :       return true;
    1396                 :             :     }
    1397                 :             :   else
    1398                 :           0 :     gcc_unreachable ();
    1399                 :             : }
    1400                 :             : 
    1401                 :             : /* Common initialization performed by all ipa_param_body_adjustments
    1402                 :             :    constructors.  OLD_FNDECL is the declaration we take original arguments
    1403                 :             :    from, (it may be the same as M_FNDECL).  VARS, if non-NULL, is a pointer to
    1404                 :             :    a chained list of new local variables.  TREE_MAP is the IPA-CP produced
    1405                 :             :    mapping of trees to constants.
    1406                 :             : 
    1407                 :             :    The function is rather long but it really onlu initializes all data members
    1408                 :             :    of the class.  It creates new param DECLs, finds their new types,   */
    1409                 :             : 
    1410                 :             : void
    1411                 :      147487 : ipa_param_body_adjustments::common_initialization (tree old_fndecl,
    1412                 :             :                                                    tree *vars,
    1413                 :             :                                                    vec<ipa_replace_map *,
    1414                 :             :                                                        va_gc> *tree_map)
    1415                 :             : {
    1416                 :      147487 :   push_function_arg_decls (&m_oparms, old_fndecl);
    1417                 :      147487 :   auto_vec<tree,16> otypes;
    1418                 :      147487 :   if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl)) != NULL_TREE)
    1419                 :      147325 :     push_function_arg_types (&otypes, TREE_TYPE (old_fndecl));
    1420                 :             :   else
    1421                 :             :     {
    1422                 :         162 :       auto_vec<tree,16> oparms;
    1423                 :         162 :       push_function_arg_decls (&oparms, old_fndecl);
    1424                 :         162 :       unsigned ocount = oparms.length ();
    1425                 :         162 :       otypes.reserve_exact (ocount);
    1426                 :         432 :       for (unsigned i = 0; i < ocount; i++)
    1427                 :         270 :         otypes.quick_push (TREE_TYPE (oparms[i]));
    1428                 :         162 :     }
    1429                 :      147487 :   fill_vector_of_new_param_types (&m_new_types, &otypes, m_adj_params, true);
    1430                 :             : 
    1431                 :      147487 :   auto_vec<bool, 16> kept;
    1432                 :      294974 :   kept.reserve_exact (m_oparms.length ());
    1433                 :      294974 :   kept.quick_grow_cleared (m_oparms.length ());
    1434                 :      147487 :   auto_vec<bool, 16> split;
    1435                 :      147487 :   split.reserve_exact (m_oparms.length ());
    1436                 :      294974 :   split.quick_grow_cleared (m_oparms.length ());
    1437                 :             : 
    1438                 :      147487 :   unsigned adj_len = vec_safe_length (m_adj_params);
    1439                 :      147487 :   m_method2func = ((TREE_CODE (TREE_TYPE (m_fndecl)) == METHOD_TYPE)
    1440                 :      147487 :                    && (adj_len == 0
    1441                 :       40074 :                        || (*m_adj_params)[0].op != IPA_PARAM_OP_COPY
    1442                 :       39954 :                        || (*m_adj_params)[0].base_index != 0));
    1443                 :             : 
    1444                 :             :   /* The main job of the this function is to go over the vector of adjusted
    1445                 :             :      parameters and create declarations or find corresponding old ones and push
    1446                 :             :      them to m_new_decls.  For IPA-SRA replacements it also creates
    1447                 :             :      corresponding m_id->dst_node->clone.performed_splits entries.  */
    1448                 :             : 
    1449                 :      147487 :   m_new_decls.reserve_exact (adj_len);
    1450                 :      453902 :   for (unsigned i = 0; i < adj_len ; i++)
    1451                 :             :     {
    1452                 :      306415 :       ipa_adjusted_param *apm = &(*m_adj_params)[i];
    1453                 :      306415 :       unsigned prev_index = apm->prev_clone_index;
    1454                 :      306415 :       tree new_parm;
    1455                 :      306415 :       if (apm->op == IPA_PARAM_OP_COPY
    1456                 :       85325 :           || apm->prev_clone_adjustment)
    1457                 :             :         {
    1458                 :      221090 :           kept[prev_index] = true;
    1459                 :      221090 :           new_parm = carry_over_param (m_oparms[prev_index]);
    1460                 :      221090 :           m_new_decls.quick_push (new_parm);
    1461                 :             :         }
    1462                 :       85325 :       else if (apm->op == IPA_PARAM_OP_NEW
    1463                 :       85325 :                || apm->op == IPA_PARAM_OP_SPLIT)
    1464                 :             :         {
    1465                 :       85325 :           tree new_type = m_new_types[i];
    1466                 :       85325 :           gcc_checking_assert (new_type);
    1467                 :       85325 :           new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
    1468                 :             :                                  new_type);
    1469                 :       85325 :           const char *prefix = ipa_param_prefixes[apm->param_prefix_index];
    1470                 :       85325 :           DECL_NAME (new_parm) = create_tmp_var_name (prefix);
    1471                 :       85325 :           DECL_ARTIFICIAL (new_parm) = 1;
    1472                 :       85325 :           DECL_ARG_TYPE (new_parm) = new_type;
    1473                 :       85325 :           DECL_CONTEXT (new_parm) = m_fndecl;
    1474                 :       85325 :           TREE_USED (new_parm) = 1;
    1475                 :       85325 :           DECL_IGNORED_P (new_parm) = 1;
    1476                 :       85325 :           layout_decl (new_parm, 0);
    1477                 :       85325 :           m_new_decls.quick_push (new_parm);
    1478                 :             : 
    1479                 :       85325 :           if (apm->op == IPA_PARAM_OP_SPLIT)
    1480                 :             :             {
    1481                 :       76597 :               split[prev_index] = true;
    1482                 :       76597 :               register_replacement (apm, new_parm);
    1483                 :             :             }
    1484                 :             :         }
    1485                 :             :       else
    1486                 :           0 :         gcc_unreachable ();
    1487                 :             :     }
    1488                 :             : 
    1489                 :      147487 :   auto_vec <int, 16> index_mapping;
    1490                 :      147487 :   bool need_remap = false;
    1491                 :      147487 :   if (m_id)
    1492                 :             :     {
    1493                 :      143027 :       clone_info *cinfo = clone_info::get (m_id->src_node);
    1494                 :      143027 :       if (cinfo && cinfo->param_adjustments)
    1495                 :             :         {
    1496                 :        2254 :           cinfo->param_adjustments->get_updated_indices (&index_mapping);
    1497                 :        2254 :           need_remap = true;
    1498                 :             :         }
    1499                 :             : 
    1500                 :      143027 :       if (ipcp_transformation *ipcp_ts
    1501                 :      143027 :           = ipcp_get_transformation_summary (m_id->src_node))
    1502                 :             :         {
    1503                 :       37120 :           for (const ipa_argagg_value &av : ipcp_ts->m_agg_values)
    1504                 :             :             {
    1505                 :       14181 :               int parm_num = av.index;
    1506                 :             : 
    1507                 :       14181 :               if (need_remap)
    1508                 :             :                 {
    1509                 :             :                   /* FIXME: We cannot handle the situation when IPA-CP
    1510                 :             :                      identified that a parameter is a pointer to a global
    1511                 :             :                      variable and at the same time the variable has some known
    1512                 :             :                      constant contents (PR 107640).  The best place to make
    1513                 :             :                      sure we don't drop such constants on the floor probably is
    1514                 :             :                      not here, but we have to make sure that it does not
    1515                 :             :                      confuse the remapping.  */
    1516                 :       13110 :                   if (parm_num >= (int) index_mapping.length ())
    1517                 :          23 :                     continue;
    1518                 :        6532 :                   parm_num = index_mapping[parm_num];
    1519                 :        6532 :                   if (parm_num < 0)
    1520                 :          30 :                     continue;
    1521                 :             :                 }
    1522                 :             : 
    1523                 :       14128 :               if (!kept[parm_num])
    1524                 :             :                 {
    1525                 :             :                   /* IPA-CP has detected an aggregate constant in a parameter
    1526                 :             :                      that will not be kept, which means that IPA-SRA would have
    1527                 :             :                      split it if there wasn't a constant.  Because we are about
    1528                 :             :                      to remove the original, this is the last chance where we
    1529                 :             :                      can substitute the uses with a constant (for values passed
    1530                 :             :                      by reference) or do the split but initialize the
    1531                 :             :                      replacement with a constant (for split aggregates passed
    1532                 :             :                      by value).  */
    1533                 :             : 
    1534                 :       10744 :                   if (split[parm_num])
    1535                 :             :                     {
    1536                 :             :                       /* We must be careful not to add a duplicate
    1537                 :             :                          replacement. */
    1538                 :        9531 :                       sort_replacements ();
    1539                 :        9531 :                       ipa_param_body_replacement *pbr
    1540                 :        9531 :                         = lookup_replacement_1 (m_oparms[parm_num],
    1541                 :        9531 :                                                 av.unit_offset);
    1542                 :        9531 :                       if (pbr)
    1543                 :             :                         {
    1544                 :             :                           /* Otherwise IPA-SRA should have bailed out.  */
    1545                 :           2 :                           gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (pbr->repl)));
    1546                 :           2 :                           continue;
    1547                 :             :                         }
    1548                 :             :                     }
    1549                 :             : 
    1550                 :       10742 :                   tree repl;
    1551                 :       10742 :                   if (av.by_ref)
    1552                 :        9482 :                     repl = av.value;
    1553                 :             :                   else
    1554                 :             :                     {
    1555                 :        1260 :                       repl = create_tmp_var (TREE_TYPE (av.value),
    1556                 :             :                                              "removed_ipa_cp");
    1557                 :        1260 :                       gimple *init_stmt = gimple_build_assign (repl, av.value);
    1558                 :        1260 :                       m_split_agg_csts_inits.safe_push (init_stmt);
    1559                 :             :                     }
    1560                 :       10742 :                   register_replacement (m_oparms[parm_num], av.unit_offset,
    1561                 :             :                                         repl);
    1562                 :       10742 :                   split[parm_num] = true;
    1563                 :             :                 }
    1564                 :             :             }
    1565                 :             :         }
    1566                 :             :     }
    1567                 :      147487 :   sort_replacements ();
    1568                 :             : 
    1569                 :      147487 :   if (tree_map)
    1570                 :             :     {
    1571                 :             :       /* Do not treat parameters which were replaced with a constant as
    1572                 :             :          completely vanished.  */
    1573                 :       27598 :       for (unsigned i = 0; i < tree_map->length (); i++)
    1574                 :             :         {
    1575                 :       16673 :           int parm_num = (*tree_map)[i]->parm_num;
    1576                 :       16673 :           gcc_assert (parm_num >= 0);
    1577                 :       16673 :           if (need_remap)
    1578                 :           0 :             parm_num = index_mapping[parm_num];
    1579                 :       16673 :           kept[parm_num] = true;
    1580                 :             :         }
    1581                 :             :     }
    1582                 :             : 
    1583                 :             :   /* As part of body modifications, we will also have to replace remaining uses
    1584                 :             :      of remaining uses of removed PARM_DECLs (which do not however use the
    1585                 :             :      initial value) with their VAR_DECL copies.
    1586                 :             : 
    1587                 :             :      We do this differently with and without m_id.  With m_id, we rely on its
    1588                 :             :      mapping and create a replacement straight away.  Without it, we have our
    1589                 :             :      own mechanism for which we have to populate m_removed_decls vector.  Just
    1590                 :             :      don't mix them, that is why you should not call
    1591                 :             :      replace_removed_params_ssa_names or perform_cfun_body_modifications when
    1592                 :             :      you construct with ID not equal to NULL.  */
    1593                 :             : 
    1594                 :      147487 :   auto_vec<tree, 8> ssas_to_process_debug;
    1595                 :      147487 :   unsigned op_len = m_oparms.length ();
    1596                 :      536049 :   for (unsigned i = 0; i < op_len; i++)
    1597                 :      388562 :     if (!kept[i])
    1598                 :             :       {
    1599                 :      150799 :         if (m_id)
    1600                 :             :           {
    1601                 :      146308 :             gcc_assert (!m_id->decl_map->get (m_oparms[i]));
    1602                 :      146308 :             tree var = copy_decl_to_var (m_oparms[i], m_id);
    1603                 :      146308 :             insert_decl_map (m_id, m_oparms[i], var);
    1604                 :             :             /* Declare this new variable.  */
    1605                 :      146308 :             DECL_CHAIN (var) = *vars;
    1606                 :      146308 :             *vars = var;
    1607                 :             : 
    1608                 :             :             /* If this is not a split but a real removal, init hash sets
    1609                 :             :                that will guide what not to copy to the new body.  */
    1610                 :      146308 :             if (!split[i])
    1611                 :       98962 :               mark_dead_statements (m_oparms[i], &ssas_to_process_debug);
    1612                 :             :             else
    1613                 :       47346 :               mark_clobbers_dead (m_oparms[i]);
    1614                 :       18160 :             if (MAY_HAVE_DEBUG_STMTS
    1615                 :      146308 :                 && is_gimple_reg (m_oparms[i]))
    1616                 :       99558 :               m_reset_debug_decls.safe_push (m_oparms[i]);
    1617                 :             :           }
    1618                 :             :         else
    1619                 :             :           {
    1620                 :        4491 :             m_removed_decls.safe_push (m_oparms[i]);
    1621                 :        8982 :             m_removed_map.put (m_oparms[i], m_removed_decls.length () - 1);
    1622                 :        4218 :             if (MAY_HAVE_DEBUG_STMTS
    1623                 :         273 :                 && !kept[i]
    1624                 :        4764 :                 && is_gimple_reg (m_oparms[i]))
    1625                 :         233 :               m_reset_debug_decls.safe_push (m_oparms[i]);
    1626                 :             :           }
    1627                 :             :       }
    1628                 :             : 
    1629                 :      298247 :   while (!ssas_to_process_debug.is_empty ())
    1630                 :        3273 :     prepare_debug_expressions (ssas_to_process_debug.pop ());
    1631                 :      147487 : }
    1632                 :             : 
    1633                 :             : /* Constructor of ipa_param_body_adjustments from a simple list of
    1634                 :             :    modifications to parameters listed in ADJ_PARAMS which will prepare ground
    1635                 :             :    for modification of parameters of fndecl.  Return value of the function will
    1636                 :             :    not be removed and the object will assume it does not run as a part of
    1637                 :             :    tree-function_versioning.  */
    1638                 :             : 
    1639                 :        4432 : ipa_param_body_adjustments
    1640                 :             : ::ipa_param_body_adjustments (vec<ipa_adjusted_param, va_gc> *adj_params,
    1641                 :        4432 :                               tree fndecl)
    1642                 :        4432 :   : m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
    1643                 :        4432 :     m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
    1644                 :        4432 :     m_dead_stmt_debug_equiv (), m_fndecl (fndecl), m_id (NULL), m_oparms (),
    1645                 :        4432 :     m_new_decls (), m_new_types (), m_replacements (),
    1646                 :        4432 :     m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
    1647                 :        4432 :     m_method2func (false), m_sorted_replacements_p (true)
    1648                 :             : {
    1649                 :        4432 :   common_initialization (fndecl, NULL, NULL);
    1650                 :        4432 : }
    1651                 :             : 
    1652                 :             : /* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
    1653                 :             :    ADJUSTMENTS which will prepare ground for modification of parameters of
    1654                 :             :    fndecl.  The object will assume it does not run as a part of
    1655                 :             :    tree-function_versioning.  */
    1656                 :             : 
    1657                 :          28 : ipa_param_body_adjustments
    1658                 :             : ::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
    1659                 :          28 :                               tree fndecl)
    1660                 :          28 :   : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    1661                 :          28 :     m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
    1662                 :          28 :     m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
    1663                 :          28 :     m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
    1664                 :          28 :     m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
    1665                 :          28 :     m_method2func (false), m_sorted_replacements_p (true)
    1666                 :             : {
    1667                 :          28 :   common_initialization (fndecl, NULL, NULL);
    1668                 :          28 : }
    1669                 :             : 
    1670                 :             : /* Constructor of ipa_param_body_adjustments which sets it up as a part of
    1671                 :             :    running tree_function_versioning.  Planned modifications to the function are
    1672                 :             :    in ADJUSTMENTS.  FNDECL designates the new function clone which is being
    1673                 :             :    modified.  OLD_FNDECL is the function of which FNDECL is a clone (and which
    1674                 :             :    at the time of invocation still share DECL_ARGUMENTS).  ID is the
    1675                 :             :    copy_body_data structure driving the wholy body copying process.  VARS is a
    1676                 :             :    pointer to the head of the list of new local variables, TREE_MAP is the map
    1677                 :             :    that drives tree substitution in the cloning process.  */
    1678                 :             : 
    1679                 :      143027 : ipa_param_body_adjustments
    1680                 :             : ::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
    1681                 :             :                               tree fndecl, tree old_fndecl,
    1682                 :             :                               copy_body_data *id, tree *vars,
    1683                 :      143027 :                               vec<ipa_replace_map *, va_gc> *tree_map)
    1684                 :      143027 :   : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    1685                 :      143027 :     m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
    1686                 :      143027 :     m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
    1687                 :      143027 :     m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
    1688                 :      143027 :     m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
    1689                 :      143027 :     m_method2func (false), m_sorted_replacements_p (true)
    1690                 :             : {
    1691                 :      143027 :   common_initialization (old_fndecl, vars, tree_map);
    1692                 :      143027 : }
    1693                 :             : 
    1694                 :             : /* Chain new param decls up and return them.  */
    1695                 :             : 
    1696                 :             : tree
    1697                 :      147487 : ipa_param_body_adjustments::get_new_param_chain ()
    1698                 :             : {
    1699                 :      147487 :   tree result;
    1700                 :      147487 :   tree *link = &result;
    1701                 :             : 
    1702                 :      147487 :   unsigned len = vec_safe_length (m_adj_params);
    1703                 :      453902 :   for (unsigned i = 0; i < len; i++)
    1704                 :             :     {
    1705                 :      306415 :       tree new_decl = m_new_decls[i];
    1706                 :      306415 :       *link = new_decl;
    1707                 :      306415 :       link = &DECL_CHAIN (new_decl);
    1708                 :             :     }
    1709                 :      147487 :   *link = NULL_TREE;
    1710                 :      147487 :   return result;
    1711                 :             : }
    1712                 :             : 
    1713                 :             : /* Modify the function parameters FNDECL and its type according to the plan in
    1714                 :             :    ADJUSTMENTS.  This function needs to be called when the decl has not already
    1715                 :             :    been processed with ipa_param_adjustments::adjust_decl, otherwise just
    1716                 :             :    seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough.  */
    1717                 :             : 
    1718                 :             : void
    1719                 :        4460 : ipa_param_body_adjustments::modify_formal_parameters ()
    1720                 :             : {
    1721                 :        4460 :   tree orig_type = TREE_TYPE (m_fndecl);
    1722                 :        4460 :   DECL_ARGUMENTS (m_fndecl) = get_new_param_chain ();
    1723                 :             : 
    1724                 :             :   /* When signature changes, we need to clear builtin info.  */
    1725                 :        4460 :   if (fndecl_built_in_p (m_fndecl))
    1726                 :           0 :     set_decl_built_in_function (m_fndecl, NOT_BUILT_IN, 0);
    1727                 :             : 
    1728                 :        4460 :   bool modified = false;
    1729                 :        4460 :   size_t index = 0;
    1730                 :        4460 :   if (m_adj_params)
    1731                 :        4108 :     for (tree t = TYPE_ARG_TYPES (orig_type);
    1732                 :       10554 :          t && !modified;
    1733                 :        6446 :          t = TREE_CHAIN (t), index++)
    1734                 :        6446 :       if (index >= m_adj_params->length ()
    1735                 :        5861 :           || (*m_adj_params)[index].op != IPA_PARAM_OP_COPY
    1736                 :        8825 :           || (*m_adj_params)[index].base_index != index)
    1737                 :             :         modified = true;
    1738                 :             : 
    1739                 :             :   /* At this point, removing return value is only implemented when going
    1740                 :             :      through tree_function_versioning, not when modifying function body
    1741                 :             :      directly.  */
    1742                 :        4460 :   gcc_assert (!m_adjustments || !m_adjustments->m_skip_return);
    1743                 :        8920 :   tree new_type = build_adjusted_function_type (orig_type, &m_new_types,
    1744                 :        4460 :                                                 m_method2func, false, modified);
    1745                 :             : 
    1746                 :        4460 :   TREE_TYPE (m_fndecl) = new_type;
    1747                 :        4460 :   DECL_VIRTUAL_P (m_fndecl) = 0;
    1748                 :        4460 :   DECL_LANG_SPECIFIC (m_fndecl) = NULL;
    1749                 :        4460 :   if (m_method2func)
    1750                 :         120 :     DECL_VINDEX (m_fndecl) = NULL_TREE;
    1751                 :        4460 : }
    1752                 :             : 
    1753                 :             : /* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
    1754                 :             :    structures.  */
    1755                 :             : 
    1756                 :             : ipa_param_body_replacement *
    1757                 :      167198 : ipa_param_body_adjustments::lookup_replacement_1 (tree base,
    1758                 :             :                                                   unsigned unit_offset)
    1759                 :             : {
    1760                 :      167198 :   gcc_assert (m_sorted_replacements_p);
    1761                 :      167198 :   ipa_param_body_replacement key;
    1762                 :      167198 :   key.base = base;
    1763                 :      167198 :   key.unit_offset = unit_offset;
    1764                 :      167198 :   ipa_param_body_replacement *res
    1765                 :      334396 :     = std::lower_bound (m_replacements.begin (), m_replacements.end (), key,
    1766                 :      321905 :                         [] (const ipa_param_body_replacement &elt,
    1767                 :             :                             const ipa_param_body_replacement &val)
    1768                 :             :                         {
    1769                 :      321905 :                           return (compare_param_body_replacement (&elt, &val)
    1770                 :             :                                   < 0);
    1771                 :             :                         });
    1772                 :             : 
    1773                 :      167198 :   if (res == m_replacements.end ()
    1774                 :      132255 :       || res->base != base
    1775                 :      256629 :       || res->unit_offset != unit_offset)
    1776                 :       78947 :     return NULL;
    1777                 :             :   return res;
    1778                 :             : }
    1779                 :             : 
    1780                 :             : /* Find the first replacement for BASE among m_replacements and return pointer
    1781                 :             :    to it, or NULL if there is none.  */
    1782                 :             : 
    1783                 :             : ipa_param_body_replacement *
    1784                 :       24351 : ipa_param_body_adjustments::lookup_first_base_replacement (tree base)
    1785                 :             : {
    1786                 :       24351 :   gcc_assert (m_sorted_replacements_p);
    1787                 :       24351 :   ipa_param_body_replacement key;
    1788                 :       24351 :   key.base = base;
    1789                 :       24351 :   ipa_param_body_replacement *res
    1790                 :       48702 :     = std::lower_bound (m_replacements.begin (), m_replacements.end (), key,
    1791                 :       37629 :                         [] (const ipa_param_body_replacement &elt,
    1792                 :             :                             const ipa_param_body_replacement &val)
    1793                 :             :                         {
    1794                 :       37629 :                           if (DECL_UID (elt.base) < DECL_UID (val.base))
    1795                 :       12275 :                             return true;
    1796                 :             :                           return false;
    1797                 :             :                         });
    1798                 :             : 
    1799                 :       24351 :   if (res == m_replacements.end ()
    1800                 :       24351 :       || res->base != base)
    1801                 :       18982 :     return NULL;
    1802                 :             :   return res;
    1803                 :             : }
    1804                 :             : 
    1805                 :             : /* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
    1806                 :             :    and return it, assuming it is known it does not hold value by reference or
    1807                 :             :    in reverse storage order.  */
    1808                 :             : 
    1809                 :             : tree
    1810                 :        4019 : ipa_param_body_adjustments::lookup_replacement (tree base, unsigned unit_offset)
    1811                 :             : {
    1812                 :        4019 :   ipa_param_body_replacement *pbr = lookup_replacement_1 (base, unit_offset);
    1813                 :        4019 :   if (!pbr)
    1814                 :             :     return NULL;
    1815                 :        4019 :   return pbr->repl;
    1816                 :             : }
    1817                 :             : 
    1818                 :             : /* If T is an SSA_NAME, return NULL if it is not a default def or
    1819                 :             :    return its base variable if it is.  If IGNORE_DEFAULT_DEF is true,
    1820                 :             :    the base variable is always returned, regardless if it is a default
    1821                 :             :    def.  Return T if it is not an SSA_NAME.  */
    1822                 :             : 
    1823                 :             : static tree
    1824                 :      998643 : get_ssa_base_param (tree t, bool ignore_default_def)
    1825                 :             : {
    1826                 :      998643 :   if (TREE_CODE (t) == SSA_NAME)
    1827                 :             :     {
    1828                 :      614548 :       if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
    1829                 :      129298 :         return SSA_NAME_VAR (t);
    1830                 :             :       else
    1831                 :             :         return NULL_TREE;
    1832                 :             :     }
    1833                 :             :   return t;
    1834                 :             : }
    1835                 :             : 
    1836                 :             : /* Given an expression, return the structure describing how it should be
    1837                 :             :    replaced if it accesses a part of a split parameter or NULL otherwise.
    1838                 :             : 
    1839                 :             :    Do not free the result, it will be deallocated when the object is destroyed.
    1840                 :             : 
    1841                 :             :    If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
    1842                 :             :    which are default definitions, if set, consider all SSA_NAMEs of
    1843                 :             :    PARM_DECLs.  */
    1844                 :             : 
    1845                 :             : ipa_param_body_replacement *
    1846                 :     1004348 : ipa_param_body_adjustments::get_expr_replacement (tree expr,
    1847                 :             :                                                   bool ignore_default_def)
    1848                 :             : {
    1849                 :     1004348 :   tree base;
    1850                 :     1004348 :   unsigned unit_offset;
    1851                 :             : 
    1852                 :     1004348 :   if (!isra_get_ref_base_and_offset (expr, &base, &unit_offset))
    1853                 :             :     return NULL;
    1854                 :             : 
    1855                 :      998643 :   base = get_ssa_base_param (base, ignore_default_def);
    1856                 :      998643 :   if (!base || TREE_CODE (base) != PARM_DECL)
    1857                 :             :     return NULL;
    1858                 :      152740 :   return lookup_replacement_1 (base, unit_offset);
    1859                 :             : }
    1860                 :             : 
    1861                 :             : /* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
    1862                 :             :    (which includes it being split or replaced), return a new variable that
    1863                 :             :    should be used for any SSA names that will remain in the function that
    1864                 :             :    previously belonged to OLD_DECL.  */
    1865                 :             : 
    1866                 :             : tree
    1867                 :        7905 : ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl)
    1868                 :             : {
    1869                 :        7905 :   unsigned *idx = m_removed_map.get (old_decl);
    1870                 :        7905 :   if (!idx)
    1871                 :             :     return NULL;
    1872                 :             : 
    1873                 :        4451 :   tree repl;
    1874                 :        4451 :   if (TREE_CODE (m_removed_decls[*idx]) == PARM_DECL)
    1875                 :             :     {
    1876                 :        4019 :       gcc_assert (m_removed_decls[*idx] == old_decl);
    1877                 :        4019 :       repl = copy_var_decl (old_decl, DECL_NAME (old_decl),
    1878                 :        4019 :                             TREE_TYPE (old_decl));
    1879                 :        4019 :       m_removed_decls[*idx] = repl;
    1880                 :             :     }
    1881                 :             :   else
    1882                 :             :     repl = m_removed_decls[*idx];
    1883                 :             :   return repl;
    1884                 :             : }
    1885                 :             : 
    1886                 :             : /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
    1887                 :             :    parameter which is to be removed because its value is not used, create a new
    1888                 :             :    SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
    1889                 :             :    original with it and return it.  If there is no need to re-map, return NULL.
    1890                 :             :    ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments.  */
    1891                 :             : 
    1892                 :             : tree
    1893                 :           0 : ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name,
    1894                 :             :                                                               gimple *stmt)
    1895                 :             : {
    1896                 :           0 :   gcc_assert (!m_id);
    1897                 :           0 :   if (TREE_CODE (old_name) != SSA_NAME)
    1898                 :             :     return NULL;
    1899                 :             : 
    1900                 :           0 :   tree decl = SSA_NAME_VAR (old_name);
    1901                 :           0 :   if (decl == NULL_TREE
    1902                 :           0 :       || TREE_CODE (decl) != PARM_DECL)
    1903                 :             :     return NULL;
    1904                 :             : 
    1905                 :           0 :   tree repl = get_replacement_ssa_base (decl);
    1906                 :           0 :   if (!repl)
    1907                 :             :     return NULL;
    1908                 :             : 
    1909                 :           0 :   tree new_name = make_ssa_name (repl, stmt);
    1910                 :           0 :   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
    1911                 :           0 :     = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);
    1912                 :             : 
    1913                 :           0 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1914                 :             :     {
    1915                 :           0 :       fprintf (dump_file, "replacing an SSA name of a removed param ");
    1916                 :           0 :       print_generic_expr (dump_file, old_name);
    1917                 :           0 :       fprintf (dump_file, " with ");
    1918                 :           0 :       print_generic_expr (dump_file, new_name);
    1919                 :           0 :       fprintf (dump_file, "\n");
    1920                 :             :     }
    1921                 :             : 
    1922                 :           0 :   replace_uses_by (old_name, new_name);
    1923                 :           0 :   return new_name;
    1924                 :             : }
    1925                 :             : 
    1926                 :             : /* If the expression *EXPR_P should be replaced, do so.  CONVERT specifies
    1927                 :             :    whether the function should care about type incompatibility of the current
    1928                 :             :    and new expressions.  If it is false, the function will leave
    1929                 :             :    incompatibility issues to the caller - note that when the function
    1930                 :             :    encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
    1931                 :             :    their bases instead of the expressions themselves and then also performs any
    1932                 :             :    necessary conversions.  */
    1933                 :             : 
    1934                 :             : bool
    1935                 :     2322018 : ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert,
    1936                 :             :                                                gimple_seq *extra_stmts)
    1937                 :             : {
    1938                 :     2322018 :   tree expr = *expr_p;
    1939                 :             : 
    1940                 :     4562012 :   if (m_replacements.is_empty ())
    1941                 :             :     return false;
    1942                 :     1002264 :   if (TREE_CODE (expr) == BIT_FIELD_REF
    1943                 :     1002264 :       || TREE_CODE (expr) == IMAGPART_EXPR
    1944                 :     1001476 :       || TREE_CODE (expr) == REALPART_EXPR)
    1945                 :             :     {
    1946                 :             :       /* For a BIT_FIELD_REF do not bother to VIEW_CONVERT the base,
    1947                 :             :          instead reference the replacement directly.  */
    1948                 :        1117 :       convert = TREE_CODE (expr) != BIT_FIELD_REF;
    1949                 :        1117 :       expr_p = &TREE_OPERAND (expr, 0);
    1950                 :        1117 :       expr = *expr_p;
    1951                 :             :     }
    1952                 :             : 
    1953                 :     1002264 :   ipa_param_body_replacement *pbr = get_expr_replacement (expr, false);
    1954                 :     1002264 :   if (!pbr)
    1955                 :             :     return false;
    1956                 :             : 
    1957                 :       82024 :   tree repl = pbr->repl;
    1958                 :       82024 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1959                 :             :     {
    1960                 :           8 :       fprintf (dump_file, "About to replace expr ");
    1961                 :           8 :       print_generic_expr (dump_file, expr);
    1962                 :           8 :       fprintf (dump_file, " with ");
    1963                 :           8 :       print_generic_expr (dump_file, repl);
    1964                 :           8 :       fprintf (dump_file, "\n");
    1965                 :             :     }
    1966                 :             : 
    1967                 :       82261 :   if (convert && !useless_type_conversion_p (TREE_TYPE (expr),
    1968                 :         237 :                                              TREE_TYPE (repl)))
    1969                 :             :     {
    1970                 :           8 :       gcc_checking_assert (tree_to_shwi (TYPE_SIZE (TREE_TYPE (expr)))
    1971                 :             :                            == tree_to_shwi (TYPE_SIZE (TREE_TYPE (repl))));
    1972                 :           8 :       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), repl);
    1973                 :           8 :       if (is_gimple_reg (repl)
    1974                 :           8 :           && is_gimple_reg_type (TREE_TYPE (expr)))
    1975                 :             :         {
    1976                 :           0 :           gcc_assert (extra_stmts);
    1977                 :           0 :           vce = force_gimple_operand (vce, extra_stmts, true, NULL_TREE);
    1978                 :             :         }
    1979                 :           8 :       *expr_p = vce;
    1980                 :             :     }
    1981                 :             :   else
    1982                 :       82016 :     *expr_p = repl;
    1983                 :             :   return true;
    1984                 :             : }
    1985                 :             : 
    1986                 :             : /* If the assignment statement STMT contains any expressions that need to
    1987                 :             :    replaced with a different one as noted by ADJUSTMENTS, do so.  Handle any
    1988                 :             :    potential type incompatibilities.  If any conversion sttements have to be
    1989                 :             :    pre-pended to STMT, they will be added to EXTRA_STMTS.  Return true iff the
    1990                 :             :    statement was modified.  */
    1991                 :             : 
    1992                 :             : bool
    1993                 :     1738579 : ipa_param_body_adjustments::modify_assignment (gimple *stmt,
    1994                 :             :                                                gimple_seq *extra_stmts)
    1995                 :             : {
    1996                 :     1738579 :   tree *lhs_p, *rhs_p;
    1997                 :     1738579 :   bool any;
    1998                 :             : 
    1999                 :     2288635 :   if (m_replacements.is_empty () || !gimple_assign_single_p (stmt))
    2000                 :             :     return false;
    2001                 :             : 
    2002                 :      378292 :   rhs_p = gimple_assign_rhs1_ptr (stmt);
    2003                 :      378292 :   lhs_p = gimple_assign_lhs_ptr (stmt);
    2004                 :             : 
    2005                 :      378292 :   any = modify_expression (lhs_p, false);
    2006                 :      378292 :   any |= modify_expression (rhs_p, false, extra_stmts);
    2007                 :      378292 :   if (any
    2008                 :      378292 :       && !useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
    2009                 :             :     {
    2010                 :           3 :       if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
    2011                 :             :         {
    2012                 :             :           /* V_C_Es of constructors can cause trouble (PR 42714).  */
    2013                 :           0 :           if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
    2014                 :           0 :             *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
    2015                 :             :           else
    2016                 :           0 :             *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
    2017                 :             :                                         NULL);
    2018                 :             :         }
    2019                 :             :       else
    2020                 :             :         {
    2021                 :           3 :           gcc_checking_assert (tree_to_shwi (TYPE_SIZE (TREE_TYPE (*lhs_p)))
    2022                 :             :                               == tree_to_shwi (TYPE_SIZE (TREE_TYPE (*rhs_p))));
    2023                 :           3 :           tree new_rhs = fold_build1_loc (gimple_location (stmt),
    2024                 :           3 :                                           VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
    2025                 :             :                                           *rhs_p);
    2026                 :           3 :           tree tmp = force_gimple_operand (new_rhs, extra_stmts, true,
    2027                 :             :                                            NULL_TREE);
    2028                 :           3 :           gimple_assign_set_rhs1 (stmt, tmp);
    2029                 :             :         }
    2030                 :           3 :       return true;
    2031                 :             :     }
    2032                 :             : 
    2033                 :             :   return any;
    2034                 :             : }
    2035                 :             : 
    2036                 :             : /* Record information about what modifications to call arguments have already
    2037                 :             :    been done by clone materialization into a summary describing CS.  The
    2038                 :             :    information is stored in NEW_INDEX_MAP, NEW_PT_MAP and NEW_ALWAYS_COPY_DELTA
    2039                 :             :    and correspond to equivalent fields in ipa_edge_modification_info.  Return
    2040                 :             :    the edge summary.  */
    2041                 :             : 
    2042                 :             : static ipa_edge_modification_info *
    2043                 :       11376 : record_argument_state_1 (cgraph_edge *cs, const vec<int> &new_index_map,
    2044                 :             :                          const vec<pass_through_split_map> &new_pt_map,
    2045                 :             :                          int new_always_copy_delta)
    2046                 :             : 
    2047                 :             : {
    2048                 :       11376 :   ipa_edge_modification_info *sum = ipa_edge_modifications->get_create (cs);
    2049                 :             : 
    2050                 :       11376 :   unsigned len = sum->pass_through_map.length ();
    2051                 :       11376 :   for (unsigned i = 0; i < len; i++)
    2052                 :             :     {
    2053                 :           0 :       unsigned oldnew = sum->pass_through_map[i].new_index;
    2054                 :           0 :       sum->pass_through_map[i].new_index = new_index_map[oldnew];
    2055                 :             :     }
    2056                 :             : 
    2057                 :       11376 :   len = sum->index_map.length ();
    2058                 :           0 :   if (len > 0)
    2059                 :             :     {
    2060                 :           0 :       unsigned nptlen = new_pt_map.length ();
    2061                 :           0 :       for (unsigned j = 0; j < nptlen; j++)
    2062                 :             :         {
    2063                 :           0 :           int inverse = -1;
    2064                 :           0 :           for (unsigned i = 0; i < len ; i++)
    2065                 :           0 :             if ((unsigned) sum->index_map[i] == new_pt_map[j].base_index)
    2066                 :             :             {
    2067                 :           0 :               inverse = i;
    2068                 :           0 :               break;
    2069                 :             :             }
    2070                 :           0 :           gcc_assert (inverse >= 0);
    2071                 :           0 :           pass_through_split_map ptm_item;
    2072                 :             : 
    2073                 :           0 :           ptm_item.base_index = inverse;
    2074                 :           0 :           ptm_item.unit_offset = new_pt_map[j].unit_offset;
    2075                 :           0 :           ptm_item.new_index = new_pt_map[j].new_index;
    2076                 :           0 :           sum->pass_through_map.safe_push (ptm_item);
    2077                 :             :         }
    2078                 :             : 
    2079                 :           0 :       for (unsigned i = 0; i < len; i++)
    2080                 :             :         {
    2081                 :           0 :           int idx = sum->index_map[i];
    2082                 :           0 :           if (idx < 0)
    2083                 :           0 :             continue;
    2084                 :           0 :           sum->index_map[i] = new_index_map[idx];
    2085                 :             :         }
    2086                 :             :     }
    2087                 :             :   else
    2088                 :             :     {
    2089                 :       11376 :       sum->pass_through_map.safe_splice (new_pt_map);
    2090                 :       11376 :       sum->index_map.safe_splice (new_index_map);
    2091                 :             :     }
    2092                 :       11376 :   sum->always_copy_delta += new_always_copy_delta;
    2093                 :       11376 :   return sum;
    2094                 :             : }
    2095                 :             : 
    2096                 :             : /* Record information about what modifications to call arguments have already
    2097                 :             :    been done by clone materialization into a summary of an edge describing the
    2098                 :             :    call in this clone and all its clones.  NEW_INDEX_MAP, NEW_PT_MAP and
    2099                 :             :    NEW_ALWAYS_COPY_DELTA have the same meaning as record_argument_state_1.
    2100                 :             : 
    2101                 :             :    In order to associate the info with the right edge summaries, we need
    2102                 :             :    address of the ORIG_STMT in the function from which we are cloning (because
    2103                 :             :    the edges have not yet been re-assigned to the new statement that has just
    2104                 :             :    been created) and ID, the structure governing function body copying.  */
    2105                 :             : 
    2106                 :             : static void
    2107                 :       11376 : record_argument_state (copy_body_data *id, gimple *orig_stmt,
    2108                 :             :                        const vec<int> &new_index_map,
    2109                 :             :                        const vec<pass_through_split_map> &new_pt_map,
    2110                 :             :                        int new_always_copy_delta)
    2111                 :             : {
    2112                 :       11376 :   if (!ipa_edge_modifications)
    2113                 :        2312 :     ipa_edge_modifications = new ipa_edge_modification_sum (symtab);
    2114                 :             : 
    2115                 :       11376 :   struct cgraph_node *this_node = id->dst_node;
    2116                 :       11376 :   ipa_edge_modification_info *first_sum = NULL;
    2117                 :       11376 :   cgraph_edge *cs = this_node->get_edge (orig_stmt);
    2118                 :       11376 :   if (cs)
    2119                 :       11376 :     first_sum = record_argument_state_1 (cs, new_index_map, new_pt_map,
    2120                 :             :                                          new_always_copy_delta);
    2121                 :             :   else
    2122                 :           0 :     gcc_assert (this_node->clones);
    2123                 :             : 
    2124                 :       11376 :   if (!this_node->clones)
    2125                 :             :     return;
    2126                 :       20649 :   for (cgraph_node *subclone = this_node->clones; subclone != this_node;)
    2127                 :             :     {
    2128                 :       17168 :       cs = subclone->get_edge (orig_stmt);
    2129                 :       17168 :       if (cs)
    2130                 :             :         {
    2131                 :       17168 :           if (!first_sum)
    2132                 :           0 :             first_sum = record_argument_state_1 (cs, new_index_map, new_pt_map,
    2133                 :             :                                                  new_always_copy_delta);
    2134                 :             :           else
    2135                 :             :             {
    2136                 :       17168 :               ipa_edge_modification_info *s2
    2137                 :       17168 :                 = ipa_edge_modifications->get_create (cs);
    2138                 :       17168 :               s2->index_map.truncate (0);
    2139                 :       17168 :               s2->index_map.safe_splice (first_sum->index_map);
    2140                 :       17168 :               s2->pass_through_map.truncate (0);
    2141                 :       17168 :               s2->pass_through_map.safe_splice (first_sum->pass_through_map);
    2142                 :       17168 :               s2->always_copy_delta = first_sum->always_copy_delta;
    2143                 :             :             }
    2144                 :             :         }
    2145                 :             :       else
    2146                 :           0 :         gcc_assert (subclone->clones);
    2147                 :             : 
    2148                 :       17168 :       if (subclone->clones)
    2149                 :             :         subclone = subclone->clones;
    2150                 :       16441 :       else if (subclone->next_sibling_clone)
    2151                 :             :         subclone = subclone->next_sibling_clone;
    2152                 :             :       else
    2153                 :             :         {
    2154                 :        8098 :           while (subclone != this_node && !subclone->next_sibling_clone)
    2155                 :        4208 :             subclone = subclone->clone_of;
    2156                 :        3890 :           if (subclone != this_node)
    2157                 :         409 :             subclone = subclone->next_sibling_clone;
    2158                 :             :         }
    2159                 :             :     }
    2160                 :             : }
    2161                 :             : 
    2162                 :             : /* If the call statement pointed at by STMT_P contains any expressions that
    2163                 :             :    need to replaced with a different one as noted by ADJUSTMENTS, do so.  f the
    2164                 :             :    statement needs to be rebuilt, do so.  Return true if any modifications have
    2165                 :             :    been performed.  ORIG_STMT, if not NULL, is the original statement in the
    2166                 :             :    function that is being cloned from, which at this point can be used to look
    2167                 :             :    up call_graph edges.
    2168                 :             : 
    2169                 :             :    If the method is invoked as a part of IPA clone materialization and if any
    2170                 :             :    parameter split is pass-through, i.e. it applies to the functin that is
    2171                 :             :    being modified and also to the callee of the statement, replace the
    2172                 :             :    parameter passed to old callee with all of the replacement a callee might
    2173                 :             :    possibly want and record the performed argument modifications in
    2174                 :             :    ipa_edge_modifications.  Likewise if any argument has already been left out
    2175                 :             :    because it is not necessary.  */
    2176                 :             : 
    2177                 :             : bool
    2178                 :      564485 : ipa_param_body_adjustments::modify_call_stmt (gcall **stmt_p,
    2179                 :             :                                               gimple *orig_stmt)
    2180                 :             : {
    2181                 :      564485 :   auto_vec <unsigned, 4> pass_through_args;
    2182                 :      564485 :   auto_vec <unsigned, 4> pass_through_pbr_indices;
    2183                 :      564485 :   auto_vec <HOST_WIDE_INT, 4> pass_through_offsets;
    2184                 :      564485 :   gcall *stmt = *stmt_p;
    2185                 :      564485 :   unsigned nargs = gimple_call_num_args (stmt);
    2186                 :      564485 :   bool recreate = false;
    2187                 :      564485 :   gcc_assert (m_sorted_replacements_p);
    2188                 :             : 
    2189                 :     1884026 :   for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
    2190                 :             :     {
    2191                 :     1319541 :       tree t = gimple_call_arg (stmt, i);
    2192                 :     1319541 :       gcc_assert (TREE_CODE (t) != BIT_FIELD_REF
    2193                 :             :                   && TREE_CODE (t) != IMAGPART_EXPR
    2194                 :             :                   && TREE_CODE (t) != REALPART_EXPR);
    2195                 :             : 
    2196                 :     1319541 :       if (TREE_CODE (t) == SSA_NAME
    2197                 :     1319541 :           && m_dead_ssas.contains (t))
    2198                 :             :         recreate = true;
    2199                 :             : 
    2200                 :     1319541 :       if (m_replacements.is_empty ())
    2201                 :     1314172 :         continue;
    2202                 :             : 
    2203                 :      184380 :       tree base;
    2204                 :      184380 :       unsigned agg_arg_offset;
    2205                 :      184380 :       if (!isra_get_ref_base_and_offset (t, &base, &agg_arg_offset))
    2206                 :           0 :         continue;
    2207                 :             : 
    2208                 :      184380 :       bool by_ref = false;
    2209                 :      184380 :       if (TREE_CODE (base) == SSA_NAME)
    2210                 :             :         {
    2211                 :       95688 :           if (!SSA_NAME_IS_DEFAULT_DEF (base))
    2212                 :       74531 :             continue;
    2213                 :       21157 :           base = SSA_NAME_VAR (base);
    2214                 :       21157 :           gcc_checking_assert (base);
    2215                 :             :           by_ref = true;
    2216                 :             :         }
    2217                 :      109849 :       if (TREE_CODE (base) != PARM_DECL)
    2218                 :       85498 :         continue;
    2219                 :             : 
    2220                 :       24351 :       ipa_param_body_replacement *first_rep
    2221                 :       24351 :         = lookup_first_base_replacement (base);
    2222                 :       24351 :       if (!first_rep)
    2223                 :       18982 :         continue;
    2224                 :        5369 :       unsigned first_rep_index = first_rep - m_replacements.begin ();
    2225                 :             : 
    2226                 :             :       /* We still have to distinguish between an end-use that we have to
    2227                 :             :          transform now and a pass-through, which happens in the following
    2228                 :             :          two cases.  */
    2229                 :             : 
    2230                 :             :       /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
    2231                 :             :          &MEM_REF[ssa_name + offset], we will also have to detect that case
    2232                 :             :          here.    */
    2233                 :             : 
    2234                 :        5369 :       if (TREE_CODE (t) == SSA_NAME
    2235                 :        4452 :           && SSA_NAME_IS_DEFAULT_DEF (t)
    2236                 :        4452 :           && SSA_NAME_VAR (t)
    2237                 :        9821 :           && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL)
    2238                 :             :         {
    2239                 :             :           /* This must be a by_reference pass-through.  */
    2240                 :        4452 :           recreate = true;
    2241                 :        4452 :           gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
    2242                 :        4452 :           pass_through_args.safe_push (i);
    2243                 :        4452 :           pass_through_pbr_indices.safe_push (first_rep_index);
    2244                 :        4452 :           pass_through_offsets.safe_push (agg_arg_offset);
    2245                 :             :         }
    2246                 :         917 :       else if (!by_ref && AGGREGATE_TYPE_P (TREE_TYPE (t)))
    2247                 :             :         {
    2248                 :             :           /* Currently IPA-SRA guarantees the aggregate access type
    2249                 :             :              exactly matches in this case.  So if it does not match, it is
    2250                 :             :              a pass-through argument that will be sorted out at edge
    2251                 :             :              redirection time.  */
    2252                 :         908 :           ipa_param_body_replacement *pbr
    2253                 :         908 :             = lookup_replacement_1 (base, agg_arg_offset);
    2254                 :             : 
    2255                 :         908 :           if (!pbr
    2256                 :         908 :               || (TYPE_MAIN_VARIANT (TREE_TYPE (t))
    2257                 :         902 :                   != TYPE_MAIN_VARIANT (TREE_TYPE (pbr->repl))))
    2258                 :             :             {
    2259                 :         887 :               recreate = true;
    2260                 :         887 :               pass_through_args.safe_push (i);
    2261                 :         887 :               pass_through_pbr_indices.safe_push (first_rep_index);
    2262                 :         887 :               pass_through_offsets.safe_push (agg_arg_offset);
    2263                 :             :             }
    2264                 :             :         }
    2265                 :             :     }
    2266                 :             : 
    2267                 :      564485 :   if (!recreate)
    2268                 :             :     {
    2269                 :             :       /* No need to rebuild the statement, let's just modify arguments
    2270                 :             :          and the LHS if/as appropriate.  */
    2271                 :             :       bool modified = false;
    2272                 :     1833888 :       for (unsigned i = 0; i < nargs; i++)
    2273                 :             :         {
    2274                 :     1280779 :           tree *t = gimple_call_arg_ptr (stmt, i);
    2275                 :     1280779 :           modified |= modify_expression (t, true);
    2276                 :             :         }
    2277                 :      553109 :       if (gimple_call_lhs (stmt))
    2278                 :             :         {
    2279                 :      193740 :           tree *t = gimple_call_lhs_ptr (stmt);
    2280                 :      193740 :           modified |= modify_expression (t, false);
    2281                 :             :         }
    2282                 :      553109 :       return modified;
    2283                 :             :     }
    2284                 :             : 
    2285                 :       11376 :   auto_vec<int, 16> index_map;
    2286                 :       11376 :   auto_vec<pass_through_split_map, 4> pass_through_map;
    2287                 :       11376 :   auto_vec<tree, 16> vargs;
    2288                 :       11376 :   int always_copy_delta = 0;
    2289                 :       11376 :   unsigned pt_idx = 0;
    2290                 :       11376 :   int new_arg_idx = 0;
    2291                 :       50138 :   for (unsigned i = 0; i < nargs; i++)
    2292                 :             :     {
    2293                 :       38762 :       if (pt_idx < pass_through_args.length ()
    2294                 :       46737 :           && i == pass_through_args[pt_idx])
    2295                 :             :         {
    2296                 :        5339 :           unsigned j = pass_through_pbr_indices[pt_idx];
    2297                 :        5339 :           unsigned agg_arg_offset = pass_through_offsets[pt_idx];
    2298                 :        5339 :           pt_idx++;
    2299                 :        5339 :           always_copy_delta--;
    2300                 :        5339 :           tree base = m_replacements[j].base;
    2301                 :             : 
    2302                 :             :           /* In order to be put into SSA form, we have to push all replacements
    2303                 :             :              pertaining to this parameter as parameters to the call statement.
    2304                 :             :              Edge redirection will need to use edge summary to weed out the
    2305                 :             :              unnecessary ones.  */
    2306                 :        5339 :           unsigned repl_list_len = m_replacements.length ();
    2307                 :       15074 :           for (; j < repl_list_len; j++)
    2308                 :             :             {
    2309                 :       10425 :               if (m_replacements[j].base != base)
    2310                 :             :                 break;
    2311                 :        9735 :               if (m_replacements[j].unit_offset < agg_arg_offset)
    2312                 :           1 :                 continue;
    2313                 :        9734 :               pass_through_split_map pt_map;
    2314                 :        9734 :               pt_map.base_index = i;
    2315                 :        9734 :               pt_map.unit_offset
    2316                 :        9734 :                 = m_replacements[j].unit_offset - agg_arg_offset;
    2317                 :        9734 :               pt_map.new_index = new_arg_idx;
    2318                 :        9734 :               pass_through_map.safe_push (pt_map);
    2319                 :        9734 :               vargs.safe_push (m_replacements[j].repl);
    2320                 :        9734 :               new_arg_idx++;
    2321                 :        9734 :               always_copy_delta++;
    2322                 :             :             }
    2323                 :        5339 :           index_map.safe_push (-1);
    2324                 :             :         }
    2325                 :             :       else
    2326                 :             :         {
    2327                 :       33423 :           tree t = gimple_call_arg (stmt, i);
    2328                 :       33423 :           if (TREE_CODE (t) == SSA_NAME
    2329                 :       33423 :               && m_dead_ssas.contains (t))
    2330                 :             :             {
    2331                 :        7052 :               always_copy_delta--;
    2332                 :        7052 :               index_map.safe_push (-1);
    2333                 :             :             }
    2334                 :             :           else
    2335                 :             :             {
    2336                 :       26371 :               modify_expression (&t, true);
    2337                 :       26371 :               vargs.safe_push (t);
    2338                 :       26371 :               index_map.safe_push (new_arg_idx);
    2339                 :       26371 :               new_arg_idx++;
    2340                 :             :             }
    2341                 :             :         }
    2342                 :             :     }
    2343                 :             : 
    2344                 :       11376 :   gcall *new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs);
    2345                 :       11376 :   if (gimple_has_location (stmt))
    2346                 :        9979 :     gimple_set_location (new_stmt, gimple_location (stmt));
    2347                 :       11376 :   gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
    2348                 :       11376 :   gimple_call_copy_flags (new_stmt, stmt);
    2349                 :       11376 :   if (tree lhs = gimple_call_lhs (stmt))
    2350                 :             :     {
    2351                 :        8900 :       modify_expression (&lhs, false);
    2352                 :             :       /* Avoid adjusting SSA_NAME_DEF_STMT of a SSA lhs, SSA names
    2353                 :             :          have not yet been remapped.  */
    2354                 :        8900 :       *gimple_call_lhs_ptr (new_stmt) = lhs;
    2355                 :             :     }
    2356                 :       11376 :   *stmt_p = new_stmt;
    2357                 :             : 
    2358                 :       11376 :   if (orig_stmt)
    2359                 :       11376 :     record_argument_state (m_id, orig_stmt, index_map, pass_through_map,
    2360                 :             :                            always_copy_delta);
    2361                 :       11376 :   return true;
    2362                 :      575861 : }
    2363                 :             : 
    2364                 :             : /* If the statement STMT contains any expressions that need to replaced with a
    2365                 :             :    different one as noted by ADJUSTMENTS, do so.  Handle any potential type
    2366                 :             :    incompatibilities.  If any conversion sttements have to be pre-pended to
    2367                 :             :    STMT, they will be added to EXTRA_STMTS.  Return true iff the statement was
    2368                 :             :    modified.  */
    2369                 :             : 
    2370                 :             : bool
    2371                 :     2930743 : ipa_param_body_adjustments::modify_gimple_stmt (gimple **stmt,
    2372                 :             :                                                 gimple_seq *extra_stmts,
    2373                 :             :                                                 gimple *orig_stmt)
    2374                 :             : {
    2375                 :     2930743 :   bool modified = false;
    2376                 :     2930743 :   tree *t;
    2377                 :             : 
    2378                 :     2930743 :   switch (gimple_code (*stmt))
    2379                 :             :     {
    2380                 :      129804 :     case GIMPLE_RETURN:
    2381                 :      129804 :       t = gimple_return_retval_ptr (as_a <greturn *> (*stmt));
    2382                 :      129804 :       if (m_adjustments && m_adjustments->m_skip_return)
    2383                 :       31819 :         *t = NULL_TREE;
    2384                 :       97985 :       else if (*t != NULL_TREE)
    2385                 :       52625 :         modified |= modify_expression (t, true);
    2386                 :             :       break;
    2387                 :             : 
    2388                 :     1738579 :     case GIMPLE_ASSIGN:
    2389                 :     1738579 :       modified |= modify_assignment (*stmt, extra_stmts);
    2390                 :     1738579 :       break;
    2391                 :             : 
    2392                 :      564485 :     case GIMPLE_CALL:
    2393                 :      564485 :       modified |= modify_call_stmt ((gcall **) stmt, orig_stmt);
    2394                 :      564485 :       break;
    2395                 :             : 
    2396                 :        1054 :     case GIMPLE_ASM:
    2397                 :        1054 :       {
    2398                 :        1054 :         gasm *asm_stmt = as_a <gasm *> (*stmt);
    2399                 :        2559 :         for (unsigned i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
    2400                 :             :           {
    2401                 :        1505 :             t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
    2402                 :        1505 :             modified |= modify_expression (t, true);
    2403                 :             :           }
    2404                 :        2568 :         for (unsigned i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
    2405                 :             :           {
    2406                 :        1514 :             t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
    2407                 :        1514 :             modified |= modify_expression (t, false);
    2408                 :             :           }
    2409                 :             :       }
    2410                 :             :       break;
    2411                 :             : 
    2412                 :             :     default:
    2413                 :             :       break;
    2414                 :             :     }
    2415                 :     2930743 :   return modified;
    2416                 :             : }
    2417                 :             : 
    2418                 :             : 
    2419                 :             : /* Traverse body of the current function and perform the requested adjustments
    2420                 :             :    on its statements.  Return true iff the CFG has been changed.  */
    2421                 :             : 
    2422                 :             : bool
    2423                 :           0 : ipa_param_body_adjustments::modify_cfun_body ()
    2424                 :             : {
    2425                 :           0 :   bool cfg_changed = false;
    2426                 :           0 :   basic_block bb;
    2427                 :             : 
    2428                 :           0 :   FOR_EACH_BB_FN (bb, cfun)
    2429                 :             :     {
    2430                 :           0 :       gimple_stmt_iterator gsi;
    2431                 :             : 
    2432                 :           0 :       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    2433                 :             :         {
    2434                 :           0 :           gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
    2435                 :           0 :           tree new_lhs, old_lhs = gimple_phi_result (phi);
    2436                 :           0 :           new_lhs = replace_removed_params_ssa_names (old_lhs, phi);
    2437                 :           0 :           if (new_lhs)
    2438                 :             :             {
    2439                 :           0 :               gimple_phi_set_result (phi, new_lhs);
    2440                 :           0 :               release_ssa_name (old_lhs);
    2441                 :             :             }
    2442                 :             :         }
    2443                 :             : 
    2444                 :           0 :       gsi = gsi_start_bb (bb);
    2445                 :           0 :       while (!gsi_end_p (gsi))
    2446                 :             :         {
    2447                 :           0 :           gimple *stmt = gsi_stmt (gsi);
    2448                 :           0 :           gimple *stmt_copy = stmt;
    2449                 :           0 :           gimple_seq extra_stmts = NULL;
    2450                 :           0 :           bool modified = modify_gimple_stmt (&stmt, &extra_stmts, NULL);
    2451                 :           0 :           if (stmt != stmt_copy)
    2452                 :             :             {
    2453                 :           0 :               gcc_checking_assert (modified);
    2454                 :           0 :               gsi_replace (&gsi, stmt, false);
    2455                 :             :             }
    2456                 :           0 :           if (!gimple_seq_empty_p (extra_stmts))
    2457                 :           0 :             gsi_insert_seq_before (&gsi, extra_stmts, GSI_SAME_STMT);
    2458                 :             : 
    2459                 :           0 :           def_operand_p defp;
    2460                 :           0 :           ssa_op_iter iter;
    2461                 :           0 :           FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
    2462                 :             :             {
    2463                 :           0 :               tree old_def = DEF_FROM_PTR (defp);
    2464                 :           0 :               if (tree new_def = replace_removed_params_ssa_names (old_def,
    2465                 :             :                                                                    stmt))
    2466                 :             :                 {
    2467                 :           0 :                   SET_DEF (defp, new_def);
    2468                 :           0 :                   release_ssa_name (old_def);
    2469                 :           0 :                   modified = true;
    2470                 :             :                 }
    2471                 :             :             }
    2472                 :             : 
    2473                 :           0 :           if (modified)
    2474                 :             :             {
    2475                 :           0 :               update_stmt (stmt);
    2476                 :           0 :               if (maybe_clean_eh_stmt (stmt)
    2477                 :           0 :                   && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
    2478                 :             :                 cfg_changed = true;
    2479                 :             :             }
    2480                 :           0 :           gsi_next (&gsi);
    2481                 :             :         }
    2482                 :             :     }
    2483                 :             : 
    2484                 :           0 :   return cfg_changed;
    2485                 :             : }
    2486                 :             : 
    2487                 :             : /* Call gimple_debug_bind_reset_value on all debug statements describing
    2488                 :             :    gimple register parameters that are being removed or replaced.  */
    2489                 :             : 
    2490                 :             : void
    2491                 :           0 : ipa_param_body_adjustments::reset_debug_stmts ()
    2492                 :             : {
    2493                 :           0 :   int i, len;
    2494                 :           0 :   gimple_stmt_iterator *gsip = NULL, gsi;
    2495                 :             : 
    2496                 :           0 :   if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    2497                 :             :     {
    2498                 :           0 :       gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
    2499                 :           0 :       gsip = &gsi;
    2500                 :             :     }
    2501                 :           0 :   len = m_reset_debug_decls.length ();
    2502                 :           0 :   for (i = 0; i < len; i++)
    2503                 :             :     {
    2504                 :           0 :       imm_use_iterator ui;
    2505                 :           0 :       gimple *stmt;
    2506                 :           0 :       gdebug *def_temp;
    2507                 :           0 :       tree name, vexpr, copy = NULL_TREE;
    2508                 :           0 :       use_operand_p use_p;
    2509                 :           0 :       tree decl = m_reset_debug_decls[i];
    2510                 :             : 
    2511                 :           0 :       gcc_checking_assert (is_gimple_reg (decl));
    2512                 :           0 :       name = ssa_default_def (cfun, decl);
    2513                 :           0 :       vexpr = NULL;
    2514                 :           0 :       if (name)
    2515                 :           0 :         FOR_EACH_IMM_USE_STMT (stmt, ui, name)
    2516                 :             :           {
    2517                 :           0 :             if (gimple_clobber_p (stmt))
    2518                 :             :               {
    2519                 :           0 :                 gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
    2520                 :           0 :                 unlink_stmt_vdef (stmt);
    2521                 :           0 :                 gsi_remove (&cgsi, true);
    2522                 :           0 :                 release_defs (stmt);
    2523                 :           0 :                 continue;
    2524                 :           0 :               }
    2525                 :             :             /* All other users must have been removed by function body
    2526                 :             :                modification.  */
    2527                 :           0 :             gcc_assert (is_gimple_debug (stmt));
    2528                 :           0 :             if (vexpr == NULL && gsip != NULL)
    2529                 :             :               {
    2530                 :           0 :                 vexpr = build_debug_expr_decl (TREE_TYPE (name));
    2531                 :             :                 /* FIXME: Is setting the mode really necessary? */
    2532                 :           0 :                 SET_DECL_MODE (vexpr, DECL_MODE (decl));
    2533                 :           0 :                 def_temp = gimple_build_debug_source_bind (vexpr, decl, NULL);
    2534                 :           0 :                 gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
    2535                 :             :               }
    2536                 :           0 :             if (vexpr)
    2537                 :             :               {
    2538                 :           0 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
    2539                 :           0 :                   SET_USE (use_p, vexpr);
    2540                 :             :               }
    2541                 :             :             else
    2542                 :           0 :               gimple_debug_bind_reset_value (stmt);
    2543                 :           0 :             update_stmt (stmt);
    2544                 :           0 :           }
    2545                 :             :       /* Create a VAR_DECL for debug info purposes.  */
    2546                 :           0 :       if (!DECL_IGNORED_P (decl))
    2547                 :             :         {
    2548                 :           0 :           copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
    2549                 :           0 :                              VAR_DECL, DECL_NAME (decl),
    2550                 :           0 :                              TREE_TYPE (decl));
    2551                 :           0 :           if (DECL_PT_UID_SET_P (decl))
    2552                 :           0 :             SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
    2553                 :           0 :           TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
    2554                 :           0 :           TREE_READONLY (copy) = TREE_READONLY (decl);
    2555                 :           0 :           TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
    2556                 :           0 :           DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
    2557                 :           0 :           DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
    2558                 :           0 :           DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
    2559                 :           0 :           DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
    2560                 :           0 :           DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
    2561                 :           0 :           SET_DECL_RTL (copy, 0);
    2562                 :           0 :           TREE_USED (copy) = 1;
    2563                 :           0 :           DECL_CONTEXT (copy) = current_function_decl;
    2564                 :           0 :           add_local_decl (cfun, copy);
    2565                 :           0 :           DECL_CHAIN (copy)
    2566                 :           0 :             = BLOCK_VARS (DECL_INITIAL (current_function_decl));
    2567                 :           0 :           BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
    2568                 :             :         }
    2569                 :           0 :       if (gsip != NULL && copy && target_for_debug_bind (decl))
    2570                 :             :         {
    2571                 :           0 :           gcc_assert (TREE_CODE (decl) == PARM_DECL);
    2572                 :           0 :           if (vexpr)
    2573                 :           0 :             def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
    2574                 :             :           else
    2575                 :           0 :             def_temp = gimple_build_debug_source_bind (copy, decl,
    2576                 :             :                                                        NULL);
    2577                 :           0 :           gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
    2578                 :             :         }
    2579                 :             :     }
    2580                 :           0 : }
    2581                 :             : 
    2582                 :             : /* Perform all necessary body changes to change signature, body and debug info
    2583                 :             :    of fun according to adjustments passed at construction.  Return true if CFG
    2584                 :             :    was changed in any way.  The main entry point for modification of standalone
    2585                 :             :    functions that is not part of IPA clone materialization.  */
    2586                 :             : 
    2587                 :             : bool
    2588                 :           0 : ipa_param_body_adjustments::perform_cfun_body_modifications ()
    2589                 :             : {
    2590                 :           0 :   bool cfg_changed;
    2591                 :           0 :   modify_formal_parameters ();
    2592                 :           0 :   cfg_changed = modify_cfun_body ();
    2593                 :           0 :   reset_debug_stmts ();
    2594                 :             : 
    2595                 :           0 :   return cfg_changed;
    2596                 :             : }
    2597                 :             : 
    2598                 :             : 
    2599                 :             : /* If there are any initialization statements that need to be emitted into
    2600                 :             :    the basic block BB right at ther start of the new function, do so.  */
    2601                 :             : void
    2602                 :      143027 : ipa_param_body_adjustments::append_init_stmts (basic_block bb)
    2603                 :             : {
    2604                 :      143027 :   gimple_stmt_iterator si = gsi_last_bb (bb);
    2605                 :      144287 :   while (!m_split_agg_csts_inits.is_empty ())
    2606                 :        1260 :     gsi_insert_after (&si, m_split_agg_csts_inits.pop (), GSI_NEW_STMT);
    2607                 :      143027 : }
    2608                 :             : 
    2609                 :             : /* Deallocate summaries which otherwise stay alive until the end of
    2610                 :             :    compilation.  */
    2611                 :             : 
    2612                 :             : void
    2613                 :      249859 : ipa_edge_modifications_finalize ()
    2614                 :             : {
    2615                 :      249859 :   if (!ipa_edge_modifications)
    2616                 :             :     return;
    2617                 :        2312 :   delete ipa_edge_modifications;
    2618                 :        2312 :   ipa_edge_modifications = NULL;
    2619                 :             : }
    2620                 :             : 
    2621                 :             : /* Helper used to sort a vector of SSA_NAMES. */
    2622                 :             : 
    2623                 :             : static int
    2624                 :       20902 : compare_ssa_versions (const void *va, const void *vb)
    2625                 :             : {
    2626                 :       20902 :   const_tree const a = *(const_tree const*)va;
    2627                 :       20902 :   const_tree const b = *(const_tree const*)vb;
    2628                 :             : 
    2629                 :       20902 :   if (SSA_NAME_VERSION (a) < SSA_NAME_VERSION (b))
    2630                 :             :     return -1;
    2631                 :        8920 :   if (SSA_NAME_VERSION (a) > SSA_NAME_VERSION (b))
    2632                 :        8920 :     return 1;
    2633                 :             :   return 0;
    2634                 :             : }
    2635                 :             : 
    2636                 :             : /* Call release_ssa_name on all elements in KILLED_SSAS in a defined order.  */
    2637                 :             : 
    2638                 :             : void
    2639                 :     1962974 : ipa_release_ssas_in_hash (hash_set <tree> *killed_ssas)
    2640                 :             : {
    2641                 :     1962974 :   auto_vec<tree, 16> ssas_to_release;
    2642                 :     1977599 :   for (tree sn : *killed_ssas)
    2643                 :       14625 :     ssas_to_release.safe_push (sn);
    2644                 :     1962974 :   ssas_to_release.qsort (compare_ssa_versions);
    2645                 :     5903547 :   for (tree sn : ssas_to_release)
    2646                 :       14625 :     release_ssa_name (sn);
    2647                 :     1962974 : }
        

Generated by: LCOV version 2.1-beta

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