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