1 /* Manipulation of formal and actual parameters of functions and function
3 Copyright (C) 2017-2023 Free Software Foundation, Inc.
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
29 #include "fold-const.h"
31 #include "stor-layout.h"
33 #include "gimple-iterator.h"
34 #include "gimplify-me.h"
37 #include "ipa-param-manipulation.h"
38 #include "print-tree.h"
39 #include "gimple-pretty-print.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"
51 /* Actual prefixes of different newly synthetized parameters. Keep in sync
52 with IPA_PARAM_PREFIX_* defines. */
54 static const char *ipa_param_prefixes
[IPA_PARAM_PREFIX_COUNT
]
60 /* Names of parameters for dumping. Keep in sync with enum ipa_parm_op. */
62 static const char *ipa_param_op_names
[IPA_PARAM_PREFIX_COUNT
]
63 = {"IPA_PARAM_OP_UNDEFINED",
66 "IPA_PARAM_OP_SPLIT"};
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
72 struct pass_through_split_map
74 /* Original argument index. */
76 /* Offset of the split part in the original argument. */
78 /* Index of the split part in the call statement - where clone
79 materialization put it. */
83 /* Information about some call statements that needs to be conveyed from clone
84 materialization to edge redirection. */
86 class ipa_edge_modification_info
89 ipa_edge_modification_info ()
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;
103 /* Class for storing and retrieving summaries about cal statement
106 class ipa_edge_modification_sum
107 : public call_summary
<ipa_edge_modification_info
*>
110 ipa_edge_modification_sum (symbol_table
*table
)
111 : call_summary
<ipa_edge_modification_info
*> (table
)
115 /* Hook that is called by summary when an edge is duplicated. */
117 void duplicate (cgraph_edge
*,
119 ipa_edge_modification_info
*old_info
,
120 ipa_edge_modification_info
*new_info
) final override
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
;
128 /* Call summary to store information about edges which have had their arguments
129 partially modified already. */
131 static ipa_edge_modification_sum
*ipa_edge_modifications
;
133 /* Fail compilation if CS has any summary associated with it in
134 ipa_edge_modifications. */
137 ipa_verify_edge_has_no_modifications (cgraph_edge
*cs
)
139 gcc_assert (!ipa_edge_modifications
|| !ipa_edge_modifications
->get (cs
));
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). */
147 push_function_arg_decls (vec
<tree
> *args
, tree fndecl
)
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
));
159 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
162 args
->reserve_exact (count
);
163 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
164 args
->quick_push (parm
);
167 /* Fill an empty vector TYPES with trees representing formal parameters of
168 function type FNTYPE. */
171 push_function_arg_types (vec
<tree
> *types
, tree fntype
)
176 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
179 types
->reserve_exact (count
);
180 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
181 types
->quick_push (TREE_VALUE (t
));
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. */
188 ipa_dump_adjusted_parameters (FILE *f
,
189 vec
<ipa_adjusted_param
, va_gc
> *adj_params
)
191 unsigned i
, len
= vec_safe_length (adj_params
);
197 fprintf (f
, " IPA adjusted parameters: ");
198 for (i
= 0; i
< len
; i
++)
200 struct ipa_adjusted_param
*apm
;
201 apm
= &(*adj_params
)[i
];
208 fprintf (f
, "%i. %s %s", i
, ipa_param_op_names
[apm
->op
],
209 apm
->prev_clone_adjustment
? "prev_clone_adjustment " : "");
212 case IPA_PARAM_OP_UNDEFINED
:
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
);
220 case IPA_PARAM_OP_SPLIT
:
221 fprintf (f
, ", offset: %u", apm
->unit_offset
);
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
]);
231 fprintf (f
, ", reverse");
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
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
)
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
++)
252 ipa_adjusted_param
*apm
= &(*adj_params
)[i
];
253 if (apm
->op
== IPA_PARAM_OP_COPY
)
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 ())
262 new_types
->quick_push ((*otypes
)[index
]);
264 else if (apm
->op
== IPA_PARAM_OP_NEW
265 || apm
->op
== IPA_PARAM_OP_SPLIT
)
267 tree ntype
= apm
->type
;
268 if (is_gimple_reg_type (ntype
)
269 && TYPE_MODE (ntype
) != BLKmode
)
271 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ntype
));
272 if (TYPE_ALIGN (ntype
) != malign
)
273 ntype
= build_aligned_type (ntype
, malign
);
275 new_types
->quick_push (ntype
);
282 /* Return false if given attribute should prevent type adjustments. */
285 ipa_param_adjustments::type_attribute_allowed_p (tree name
)
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
))
297 /* Return true if attribute should be dropped if parameter changed. */
300 drop_type_attribute_if_params_changed_p (tree name
)
302 if (is_attribute_p ("fn spec", name
)
303 || is_attribute_p ("access", name
))
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. */
315 build_adjusted_function_type (tree orig_type
, vec
<tree
> *new_param_types
,
316 bool method2func
, bool skip_return
,
319 tree new_arg_types
= NULL
;
320 if (TYPE_ARG_TYPES (orig_type
))
322 gcc_checking_assert (new_param_types
);
323 bool last_parm_void
= (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type
)))
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
],
330 tree new_reversed
= nreverse (new_arg_types
);
334 TREE_CHAIN (new_arg_types
) = void_list_node
;
336 new_reversed
= void_list_node
;
338 new_arg_types
= new_reversed
;
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
;
350 ret_type
= void_type_node
;
352 ret_type
= TREE_TYPE (orig_type
);
355 = build_distinct_type_copy (build_function_type (ret_type
,
357 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
361 new_type
= build_distinct_type_copy (orig_type
);
362 TYPE_ARG_TYPES (new_type
) = new_arg_types
;
364 TREE_TYPE (new_type
) = void_type_node
;
366 if (args_modified
&& TYPE_ATTRIBUTES (new_type
))
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
)))
375 *last
= copy_node (t
);
376 TREE_CHAIN (*last
) = NULL
;
377 last
= &TREE_CHAIN (*last
);
384 /* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
388 ipa_param_adjustments::get_max_base_index ()
390 unsigned adj_len
= vec_safe_length (m_adj_params
);
392 for (unsigned i
= 0; i
< adj_len
; i
++)
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
;
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. */
410 ipa_param_adjustments::get_surviving_params (vec
<bool> *surviving_params
)
412 unsigned adj_len
= vec_safe_length (m_adj_params
);
413 int max_index
= get_max_base_index ();
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
++)
421 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
422 if (apm
->op
== IPA_PARAM_OP_COPY
)
423 (*surviving_params
)[apm
->base_index
] = true;
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. */
433 ipa_param_adjustments::get_updated_indices (vec
<int> *new_indices
)
435 unsigned adj_len
= vec_safe_length (m_adj_params
);
436 int max_index
= get_max_base_index ();
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
++)
446 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
447 if (apm
->op
== IPA_PARAM_OP_COPY
)
448 (*new_indices
)[apm
->base_index
] = i
;
452 /* Return the original index for the given new parameter index. Return a
453 negative number if not available. */
456 ipa_param_adjustments::get_original_index (int newidx
)
458 const ipa_adjusted_param
*adj
= &(*m_adj_params
)[newidx
];
459 if (adj
->op
!= IPA_PARAM_OP_COPY
)
461 return adj
->base_index
;
464 /* Return true if the first parameter (assuming there was one) survives the
465 transformation intact and remains the first one. */
468 ipa_param_adjustments::first_param_intact_p ()
470 return (!vec_safe_is_empty (m_adj_params
)
471 && (*m_adj_params
)[0].op
== IPA_PARAM_OP_COPY
472 && (*m_adj_params
)[0].base_index
== 0);
475 /* Return true if we have to change what has formerly been a method into a
479 ipa_param_adjustments::method2func_p (tree orig_type
)
481 return ((TREE_CODE (orig_type
) == METHOD_TYPE
) && !first_param_intact_p ());
484 /* Given function type OLD_TYPE, return a new type derived from it after
485 performing all atored modifications. TYPE_ORIGINAL_P should be true when
486 OLD_TYPE refers to the type before any IPA transformations, as opposed to a
487 type that can be an intermediate one in between various IPA
491 ipa_param_adjustments::build_new_function_type (tree old_type
,
492 bool type_original_p
)
494 auto_vec
<tree
,16> new_param_types
, *new_param_types_p
;
495 if (prototype_p (old_type
))
497 auto_vec
<tree
, 16> otypes
;
498 push_function_arg_types (&otypes
, old_type
);
499 fill_vector_of_new_param_types (&new_param_types
, &otypes
, m_adj_params
,
501 new_param_types_p
= &new_param_types
;
504 new_param_types_p
= NULL
;
506 /* Check if any params type cares about are modified. In this case will
507 need to drop some type attributes. */
508 bool modified
= false;
511 for (tree t
= TYPE_ARG_TYPES (old_type
);
512 t
&& (int)index
< m_always_copy_start
&& !modified
;
513 t
= TREE_CHAIN (t
), index
++)
514 if (index
>= m_adj_params
->length ()
515 || get_original_index (index
) != (int)index
)
519 return build_adjusted_function_type (old_type
, new_param_types_p
,
520 method2func_p (old_type
), m_skip_return
,
524 /* Build variant of function decl ORIG_DECL which has no return value if
525 M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
526 this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
527 DECL_ARGUMENTS list are not processed now, since they are linked by
528 TREE_CHAIN directly and not accessible in LTO during WPA. The caller is
529 responsible for eliminating them when clones are properly materialized. */
532 ipa_param_adjustments::adjust_decl (tree orig_decl
)
534 tree new_decl
= copy_node (orig_decl
);
535 tree orig_type
= TREE_TYPE (orig_decl
);
536 if (prototype_p (orig_type
)
537 || (m_skip_return
&& !VOID_TYPE_P (TREE_TYPE (orig_type
))))
539 tree new_type
= build_new_function_type (orig_type
, false);
540 TREE_TYPE (new_decl
) = new_type
;
542 if (method2func_p (orig_type
))
543 DECL_VINDEX (new_decl
) = NULL_TREE
;
545 /* When signature changes, we need to clear builtin info. */
546 if (fndecl_built_in_p (new_decl
))
547 set_decl_built_in_function (new_decl
, NOT_BUILT_IN
, 0);
549 DECL_VIRTUAL_P (new_decl
) = 0;
550 DECL_LANG_SPECIFIC (new_decl
) = NULL
;
552 /* Drop MALLOC attribute for a void function. */
554 DECL_IS_MALLOC (new_decl
) = 0;
559 /* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
560 transformations. Return true if EXPR has an interesting form and fill in
561 *BASE_P and *UNIT_OFFSET_P with the appropriate info. */
564 isra_get_ref_base_and_offset (tree expr
, tree
*base_p
, unsigned *unit_offset_p
)
566 HOST_WIDE_INT offset
, size
;
569 = get_ref_base_and_extent_hwi (expr
, &offset
, &size
, &reverse
);
570 if (!base
|| size
< 0)
573 if ((offset
% BITS_PER_UNIT
) != 0)
576 if (TREE_CODE (base
) == MEM_REF
)
578 poly_int64 plmoff
= mem_ref_offset (base
).force_shwi ();
580 bool is_cst
= plmoff
.is_constant (&moff
);
583 offset
+= moff
* BITS_PER_UNIT
;
584 base
= TREE_OPERAND (base
, 0);
587 if (offset
< 0 || (offset
/ BITS_PER_UNIT
) > UINT_MAX
)
591 *unit_offset_p
= offset
/ BITS_PER_UNIT
;
595 /* Modify actual arguments of a function call in statement currently belonging
596 to CS, and make it call CS->callee->decl. Return the new statement that
597 replaced the old one. When invoked, cfun and current_function_decl have to
598 be set to the caller. */
601 ipa_param_adjustments::modify_call (cgraph_edge
*cs
,
602 bool update_references
)
604 gcall
*stmt
= cs
->call_stmt
;
605 tree callee_decl
= cs
->callee
->decl
;
607 ipa_edge_modification_info
*mod_info
608 = ipa_edge_modifications
? ipa_edge_modifications
->get (cs
) : NULL
;
609 if (mod_info
&& symtab
->dump_file
)
611 fprintf (symtab
->dump_file
, "Information about pre-exiting "
612 "modifications.\n Index map:");
613 unsigned idx_len
= mod_info
->index_map
.length ();
614 for (unsigned i
= 0; i
< idx_len
; i
++)
615 fprintf (symtab
->dump_file
, " %i", mod_info
->index_map
[i
]);
616 fprintf (symtab
->dump_file
, "\n Pass-through split map: ");
617 unsigned ptm_len
= mod_info
->pass_through_map
.length ();
618 for (unsigned i
= 0; i
< ptm_len
; i
++)
619 fprintf (symtab
->dump_file
,
620 " (base_index: %u, offset: %u, new_index: %i)",
621 mod_info
->pass_through_map
[i
].base_index
,
622 mod_info
->pass_through_map
[i
].unit_offset
,
623 mod_info
->pass_through_map
[i
].new_index
);
624 fprintf (symtab
->dump_file
, "\n Always-copy delta: %i\n",
625 mod_info
->always_copy_delta
);
628 unsigned len
= vec_safe_length (m_adj_params
);
629 auto_vec
<tree
, 16> vargs (len
);
630 unsigned old_nargs
= gimple_call_num_args (stmt
);
631 unsigned orig_nargs
= mod_info
? mod_info
->index_map
.length () : old_nargs
;
632 auto_vec
<bool, 16> kept (old_nargs
);
633 kept
.quick_grow_cleared (old_nargs
);
635 cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
636 if (update_references
)
637 current_node
->remove_stmt_references (stmt
);
639 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
640 gimple_stmt_iterator prev_gsi
= gsi
;
641 gsi_prev (&prev_gsi
);
642 for (unsigned i
= 0; i
< len
; i
++)
644 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
645 if (apm
->op
== IPA_PARAM_OP_COPY
)
647 int index
= apm
->base_index
;
648 if ((unsigned) index
>= orig_nargs
)
649 /* Can happen if the original call has argument mismatch,
654 index
= mod_info
->index_map
[apm
->base_index
];
655 gcc_assert (index
>= 0);
658 tree arg
= gimple_call_arg (stmt
, index
);
660 vargs
.quick_push (arg
);
665 /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
666 If we ever want to support it during WPA IPA stage, we'll need a
667 mechanism to call into the IPA passes that introduced them. Currently
668 we simply mandate that IPA infrastructure understands all argument
669 modifications. Remember, edge redirection/modification is done only
670 once, not in steps for each pass modifying the callee like clone
672 gcc_assert (apm
->op
== IPA_PARAM_OP_SPLIT
);
674 /* We have to handle pass-through changes differently using the map
675 clone materialziation might have left behind. */
676 tree repl
= NULL_TREE
;
677 unsigned ptm_len
= mod_info
? mod_info
->pass_through_map
.length () : 0;
678 for (unsigned j
= 0; j
< ptm_len
; j
++)
679 if (mod_info
->pass_through_map
[j
].base_index
== apm
->base_index
680 && mod_info
->pass_through_map
[j
].unit_offset
== apm
->unit_offset
)
682 int repl_idx
= mod_info
->pass_through_map
[j
].new_index
;
683 gcc_assert (repl_idx
>= 0);
684 repl
= gimple_call_arg (stmt
, repl_idx
);
689 vargs
.quick_push (repl
);
693 int index
= apm
->base_index
;
694 if ((unsigned) index
>= orig_nargs
)
695 /* Can happen if the original call has argument mismatch, ignore. */
699 index
= mod_info
->index_map
[apm
->base_index
];
700 gcc_assert (index
>= 0);
702 tree base
= gimple_call_arg (stmt
, index
);
704 /* We create a new parameter out of the value of the old one, we can
705 do the following kind of transformations:
707 - A scalar passed by reference, potentially as a part of a larger
708 aggregate, is converted to a scalar passed by value.
710 - A part of an aggregate is passed instead of the whole aggregate. */
712 location_t loc
= gimple_location (stmt
);
714 bool deref_base
= false;
715 unsigned int deref_align
= 0;
716 if (TREE_CODE (base
) != ADDR_EXPR
717 && is_gimple_reg_type (TREE_TYPE (base
)))
719 /* Detect type mismatches in calls in invalid programs and make a
720 poor attempt to gracefully convert them so that we don't ICE. */
721 if (!POINTER_TYPE_P (TREE_TYPE (base
)))
722 base
= force_value_to_type (ptr_type_node
, base
);
724 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
729 if (TREE_CODE (base
) == ADDR_EXPR
)
731 base
= TREE_OPERAND (base
, 0);
737 tree prev_base
= base
;
738 poly_int64 base_offset
;
739 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
741 /* Aggregate arguments can have non-invariant addresses. */
744 base
= build_fold_addr_expr (prev_base
);
745 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
747 else if (TREE_CODE (base
) == MEM_REF
)
752 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
754 off
= build_int_cst (apm
->alias_ptr_type
,
755 base_offset
+ apm
->unit_offset
);
756 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
758 base
= TREE_OPERAND (base
, 0);
762 off
= build_int_cst (apm
->alias_ptr_type
,
763 base_offset
+ apm
->unit_offset
);
764 base
= build_fold_addr_expr (base
);
768 tree type
= apm
->type
;
770 unsigned HOST_WIDE_INT misalign
;
779 get_pointer_alignment_1 (base
, &align
, &misalign
);
780 /* All users must make sure that we can be optimistic when it
781 comes to alignment in this case (by inspecting the final users
782 of these new parameters). */
783 if (TYPE_ALIGN (type
) > align
)
784 align
= TYPE_ALIGN (type
);
787 += (offset_int::from (wi::to_wide (off
), SIGNED
).to_short_addr ()
789 misalign
= misalign
& (align
- 1);
791 align
= least_bit_hwi (misalign
);
792 if (align
< TYPE_ALIGN (type
))
793 type
= build_aligned_type (type
, align
);
794 base
= force_gimple_operand_gsi (&gsi
, base
,
795 true, NULL
, true, GSI_SAME_STMT
);
796 tree expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
797 REF_REVERSE_STORAGE_ORDER (expr
) = apm
->reverse
;
798 /* If expr is not a valid gimple call argument emit
799 a load into a temporary. */
800 if (is_gimple_reg_type (TREE_TYPE (expr
)))
802 gimple
*tem
= gimple_build_assign (NULL_TREE
, expr
);
803 if (gimple_in_ssa_p (cfun
))
805 gimple_set_vuse (tem
, gimple_vuse (stmt
));
806 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
809 expr
= create_tmp_reg (TREE_TYPE (expr
));
810 gimple_assign_set_lhs (tem
, expr
);
811 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
813 vargs
.quick_push (expr
);
816 if (m_always_copy_start
>= 0)
818 int always_copy_start
= m_always_copy_start
;
821 always_copy_start
+= mod_info
->always_copy_delta
;
822 gcc_assert (always_copy_start
>= 0);
824 for (unsigned i
= always_copy_start
; i
< old_nargs
; i
++)
825 vargs
.safe_push (gimple_call_arg (stmt
, i
));
828 /* For optimized away parameters, add on the caller side
830 DEBUG D#X => parm_Y(D)
831 stmts and associate D#X with parm in decl_debug_args_lookup
832 vector to say for debug info that if parameter parm had been passed,
833 it would have value parm_Y(D). */
834 tree old_decl
= gimple_call_fndecl (stmt
);
835 if (MAY_HAVE_DEBUG_BIND_STMTS
&& old_decl
&& callee_decl
)
837 vec
<tree
, va_gc
> **debug_args
= NULL
;
839 cgraph_node
*callee_node
= cgraph_node::get (callee_decl
);
841 /* FIXME: we don't seem to be able to insert debug args before clone
842 is materialized. Materializing them early leads to extra memory
844 if (callee_node
->clone_of
)
845 callee_node
->get_untransformed_body ();
846 for (tree old_parm
= DECL_ARGUMENTS (old_decl
);
847 old_parm
&& i
< old_nargs
&& ((int) i
) < m_always_copy_start
;
848 old_parm
= DECL_CHAIN (old_parm
), i
++)
850 if (!is_gimple_reg (old_parm
) || kept
[i
])
855 if (mod_info
->index_map
[i
] < 0)
857 arg
= gimple_call_arg (stmt
, mod_info
->index_map
[i
]);
860 arg
= gimple_call_arg (stmt
, i
);
862 tree origin
= DECL_ORIGIN (old_parm
);
863 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
865 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
868 if (TREE_CODE (arg
) == SSA_NAME
869 && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg
))
871 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg
)))
872 && useless_type_conversion_p (TREE_TYPE (origin
),
876 arg
= fold_convert_loc (gimple_location (stmt
),
877 TREE_TYPE (origin
), arg
);
879 if (debug_args
== NULL
)
880 debug_args
= decl_debug_args_insert (callee_decl
);
882 tree ddecl
= NULL_TREE
;
883 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
886 ddecl
= (**debug_args
)[ix
+ 1];
891 ddecl
= build_debug_expr_decl (TREE_TYPE (origin
));
892 /* FIXME: Is setting the mode really necessary? */
893 SET_DECL_MODE (ddecl
, DECL_MODE (origin
));
895 vec_safe_push (*debug_args
, origin
);
896 vec_safe_push (*debug_args
, ddecl
);
898 gimple
*def_temp
= gimple_build_debug_bind (ddecl
,
899 unshare_expr (arg
), stmt
);
900 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
904 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
906 fprintf (dump_file
, "replacing stmt:");
907 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0);
910 gcall
*new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
912 tree ssa_to_remove
= NULL
;
913 if (tree lhs
= gimple_call_lhs (stmt
))
916 gimple_call_set_lhs (new_stmt
, lhs
);
917 else if (TREE_CODE (lhs
) == SSA_NAME
)
919 /* LHS should now by a default-def SSA. Unfortunately default-def
920 SSA_NAMEs need a backing variable (or at least some code examining
921 SSAs assumes it is non-NULL). So we either have to re-use the
922 decl we have at hand or introdice a new one. */
923 tree repl
= create_tmp_var (TREE_TYPE (lhs
), "removed_return");
924 repl
= get_or_create_ssa_default_def (cfun
, repl
);
925 SSA_NAME_IS_DEFAULT_DEF (repl
) = true;
929 FOR_EACH_IMM_USE_STMT (using_stmt
, ui
, lhs
)
931 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
933 SET_USE (use_p
, repl
);
935 update_stmt (using_stmt
);
941 gimple_set_block (new_stmt
, gimple_block (stmt
));
942 if (gimple_has_location (stmt
))
943 gimple_set_location (new_stmt
, gimple_location (stmt
));
944 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
945 gimple_call_copy_flags (new_stmt
, stmt
);
946 if (gimple_in_ssa_p (cfun
))
947 gimple_move_vops (new_stmt
, stmt
);
949 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
951 fprintf (dump_file
, "with stmt:");
952 print_gimple_stmt (dump_file
, new_stmt
, 0);
953 fprintf (dump_file
, "\n");
955 gsi_replace (&gsi
, new_stmt
, true);
957 release_ssa_name (ssa_to_remove
);
958 if (update_references
)
961 current_node
->record_stmt_references (gsi_stmt (gsi
));
964 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
967 ipa_edge_modifications
->remove (cs
);
971 /* Dump information contained in the object in textual form to F. */
974 ipa_param_adjustments::dump (FILE *f
)
976 fprintf (f
, " m_always_copy_start: %i\n", m_always_copy_start
);
977 ipa_dump_adjusted_parameters (f
, m_adj_params
);
979 fprintf (f
, " Will SKIP return.\n");
982 /* Dump information contained in the object in textual form to stderr. */
985 ipa_param_adjustments::debug ()
990 /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
993 ipa_param_body_adjustments::register_replacement (tree base
,
994 unsigned unit_offset
,
997 ipa_param_body_replacement psr
;
999 psr
.repl
= replacement
;
1000 psr
.dummy
= NULL_TREE
;
1001 psr
.unit_offset
= unit_offset
;
1002 m_replacements
.safe_push (psr
);
1005 /* Register that REPLACEMENT should replace parameter described in APM. */
1008 ipa_param_body_adjustments::register_replacement (ipa_adjusted_param
*apm
,
1011 gcc_checking_assert (apm
->op
== IPA_PARAM_OP_SPLIT
1012 || apm
->op
== IPA_PARAM_OP_NEW
);
1013 gcc_checking_assert (!apm
->prev_clone_adjustment
);
1014 register_replacement (m_oparms
[apm
->prev_clone_index
], apm
->unit_offset
,
1018 /* Copy or not, as appropriate given m_id and decl context, a pre-existing
1019 PARM_DECL T so that it can be included in the parameters of the modified
1023 ipa_param_body_adjustments::carry_over_param (tree t
)
1028 new_parm
= remap_decl (t
, m_id
);
1029 if (TREE_CODE (new_parm
) != PARM_DECL
)
1030 new_parm
= m_id
->copy_decl (t
, m_id
);
1032 else if (DECL_CONTEXT (t
) != m_fndecl
)
1034 new_parm
= copy_node (t
);
1035 DECL_CONTEXT (new_parm
) = m_fndecl
;
1042 /* Populate m_dead_stmts given that DEAD_PARAM is going to be removed without
1043 any replacement or splitting. REPL is the replacement VAR_SECL to base any
1044 remaining uses of a removed parameter on. Push all removed SSA names that
1045 are used within debug statements to DEBUGSTACK. */
1048 ipa_param_body_adjustments::mark_dead_statements (tree dead_param
,
1049 vec
<tree
> *debugstack
)
1051 /* Current IPA analyses which remove unused parameters never remove a
1052 non-gimple register ones which have any use except as parameters in other
1053 calls, so we can safely leve them as they are. */
1054 if (!is_gimple_reg (dead_param
))
1056 tree parm_ddef
= ssa_default_def (m_id
->src_cfun
, dead_param
);
1057 if (!parm_ddef
|| has_zero_uses (parm_ddef
))
1060 auto_vec
<tree
, 4> stack
;
1061 hash_set
<tree
> used_in_debug
;
1062 m_dead_ssas
.add (parm_ddef
);
1063 stack
.safe_push (parm_ddef
);
1064 while (!stack
.is_empty ())
1066 imm_use_iterator imm_iter
;
1067 use_operand_p use_p
;
1068 tree t
= stack
.pop ();
1070 insert_decl_map (m_id
, t
, error_mark_node
);
1071 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, t
)
1073 gimple
*stmt
= USE_STMT (use_p
);
1075 /* Calls containing dead arguments cannot be deleted,
1076 modify_call_stmt will instead remove just the argument later on.
1077 If isra_track_scalar_value_uses in ipa-sra.cc is extended to look
1078 through const functions, we will need to do so here too. */
1079 if (is_gimple_call (stmt
)
1080 || (m_id
->blocks_to_copy
1081 && !bitmap_bit_p (m_id
->blocks_to_copy
,
1082 gimple_bb (stmt
)->index
)))
1085 if (is_gimple_debug (stmt
))
1087 m_dead_stmts
.add (stmt
);
1088 gcc_assert (gimple_debug_bind_p (stmt
));
1089 if (!used_in_debug
.contains (t
))
1091 used_in_debug
.add (t
);
1092 debugstack
->safe_push (t
);
1095 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1097 gphi
*phi
= as_a
<gphi
*> (stmt
);
1098 int ix
= PHI_ARG_INDEX_FROM_USE (use_p
);
1100 if (!m_id
->blocks_to_copy
1101 || bitmap_bit_p (m_id
->blocks_to_copy
,
1102 gimple_phi_arg_edge (phi
, ix
)->src
->index
))
1104 m_dead_stmts
.add (phi
);
1105 tree res
= gimple_phi_result (phi
);
1106 if (!m_dead_ssas
.add (res
))
1107 stack
.safe_push (res
);
1110 else if (is_gimple_assign (stmt
))
1112 m_dead_stmts
.add (stmt
);
1113 if (!gimple_clobber_p (stmt
))
1115 tree lhs
= gimple_assign_lhs (stmt
);
1116 gcc_assert (TREE_CODE (lhs
) == SSA_NAME
);
1117 if (!m_dead_ssas
.add (lhs
))
1118 stack
.safe_push (lhs
);
1122 /* IPA-SRA does not analyze other types of statements. */
1127 if (!MAY_HAVE_DEBUG_STMTS
)
1129 gcc_assert (debugstack
->is_empty ());
1133 tree dp_ddecl
= build_debug_expr_decl (TREE_TYPE (dead_param
));
1134 /* FIXME: Is setting the mode really necessary? */
1135 SET_DECL_MODE (dp_ddecl
, DECL_MODE (dead_param
));
1136 m_dead_ssa_debug_equiv
.put (parm_ddef
, dp_ddecl
);
1139 /* Callback to walk_tree. If REMAP is an SSA_NAME that is present in hash_map
1140 passed in DATA, replace it with unshared version of what it was mapped to.
1141 If an SSA argument would be remapped to NULL, the whole operation needs to
1142 abort which is signaled by returning error_mark_node. */
1145 replace_with_mapped_expr (tree
*remap
, int *walk_subtrees
, void *data
)
1147 if (TYPE_P (*remap
))
1152 if (TREE_CODE (*remap
) != SSA_NAME
)
1157 hash_map
<tree
, tree
> *equivs
= (hash_map
<tree
, tree
> *) data
;
1158 if (tree
*p
= equivs
->get (*remap
))
1161 return error_mark_node
;
1162 *remap
= unshare_expr (*p
);
1167 /* Replace all occurances of SSAs in m_dead_ssa_debug_equiv in t with what they
1171 ipa_param_body_adjustments::remap_with_debug_expressions (tree
*t
)
1173 /* If *t is an SSA_NAME which should have its debug statements reset, it is
1174 mapped to NULL in the hash_map.
1176 It is perhaps simpler to handle the SSA_NAME cases directly and only
1177 invoke walk_tree on more complex expressions. When
1178 remap_with_debug_expressions is called from tree-inline.cc, a to-be-reset
1179 SSA_NAME can be an operand to such expressions and the entire debug
1180 variable we are remapping should be reset. This is signaled by walk_tree
1181 returning error_mark_node and done by setting *t to NULL. */
1182 if (TREE_CODE (*t
) == SSA_NAME
)
1184 if (tree
*p
= m_dead_ssa_debug_equiv
.get (*t
))
1187 else if (walk_tree (t
, replace_with_mapped_expr
,
1188 &m_dead_ssa_debug_equiv
, NULL
) == error_mark_node
)
1192 /* For an SSA_NAME DEAD_SSA which is about to be DCEd because it is based on a
1193 useless parameter, prepare an expression that should represent it in
1194 debug_binds in the cloned function and add a mapping from DEAD_SSA to
1195 m_dead_ssa_debug_equiv. That mapping is to NULL when the associated
1196 debug_statement has to be reset instead. In such case return false,
1197 ottherwise return true. If DEAD_SSA comes from a basic block which is not
1198 about to be copied, ignore it and return true. */
1201 ipa_param_body_adjustments::prepare_debug_expressions (tree dead_ssa
)
1203 gcc_checking_assert (m_dead_ssas
.contains (dead_ssa
));
1204 if (tree
*d
= m_dead_ssa_debug_equiv
.get (dead_ssa
))
1205 return (*d
!= NULL_TREE
);
1207 gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (dead_ssa
));
1208 gimple
*def
= SSA_NAME_DEF_STMT (dead_ssa
);
1209 if (m_id
->blocks_to_copy
1210 && !bitmap_bit_p (m_id
->blocks_to_copy
, gimple_bb (def
)->index
))
1213 if (gimple_code (def
) == GIMPLE_PHI
)
1215 /* In theory, we could ignore all SSAs coming from BBs not in
1216 m_id->blocks_to_copy but at the time of the writing this code that
1217 should never really be the case because only fnsplit uses that bitmap,
1219 tree value
= degenerate_phi_result (as_a
<gphi
*> (def
));
1221 || (m_dead_ssas
.contains (value
)
1222 && !prepare_debug_expressions (value
)))
1224 m_dead_ssa_debug_equiv
.put (dead_ssa
, NULL_TREE
);
1228 gcc_assert (TREE_CODE (value
) == SSA_NAME
);
1229 tree
*d
= m_dead_ssa_debug_equiv
.get (value
);
1230 m_dead_ssa_debug_equiv
.put (dead_ssa
, *d
);
1235 use_operand_p use_p
;
1237 FOR_EACH_PHI_OR_STMT_USE (use_p
, def
, oi
, SSA_OP_USE
)
1239 tree use
= USE_FROM_PTR (use_p
);
1240 if (m_dead_ssas
.contains (use
)
1241 && !prepare_debug_expressions (use
))
1250 m_dead_ssa_debug_equiv
.put (dead_ssa
, NULL_TREE
);
1254 if (is_gimple_assign (def
))
1256 gcc_assert (!gimple_clobber_p (def
));
1257 if (gimple_assign_copy_p (def
)
1258 && TREE_CODE (gimple_assign_rhs1 (def
)) == SSA_NAME
)
1260 tree d
= *m_dead_ssa_debug_equiv
.get (gimple_assign_rhs1 (def
));
1262 m_dead_ssa_debug_equiv
.put (dead_ssa
, d
);
1267 = unshare_expr_without_location (gimple_assign_rhs_to_tree (def
));
1268 remap_with_debug_expressions (&val
);
1270 tree vexpr
= build_debug_expr_decl (TREE_TYPE (val
));
1271 m_dead_stmt_debug_equiv
.put (def
, val
);
1272 m_dead_ssa_debug_equiv
.put (dead_ssa
, vexpr
);
1279 /* Common initialization performed by all ipa_param_body_adjustments
1280 constructors. OLD_FNDECL is the declaration we take original arguments
1281 from, (it may be the same as M_FNDECL). VARS, if non-NULL, is a pointer to
1282 a chained list of new local variables. TREE_MAP is the IPA-CP produced
1283 mapping of trees to constants.
1285 The function is rather long but it really onlu initializes all data members
1286 of the class. It creates new param DECLs, finds their new types, */
1289 ipa_param_body_adjustments::common_initialization (tree old_fndecl
,
1291 vec
<ipa_replace_map
*,
1294 push_function_arg_decls (&m_oparms
, old_fndecl
);
1295 auto_vec
<tree
,16> otypes
;
1296 if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl
)) != NULL_TREE
)
1297 push_function_arg_types (&otypes
, TREE_TYPE (old_fndecl
));
1300 auto_vec
<tree
,16> oparms
;
1301 push_function_arg_decls (&oparms
, old_fndecl
);
1302 unsigned ocount
= oparms
.length ();
1303 otypes
.reserve_exact (ocount
);
1304 for (unsigned i
= 0; i
< ocount
; i
++)
1305 otypes
.quick_push (TREE_TYPE (oparms
[i
]));
1307 fill_vector_of_new_param_types (&m_new_types
, &otypes
, m_adj_params
, true);
1309 auto_vec
<bool, 16> kept
;
1310 kept
.reserve_exact (m_oparms
.length ());
1311 kept
.quick_grow_cleared (m_oparms
.length ());
1312 auto_vec
<bool, 16> split
;
1313 split
.reserve_exact (m_oparms
.length ());
1314 split
.quick_grow_cleared (m_oparms
.length ());
1316 unsigned adj_len
= vec_safe_length (m_adj_params
);
1317 m_method2func
= ((TREE_CODE (TREE_TYPE (m_fndecl
)) == METHOD_TYPE
)
1319 || (*m_adj_params
)[0].op
!= IPA_PARAM_OP_COPY
1320 || (*m_adj_params
)[0].base_index
!= 0));
1322 /* The main job of the this function is to go over the vector of adjusted
1323 parameters and create declarations or find corresponding old ones and push
1324 them to m_new_decls. For IPA-SRA replacements it also creates
1325 corresponding m_id->dst_node->clone.performed_splits entries. */
1327 m_new_decls
.reserve_exact (adj_len
);
1328 for (unsigned i
= 0; i
< adj_len
; i
++)
1330 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
1331 unsigned prev_index
= apm
->prev_clone_index
;
1333 if (apm
->op
== IPA_PARAM_OP_COPY
1334 || apm
->prev_clone_adjustment
)
1336 kept
[prev_index
] = true;
1337 new_parm
= carry_over_param (m_oparms
[prev_index
]);
1338 m_new_decls
.quick_push (new_parm
);
1340 else if (apm
->op
== IPA_PARAM_OP_NEW
1341 || apm
->op
== IPA_PARAM_OP_SPLIT
)
1343 tree new_type
= m_new_types
[i
];
1344 gcc_checking_assert (new_type
);
1345 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
1347 const char *prefix
= ipa_param_prefixes
[apm
->param_prefix_index
];
1348 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
1349 DECL_ARTIFICIAL (new_parm
) = 1;
1350 DECL_ARG_TYPE (new_parm
) = new_type
;
1351 DECL_CONTEXT (new_parm
) = m_fndecl
;
1352 TREE_USED (new_parm
) = 1;
1353 DECL_IGNORED_P (new_parm
) = 1;
1354 layout_decl (new_parm
, 0);
1355 m_new_decls
.quick_push (new_parm
);
1357 if (apm
->op
== IPA_PARAM_OP_SPLIT
)
1359 split
[prev_index
] = true;
1360 register_replacement (apm
, new_parm
);
1367 auto_vec
<int, 16> index_mapping
;
1368 bool need_remap
= false;
1371 clone_info
*cinfo
= clone_info::get (m_id
->src_node
);
1372 if (cinfo
&& cinfo
->param_adjustments
)
1374 cinfo
->param_adjustments
->get_updated_indices (&index_mapping
);
1378 if (ipcp_transformation
*ipcp_ts
1379 = ipcp_get_transformation_summary (m_id
->src_node
))
1381 for (const ipa_argagg_value
&av
: ipcp_ts
->m_agg_values
)
1383 int parm_num
= av
.index
;
1387 /* FIXME: We cannot handle the situation when IPA-CP
1388 identified that a parameter is a pointer to a global
1389 variable and at the same time the variable has some known
1390 constant contents (PR 107640). The best place to make
1391 sure we don't drop such constants on the floor probably is
1392 not here, but we have to make sure that it does not
1393 confuse the remapping. */
1394 if (parm_num
>= (int) index_mapping
.length ())
1396 parm_num
= index_mapping
[parm_num
];
1401 if (!kept
[parm_num
])
1403 /* IPA-CP has detected an aggregate constant in a parameter
1404 that will not be kept, which means that IPA-SRA would have
1405 split it if there wasn't a constant. Because we are about
1406 to remove the original, this is the last chance where we
1407 can substitute the uses with a constant (for values passed
1408 by reference) or do the split but initialize the
1409 replacement with a constant (for split aggregates passed
1417 repl
= create_tmp_var (TREE_TYPE (av
.value
),
1419 gimple
*init_stmt
= gimple_build_assign (repl
, av
.value
);
1420 m_split_agg_csts_inits
.safe_push (init_stmt
);
1422 register_replacement (m_oparms
[parm_num
], av
.unit_offset
,
1424 split
[parm_num
] = true;
1432 /* Do not treat parameters which were replaced with a constant as
1433 completely vanished. */
1434 for (unsigned i
= 0; i
< tree_map
->length (); i
++)
1436 int parm_num
= (*tree_map
)[i
]->parm_num
;
1437 gcc_assert (parm_num
>= 0);
1439 parm_num
= index_mapping
[parm_num
];
1440 kept
[parm_num
] = true;
1444 /* As part of body modifications, we will also have to replace remaining uses
1445 of remaining uses of removed PARM_DECLs (which do not however use the
1446 initial value) with their VAR_DECL copies.
1448 We do this differently with and without m_id. With m_id, we rely on its
1449 mapping and create a replacement straight away. Without it, we have our
1450 own mechanism for which we have to populate m_removed_decls vector. Just
1451 don't mix them, that is why you should not call
1452 replace_removed_params_ssa_names or perform_cfun_body_modifications when
1453 you construct with ID not equal to NULL. */
1455 auto_vec
<tree
, 8> ssas_to_process_debug
;
1456 unsigned op_len
= m_oparms
.length ();
1457 for (unsigned i
= 0; i
< op_len
; i
++)
1462 gcc_assert (!m_id
->decl_map
->get (m_oparms
[i
]));
1463 tree var
= copy_decl_to_var (m_oparms
[i
], m_id
);
1464 insert_decl_map (m_id
, m_oparms
[i
], var
);
1465 /* Declare this new variable. */
1466 DECL_CHAIN (var
) = *vars
;
1469 /* If this is not a split but a real removal, init hash sets
1470 that will guide what not to copy to the new body. */
1472 mark_dead_statements (m_oparms
[i
], &ssas_to_process_debug
);
1473 if (MAY_HAVE_DEBUG_STMTS
1474 && is_gimple_reg (m_oparms
[i
]))
1475 m_reset_debug_decls
.safe_push (m_oparms
[i
]);
1479 m_removed_decls
.safe_push (m_oparms
[i
]);
1480 m_removed_map
.put (m_oparms
[i
], m_removed_decls
.length () - 1);
1481 if (MAY_HAVE_DEBUG_STMTS
1483 && is_gimple_reg (m_oparms
[i
]))
1484 m_reset_debug_decls
.safe_push (m_oparms
[i
]);
1488 while (!ssas_to_process_debug
.is_empty ())
1489 prepare_debug_expressions (ssas_to_process_debug
.pop ());
1492 /* Constructor of ipa_param_body_adjustments from a simple list of
1493 modifications to parameters listed in ADJ_PARAMS which will prepare ground
1494 for modification of parameters of fndecl. Return value of the function will
1495 not be removed and the object will assume it does not run as a part of
1496 tree-function_versioning. */
1498 ipa_param_body_adjustments
1499 ::ipa_param_body_adjustments (vec
<ipa_adjusted_param
, va_gc
> *adj_params
,
1501 : m_adj_params (adj_params
), m_adjustments (NULL
), m_reset_debug_decls (),
1502 m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
1503 m_dead_stmt_debug_equiv (), m_fndecl (fndecl
), m_id (NULL
), m_oparms (),
1504 m_new_decls (), m_new_types (), m_replacements (),
1505 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1506 m_method2func (false)
1508 common_initialization (fndecl
, NULL
, NULL
);
1511 /* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
1512 ADJUSTMENTS which will prepare ground for modification of parameters of
1513 fndecl. The object will assume it does not run as a part of
1514 tree-function_versioning. */
1516 ipa_param_body_adjustments
1517 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1519 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1520 m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
1521 m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl
),
1522 m_id (NULL
), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1523 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1524 m_method2func (false)
1526 common_initialization (fndecl
, NULL
, NULL
);
1529 /* Constructor of ipa_param_body_adjustments which sets it up as a part of
1530 running tree_function_versioning. Planned modifications to the function are
1531 in ADJUSTMENTS. FNDECL designates the new function clone which is being
1532 modified. OLD_FNDECL is the function of which FNDECL is a clone (and which
1533 at the time of invocation still share DECL_ARGUMENTS). ID is the
1534 copy_body_data structure driving the wholy body copying process. VARS is a
1535 pointer to the head of the list of new local variables, TREE_MAP is the map
1536 that drives tree substitution in the cloning process. */
1538 ipa_param_body_adjustments
1539 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1540 tree fndecl
, tree old_fndecl
,
1541 copy_body_data
*id
, tree
*vars
,
1542 vec
<ipa_replace_map
*, va_gc
> *tree_map
)
1543 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1544 m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
1545 m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl
),
1546 m_id (id
), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1547 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1548 m_method2func (false)
1550 common_initialization (old_fndecl
, vars
, tree_map
);
1553 /* Chain new param decls up and return them. */
1556 ipa_param_body_adjustments::get_new_param_chain ()
1559 tree
*link
= &result
;
1561 unsigned len
= vec_safe_length (m_adj_params
);
1562 for (unsigned i
= 0; i
< len
; i
++)
1564 tree new_decl
= m_new_decls
[i
];
1566 link
= &DECL_CHAIN (new_decl
);
1572 /* Modify the function parameters FNDECL and its type according to the plan in
1573 ADJUSTMENTS. This function needs to be called when the decl has not already
1574 been processed with ipa_param_adjustments::adjust_decl, otherwise just
1575 seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough. */
1578 ipa_param_body_adjustments::modify_formal_parameters ()
1580 tree orig_type
= TREE_TYPE (m_fndecl
);
1581 DECL_ARGUMENTS (m_fndecl
) = get_new_param_chain ();
1583 /* When signature changes, we need to clear builtin info. */
1584 if (fndecl_built_in_p (m_fndecl
))
1585 set_decl_built_in_function (m_fndecl
, NOT_BUILT_IN
, 0);
1587 bool modified
= false;
1590 for (tree t
= TYPE_ARG_TYPES (orig_type
);
1592 t
= TREE_CHAIN (t
), index
++)
1593 if (index
>= m_adj_params
->length ()
1594 || (*m_adj_params
)[index
].op
!= IPA_PARAM_OP_COPY
1595 || (*m_adj_params
)[index
].base_index
!= index
)
1598 /* At this point, removing return value is only implemented when going
1599 through tree_function_versioning, not when modifying function body
1601 gcc_assert (!m_adjustments
|| !m_adjustments
->m_skip_return
);
1602 tree new_type
= build_adjusted_function_type (orig_type
, &m_new_types
,
1603 m_method2func
, false, modified
);
1605 TREE_TYPE (m_fndecl
) = new_type
;
1606 DECL_VIRTUAL_P (m_fndecl
) = 0;
1607 DECL_LANG_SPECIFIC (m_fndecl
) = NULL
;
1609 DECL_VINDEX (m_fndecl
) = NULL_TREE
;
1612 /* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
1615 ipa_param_body_replacement
*
1616 ipa_param_body_adjustments::lookup_replacement_1 (tree base
,
1617 unsigned unit_offset
)
1619 unsigned int len
= m_replacements
.length ();
1620 for (unsigned i
= 0; i
< len
; i
++)
1622 ipa_param_body_replacement
*pbr
= &m_replacements
[i
];
1624 if (pbr
->base
== base
1625 && (pbr
->unit_offset
== unit_offset
))
1631 /* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
1632 and return it, assuming it is known it does not hold value by reference or
1633 in reverse storage order. */
1636 ipa_param_body_adjustments::lookup_replacement (tree base
, unsigned unit_offset
)
1638 ipa_param_body_replacement
*pbr
= lookup_replacement_1 (base
, unit_offset
);
1644 /* If T is an SSA_NAME, return NULL if it is not a default def or
1645 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
1646 the base variable is always returned, regardless if it is a default
1647 def. Return T if it is not an SSA_NAME. */
1650 get_ssa_base_param (tree t
, bool ignore_default_def
)
1652 if (TREE_CODE (t
) == SSA_NAME
)
1654 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
1655 return SSA_NAME_VAR (t
);
1662 /* Given an expression, return the structure describing how it should be
1663 replaced if it accesses a part of a split parameter or NULL otherwise.
1665 Do not free the result, it will be deallocated when the object is destroyed.
1667 If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
1668 which are default definitions, if set, consider all SSA_NAMEs of
1671 ipa_param_body_replacement
*
1672 ipa_param_body_adjustments::get_expr_replacement (tree expr
,
1673 bool ignore_default_def
)
1676 unsigned unit_offset
;
1678 if (!isra_get_ref_base_and_offset (expr
, &base
, &unit_offset
))
1681 base
= get_ssa_base_param (base
, ignore_default_def
);
1682 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
1684 return lookup_replacement_1 (base
, unit_offset
);
1687 /* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
1688 (which includes it being split or replaced), return a new variable that
1689 should be used for any SSA names that will remain in the function that
1690 previously belonged to OLD_DECL. */
1693 ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl
)
1695 unsigned *idx
= m_removed_map
.get (old_decl
);
1700 if (TREE_CODE (m_removed_decls
[*idx
]) == PARM_DECL
)
1702 gcc_assert (m_removed_decls
[*idx
] == old_decl
);
1703 repl
= copy_var_decl (old_decl
, DECL_NAME (old_decl
),
1704 TREE_TYPE (old_decl
));
1705 m_removed_decls
[*idx
] = repl
;
1708 repl
= m_removed_decls
[*idx
];
1712 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
1713 parameter which is to be removed because its value is not used, create a new
1714 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
1715 original with it and return it. If there is no need to re-map, return NULL.
1716 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
1719 ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name
,
1723 if (TREE_CODE (old_name
) != SSA_NAME
)
1726 tree decl
= SSA_NAME_VAR (old_name
);
1727 if (decl
== NULL_TREE
1728 || TREE_CODE (decl
) != PARM_DECL
)
1731 tree repl
= get_replacement_ssa_base (decl
);
1735 tree new_name
= make_ssa_name (repl
, stmt
);
1736 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name
)
1737 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name
);
1739 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1741 fprintf (dump_file
, "replacing an SSA name of a removed param ");
1742 print_generic_expr (dump_file
, old_name
);
1743 fprintf (dump_file
, " with ");
1744 print_generic_expr (dump_file
, new_name
);
1745 fprintf (dump_file
, "\n");
1748 replace_uses_by (old_name
, new_name
);
1752 /* If the expression *EXPR_P should be replaced, do so. CONVERT specifies
1753 whether the function should care about type incompatibility of the current
1754 and new expressions. If it is false, the function will leave
1755 incompatibility issues to the caller - note that when the function
1756 encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
1757 their bases instead of the expressions themselves and then also performs any
1758 necessary conversions. */
1761 ipa_param_body_adjustments::modify_expression (tree
*expr_p
, bool convert
)
1763 tree expr
= *expr_p
;
1765 if (m_replacements
.is_empty ())
1767 if (TREE_CODE (expr
) == BIT_FIELD_REF
1768 || TREE_CODE (expr
) == IMAGPART_EXPR
1769 || TREE_CODE (expr
) == REALPART_EXPR
)
1771 expr_p
= &TREE_OPERAND (expr
, 0);
1776 ipa_param_body_replacement
*pbr
= get_expr_replacement (expr
, false);
1780 tree repl
= pbr
->repl
;
1781 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1783 fprintf (dump_file
, "About to replace expr ");
1784 print_generic_expr (dump_file
, expr
);
1785 fprintf (dump_file
, " with ");
1786 print_generic_expr (dump_file
, repl
);
1787 fprintf (dump_file
, "\n");
1790 if (convert
&& !useless_type_conversion_p (TREE_TYPE (expr
),
1793 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (expr
), repl
);
1801 /* If the assignment statement STMT contains any expressions that need to
1802 replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
1803 potential type incompatibilities. If any conversion sttements have to be
1804 pre-pended to STMT, they will be added to EXTRA_STMTS. Return true iff the
1805 statement was modified. */
1808 ipa_param_body_adjustments::modify_assignment (gimple
*stmt
,
1809 gimple_seq
*extra_stmts
)
1811 tree
*lhs_p
, *rhs_p
;
1814 if (m_replacements
.is_empty () || !gimple_assign_single_p (stmt
))
1817 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
1818 lhs_p
= gimple_assign_lhs_ptr (stmt
);
1820 any
= modify_expression (lhs_p
, false);
1821 any
|= modify_expression (rhs_p
, false);
1823 && !useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
1825 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
1827 /* V_C_Es of constructors can cause trouble (PR 42714). */
1828 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
1829 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
1831 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
1836 tree new_rhs
= fold_build1_loc (gimple_location (stmt
),
1837 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
1839 tree tmp
= force_gimple_operand (new_rhs
, extra_stmts
, true,
1841 gimple_assign_set_rhs1 (stmt
, tmp
);
1849 /* Record information about what modifications to call arguments have already
1850 been done by clone materialization into a summary describing CS. The
1851 information is stored in NEW_INDEX_MAP, NEW_PT_MAP and NEW_ALWAYS_COPY_DELTA
1852 and correspond to equivalent fields in ipa_edge_modification_info. Return
1853 the edge summary. */
1855 static ipa_edge_modification_info
*
1856 record_argument_state_1 (cgraph_edge
*cs
, const vec
<int> &new_index_map
,
1857 const vec
<pass_through_split_map
> &new_pt_map
,
1858 int new_always_copy_delta
)
1861 ipa_edge_modification_info
*sum
= ipa_edge_modifications
->get_create (cs
);
1863 unsigned len
= sum
->pass_through_map
.length ();
1864 for (unsigned i
= 0; i
< len
; i
++)
1866 unsigned oldnew
= sum
->pass_through_map
[i
].new_index
;
1867 sum
->pass_through_map
[i
].new_index
= new_index_map
[oldnew
];
1870 len
= sum
->index_map
.length ();
1873 unsigned nptlen
= new_pt_map
.length ();
1874 for (unsigned j
= 0; j
< nptlen
; j
++)
1877 for (unsigned i
= 0; i
< len
; i
++)
1878 if ((unsigned) sum
->index_map
[i
] == new_pt_map
[j
].base_index
)
1883 gcc_assert (inverse
>= 0);
1884 pass_through_split_map ptm_item
;
1886 ptm_item
.base_index
= inverse
;
1887 ptm_item
.unit_offset
= new_pt_map
[j
].unit_offset
;
1888 ptm_item
.new_index
= new_pt_map
[j
].new_index
;
1889 sum
->pass_through_map
.safe_push (ptm_item
);
1892 for (unsigned i
= 0; i
< len
; i
++)
1894 int idx
= sum
->index_map
[i
];
1897 sum
->index_map
[i
] = new_index_map
[idx
];
1902 sum
->pass_through_map
.safe_splice (new_pt_map
);
1903 sum
->index_map
.safe_splice (new_index_map
);
1905 sum
->always_copy_delta
+= new_always_copy_delta
;
1909 /* Record information about what modifications to call arguments have already
1910 been done by clone materialization into a summary of an edge describing the
1911 call in this clone and all its clones. NEW_INDEX_MAP, NEW_PT_MAP and
1912 NEW_ALWAYS_COPY_DELTA have the same meaning as record_argument_state_1.
1914 In order to associate the info with the right edge summaries, we need
1915 address of the ORIG_STMT in the function from which we are cloning (because
1916 the edges have not yet been re-assigned to the new statement that has just
1917 been created) and ID, the structure governing function body copying. */
1920 record_argument_state (copy_body_data
*id
, gimple
*orig_stmt
,
1921 const vec
<int> &new_index_map
,
1922 const vec
<pass_through_split_map
> &new_pt_map
,
1923 int new_always_copy_delta
)
1925 if (!ipa_edge_modifications
)
1926 ipa_edge_modifications
= new ipa_edge_modification_sum (symtab
);
1928 struct cgraph_node
*this_node
= id
->dst_node
;
1929 ipa_edge_modification_info
*first_sum
= NULL
;
1930 cgraph_edge
*cs
= this_node
->get_edge (orig_stmt
);
1932 first_sum
= record_argument_state_1 (cs
, new_index_map
, new_pt_map
,
1933 new_always_copy_delta
);
1935 gcc_assert (this_node
->clones
);
1937 if (!this_node
->clones
)
1939 for (cgraph_node
*subclone
= this_node
->clones
; subclone
!= this_node
;)
1941 cs
= subclone
->get_edge (orig_stmt
);
1945 first_sum
= record_argument_state_1 (cs
, new_index_map
, new_pt_map
,
1946 new_always_copy_delta
);
1949 ipa_edge_modification_info
*s2
1950 = ipa_edge_modifications
->get_create (cs
);
1951 s2
->index_map
.truncate (0);
1952 s2
->index_map
.safe_splice (first_sum
->index_map
);
1953 s2
->pass_through_map
.truncate (0);
1954 s2
->pass_through_map
.safe_splice (first_sum
->pass_through_map
);
1955 s2
->always_copy_delta
= first_sum
->always_copy_delta
;
1959 gcc_assert (subclone
->clones
);
1961 if (subclone
->clones
)
1962 subclone
= subclone
->clones
;
1963 else if (subclone
->next_sibling_clone
)
1964 subclone
= subclone
->next_sibling_clone
;
1967 while (subclone
!= this_node
&& !subclone
->next_sibling_clone
)
1968 subclone
= subclone
->clone_of
;
1969 if (subclone
!= this_node
)
1970 subclone
= subclone
->next_sibling_clone
;
1975 /* If the call statement pointed at by STMT_P contains any expressions that
1976 need to replaced with a different one as noted by ADJUSTMENTS, do so. f the
1977 statement needs to be rebuilt, do so. Return true if any modifications have
1978 been performed. ORIG_STMT, if not NULL, is the original statement in the
1979 function that is being cloned from, which at this point can be used to look
1980 up call_graph edges.
1982 If the method is invoked as a part of IPA clone materialization and if any
1983 parameter split is pass-through, i.e. it applies to the functin that is
1984 being modified and also to the callee of the statement, replace the
1985 parameter passed to old callee with all of the replacement a callee might
1986 possibly want and record the performed argument modifications in
1987 ipa_edge_modifications. Likewise if any argument has already been left out
1988 because it is not necessary. */
1991 ipa_param_body_adjustments::modify_call_stmt (gcall
**stmt_p
,
1994 auto_vec
<unsigned, 4> pass_through_args
;
1995 auto_vec
<unsigned, 4> pass_through_pbr_indices
;
1996 auto_vec
<HOST_WIDE_INT
, 4> pass_through_offsets
;
1997 gcall
*stmt
= *stmt_p
;
1998 unsigned nargs
= gimple_call_num_args (stmt
);
1999 bool recreate
= false;
2001 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); i
++)
2003 tree t
= gimple_call_arg (stmt
, i
);
2004 gcc_assert (TREE_CODE (t
) != BIT_FIELD_REF
2005 && TREE_CODE (t
) != IMAGPART_EXPR
2006 && TREE_CODE (t
) != REALPART_EXPR
);
2008 if (TREE_CODE (t
) == SSA_NAME
2009 && m_dead_ssas
.contains (t
))
2012 if (m_replacements
.is_empty ())
2016 unsigned agg_arg_offset
;
2017 if (!isra_get_ref_base_and_offset (t
, &base
, &agg_arg_offset
))
2020 bool by_ref
= false;
2021 if (TREE_CODE (base
) == SSA_NAME
)
2023 if (!SSA_NAME_IS_DEFAULT_DEF (base
))
2025 base
= SSA_NAME_VAR (base
);
2026 gcc_checking_assert (base
);
2029 if (TREE_CODE (base
) != PARM_DECL
)
2032 bool base_among_replacements
= false;
2033 unsigned j
, repl_list_len
= m_replacements
.length ();
2034 for (j
= 0; j
< repl_list_len
; j
++)
2036 ipa_param_body_replacement
*pbr
= &m_replacements
[j
];
2037 if (pbr
->base
== base
)
2039 base_among_replacements
= true;
2043 if (!base_among_replacements
)
2046 /* We still have to distinguish between an end-use that we have to
2047 transform now and a pass-through, which happens in the following
2050 /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
2051 &MEM_REF[ssa_name + offset], we will also have to detect that case
2054 if (TREE_CODE (t
) == SSA_NAME
2055 && SSA_NAME_IS_DEFAULT_DEF (t
)
2057 && TREE_CODE (SSA_NAME_VAR (t
)) == PARM_DECL
)
2059 /* This must be a by_reference pass-through. */
2061 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t
)));
2062 pass_through_args
.safe_push (i
);
2063 pass_through_pbr_indices
.safe_push (j
);
2064 pass_through_offsets
.safe_push (agg_arg_offset
);
2066 else if (!by_ref
&& AGGREGATE_TYPE_P (TREE_TYPE (t
)))
2068 /* Currently IPA-SRA guarantees the aggregate access type
2069 exactly matches in this case. So if it does not match, it is
2070 a pass-through argument that will be sorted out at edge
2071 redirection time. */
2072 ipa_param_body_replacement
*pbr
2073 = lookup_replacement_1 (base
, agg_arg_offset
);
2076 || (TYPE_MAIN_VARIANT (TREE_TYPE (t
))
2077 != TYPE_MAIN_VARIANT (TREE_TYPE (pbr
->repl
))))
2080 pass_through_args
.safe_push (i
);
2081 pass_through_pbr_indices
.safe_push (j
);
2082 pass_through_offsets
.safe_push (agg_arg_offset
);
2089 /* No need to rebuild the statement, let's just modify arguments
2090 and the LHS if/as appropriate. */
2091 bool modified
= false;
2092 for (unsigned i
= 0; i
< nargs
; i
++)
2094 tree
*t
= gimple_call_arg_ptr (stmt
, i
);
2095 modified
|= modify_expression (t
, true);
2097 if (gimple_call_lhs (stmt
))
2099 tree
*t
= gimple_call_lhs_ptr (stmt
);
2100 modified
|= modify_expression (t
, false);
2105 auto_vec
<int, 16> index_map
;
2106 auto_vec
<pass_through_split_map
, 4> pass_through_map
;
2107 auto_vec
<tree
, 16> vargs
;
2108 int always_copy_delta
= 0;
2109 unsigned pt_idx
= 0;
2110 int new_arg_idx
= 0;
2111 for (unsigned i
= 0; i
< nargs
; i
++)
2113 if (pt_idx
< pass_through_args
.length ()
2114 && i
== pass_through_args
[pt_idx
])
2116 unsigned j
= pass_through_pbr_indices
[pt_idx
];
2117 unsigned agg_arg_offset
= pass_through_offsets
[pt_idx
];
2119 always_copy_delta
--;
2120 tree base
= m_replacements
[j
].base
;
2122 /* In order to be put into SSA form, we have to push all replacements
2123 pertaining to this parameter as parameters to the call statement.
2124 Edge redirection will need to use edge summary to weed out the
2125 unnecessary ones. */
2126 unsigned repl_list_len
= m_replacements
.length ();
2127 for (; j
< repl_list_len
; j
++)
2129 if (m_replacements
[j
].base
!= base
)
2131 if (m_replacements
[j
].unit_offset
< agg_arg_offset
)
2133 pass_through_split_map pt_map
;
2134 pt_map
.base_index
= i
;
2136 = m_replacements
[j
].unit_offset
- agg_arg_offset
;
2137 pt_map
.new_index
= new_arg_idx
;
2138 pass_through_map
.safe_push (pt_map
);
2139 vargs
.safe_push (m_replacements
[j
].repl
);
2141 always_copy_delta
++;
2143 index_map
.safe_push (-1);
2147 tree t
= gimple_call_arg (stmt
, i
);
2148 if (TREE_CODE (t
) == SSA_NAME
2149 && m_dead_ssas
.contains (t
))
2151 always_copy_delta
--;
2152 index_map
.safe_push (-1);
2156 modify_expression (&t
, true);
2157 vargs
.safe_push (t
);
2158 index_map
.safe_push (new_arg_idx
);
2164 gcall
*new_stmt
= gimple_build_call_vec (gimple_call_fn (stmt
), vargs
);
2165 if (gimple_has_location (stmt
))
2166 gimple_set_location (new_stmt
, gimple_location (stmt
));
2167 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
2168 gimple_call_copy_flags (new_stmt
, stmt
);
2169 if (tree lhs
= gimple_call_lhs (stmt
))
2171 modify_expression (&lhs
, false);
2172 /* Avoid adjusting SSA_NAME_DEF_STMT of a SSA lhs, SSA names
2173 have not yet been remapped. */
2174 *gimple_call_lhs_ptr (new_stmt
) = lhs
;
2179 record_argument_state (m_id
, orig_stmt
, index_map
, pass_through_map
,
2184 /* If the statement STMT contains any expressions that need to replaced with a
2185 different one as noted by ADJUSTMENTS, do so. Handle any potential type
2186 incompatibilities. If any conversion sttements have to be pre-pended to
2187 STMT, they will be added to EXTRA_STMTS. Return true iff the statement was
2191 ipa_param_body_adjustments::modify_gimple_stmt (gimple
**stmt
,
2192 gimple_seq
*extra_stmts
,
2195 bool modified
= false;
2198 switch (gimple_code (*stmt
))
2201 t
= gimple_return_retval_ptr (as_a
<greturn
*> (*stmt
));
2202 if (m_adjustments
&& m_adjustments
->m_skip_return
)
2204 else if (*t
!= NULL_TREE
)
2205 modified
|= modify_expression (t
, true);
2209 modified
|= modify_assignment (*stmt
, extra_stmts
);
2213 modified
|= modify_call_stmt ((gcall
**) stmt
, orig_stmt
);
2218 gasm
*asm_stmt
= as_a
<gasm
*> (*stmt
);
2219 for (unsigned i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
2221 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
2222 modified
|= modify_expression (t
, true);
2224 for (unsigned i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
2226 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
2227 modified
|= modify_expression (t
, false);
2239 /* Traverse body of the current function and perform the requested adjustments
2240 on its statements. Return true iff the CFG has been changed. */
2243 ipa_param_body_adjustments::modify_cfun_body ()
2245 bool cfg_changed
= false;
2248 FOR_EACH_BB_FN (bb
, cfun
)
2250 gimple_stmt_iterator gsi
;
2252 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2254 gphi
*phi
= as_a
<gphi
*> (gsi_stmt (gsi
));
2255 tree new_lhs
, old_lhs
= gimple_phi_result (phi
);
2256 new_lhs
= replace_removed_params_ssa_names (old_lhs
, phi
);
2259 gimple_phi_set_result (phi
, new_lhs
);
2260 release_ssa_name (old_lhs
);
2264 gsi
= gsi_start_bb (bb
);
2265 while (!gsi_end_p (gsi
))
2267 gimple
*stmt
= gsi_stmt (gsi
);
2268 gimple
*stmt_copy
= stmt
;
2269 gimple_seq extra_stmts
= NULL
;
2270 bool modified
= modify_gimple_stmt (&stmt
, &extra_stmts
, NULL
);
2271 if (stmt
!= stmt_copy
)
2273 gcc_checking_assert (modified
);
2274 gsi_replace (&gsi
, stmt
, false);
2276 if (!gimple_seq_empty_p (extra_stmts
))
2277 gsi_insert_seq_before (&gsi
, extra_stmts
, GSI_SAME_STMT
);
2281 FOR_EACH_SSA_DEF_OPERAND (defp
, stmt
, iter
, SSA_OP_DEF
)
2283 tree old_def
= DEF_FROM_PTR (defp
);
2284 if (tree new_def
= replace_removed_params_ssa_names (old_def
,
2287 SET_DEF (defp
, new_def
);
2288 release_ssa_name (old_def
);
2296 if (maybe_clean_eh_stmt (stmt
)
2297 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
2307 /* Call gimple_debug_bind_reset_value on all debug statements describing
2308 gimple register parameters that are being removed or replaced. */
2311 ipa_param_body_adjustments::reset_debug_stmts ()
2314 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
2316 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
2318 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
2321 len
= m_reset_debug_decls
.length ();
2322 for (i
= 0; i
< len
; i
++)
2324 imm_use_iterator ui
;
2327 tree name
, vexpr
, copy
= NULL_TREE
;
2328 use_operand_p use_p
;
2329 tree decl
= m_reset_debug_decls
[i
];
2331 gcc_checking_assert (is_gimple_reg (decl
));
2332 name
= ssa_default_def (cfun
, decl
);
2335 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
2337 if (gimple_clobber_p (stmt
))
2339 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
2340 unlink_stmt_vdef (stmt
);
2341 gsi_remove (&cgsi
, true);
2342 release_defs (stmt
);
2345 /* All other users must have been removed by function body
2347 gcc_assert (is_gimple_debug (stmt
));
2348 if (vexpr
== NULL
&& gsip
!= NULL
)
2350 vexpr
= build_debug_expr_decl (TREE_TYPE (name
));
2351 /* FIXME: Is setting the mode really necessary? */
2352 SET_DECL_MODE (vexpr
, DECL_MODE (decl
));
2353 def_temp
= gimple_build_debug_source_bind (vexpr
, decl
, NULL
);
2354 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
2358 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
2359 SET_USE (use_p
, vexpr
);
2362 gimple_debug_bind_reset_value (stmt
);
2365 /* Create a VAR_DECL for debug info purposes. */
2366 if (!DECL_IGNORED_P (decl
))
2368 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
2369 VAR_DECL
, DECL_NAME (decl
),
2371 if (DECL_PT_UID_SET_P (decl
))
2372 SET_DECL_PT_UID (copy
, DECL_PT_UID (decl
));
2373 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (decl
);
2374 TREE_READONLY (copy
) = TREE_READONLY (decl
);
2375 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (decl
);
2376 DECL_NOT_GIMPLE_REG_P (copy
) = DECL_NOT_GIMPLE_REG_P (decl
);
2377 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (decl
);
2378 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (decl
);
2379 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (decl
);
2380 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
2381 SET_DECL_RTL (copy
, 0);
2382 TREE_USED (copy
) = 1;
2383 DECL_CONTEXT (copy
) = current_function_decl
;
2384 add_local_decl (cfun
, copy
);
2386 = BLOCK_VARS (DECL_INITIAL (current_function_decl
));
2387 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
2389 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (decl
))
2391 gcc_assert (TREE_CODE (decl
) == PARM_DECL
);
2393 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
2395 def_temp
= gimple_build_debug_source_bind (copy
, decl
,
2397 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
2402 /* Perform all necessary body changes to change signature, body and debug info
2403 of fun according to adjustments passed at construction. Return true if CFG
2404 was changed in any way. The main entry point for modification of standalone
2405 functions that is not part of IPA clone materialization. */
2408 ipa_param_body_adjustments::perform_cfun_body_modifications ()
2411 modify_formal_parameters ();
2412 cfg_changed
= modify_cfun_body ();
2413 reset_debug_stmts ();
2419 /* If there are any initialization statements that need to be emitted into
2420 the basic block BB right at ther start of the new function, do so. */
2422 ipa_param_body_adjustments::append_init_stmts (basic_block bb
)
2424 gimple_stmt_iterator si
= gsi_last_bb (bb
);
2425 while (!m_split_agg_csts_inits
.is_empty ())
2426 gsi_insert_after (&si
, m_split_agg_csts_inits
.pop (), GSI_NEW_STMT
);
2429 /* Deallocate summaries which otherwise stay alive until the end of
2433 ipa_edge_modifications_finalize ()
2435 if (!ipa_edge_modifications
)
2437 delete ipa_edge_modifications
;
2438 ipa_edge_modifications
= NULL
;