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/>. */
21 #define INCLUDE_ALGORITHM
24 #include "coretypes.h"
30 #include "fold-const.h"
32 #include "stor-layout.h"
34 #include "gimple-iterator.h"
35 #include "gimplify-me.h"
38 #include "ipa-param-manipulation.h"
39 #include "print-tree.h"
40 #include "gimple-pretty-print.h"
43 #include "tree-inline.h"
44 #include "alloc-pool.h"
45 #include "symbol-summary.h"
46 #include "symtab-clones.h"
47 #include "tree-phinodes.h"
48 #include "cfgexpand.h"
52 /* Actual prefixes of different newly synthetized parameters. Keep in sync
53 with IPA_PARAM_PREFIX_* defines. */
55 static const char *ipa_param_prefixes
[IPA_PARAM_PREFIX_COUNT
]
61 /* Names of parameters for dumping. Keep in sync with enum ipa_parm_op. */
63 static const char *ipa_param_op_names
[IPA_PARAM_PREFIX_COUNT
]
64 = {"IPA_PARAM_OP_UNDEFINED",
67 "IPA_PARAM_OP_SPLIT"};
69 /* Structure to hold declarations representing pass-through IPA-SRA splits. In
70 essence, it tells new index for a combination of original index and
73 struct pass_through_split_map
75 /* Original argument index. */
77 /* Offset of the split part in the original argument. */
79 /* Index of the split part in the call statement - where clone
80 materialization put it. */
84 /* Information about some call statements that needs to be conveyed from clone
85 materialization to edge redirection. */
87 class ipa_edge_modification_info
90 ipa_edge_modification_info ()
93 /* Mapping of original argument indices to where those arguments sit in the
94 call statement now or to a negative index if they were removed. */
95 auto_vec
<int> index_map
;
96 /* Information about ISRA replacements put into the call statement at the
97 clone materialization stages. */
98 auto_vec
<pass_through_split_map
> pass_through_map
;
99 /* Necessary adjustment to ipa_param_adjustments::m_always_copy_start when
100 redirecting the call. */
101 int always_copy_delta
= 0;
104 /* Class for storing and retrieving summaries about cal statement
107 class ipa_edge_modification_sum
108 : public call_summary
<ipa_edge_modification_info
*>
111 ipa_edge_modification_sum (symbol_table
*table
)
112 : call_summary
<ipa_edge_modification_info
*> (table
)
116 /* Hook that is called by summary when an edge is duplicated. */
118 void duplicate (cgraph_edge
*,
120 ipa_edge_modification_info
*old_info
,
121 ipa_edge_modification_info
*new_info
) final override
123 new_info
->index_map
.safe_splice (old_info
->index_map
);
124 new_info
->pass_through_map
.safe_splice (old_info
->pass_through_map
);
125 new_info
->always_copy_delta
= old_info
->always_copy_delta
;
129 /* Call summary to store information about edges which have had their arguments
130 partially modified already. */
132 static ipa_edge_modification_sum
*ipa_edge_modifications
;
134 /* Fail compilation if CS has any summary associated with it in
135 ipa_edge_modifications. */
138 ipa_verify_edge_has_no_modifications (cgraph_edge
*cs
)
140 gcc_assert (!ipa_edge_modifications
|| !ipa_edge_modifications
->get (cs
));
143 /* Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
144 FNDECL. The function should not be called during LTO WPA phase except for
145 thunks (or functions with bodies streamed in). */
148 push_function_arg_decls (vec
<tree
> *args
, tree fndecl
)
153 /* Safety check that we do not attempt to use the function in WPA, except
154 when the function is a thunk and then we have DECL_ARGUMENTS or when we
155 have already explicitely loaded its body. */
156 gcc_assert (!flag_wpa
157 || DECL_ARGUMENTS (fndecl
)
158 || gimple_has_body_p (fndecl
));
160 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
163 args
->reserve_exact (count
);
164 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
165 args
->quick_push (parm
);
168 /* Fill an empty vector TYPES with trees representing formal parameters of
169 function type FNTYPE. */
172 push_function_arg_types (vec
<tree
> *types
, tree fntype
)
177 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
180 types
->reserve_exact (count
);
181 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
182 types
->quick_push (TREE_VALUE (t
));
185 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
186 friendly way, assuming they are meant to be applied to FNDECL. */
189 ipa_dump_adjusted_parameters (FILE *f
,
190 vec
<ipa_adjusted_param
, va_gc
> *adj_params
)
192 unsigned i
, len
= vec_safe_length (adj_params
);
198 fprintf (f
, " IPA adjusted parameters: ");
199 for (i
= 0; i
< len
; i
++)
201 struct ipa_adjusted_param
*apm
;
202 apm
= &(*adj_params
)[i
];
209 fprintf (f
, "%i. %s %s", i
, ipa_param_op_names
[apm
->op
],
210 apm
->prev_clone_adjustment
? "prev_clone_adjustment " : "");
213 case IPA_PARAM_OP_UNDEFINED
:
216 case IPA_PARAM_OP_COPY
:
217 fprintf (f
, ", base_index: %u", apm
->base_index
);
218 fprintf (f
, ", prev_clone_index: %u", apm
->prev_clone_index
);
221 case IPA_PARAM_OP_SPLIT
:
222 fprintf (f
, ", offset: %u", apm
->unit_offset
);
224 case IPA_PARAM_OP_NEW
:
225 fprintf (f
, ", base_index: %u", apm
->base_index
);
226 fprintf (f
, ", prev_clone_index: %u", apm
->prev_clone_index
);
227 print_node_brief (f
, ", type: ", apm
->type
, 0);
228 print_node_brief (f
, ", alias type: ", apm
->alias_ptr_type
, 0);
229 fprintf (f
, " prefix: %s",
230 ipa_param_prefixes
[apm
->param_prefix_index
]);
232 fprintf (f
, ", reverse");
239 /* Fill NEW_TYPES with types of a function after its current OTYPES have been
240 modified as described in ADJ_PARAMS. When USE_PREV_INDICES is true, use
241 prev_clone_index from ADJ_PARAMS as opposed to base_index when the parameter
245 fill_vector_of_new_param_types (vec
<tree
> *new_types
, vec
<tree
> *otypes
,
246 vec
<ipa_adjusted_param
, va_gc
> *adj_params
,
247 bool use_prev_indices
)
249 unsigned adj_len
= vec_safe_length (adj_params
);
250 new_types
->reserve_exact (adj_len
);
251 for (unsigned i
= 0; i
< adj_len
; i
++)
253 ipa_adjusted_param
*apm
= &(*adj_params
)[i
];
254 if (apm
->op
== IPA_PARAM_OP_COPY
)
257 = use_prev_indices
? apm
->prev_clone_index
: apm
->base_index
;
258 /* The following needs to be handled gracefully because of type
259 mismatches. This happens with LTO but apparently also in Fortran
260 with -fcoarray=lib -O2 -lcaf_single -latomic. */
261 if (index
>= otypes
->length ())
263 new_types
->quick_push ((*otypes
)[index
]);
265 else if (apm
->op
== IPA_PARAM_OP_NEW
266 || apm
->op
== IPA_PARAM_OP_SPLIT
)
268 tree ntype
= apm
->type
;
269 if (is_gimple_reg_type (ntype
)
270 && TYPE_MODE (ntype
) != BLKmode
)
272 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ntype
));
273 if (TYPE_ALIGN (ntype
) != malign
)
274 ntype
= build_aligned_type (ntype
, malign
);
276 new_types
->quick_push (ntype
);
283 /* Return false if given attribute should prevent type adjustments. */
286 ipa_param_adjustments::type_attribute_allowed_p (tree name
)
288 if ((is_attribute_p ("fn spec", name
) && flag_ipa_modref
)
289 || is_attribute_p ("access", name
)
290 || is_attribute_p ("returns_nonnull", name
)
291 || is_attribute_p ("assume_aligned", name
)
292 || is_attribute_p ("nocf_check", name
)
293 || is_attribute_p ("warn_unused_result", name
))
298 /* Return true if attribute should be dropped if parameter changed. */
301 drop_type_attribute_if_params_changed_p (tree name
)
303 if (is_attribute_p ("fn spec", name
)
304 || is_attribute_p ("access", name
))
309 /* Build and return a function type just like ORIG_TYPE but with parameter
310 types given in NEW_PARAM_TYPES - which can be NULL if, but only if,
311 ORIG_TYPE itself has NULL TREE_ARG_TYPEs. If METHOD2FUNC is true, also make
312 it a FUNCTION_TYPE instead of FUNCTION_TYPE.
313 If ARG_MODIFIED is true drop attributes that are no longer up to date. */
316 build_adjusted_function_type (tree orig_type
, vec
<tree
> *new_param_types
,
317 bool method2func
, bool skip_return
,
320 tree new_arg_types
= NULL
;
321 if (TYPE_ARG_TYPES (orig_type
))
323 gcc_checking_assert (new_param_types
);
324 bool last_parm_void
= (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type
)))
326 unsigned len
= new_param_types
->length ();
327 for (unsigned i
= 0; i
< len
; i
++)
328 new_arg_types
= tree_cons (NULL_TREE
, (*new_param_types
)[i
],
331 tree new_reversed
= nreverse (new_arg_types
);
335 TREE_CHAIN (new_arg_types
) = void_list_node
;
337 new_reversed
= void_list_node
;
339 new_arg_types
= new_reversed
;
342 /* Use build_distinct_type_copy to preserve as much as possible from original
343 type (debug info, attribute lists etc.). The one exception is
344 METHOD_TYPEs which must have THIS argument and when we are asked to remove
345 it, we need to build new FUNCTION_TYPE instead. */
346 tree new_type
= NULL
;
351 ret_type
= void_type_node
;
353 ret_type
= TREE_TYPE (orig_type
);
356 = build_distinct_type_copy (build_function_type (ret_type
,
358 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
362 new_type
= build_distinct_type_copy (orig_type
);
363 TYPE_ARG_TYPES (new_type
) = new_arg_types
;
365 TREE_TYPE (new_type
) = void_type_node
;
367 if (args_modified
&& TYPE_ATTRIBUTES (new_type
))
369 tree t
= TYPE_ATTRIBUTES (new_type
);
370 tree
*last
= &TYPE_ATTRIBUTES (new_type
);
371 TYPE_ATTRIBUTES (new_type
) = NULL
;
372 for (;t
; t
= TREE_CHAIN (t
))
373 if (!drop_type_attribute_if_params_changed_p
374 (get_attribute_name (t
)))
376 *last
= copy_node (t
);
377 TREE_CHAIN (*last
) = NULL
;
378 last
= &TREE_CHAIN (*last
);
385 /* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
389 ipa_param_adjustments::get_max_base_index ()
391 unsigned adj_len
= vec_safe_length (m_adj_params
);
393 for (unsigned i
= 0; i
< adj_len
; i
++)
395 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
396 if (apm
->op
== IPA_PARAM_OP_COPY
397 && max_index
< apm
->base_index
)
398 max_index
= apm
->base_index
;
404 /* Fill SURVIVING_PARAMS with an array of bools where each one says whether a
405 parameter that originally was at that position still survives in the given
406 clone or is removed/replaced. If the final array is smaller than an index
407 of an original parameter, that parameter also did not survive. That a
408 parameter survives does not mean it has the same index as before. */
411 ipa_param_adjustments::get_surviving_params (vec
<bool> *surviving_params
)
413 unsigned adj_len
= vec_safe_length (m_adj_params
);
414 int max_index
= get_max_base_index ();
418 surviving_params
->reserve_exact (max_index
+ 1);
419 surviving_params
->quick_grow_cleared (max_index
+ 1);
420 for (unsigned i
= 0; i
< adj_len
; i
++)
422 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
423 if (apm
->op
== IPA_PARAM_OP_COPY
)
424 (*surviving_params
)[apm
->base_index
] = true;
428 /* Fill NEW_INDICES with new indices of each surviving parameter or -1 for
429 those which do not survive. Any parameter outside of lenght of the vector
430 does not survive. There is currently no support for a parameter to be
431 copied to two distinct new parameters. */
434 ipa_param_adjustments::get_updated_indices (vec
<int> *new_indices
)
436 unsigned adj_len
= vec_safe_length (m_adj_params
);
437 int max_index
= get_max_base_index ();
441 unsigned res_len
= max_index
+ 1;
442 new_indices
->reserve_exact (res_len
);
443 for (unsigned i
= 0; i
< res_len
; i
++)
444 new_indices
->quick_push (-1);
445 for (unsigned i
= 0; i
< adj_len
; i
++)
447 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
448 if (apm
->op
== IPA_PARAM_OP_COPY
)
449 (*new_indices
)[apm
->base_index
] = i
;
453 /* Return the original index for the given new parameter index. Return a
454 negative number if not available. */
457 ipa_param_adjustments::get_original_index (int newidx
)
459 const ipa_adjusted_param
*adj
= &(*m_adj_params
)[newidx
];
460 if (adj
->op
!= IPA_PARAM_OP_COPY
)
462 return adj
->base_index
;
465 /* Return true if the first parameter (assuming there was one) survives the
466 transformation intact and remains the first one. */
469 ipa_param_adjustments::first_param_intact_p ()
471 return (!vec_safe_is_empty (m_adj_params
)
472 && (*m_adj_params
)[0].op
== IPA_PARAM_OP_COPY
473 && (*m_adj_params
)[0].base_index
== 0);
476 /* Return true if we have to change what has formerly been a method into a
480 ipa_param_adjustments::method2func_p (tree orig_type
)
482 return ((TREE_CODE (orig_type
) == METHOD_TYPE
) && !first_param_intact_p ());
485 /* Given function type OLD_TYPE, return a new type derived from it after
486 performing all atored modifications. TYPE_ORIGINAL_P should be true when
487 OLD_TYPE refers to the type before any IPA transformations, as opposed to a
488 type that can be an intermediate one in between various IPA
492 ipa_param_adjustments::build_new_function_type (tree old_type
,
493 bool type_original_p
)
495 auto_vec
<tree
,16> new_param_types
, *new_param_types_p
;
496 if (prototype_p (old_type
))
498 auto_vec
<tree
, 16> otypes
;
499 push_function_arg_types (&otypes
, old_type
);
500 fill_vector_of_new_param_types (&new_param_types
, &otypes
, m_adj_params
,
502 new_param_types_p
= &new_param_types
;
505 new_param_types_p
= NULL
;
507 /* Check if any params type cares about are modified. In this case will
508 need to drop some type attributes. */
509 bool modified
= false;
512 for (tree t
= TYPE_ARG_TYPES (old_type
);
513 t
&& (int)index
< m_always_copy_start
&& !modified
;
514 t
= TREE_CHAIN (t
), index
++)
515 if (index
>= m_adj_params
->length ()
516 || get_original_index (index
) != (int)index
)
520 return build_adjusted_function_type (old_type
, new_param_types_p
,
521 method2func_p (old_type
), m_skip_return
,
525 /* Build variant of function decl ORIG_DECL which has no return value if
526 M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
527 this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
528 DECL_ARGUMENTS list are not processed now, since they are linked by
529 TREE_CHAIN directly and not accessible in LTO during WPA. The caller is
530 responsible for eliminating them when clones are properly materialized. */
533 ipa_param_adjustments::adjust_decl (tree orig_decl
)
535 tree new_decl
= copy_node (orig_decl
);
536 tree orig_type
= TREE_TYPE (orig_decl
);
537 if (prototype_p (orig_type
)
538 || (m_skip_return
&& !VOID_TYPE_P (TREE_TYPE (orig_type
))))
540 tree new_type
= build_new_function_type (orig_type
, false);
541 TREE_TYPE (new_decl
) = new_type
;
543 if (method2func_p (orig_type
))
544 DECL_VINDEX (new_decl
) = NULL_TREE
;
546 /* When signature changes, we need to clear builtin info. */
547 if (fndecl_built_in_p (new_decl
))
548 set_decl_built_in_function (new_decl
, NOT_BUILT_IN
, 0);
550 DECL_VIRTUAL_P (new_decl
) = 0;
551 DECL_LANG_SPECIFIC (new_decl
) = NULL
;
553 /* Drop MALLOC attribute for a void function. */
555 DECL_IS_MALLOC (new_decl
) = 0;
560 /* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
561 transformations. Return true if EXPR has an interesting form and fill in
562 *BASE_P and *UNIT_OFFSET_P with the appropriate info. */
565 isra_get_ref_base_and_offset (tree expr
, tree
*base_p
, unsigned *unit_offset_p
)
567 HOST_WIDE_INT offset
, size
;
570 = get_ref_base_and_extent_hwi (expr
, &offset
, &size
, &reverse
);
571 if (!base
|| size
< 0)
574 if ((offset
% BITS_PER_UNIT
) != 0)
577 if (TREE_CODE (base
) == MEM_REF
)
579 poly_int64 plmoff
= mem_ref_offset (base
).force_shwi ();
581 bool is_cst
= plmoff
.is_constant (&moff
);
584 offset
+= moff
* BITS_PER_UNIT
;
585 base
= TREE_OPERAND (base
, 0);
588 if (offset
< 0 || (offset
/ BITS_PER_UNIT
) > UINT_MAX
)
592 *unit_offset_p
= offset
/ BITS_PER_UNIT
;
596 /* Modify actual arguments of a function call in statement currently belonging
597 to CS, and make it call CS->callee->decl. Return the new statement that
598 replaced the old one. When invoked, cfun and current_function_decl have to
599 be set to the caller. */
602 ipa_param_adjustments::modify_call (cgraph_edge
*cs
,
603 bool update_references
)
605 gcall
*stmt
= cs
->call_stmt
;
606 tree callee_decl
= cs
->callee
->decl
;
608 ipa_edge_modification_info
*mod_info
609 = ipa_edge_modifications
? ipa_edge_modifications
->get (cs
) : NULL
;
610 if (mod_info
&& symtab
->dump_file
)
612 fprintf (symtab
->dump_file
, "Information about pre-exiting "
613 "modifications.\n Index map:");
614 unsigned idx_len
= mod_info
->index_map
.length ();
615 for (unsigned i
= 0; i
< idx_len
; i
++)
616 fprintf (symtab
->dump_file
, " %i", mod_info
->index_map
[i
]);
617 fprintf (symtab
->dump_file
, "\n Pass-through split map: ");
618 unsigned ptm_len
= mod_info
->pass_through_map
.length ();
619 for (unsigned i
= 0; i
< ptm_len
; i
++)
620 fprintf (symtab
->dump_file
,
621 " (base_index: %u, offset: %u, new_index: %i)",
622 mod_info
->pass_through_map
[i
].base_index
,
623 mod_info
->pass_through_map
[i
].unit_offset
,
624 mod_info
->pass_through_map
[i
].new_index
);
625 fprintf (symtab
->dump_file
, "\n Always-copy delta: %i\n",
626 mod_info
->always_copy_delta
);
629 unsigned len
= vec_safe_length (m_adj_params
);
630 auto_vec
<tree
, 16> vargs (len
);
631 unsigned old_nargs
= gimple_call_num_args (stmt
);
632 unsigned orig_nargs
= mod_info
? mod_info
->index_map
.length () : old_nargs
;
633 auto_vec
<bool, 16> kept (old_nargs
);
634 kept
.quick_grow_cleared (old_nargs
);
636 cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
637 if (update_references
)
638 current_node
->remove_stmt_references (stmt
);
640 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
641 gimple_stmt_iterator prev_gsi
= gsi
;
642 gsi_prev (&prev_gsi
);
643 for (unsigned i
= 0; i
< len
; i
++)
645 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
646 if (apm
->op
== IPA_PARAM_OP_COPY
)
648 int index
= apm
->base_index
;
649 if ((unsigned) index
>= orig_nargs
)
650 /* Can happen if the original call has argument mismatch,
655 index
= mod_info
->index_map
[apm
->base_index
];
656 gcc_assert (index
>= 0);
659 tree arg
= gimple_call_arg (stmt
, index
);
661 vargs
.quick_push (arg
);
666 /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
667 If we ever want to support it during WPA IPA stage, we'll need a
668 mechanism to call into the IPA passes that introduced them. Currently
669 we simply mandate that IPA infrastructure understands all argument
670 modifications. Remember, edge redirection/modification is done only
671 once, not in steps for each pass modifying the callee like clone
673 gcc_assert (apm
->op
== IPA_PARAM_OP_SPLIT
);
675 /* We have to handle pass-through changes differently using the map
676 clone materialziation might have left behind. */
677 tree repl
= NULL_TREE
;
678 unsigned ptm_len
= mod_info
? mod_info
->pass_through_map
.length () : 0;
679 for (unsigned j
= 0; j
< ptm_len
; j
++)
680 if (mod_info
->pass_through_map
[j
].base_index
== apm
->base_index
681 && mod_info
->pass_through_map
[j
].unit_offset
== apm
->unit_offset
)
683 int repl_idx
= mod_info
->pass_through_map
[j
].new_index
;
684 gcc_assert (repl_idx
>= 0);
685 repl
= gimple_call_arg (stmt
, repl_idx
);
690 vargs
.quick_push (repl
);
694 int index
= apm
->base_index
;
695 if ((unsigned) index
>= orig_nargs
)
696 /* Can happen if the original call has argument mismatch, ignore. */
700 index
= mod_info
->index_map
[apm
->base_index
];
701 gcc_assert (index
>= 0);
703 tree base
= gimple_call_arg (stmt
, index
);
705 /* We create a new parameter out of the value of the old one, we can
706 do the following kind of transformations:
708 - A scalar passed by reference, potentially as a part of a larger
709 aggregate, is converted to a scalar passed by value.
711 - A part of an aggregate is passed instead of the whole aggregate. */
713 location_t loc
= gimple_location (stmt
);
715 bool deref_base
= false;
716 unsigned int deref_align
= 0;
717 if (TREE_CODE (base
) != ADDR_EXPR
718 && is_gimple_reg_type (TREE_TYPE (base
)))
720 /* Detect type mismatches in calls in invalid programs and make a
721 poor attempt to gracefully convert them so that we don't ICE. */
722 if (!POINTER_TYPE_P (TREE_TYPE (base
)))
723 base
= force_value_to_type (ptr_type_node
, base
);
725 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
730 if (TREE_CODE (base
) == ADDR_EXPR
)
732 base
= TREE_OPERAND (base
, 0);
738 tree prev_base
= base
;
739 poly_int64 base_offset
;
740 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
742 /* Aggregate arguments can have non-invariant addresses. */
745 base
= build_fold_addr_expr (prev_base
);
746 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
748 else if (TREE_CODE (base
) == MEM_REF
)
753 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
755 off
= build_int_cst (apm
->alias_ptr_type
,
756 base_offset
+ apm
->unit_offset
);
757 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
759 base
= TREE_OPERAND (base
, 0);
763 off
= build_int_cst (apm
->alias_ptr_type
,
764 base_offset
+ apm
->unit_offset
);
765 base
= build_fold_addr_expr (base
);
769 tree type
= apm
->type
;
771 unsigned HOST_WIDE_INT misalign
;
780 get_pointer_alignment_1 (base
, &align
, &misalign
);
781 /* All users must make sure that we can be optimistic when it
782 comes to alignment in this case (by inspecting the final users
783 of these new parameters). */
784 if (TYPE_ALIGN (type
) > align
)
785 align
= TYPE_ALIGN (type
);
788 += (offset_int::from (wi::to_wide (off
), SIGNED
).to_short_addr ()
790 misalign
= misalign
& (align
- 1);
792 align
= least_bit_hwi (misalign
);
793 if (align
< TYPE_ALIGN (type
))
794 type
= build_aligned_type (type
, align
);
795 base
= force_gimple_operand_gsi (&gsi
, base
,
796 true, NULL
, true, GSI_SAME_STMT
);
797 tree expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
798 REF_REVERSE_STORAGE_ORDER (expr
) = apm
->reverse
;
799 /* If expr is not a valid gimple call argument emit
800 a load into a temporary. */
801 if (is_gimple_reg_type (TREE_TYPE (expr
)))
803 gimple
*tem
= gimple_build_assign (NULL_TREE
, expr
);
804 if (gimple_in_ssa_p (cfun
))
806 gimple_set_vuse (tem
, gimple_vuse (stmt
));
807 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
810 expr
= create_tmp_reg (TREE_TYPE (expr
));
811 gimple_assign_set_lhs (tem
, expr
);
812 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
814 vargs
.quick_push (expr
);
817 if (m_always_copy_start
>= 0)
819 int always_copy_start
= m_always_copy_start
;
822 always_copy_start
+= mod_info
->always_copy_delta
;
823 gcc_assert (always_copy_start
>= 0);
825 for (unsigned i
= always_copy_start
; i
< old_nargs
; i
++)
826 vargs
.safe_push (gimple_call_arg (stmt
, i
));
829 /* For optimized away parameters, add on the caller side
831 DEBUG D#X => parm_Y(D)
832 stmts and associate D#X with parm in decl_debug_args_lookup
833 vector to say for debug info that if parameter parm had been passed,
834 it would have value parm_Y(D). */
835 tree old_decl
= gimple_call_fndecl (stmt
);
836 if (MAY_HAVE_DEBUG_BIND_STMTS
&& old_decl
&& callee_decl
)
838 vec
<tree
, va_gc
> **debug_args
= NULL
;
840 cgraph_node
*callee_node
= cgraph_node::get (callee_decl
);
842 /* FIXME: we don't seem to be able to insert debug args before clone
843 is materialized. Materializing them early leads to extra memory
845 if (callee_node
->clone_of
)
846 callee_node
->get_untransformed_body ();
847 for (tree old_parm
= DECL_ARGUMENTS (old_decl
);
848 old_parm
&& i
< old_nargs
&& ((int) i
) < m_always_copy_start
;
849 old_parm
= DECL_CHAIN (old_parm
), i
++)
851 if (!is_gimple_reg (old_parm
) || kept
[i
])
856 if (mod_info
->index_map
[i
] < 0)
858 arg
= gimple_call_arg (stmt
, mod_info
->index_map
[i
]);
861 arg
= gimple_call_arg (stmt
, i
);
863 tree origin
= DECL_ORIGIN (old_parm
);
864 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
866 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
869 if (TREE_CODE (arg
) == SSA_NAME
870 && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg
))
872 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg
)))
873 && useless_type_conversion_p (TREE_TYPE (origin
),
877 arg
= fold_convert_loc (gimple_location (stmt
),
878 TREE_TYPE (origin
), arg
);
880 if (debug_args
== NULL
)
881 debug_args
= decl_debug_args_insert (callee_decl
);
883 tree ddecl
= NULL_TREE
;
884 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
887 ddecl
= (**debug_args
)[ix
+ 1];
892 ddecl
= build_debug_expr_decl (TREE_TYPE (origin
));
893 /* FIXME: Is setting the mode really necessary? */
894 SET_DECL_MODE (ddecl
, DECL_MODE (origin
));
896 vec_safe_push (*debug_args
, origin
);
897 vec_safe_push (*debug_args
, ddecl
);
899 gimple
*def_temp
= gimple_build_debug_bind (ddecl
,
900 unshare_expr (arg
), stmt
);
901 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
905 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
907 fprintf (dump_file
, "replacing stmt:");
908 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0);
911 gcall
*new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
913 tree ssa_to_remove
= NULL
;
914 if (tree lhs
= gimple_call_lhs (stmt
))
917 gimple_call_set_lhs (new_stmt
, lhs
);
918 else if (TREE_CODE (lhs
) == SSA_NAME
)
920 /* LHS should now by a default-def SSA. Unfortunately default-def
921 SSA_NAMEs need a backing variable (or at least some code examining
922 SSAs assumes it is non-NULL). So we either have to re-use the
923 decl we have at hand or introdice a new one. */
924 tree repl
= create_tmp_var (TREE_TYPE (lhs
), "removed_return");
925 repl
= get_or_create_ssa_default_def (cfun
, repl
);
926 SSA_NAME_IS_DEFAULT_DEF (repl
) = true;
930 FOR_EACH_IMM_USE_STMT (using_stmt
, ui
, lhs
)
932 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
934 SET_USE (use_p
, repl
);
936 update_stmt (using_stmt
);
942 gimple_set_block (new_stmt
, gimple_block (stmt
));
943 if (gimple_has_location (stmt
))
944 gimple_set_location (new_stmt
, gimple_location (stmt
));
945 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
946 gimple_call_copy_flags (new_stmt
, stmt
);
947 if (gimple_in_ssa_p (cfun
))
948 gimple_move_vops (new_stmt
, stmt
);
950 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
952 fprintf (dump_file
, "with stmt:");
953 print_gimple_stmt (dump_file
, new_stmt
, 0);
954 fprintf (dump_file
, "\n");
956 gsi_replace (&gsi
, new_stmt
, true);
958 release_ssa_name (ssa_to_remove
);
959 if (update_references
)
962 current_node
->record_stmt_references (gsi_stmt (gsi
));
965 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
968 ipa_edge_modifications
->remove (cs
);
972 /* Dump information contained in the object in textual form to F. */
975 ipa_param_adjustments::dump (FILE *f
)
977 fprintf (f
, " m_always_copy_start: %i\n", m_always_copy_start
);
978 ipa_dump_adjusted_parameters (f
, m_adj_params
);
980 fprintf (f
, " Will SKIP return.\n");
983 /* Dump information contained in the object in textual form to stderr. */
986 ipa_param_adjustments::debug ()
991 /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
994 ipa_param_body_adjustments::register_replacement (tree base
,
995 unsigned unit_offset
,
998 ipa_param_body_replacement psr
;
1000 psr
.repl
= replacement
;
1001 psr
.dummy
= NULL_TREE
;
1002 psr
.unit_offset
= unit_offset
;
1003 m_replacements
.safe_push (psr
);
1004 m_sorted_replacements_p
= false;
1007 /* Register that REPLACEMENT should replace parameter described in APM. */
1010 ipa_param_body_adjustments::register_replacement (ipa_adjusted_param
*apm
,
1013 gcc_checking_assert (apm
->op
== IPA_PARAM_OP_SPLIT
1014 || apm
->op
== IPA_PARAM_OP_NEW
);
1015 gcc_checking_assert (!apm
->prev_clone_adjustment
);
1016 register_replacement (m_oparms
[apm
->prev_clone_index
], apm
->unit_offset
,
1020 /* Comparator for sorting and searching
1021 ipa_param_body_adjustments::m_replacements. */
1024 compare_param_body_replacement (const void *va
, const void *vb
)
1026 const ipa_param_body_replacement
*a
= (const ipa_param_body_replacement
*) va
;
1027 const ipa_param_body_replacement
*b
= (const ipa_param_body_replacement
*) vb
;
1029 if (DECL_UID (a
->base
) < DECL_UID (b
->base
))
1031 if (DECL_UID (a
->base
) > DECL_UID (b
->base
))
1033 if (a
->unit_offset
< b
->unit_offset
)
1035 if (a
->unit_offset
> b
->unit_offset
)
1040 /* Sort m_replacements and set m_sorted_replacements_p to true. */
1043 ipa_param_body_adjustments::sort_replacements ()
1045 if (m_sorted_replacements_p
)
1047 m_replacements
.qsort (compare_param_body_replacement
);
1048 m_sorted_replacements_p
= true;
1051 /* Copy or not, as appropriate given m_id and decl context, a pre-existing
1052 PARM_DECL T so that it can be included in the parameters of the modified
1056 ipa_param_body_adjustments::carry_over_param (tree t
)
1061 new_parm
= remap_decl (t
, m_id
);
1062 if (TREE_CODE (new_parm
) != PARM_DECL
)
1063 new_parm
= m_id
->copy_decl (t
, m_id
);
1065 else if (DECL_CONTEXT (t
) != m_fndecl
)
1067 new_parm
= copy_node (t
);
1068 DECL_CONTEXT (new_parm
) = m_fndecl
;
1075 /* If DECL is a gimple register that has a default definition SSA name and that
1076 has some uses, return the default definition, otherwise return NULL_TREE. */
1079 ipa_param_body_adjustments::get_ddef_if_exists_and_is_used (tree decl
)
1081 if (!is_gimple_reg (decl
))
1083 tree ddef
= ssa_default_def (m_id
->src_cfun
, decl
);
1084 if (!ddef
|| has_zero_uses (ddef
))
1089 /* Populate m_dead_stmts given that DEAD_PARAM is going to be removed without
1090 any replacement or splitting. REPL is the replacement VAR_SECL to base any
1091 remaining uses of a removed parameter on. Push all removed SSA names that
1092 are used within debug statements to DEBUGSTACK. */
1095 ipa_param_body_adjustments::mark_dead_statements (tree dead_param
,
1096 vec
<tree
> *debugstack
)
1098 /* Current IPA analyses which remove unused parameters never remove a
1099 non-gimple register ones which have any use except as parameters in other
1100 calls, so we can safely leve them as they are. */
1101 tree parm_ddef
= get_ddef_if_exists_and_is_used (dead_param
);
1105 auto_vec
<tree
, 4> stack
;
1106 hash_set
<tree
> used_in_debug
;
1107 m_dead_ssas
.add (parm_ddef
);
1108 stack
.safe_push (parm_ddef
);
1109 while (!stack
.is_empty ())
1111 imm_use_iterator imm_iter
;
1112 use_operand_p use_p
;
1113 tree t
= stack
.pop ();
1115 insert_decl_map (m_id
, t
, error_mark_node
);
1116 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, t
)
1118 gimple
*stmt
= USE_STMT (use_p
);
1120 /* Calls containing dead arguments cannot be deleted,
1121 modify_call_stmt will instead remove just the argument later on.
1122 If isra_track_scalar_value_uses in ipa-sra.cc is extended to look
1123 through const functions, we will need to do so here too. */
1124 if (is_gimple_call (stmt
)
1125 || (m_id
->blocks_to_copy
1126 && !bitmap_bit_p (m_id
->blocks_to_copy
,
1127 gimple_bb (stmt
)->index
)))
1130 if (is_gimple_debug (stmt
))
1132 m_dead_stmts
.add (stmt
);
1133 gcc_assert (gimple_debug_bind_p (stmt
));
1134 if (!used_in_debug
.contains (t
))
1136 used_in_debug
.add (t
);
1137 debugstack
->safe_push (t
);
1140 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1142 gphi
*phi
= as_a
<gphi
*> (stmt
);
1143 int ix
= PHI_ARG_INDEX_FROM_USE (use_p
);
1145 if (!m_id
->blocks_to_copy
1146 || bitmap_bit_p (m_id
->blocks_to_copy
,
1147 gimple_phi_arg_edge (phi
, ix
)->src
->index
))
1149 m_dead_stmts
.add (phi
);
1150 tree res
= gimple_phi_result (phi
);
1151 if (!m_dead_ssas
.add (res
))
1152 stack
.safe_push (res
);
1155 else if (is_gimple_assign (stmt
))
1157 m_dead_stmts
.add (stmt
);
1158 if (!gimple_clobber_p (stmt
))
1160 tree lhs
= gimple_assign_lhs (stmt
);
1161 gcc_assert (TREE_CODE (lhs
) == SSA_NAME
);
1162 if (!m_dead_ssas
.add (lhs
))
1163 stack
.safe_push (lhs
);
1167 /* IPA-SRA does not analyze other types of statements. */
1172 if (!MAY_HAVE_DEBUG_STMTS
)
1174 gcc_assert (debugstack
->is_empty ());
1178 tree dp_ddecl
= build_debug_expr_decl (TREE_TYPE (dead_param
));
1179 /* FIXME: Is setting the mode really necessary? */
1180 SET_DECL_MODE (dp_ddecl
, DECL_MODE (dead_param
));
1181 m_dead_ssa_debug_equiv
.put (parm_ddef
, dp_ddecl
);
1184 /* Put all clobbers of of dereference of default definition of PARAM into
1188 ipa_param_body_adjustments::mark_clobbers_dead (tree param
)
1190 if (!is_gimple_reg (param
))
1192 tree ddef
= get_ddef_if_exists_and_is_used (param
);
1196 imm_use_iterator imm_iter
;
1197 use_operand_p use_p
;
1198 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, ddef
)
1200 gimple
*stmt
= USE_STMT (use_p
);
1201 if (gimple_clobber_p (stmt
))
1202 m_dead_stmts
.add (stmt
);
1206 /* Callback to walk_tree. If REMAP is an SSA_NAME that is present in hash_map
1207 passed in DATA, replace it with unshared version of what it was mapped to.
1208 If an SSA argument would be remapped to NULL, the whole operation needs to
1209 abort which is signaled by returning error_mark_node. */
1212 replace_with_mapped_expr (tree
*remap
, int *walk_subtrees
, void *data
)
1214 if (TYPE_P (*remap
))
1219 if (TREE_CODE (*remap
) != SSA_NAME
)
1224 hash_map
<tree
, tree
> *equivs
= (hash_map
<tree
, tree
> *) data
;
1225 if (tree
*p
= equivs
->get (*remap
))
1228 return error_mark_node
;
1229 *remap
= unshare_expr (*p
);
1234 /* Replace all occurances of SSAs in m_dead_ssa_debug_equiv in t with what they
1238 ipa_param_body_adjustments::remap_with_debug_expressions (tree
*t
)
1240 /* If *t is an SSA_NAME which should have its debug statements reset, it is
1241 mapped to NULL in the hash_map.
1243 It is perhaps simpler to handle the SSA_NAME cases directly and only
1244 invoke walk_tree on more complex expressions. When
1245 remap_with_debug_expressions is called from tree-inline.cc, a to-be-reset
1246 SSA_NAME can be an operand to such expressions and the entire debug
1247 variable we are remapping should be reset. This is signaled by walk_tree
1248 returning error_mark_node and done by setting *t to NULL. */
1249 if (TREE_CODE (*t
) == SSA_NAME
)
1251 if (tree
*p
= m_dead_ssa_debug_equiv
.get (*t
))
1254 else if (walk_tree (t
, replace_with_mapped_expr
,
1255 &m_dead_ssa_debug_equiv
, NULL
) == error_mark_node
)
1259 /* For an SSA_NAME DEAD_SSA which is about to be DCEd because it is based on a
1260 useless parameter, prepare an expression that should represent it in
1261 debug_binds in the cloned function and add a mapping from DEAD_SSA to
1262 m_dead_ssa_debug_equiv. That mapping is to NULL when the associated
1263 debug_statement has to be reset instead. In such case return false,
1264 ottherwise return true. If DEAD_SSA comes from a basic block which is not
1265 about to be copied, ignore it and return true. */
1268 ipa_param_body_adjustments::prepare_debug_expressions (tree dead_ssa
)
1270 gcc_checking_assert (m_dead_ssas
.contains (dead_ssa
));
1271 if (tree
*d
= m_dead_ssa_debug_equiv
.get (dead_ssa
))
1272 return (*d
!= NULL_TREE
);
1274 gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (dead_ssa
));
1275 gimple
*def
= SSA_NAME_DEF_STMT (dead_ssa
);
1276 if (m_id
->blocks_to_copy
1277 && !bitmap_bit_p (m_id
->blocks_to_copy
, gimple_bb (def
)->index
))
1280 if (gimple_code (def
) == GIMPLE_PHI
)
1282 /* In theory, we could ignore all SSAs coming from BBs not in
1283 m_id->blocks_to_copy but at the time of the writing this code that
1284 should never really be the case because only fnsplit uses that bitmap,
1286 tree value
= degenerate_phi_result (as_a
<gphi
*> (def
));
1288 || (m_dead_ssas
.contains (value
)
1289 && !prepare_debug_expressions (value
)))
1291 m_dead_ssa_debug_equiv
.put (dead_ssa
, NULL_TREE
);
1295 gcc_assert (TREE_CODE (value
) == SSA_NAME
);
1296 tree
*d
= m_dead_ssa_debug_equiv
.get (value
);
1297 m_dead_ssa_debug_equiv
.put (dead_ssa
, *d
);
1302 use_operand_p use_p
;
1304 FOR_EACH_PHI_OR_STMT_USE (use_p
, def
, oi
, SSA_OP_USE
)
1306 tree use
= USE_FROM_PTR (use_p
);
1307 if (m_dead_ssas
.contains (use
)
1308 && !prepare_debug_expressions (use
))
1317 m_dead_ssa_debug_equiv
.put (dead_ssa
, NULL_TREE
);
1321 if (is_gimple_assign (def
))
1323 gcc_assert (!gimple_clobber_p (def
));
1324 if (gimple_assign_copy_p (def
)
1325 && TREE_CODE (gimple_assign_rhs1 (def
)) == SSA_NAME
)
1327 tree d
= *m_dead_ssa_debug_equiv
.get (gimple_assign_rhs1 (def
));
1329 m_dead_ssa_debug_equiv
.put (dead_ssa
, d
);
1334 = unshare_expr_without_location (gimple_assign_rhs_to_tree (def
));
1335 remap_with_debug_expressions (&val
);
1337 tree vexpr
= build_debug_expr_decl (TREE_TYPE (val
));
1338 m_dead_stmt_debug_equiv
.put (def
, val
);
1339 m_dead_ssa_debug_equiv
.put (dead_ssa
, vexpr
);
1346 /* Common initialization performed by all ipa_param_body_adjustments
1347 constructors. OLD_FNDECL is the declaration we take original arguments
1348 from, (it may be the same as M_FNDECL). VARS, if non-NULL, is a pointer to
1349 a chained list of new local variables. TREE_MAP is the IPA-CP produced
1350 mapping of trees to constants.
1352 The function is rather long but it really onlu initializes all data members
1353 of the class. It creates new param DECLs, finds their new types, */
1356 ipa_param_body_adjustments::common_initialization (tree old_fndecl
,
1358 vec
<ipa_replace_map
*,
1361 push_function_arg_decls (&m_oparms
, old_fndecl
);
1362 auto_vec
<tree
,16> otypes
;
1363 if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl
)) != NULL_TREE
)
1364 push_function_arg_types (&otypes
, TREE_TYPE (old_fndecl
));
1367 auto_vec
<tree
,16> oparms
;
1368 push_function_arg_decls (&oparms
, old_fndecl
);
1369 unsigned ocount
= oparms
.length ();
1370 otypes
.reserve_exact (ocount
);
1371 for (unsigned i
= 0; i
< ocount
; i
++)
1372 otypes
.quick_push (TREE_TYPE (oparms
[i
]));
1374 fill_vector_of_new_param_types (&m_new_types
, &otypes
, m_adj_params
, true);
1376 auto_vec
<bool, 16> kept
;
1377 kept
.reserve_exact (m_oparms
.length ());
1378 kept
.quick_grow_cleared (m_oparms
.length ());
1379 auto_vec
<bool, 16> split
;
1380 split
.reserve_exact (m_oparms
.length ());
1381 split
.quick_grow_cleared (m_oparms
.length ());
1383 unsigned adj_len
= vec_safe_length (m_adj_params
);
1384 m_method2func
= ((TREE_CODE (TREE_TYPE (m_fndecl
)) == METHOD_TYPE
)
1386 || (*m_adj_params
)[0].op
!= IPA_PARAM_OP_COPY
1387 || (*m_adj_params
)[0].base_index
!= 0));
1389 /* The main job of the this function is to go over the vector of adjusted
1390 parameters and create declarations or find corresponding old ones and push
1391 them to m_new_decls. For IPA-SRA replacements it also creates
1392 corresponding m_id->dst_node->clone.performed_splits entries. */
1394 m_new_decls
.reserve_exact (adj_len
);
1395 for (unsigned i
= 0; i
< adj_len
; i
++)
1397 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
1398 unsigned prev_index
= apm
->prev_clone_index
;
1400 if (apm
->op
== IPA_PARAM_OP_COPY
1401 || apm
->prev_clone_adjustment
)
1403 kept
[prev_index
] = true;
1404 new_parm
= carry_over_param (m_oparms
[prev_index
]);
1405 m_new_decls
.quick_push (new_parm
);
1407 else if (apm
->op
== IPA_PARAM_OP_NEW
1408 || apm
->op
== IPA_PARAM_OP_SPLIT
)
1410 tree new_type
= m_new_types
[i
];
1411 gcc_checking_assert (new_type
);
1412 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
1414 const char *prefix
= ipa_param_prefixes
[apm
->param_prefix_index
];
1415 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
1416 DECL_ARTIFICIAL (new_parm
) = 1;
1417 DECL_ARG_TYPE (new_parm
) = new_type
;
1418 DECL_CONTEXT (new_parm
) = m_fndecl
;
1419 TREE_USED (new_parm
) = 1;
1420 DECL_IGNORED_P (new_parm
) = 1;
1421 layout_decl (new_parm
, 0);
1422 m_new_decls
.quick_push (new_parm
);
1424 if (apm
->op
== IPA_PARAM_OP_SPLIT
)
1426 split
[prev_index
] = true;
1427 register_replacement (apm
, new_parm
);
1434 auto_vec
<int, 16> index_mapping
;
1435 bool need_remap
= false;
1438 clone_info
*cinfo
= clone_info::get (m_id
->src_node
);
1439 if (cinfo
&& cinfo
->param_adjustments
)
1441 cinfo
->param_adjustments
->get_updated_indices (&index_mapping
);
1445 if (ipcp_transformation
*ipcp_ts
1446 = ipcp_get_transformation_summary (m_id
->src_node
))
1448 for (const ipa_argagg_value
&av
: ipcp_ts
->m_agg_values
)
1450 int parm_num
= av
.index
;
1454 /* FIXME: We cannot handle the situation when IPA-CP
1455 identified that a parameter is a pointer to a global
1456 variable and at the same time the variable has some known
1457 constant contents (PR 107640). The best place to make
1458 sure we don't drop such constants on the floor probably is
1459 not here, but we have to make sure that it does not
1460 confuse the remapping. */
1461 if (parm_num
>= (int) index_mapping
.length ())
1463 parm_num
= index_mapping
[parm_num
];
1468 if (!kept
[parm_num
])
1470 /* IPA-CP has detected an aggregate constant in a parameter
1471 that will not be kept, which means that IPA-SRA would have
1472 split it if there wasn't a constant. Because we are about
1473 to remove the original, this is the last chance where we
1474 can substitute the uses with a constant (for values passed
1475 by reference) or do the split but initialize the
1476 replacement with a constant (for split aggregates passed
1484 repl
= create_tmp_var (TREE_TYPE (av
.value
),
1486 gimple
*init_stmt
= gimple_build_assign (repl
, av
.value
);
1487 m_split_agg_csts_inits
.safe_push (init_stmt
);
1489 register_replacement (m_oparms
[parm_num
], av
.unit_offset
,
1491 split
[parm_num
] = true;
1496 sort_replacements ();
1500 /* Do not treat parameters which were replaced with a constant as
1501 completely vanished. */
1502 for (unsigned i
= 0; i
< tree_map
->length (); i
++)
1504 int parm_num
= (*tree_map
)[i
]->parm_num
;
1505 gcc_assert (parm_num
>= 0);
1507 parm_num
= index_mapping
[parm_num
];
1508 kept
[parm_num
] = true;
1512 /* As part of body modifications, we will also have to replace remaining uses
1513 of remaining uses of removed PARM_DECLs (which do not however use the
1514 initial value) with their VAR_DECL copies.
1516 We do this differently with and without m_id. With m_id, we rely on its
1517 mapping and create a replacement straight away. Without it, we have our
1518 own mechanism for which we have to populate m_removed_decls vector. Just
1519 don't mix them, that is why you should not call
1520 replace_removed_params_ssa_names or perform_cfun_body_modifications when
1521 you construct with ID not equal to NULL. */
1523 auto_vec
<tree
, 8> ssas_to_process_debug
;
1524 unsigned op_len
= m_oparms
.length ();
1525 for (unsigned i
= 0; i
< op_len
; i
++)
1530 gcc_assert (!m_id
->decl_map
->get (m_oparms
[i
]));
1531 tree var
= copy_decl_to_var (m_oparms
[i
], m_id
);
1532 insert_decl_map (m_id
, m_oparms
[i
], var
);
1533 /* Declare this new variable. */
1534 DECL_CHAIN (var
) = *vars
;
1537 /* If this is not a split but a real removal, init hash sets
1538 that will guide what not to copy to the new body. */
1540 mark_dead_statements (m_oparms
[i
], &ssas_to_process_debug
);
1542 mark_clobbers_dead (m_oparms
[i
]);
1543 if (MAY_HAVE_DEBUG_STMTS
1544 && is_gimple_reg (m_oparms
[i
]))
1545 m_reset_debug_decls
.safe_push (m_oparms
[i
]);
1549 m_removed_decls
.safe_push (m_oparms
[i
]);
1550 m_removed_map
.put (m_oparms
[i
], m_removed_decls
.length () - 1);
1551 if (MAY_HAVE_DEBUG_STMTS
1553 && is_gimple_reg (m_oparms
[i
]))
1554 m_reset_debug_decls
.safe_push (m_oparms
[i
]);
1558 while (!ssas_to_process_debug
.is_empty ())
1559 prepare_debug_expressions (ssas_to_process_debug
.pop ());
1562 /* Constructor of ipa_param_body_adjustments from a simple list of
1563 modifications to parameters listed in ADJ_PARAMS which will prepare ground
1564 for modification of parameters of fndecl. Return value of the function will
1565 not be removed and the object will assume it does not run as a part of
1566 tree-function_versioning. */
1568 ipa_param_body_adjustments
1569 ::ipa_param_body_adjustments (vec
<ipa_adjusted_param
, va_gc
> *adj_params
,
1571 : m_adj_params (adj_params
), m_adjustments (NULL
), m_reset_debug_decls (),
1572 m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
1573 m_dead_stmt_debug_equiv (), m_fndecl (fndecl
), m_id (NULL
), m_oparms (),
1574 m_new_decls (), m_new_types (), m_replacements (),
1575 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1576 m_method2func (false), m_sorted_replacements_p (true)
1578 common_initialization (fndecl
, NULL
, NULL
);
1581 /* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
1582 ADJUSTMENTS which will prepare ground for modification of parameters of
1583 fndecl. The object will assume it does not run as a part of
1584 tree-function_versioning. */
1586 ipa_param_body_adjustments
1587 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1589 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1590 m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
1591 m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl
),
1592 m_id (NULL
), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1593 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1594 m_method2func (false), m_sorted_replacements_p (true)
1596 common_initialization (fndecl
, NULL
, NULL
);
1599 /* Constructor of ipa_param_body_adjustments which sets it up as a part of
1600 running tree_function_versioning. Planned modifications to the function are
1601 in ADJUSTMENTS. FNDECL designates the new function clone which is being
1602 modified. OLD_FNDECL is the function of which FNDECL is a clone (and which
1603 at the time of invocation still share DECL_ARGUMENTS). ID is the
1604 copy_body_data structure driving the wholy body copying process. VARS is a
1605 pointer to the head of the list of new local variables, TREE_MAP is the map
1606 that drives tree substitution in the cloning process. */
1608 ipa_param_body_adjustments
1609 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1610 tree fndecl
, tree old_fndecl
,
1611 copy_body_data
*id
, tree
*vars
,
1612 vec
<ipa_replace_map
*, va_gc
> *tree_map
)
1613 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1614 m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
1615 m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl
),
1616 m_id (id
), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1617 m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
1618 m_method2func (false), m_sorted_replacements_p (true)
1620 common_initialization (old_fndecl
, vars
, tree_map
);
1623 /* Chain new param decls up and return them. */
1626 ipa_param_body_adjustments::get_new_param_chain ()
1629 tree
*link
= &result
;
1631 unsigned len
= vec_safe_length (m_adj_params
);
1632 for (unsigned i
= 0; i
< len
; i
++)
1634 tree new_decl
= m_new_decls
[i
];
1636 link
= &DECL_CHAIN (new_decl
);
1642 /* Modify the function parameters FNDECL and its type according to the plan in
1643 ADJUSTMENTS. This function needs to be called when the decl has not already
1644 been processed with ipa_param_adjustments::adjust_decl, otherwise just
1645 seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough. */
1648 ipa_param_body_adjustments::modify_formal_parameters ()
1650 tree orig_type
= TREE_TYPE (m_fndecl
);
1651 DECL_ARGUMENTS (m_fndecl
) = get_new_param_chain ();
1653 /* When signature changes, we need to clear builtin info. */
1654 if (fndecl_built_in_p (m_fndecl
))
1655 set_decl_built_in_function (m_fndecl
, NOT_BUILT_IN
, 0);
1657 bool modified
= false;
1660 for (tree t
= TYPE_ARG_TYPES (orig_type
);
1662 t
= TREE_CHAIN (t
), index
++)
1663 if (index
>= m_adj_params
->length ()
1664 || (*m_adj_params
)[index
].op
!= IPA_PARAM_OP_COPY
1665 || (*m_adj_params
)[index
].base_index
!= index
)
1668 /* At this point, removing return value is only implemented when going
1669 through tree_function_versioning, not when modifying function body
1671 gcc_assert (!m_adjustments
|| !m_adjustments
->m_skip_return
);
1672 tree new_type
= build_adjusted_function_type (orig_type
, &m_new_types
,
1673 m_method2func
, false, modified
);
1675 TREE_TYPE (m_fndecl
) = new_type
;
1676 DECL_VIRTUAL_P (m_fndecl
) = 0;
1677 DECL_LANG_SPECIFIC (m_fndecl
) = NULL
;
1679 DECL_VINDEX (m_fndecl
) = NULL_TREE
;
1682 /* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
1685 ipa_param_body_replacement
*
1686 ipa_param_body_adjustments::lookup_replacement_1 (tree base
,
1687 unsigned unit_offset
)
1689 gcc_assert (m_sorted_replacements_p
);
1690 ipa_param_body_replacement key
;
1692 key
.unit_offset
= unit_offset
;
1693 ipa_param_body_replacement
*res
1694 = std::lower_bound (m_replacements
.begin (), m_replacements
.end (), key
,
1695 [] (const ipa_param_body_replacement
&elt
,
1696 const ipa_param_body_replacement
&val
)
1698 return (compare_param_body_replacement (&elt
, &val
)
1702 if (res
== m_replacements
.end ()
1703 || res
->base
!= base
1704 || res
->unit_offset
!= unit_offset
)
1709 /* Find the first replacement for BASE among m_replacements and return pointer
1710 to it, or NULL if there is none. */
1712 ipa_param_body_replacement
*
1713 ipa_param_body_adjustments::lookup_first_base_replacement (tree base
)
1715 gcc_assert (m_sorted_replacements_p
);
1716 ipa_param_body_replacement key
;
1718 ipa_param_body_replacement
*res
1719 = std::lower_bound (m_replacements
.begin (), m_replacements
.end (), key
,
1720 [] (const ipa_param_body_replacement
&elt
,
1721 const ipa_param_body_replacement
&val
)
1723 if (DECL_UID (elt
.base
) < DECL_UID (val
.base
))
1728 if (res
== m_replacements
.end ()
1729 || res
->base
!= base
)
1734 /* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
1735 and return it, assuming it is known it does not hold value by reference or
1736 in reverse storage order. */
1739 ipa_param_body_adjustments::lookup_replacement (tree base
, unsigned unit_offset
)
1741 ipa_param_body_replacement
*pbr
= lookup_replacement_1 (base
, unit_offset
);
1747 /* If T is an SSA_NAME, return NULL if it is not a default def or
1748 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
1749 the base variable is always returned, regardless if it is a default
1750 def. Return T if it is not an SSA_NAME. */
1753 get_ssa_base_param (tree t
, bool ignore_default_def
)
1755 if (TREE_CODE (t
) == SSA_NAME
)
1757 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
1758 return SSA_NAME_VAR (t
);
1765 /* Given an expression, return the structure describing how it should be
1766 replaced if it accesses a part of a split parameter or NULL otherwise.
1768 Do not free the result, it will be deallocated when the object is destroyed.
1770 If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
1771 which are default definitions, if set, consider all SSA_NAMEs of
1774 ipa_param_body_replacement
*
1775 ipa_param_body_adjustments::get_expr_replacement (tree expr
,
1776 bool ignore_default_def
)
1779 unsigned unit_offset
;
1781 if (!isra_get_ref_base_and_offset (expr
, &base
, &unit_offset
))
1784 base
= get_ssa_base_param (base
, ignore_default_def
);
1785 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
1787 return lookup_replacement_1 (base
, unit_offset
);
1790 /* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
1791 (which includes it being split or replaced), return a new variable that
1792 should be used for any SSA names that will remain in the function that
1793 previously belonged to OLD_DECL. */
1796 ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl
)
1798 unsigned *idx
= m_removed_map
.get (old_decl
);
1803 if (TREE_CODE (m_removed_decls
[*idx
]) == PARM_DECL
)
1805 gcc_assert (m_removed_decls
[*idx
] == old_decl
);
1806 repl
= copy_var_decl (old_decl
, DECL_NAME (old_decl
),
1807 TREE_TYPE (old_decl
));
1808 m_removed_decls
[*idx
] = repl
;
1811 repl
= m_removed_decls
[*idx
];
1815 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
1816 parameter which is to be removed because its value is not used, create a new
1817 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
1818 original with it and return it. If there is no need to re-map, return NULL.
1819 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
1822 ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name
,
1826 if (TREE_CODE (old_name
) != SSA_NAME
)
1829 tree decl
= SSA_NAME_VAR (old_name
);
1830 if (decl
== NULL_TREE
1831 || TREE_CODE (decl
) != PARM_DECL
)
1834 tree repl
= get_replacement_ssa_base (decl
);
1838 tree new_name
= make_ssa_name (repl
, stmt
);
1839 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name
)
1840 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name
);
1842 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1844 fprintf (dump_file
, "replacing an SSA name of a removed param ");
1845 print_generic_expr (dump_file
, old_name
);
1846 fprintf (dump_file
, " with ");
1847 print_generic_expr (dump_file
, new_name
);
1848 fprintf (dump_file
, "\n");
1851 replace_uses_by (old_name
, new_name
);
1855 /* If the expression *EXPR_P should be replaced, do so. CONVERT specifies
1856 whether the function should care about type incompatibility of the current
1857 and new expressions. If it is false, the function will leave
1858 incompatibility issues to the caller - note that when the function
1859 encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
1860 their bases instead of the expressions themselves and then also performs any
1861 necessary conversions. */
1864 ipa_param_body_adjustments::modify_expression (tree
*expr_p
, bool convert
,
1865 gimple_seq
*extra_stmts
)
1867 tree expr
= *expr_p
;
1869 if (m_replacements
.is_empty ())
1871 if (TREE_CODE (expr
) == BIT_FIELD_REF
1872 || TREE_CODE (expr
) == IMAGPART_EXPR
1873 || TREE_CODE (expr
) == REALPART_EXPR
)
1875 /* For a BIT_FIELD_REF do not bother to VIEW_CONVERT the base,
1876 instead reference the replacement directly. */
1877 convert
= TREE_CODE (expr
) != BIT_FIELD_REF
;
1878 expr_p
= &TREE_OPERAND (expr
, 0);
1882 ipa_param_body_replacement
*pbr
= get_expr_replacement (expr
, false);
1886 tree repl
= pbr
->repl
;
1887 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1889 fprintf (dump_file
, "About to replace expr ");
1890 print_generic_expr (dump_file
, expr
);
1891 fprintf (dump_file
, " with ");
1892 print_generic_expr (dump_file
, repl
);
1893 fprintf (dump_file
, "\n");
1896 if (convert
&& !useless_type_conversion_p (TREE_TYPE (expr
),
1899 gcc_checking_assert (tree_to_shwi (TYPE_SIZE (TREE_TYPE (expr
)))
1900 == tree_to_shwi (TYPE_SIZE (TREE_TYPE (repl
))));
1901 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (expr
), repl
);
1902 if (is_gimple_reg (repl
)
1903 && is_gimple_reg_type (TREE_TYPE (expr
)))
1905 gcc_assert (extra_stmts
);
1906 vce
= force_gimple_operand (vce
, extra_stmts
, true, NULL_TREE
);
1915 /* If the assignment statement STMT contains any expressions that need to
1916 replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
1917 potential type incompatibilities. If any conversion sttements have to be
1918 pre-pended to STMT, they will be added to EXTRA_STMTS. Return true iff the
1919 statement was modified. */
1922 ipa_param_body_adjustments::modify_assignment (gimple
*stmt
,
1923 gimple_seq
*extra_stmts
)
1925 tree
*lhs_p
, *rhs_p
;
1928 if (m_replacements
.is_empty () || !gimple_assign_single_p (stmt
))
1931 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
1932 lhs_p
= gimple_assign_lhs_ptr (stmt
);
1934 any
= modify_expression (lhs_p
, false);
1935 any
|= modify_expression (rhs_p
, false, extra_stmts
);
1937 && !useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
1939 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
1941 /* V_C_Es of constructors can cause trouble (PR 42714). */
1942 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
1943 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
1945 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
1950 gcc_checking_assert (tree_to_shwi (TYPE_SIZE (TREE_TYPE (*lhs_p
)))
1951 == tree_to_shwi (TYPE_SIZE (TREE_TYPE (*rhs_p
))));
1952 tree new_rhs
= fold_build1_loc (gimple_location (stmt
),
1953 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
1955 tree tmp
= force_gimple_operand (new_rhs
, extra_stmts
, true,
1957 gimple_assign_set_rhs1 (stmt
, tmp
);
1965 /* Record information about what modifications to call arguments have already
1966 been done by clone materialization into a summary describing CS. The
1967 information is stored in NEW_INDEX_MAP, NEW_PT_MAP and NEW_ALWAYS_COPY_DELTA
1968 and correspond to equivalent fields in ipa_edge_modification_info. Return
1969 the edge summary. */
1971 static ipa_edge_modification_info
*
1972 record_argument_state_1 (cgraph_edge
*cs
, const vec
<int> &new_index_map
,
1973 const vec
<pass_through_split_map
> &new_pt_map
,
1974 int new_always_copy_delta
)
1977 ipa_edge_modification_info
*sum
= ipa_edge_modifications
->get_create (cs
);
1979 unsigned len
= sum
->pass_through_map
.length ();
1980 for (unsigned i
= 0; i
< len
; i
++)
1982 unsigned oldnew
= sum
->pass_through_map
[i
].new_index
;
1983 sum
->pass_through_map
[i
].new_index
= new_index_map
[oldnew
];
1986 len
= sum
->index_map
.length ();
1989 unsigned nptlen
= new_pt_map
.length ();
1990 for (unsigned j
= 0; j
< nptlen
; j
++)
1993 for (unsigned i
= 0; i
< len
; i
++)
1994 if ((unsigned) sum
->index_map
[i
] == new_pt_map
[j
].base_index
)
1999 gcc_assert (inverse
>= 0);
2000 pass_through_split_map ptm_item
;
2002 ptm_item
.base_index
= inverse
;
2003 ptm_item
.unit_offset
= new_pt_map
[j
].unit_offset
;
2004 ptm_item
.new_index
= new_pt_map
[j
].new_index
;
2005 sum
->pass_through_map
.safe_push (ptm_item
);
2008 for (unsigned i
= 0; i
< len
; i
++)
2010 int idx
= sum
->index_map
[i
];
2013 sum
->index_map
[i
] = new_index_map
[idx
];
2018 sum
->pass_through_map
.safe_splice (new_pt_map
);
2019 sum
->index_map
.safe_splice (new_index_map
);
2021 sum
->always_copy_delta
+= new_always_copy_delta
;
2025 /* Record information about what modifications to call arguments have already
2026 been done by clone materialization into a summary of an edge describing the
2027 call in this clone and all its clones. NEW_INDEX_MAP, NEW_PT_MAP and
2028 NEW_ALWAYS_COPY_DELTA have the same meaning as record_argument_state_1.
2030 In order to associate the info with the right edge summaries, we need
2031 address of the ORIG_STMT in the function from which we are cloning (because
2032 the edges have not yet been re-assigned to the new statement that has just
2033 been created) and ID, the structure governing function body copying. */
2036 record_argument_state (copy_body_data
*id
, gimple
*orig_stmt
,
2037 const vec
<int> &new_index_map
,
2038 const vec
<pass_through_split_map
> &new_pt_map
,
2039 int new_always_copy_delta
)
2041 if (!ipa_edge_modifications
)
2042 ipa_edge_modifications
= new ipa_edge_modification_sum (symtab
);
2044 struct cgraph_node
*this_node
= id
->dst_node
;
2045 ipa_edge_modification_info
*first_sum
= NULL
;
2046 cgraph_edge
*cs
= this_node
->get_edge (orig_stmt
);
2048 first_sum
= record_argument_state_1 (cs
, new_index_map
, new_pt_map
,
2049 new_always_copy_delta
);
2051 gcc_assert (this_node
->clones
);
2053 if (!this_node
->clones
)
2055 for (cgraph_node
*subclone
= this_node
->clones
; subclone
!= this_node
;)
2057 cs
= subclone
->get_edge (orig_stmt
);
2061 first_sum
= record_argument_state_1 (cs
, new_index_map
, new_pt_map
,
2062 new_always_copy_delta
);
2065 ipa_edge_modification_info
*s2
2066 = ipa_edge_modifications
->get_create (cs
);
2067 s2
->index_map
.truncate (0);
2068 s2
->index_map
.safe_splice (first_sum
->index_map
);
2069 s2
->pass_through_map
.truncate (0);
2070 s2
->pass_through_map
.safe_splice (first_sum
->pass_through_map
);
2071 s2
->always_copy_delta
= first_sum
->always_copy_delta
;
2075 gcc_assert (subclone
->clones
);
2077 if (subclone
->clones
)
2078 subclone
= subclone
->clones
;
2079 else if (subclone
->next_sibling_clone
)
2080 subclone
= subclone
->next_sibling_clone
;
2083 while (subclone
!= this_node
&& !subclone
->next_sibling_clone
)
2084 subclone
= subclone
->clone_of
;
2085 if (subclone
!= this_node
)
2086 subclone
= subclone
->next_sibling_clone
;
2091 /* If the call statement pointed at by STMT_P contains any expressions that
2092 need to replaced with a different one as noted by ADJUSTMENTS, do so. f the
2093 statement needs to be rebuilt, do so. Return true if any modifications have
2094 been performed. ORIG_STMT, if not NULL, is the original statement in the
2095 function that is being cloned from, which at this point can be used to look
2096 up call_graph edges.
2098 If the method is invoked as a part of IPA clone materialization and if any
2099 parameter split is pass-through, i.e. it applies to the functin that is
2100 being modified and also to the callee of the statement, replace the
2101 parameter passed to old callee with all of the replacement a callee might
2102 possibly want and record the performed argument modifications in
2103 ipa_edge_modifications. Likewise if any argument has already been left out
2104 because it is not necessary. */
2107 ipa_param_body_adjustments::modify_call_stmt (gcall
**stmt_p
,
2110 auto_vec
<unsigned, 4> pass_through_args
;
2111 auto_vec
<unsigned, 4> pass_through_pbr_indices
;
2112 auto_vec
<HOST_WIDE_INT
, 4> pass_through_offsets
;
2113 gcall
*stmt
= *stmt_p
;
2114 unsigned nargs
= gimple_call_num_args (stmt
);
2115 bool recreate
= false;
2116 gcc_assert (m_sorted_replacements_p
);
2118 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); i
++)
2120 tree t
= gimple_call_arg (stmt
, i
);
2121 gcc_assert (TREE_CODE (t
) != BIT_FIELD_REF
2122 && TREE_CODE (t
) != IMAGPART_EXPR
2123 && TREE_CODE (t
) != REALPART_EXPR
);
2125 if (TREE_CODE (t
) == SSA_NAME
2126 && m_dead_ssas
.contains (t
))
2129 if (m_replacements
.is_empty ())
2133 unsigned agg_arg_offset
;
2134 if (!isra_get_ref_base_and_offset (t
, &base
, &agg_arg_offset
))
2137 bool by_ref
= false;
2138 if (TREE_CODE (base
) == SSA_NAME
)
2140 if (!SSA_NAME_IS_DEFAULT_DEF (base
))
2142 base
= SSA_NAME_VAR (base
);
2143 gcc_checking_assert (base
);
2146 if (TREE_CODE (base
) != PARM_DECL
)
2149 ipa_param_body_replacement
*first_rep
2150 = lookup_first_base_replacement (base
);
2153 unsigned first_rep_index
= first_rep
- m_replacements
.begin ();
2155 /* We still have to distinguish between an end-use that we have to
2156 transform now and a pass-through, which happens in the following
2159 /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
2160 &MEM_REF[ssa_name + offset], we will also have to detect that case
2163 if (TREE_CODE (t
) == SSA_NAME
2164 && SSA_NAME_IS_DEFAULT_DEF (t
)
2166 && TREE_CODE (SSA_NAME_VAR (t
)) == PARM_DECL
)
2168 /* This must be a by_reference pass-through. */
2170 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t
)));
2171 pass_through_args
.safe_push (i
);
2172 pass_through_pbr_indices
.safe_push (first_rep_index
);
2173 pass_through_offsets
.safe_push (agg_arg_offset
);
2175 else if (!by_ref
&& AGGREGATE_TYPE_P (TREE_TYPE (t
)))
2177 /* Currently IPA-SRA guarantees the aggregate access type
2178 exactly matches in this case. So if it does not match, it is
2179 a pass-through argument that will be sorted out at edge
2180 redirection time. */
2181 ipa_param_body_replacement
*pbr
2182 = lookup_replacement_1 (base
, agg_arg_offset
);
2185 || (TYPE_MAIN_VARIANT (TREE_TYPE (t
))
2186 != TYPE_MAIN_VARIANT (TREE_TYPE (pbr
->repl
))))
2189 pass_through_args
.safe_push (i
);
2190 pass_through_pbr_indices
.safe_push (first_rep_index
);
2191 pass_through_offsets
.safe_push (agg_arg_offset
);
2198 /* No need to rebuild the statement, let's just modify arguments
2199 and the LHS if/as appropriate. */
2200 bool modified
= false;
2201 for (unsigned i
= 0; i
< nargs
; i
++)
2203 tree
*t
= gimple_call_arg_ptr (stmt
, i
);
2204 modified
|= modify_expression (t
, true);
2206 if (gimple_call_lhs (stmt
))
2208 tree
*t
= gimple_call_lhs_ptr (stmt
);
2209 modified
|= modify_expression (t
, false);
2214 auto_vec
<int, 16> index_map
;
2215 auto_vec
<pass_through_split_map
, 4> pass_through_map
;
2216 auto_vec
<tree
, 16> vargs
;
2217 int always_copy_delta
= 0;
2218 unsigned pt_idx
= 0;
2219 int new_arg_idx
= 0;
2220 for (unsigned i
= 0; i
< nargs
; i
++)
2222 if (pt_idx
< pass_through_args
.length ()
2223 && i
== pass_through_args
[pt_idx
])
2225 unsigned j
= pass_through_pbr_indices
[pt_idx
];
2226 unsigned agg_arg_offset
= pass_through_offsets
[pt_idx
];
2228 always_copy_delta
--;
2229 tree base
= m_replacements
[j
].base
;
2231 /* In order to be put into SSA form, we have to push all replacements
2232 pertaining to this parameter as parameters to the call statement.
2233 Edge redirection will need to use edge summary to weed out the
2234 unnecessary ones. */
2235 unsigned repl_list_len
= m_replacements
.length ();
2236 for (; j
< repl_list_len
; j
++)
2238 if (m_replacements
[j
].base
!= base
)
2240 if (m_replacements
[j
].unit_offset
< agg_arg_offset
)
2242 pass_through_split_map pt_map
;
2243 pt_map
.base_index
= i
;
2245 = m_replacements
[j
].unit_offset
- agg_arg_offset
;
2246 pt_map
.new_index
= new_arg_idx
;
2247 pass_through_map
.safe_push (pt_map
);
2248 vargs
.safe_push (m_replacements
[j
].repl
);
2250 always_copy_delta
++;
2252 index_map
.safe_push (-1);
2256 tree t
= gimple_call_arg (stmt
, i
);
2257 if (TREE_CODE (t
) == SSA_NAME
2258 && m_dead_ssas
.contains (t
))
2260 always_copy_delta
--;
2261 index_map
.safe_push (-1);
2265 modify_expression (&t
, true);
2266 vargs
.safe_push (t
);
2267 index_map
.safe_push (new_arg_idx
);
2273 gcall
*new_stmt
= gimple_build_call_vec (gimple_call_fn (stmt
), vargs
);
2274 if (gimple_has_location (stmt
))
2275 gimple_set_location (new_stmt
, gimple_location (stmt
));
2276 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
2277 gimple_call_copy_flags (new_stmt
, stmt
);
2278 if (tree lhs
= gimple_call_lhs (stmt
))
2280 modify_expression (&lhs
, false);
2281 /* Avoid adjusting SSA_NAME_DEF_STMT of a SSA lhs, SSA names
2282 have not yet been remapped. */
2283 *gimple_call_lhs_ptr (new_stmt
) = lhs
;
2288 record_argument_state (m_id
, orig_stmt
, index_map
, pass_through_map
,
2293 /* If the statement STMT contains any expressions that need to replaced with a
2294 different one as noted by ADJUSTMENTS, do so. Handle any potential type
2295 incompatibilities. If any conversion sttements have to be pre-pended to
2296 STMT, they will be added to EXTRA_STMTS. Return true iff the statement was
2300 ipa_param_body_adjustments::modify_gimple_stmt (gimple
**stmt
,
2301 gimple_seq
*extra_stmts
,
2304 bool modified
= false;
2307 switch (gimple_code (*stmt
))
2310 t
= gimple_return_retval_ptr (as_a
<greturn
*> (*stmt
));
2311 if (m_adjustments
&& m_adjustments
->m_skip_return
)
2313 else if (*t
!= NULL_TREE
)
2314 modified
|= modify_expression (t
, true);
2318 modified
|= modify_assignment (*stmt
, extra_stmts
);
2322 modified
|= modify_call_stmt ((gcall
**) stmt
, orig_stmt
);
2327 gasm
*asm_stmt
= as_a
<gasm
*> (*stmt
);
2328 for (unsigned i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
2330 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
2331 modified
|= modify_expression (t
, true);
2333 for (unsigned i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
2335 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
2336 modified
|= modify_expression (t
, false);
2348 /* Traverse body of the current function and perform the requested adjustments
2349 on its statements. Return true iff the CFG has been changed. */
2352 ipa_param_body_adjustments::modify_cfun_body ()
2354 bool cfg_changed
= false;
2357 FOR_EACH_BB_FN (bb
, cfun
)
2359 gimple_stmt_iterator gsi
;
2361 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2363 gphi
*phi
= as_a
<gphi
*> (gsi_stmt (gsi
));
2364 tree new_lhs
, old_lhs
= gimple_phi_result (phi
);
2365 new_lhs
= replace_removed_params_ssa_names (old_lhs
, phi
);
2368 gimple_phi_set_result (phi
, new_lhs
);
2369 release_ssa_name (old_lhs
);
2373 gsi
= gsi_start_bb (bb
);
2374 while (!gsi_end_p (gsi
))
2376 gimple
*stmt
= gsi_stmt (gsi
);
2377 gimple
*stmt_copy
= stmt
;
2378 gimple_seq extra_stmts
= NULL
;
2379 bool modified
= modify_gimple_stmt (&stmt
, &extra_stmts
, NULL
);
2380 if (stmt
!= stmt_copy
)
2382 gcc_checking_assert (modified
);
2383 gsi_replace (&gsi
, stmt
, false);
2385 if (!gimple_seq_empty_p (extra_stmts
))
2386 gsi_insert_seq_before (&gsi
, extra_stmts
, GSI_SAME_STMT
);
2390 FOR_EACH_SSA_DEF_OPERAND (defp
, stmt
, iter
, SSA_OP_DEF
)
2392 tree old_def
= DEF_FROM_PTR (defp
);
2393 if (tree new_def
= replace_removed_params_ssa_names (old_def
,
2396 SET_DEF (defp
, new_def
);
2397 release_ssa_name (old_def
);
2405 if (maybe_clean_eh_stmt (stmt
)
2406 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
2416 /* Call gimple_debug_bind_reset_value on all debug statements describing
2417 gimple register parameters that are being removed or replaced. */
2420 ipa_param_body_adjustments::reset_debug_stmts ()
2423 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
2425 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
2427 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
2430 len
= m_reset_debug_decls
.length ();
2431 for (i
= 0; i
< len
; i
++)
2433 imm_use_iterator ui
;
2436 tree name
, vexpr
, copy
= NULL_TREE
;
2437 use_operand_p use_p
;
2438 tree decl
= m_reset_debug_decls
[i
];
2440 gcc_checking_assert (is_gimple_reg (decl
));
2441 name
= ssa_default_def (cfun
, decl
);
2444 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
2446 if (gimple_clobber_p (stmt
))
2448 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
2449 unlink_stmt_vdef (stmt
);
2450 gsi_remove (&cgsi
, true);
2451 release_defs (stmt
);
2454 /* All other users must have been removed by function body
2456 gcc_assert (is_gimple_debug (stmt
));
2457 if (vexpr
== NULL
&& gsip
!= NULL
)
2459 vexpr
= build_debug_expr_decl (TREE_TYPE (name
));
2460 /* FIXME: Is setting the mode really necessary? */
2461 SET_DECL_MODE (vexpr
, DECL_MODE (decl
));
2462 def_temp
= gimple_build_debug_source_bind (vexpr
, decl
, NULL
);
2463 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
2467 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
2468 SET_USE (use_p
, vexpr
);
2471 gimple_debug_bind_reset_value (stmt
);
2474 /* Create a VAR_DECL for debug info purposes. */
2475 if (!DECL_IGNORED_P (decl
))
2477 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
2478 VAR_DECL
, DECL_NAME (decl
),
2480 if (DECL_PT_UID_SET_P (decl
))
2481 SET_DECL_PT_UID (copy
, DECL_PT_UID (decl
));
2482 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (decl
);
2483 TREE_READONLY (copy
) = TREE_READONLY (decl
);
2484 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (decl
);
2485 DECL_NOT_GIMPLE_REG_P (copy
) = DECL_NOT_GIMPLE_REG_P (decl
);
2486 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (decl
);
2487 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (decl
);
2488 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (decl
);
2489 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
2490 SET_DECL_RTL (copy
, 0);
2491 TREE_USED (copy
) = 1;
2492 DECL_CONTEXT (copy
) = current_function_decl
;
2493 add_local_decl (cfun
, copy
);
2495 = BLOCK_VARS (DECL_INITIAL (current_function_decl
));
2496 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
2498 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (decl
))
2500 gcc_assert (TREE_CODE (decl
) == PARM_DECL
);
2502 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
2504 def_temp
= gimple_build_debug_source_bind (copy
, decl
,
2506 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
2511 /* Perform all necessary body changes to change signature, body and debug info
2512 of fun according to adjustments passed at construction. Return true if CFG
2513 was changed in any way. The main entry point for modification of standalone
2514 functions that is not part of IPA clone materialization. */
2517 ipa_param_body_adjustments::perform_cfun_body_modifications ()
2520 modify_formal_parameters ();
2521 cfg_changed
= modify_cfun_body ();
2522 reset_debug_stmts ();
2528 /* If there are any initialization statements that need to be emitted into
2529 the basic block BB right at ther start of the new function, do so. */
2531 ipa_param_body_adjustments::append_init_stmts (basic_block bb
)
2533 gimple_stmt_iterator si
= gsi_last_bb (bb
);
2534 while (!m_split_agg_csts_inits
.is_empty ())
2535 gsi_insert_after (&si
, m_split_agg_csts_inits
.pop (), GSI_NEW_STMT
);
2538 /* Deallocate summaries which otherwise stay alive until the end of
2542 ipa_edge_modifications_finalize ()
2544 if (!ipa_edge_modifications
)
2546 delete ipa_edge_modifications
;
2547 ipa_edge_modifications
= NULL
;