1 /* Manipulation of formal and actual parameters of functions and function
3 Copyright (C) 2017-2021 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"
48 /* Actual prefixes of different newly synthetized parameters. Keep in sync
49 with IPA_PARAM_PREFIX_* defines. */
51 static const char *ipa_param_prefixes
[IPA_PARAM_PREFIX_COUNT
]
57 /* Names of parameters for dumping. Keep in sync with enum ipa_parm_op. */
59 static const char *ipa_param_op_names
[IPA_PARAM_PREFIX_COUNT
]
60 = {"IPA_PARAM_OP_UNDEFINED",
63 "IPA_PARAM_OP_SPLIT"};
65 /* Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
66 FNDECL. The function should not be called during LTO WPA phase except for
67 thunks (or functions with bodies streamed in). */
70 push_function_arg_decls (vec
<tree
> *args
, tree fndecl
)
75 /* Safety check that we do not attempt to use the function in WPA, except
76 when the function is a thunk and then we have DECL_ARGUMENTS or when we
77 have already explicitely loaded its body. */
79 || DECL_ARGUMENTS (fndecl
)
80 || gimple_has_body_p (fndecl
));
82 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
85 args
->reserve_exact (count
);
86 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
87 args
->quick_push (parm
);
90 /* Fill an empty vector TYPES with trees representing formal parameters of
91 function type FNTYPE. */
94 push_function_arg_types (vec
<tree
> *types
, tree fntype
)
99 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
102 types
->reserve_exact (count
);
103 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
104 types
->quick_push (TREE_VALUE (t
));
107 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
108 friendly way, assuming they are meant to be applied to FNDECL. */
111 ipa_dump_adjusted_parameters (FILE *f
,
112 vec
<ipa_adjusted_param
, va_gc
> *adj_params
)
114 unsigned i
, len
= vec_safe_length (adj_params
);
120 fprintf (f
, " IPA adjusted parameters: ");
121 for (i
= 0; i
< len
; i
++)
123 struct ipa_adjusted_param
*apm
;
124 apm
= &(*adj_params
)[i
];
131 fprintf (f
, "%i. %s %s", i
, ipa_param_op_names
[apm
->op
],
132 apm
->prev_clone_adjustment
? "prev_clone_adjustment " : "");
135 case IPA_PARAM_OP_UNDEFINED
:
138 case IPA_PARAM_OP_COPY
:
139 fprintf (f
, ", base_index: %u", apm
->base_index
);
140 fprintf (f
, ", prev_clone_index: %u", apm
->prev_clone_index
);
143 case IPA_PARAM_OP_SPLIT
:
144 fprintf (f
, ", offset: %u", apm
->unit_offset
);
146 case IPA_PARAM_OP_NEW
:
147 fprintf (f
, ", base_index: %u", apm
->base_index
);
148 fprintf (f
, ", prev_clone_index: %u", apm
->prev_clone_index
);
149 print_node_brief (f
, ", type: ", apm
->type
, 0);
150 print_node_brief (f
, ", alias type: ", apm
->alias_ptr_type
, 0);
151 fprintf (f
, " prefix: %s",
152 ipa_param_prefixes
[apm
->param_prefix_index
]);
154 fprintf (f
, ", reverse-sso");
161 /* Fill NEW_TYPES with types of a function after its current OTYPES have been
162 modified as described in ADJ_PARAMS. When USE_PREV_INDICES is true, use
163 prev_clone_index from ADJ_PARAMS as opposed to base_index when the parameter
167 fill_vector_of_new_param_types (vec
<tree
> *new_types
, vec
<tree
> *otypes
,
168 vec
<ipa_adjusted_param
, va_gc
> *adj_params
,
169 bool use_prev_indices
)
171 unsigned adj_len
= vec_safe_length (adj_params
);
172 new_types
->reserve_exact (adj_len
);
173 for (unsigned i
= 0; i
< adj_len
; i
++)
175 ipa_adjusted_param
*apm
= &(*adj_params
)[i
];
176 if (apm
->op
== IPA_PARAM_OP_COPY
)
179 = use_prev_indices
? apm
->prev_clone_index
: apm
->base_index
;
180 /* The following needs to be handled gracefully because of type
181 mismatches. This happens with LTO but apparently also in Fortran
182 with -fcoarray=lib -O2 -lcaf_single -latomic. */
183 if (index
>= otypes
->length ())
185 new_types
->quick_push ((*otypes
)[index
]);
187 else if (apm
->op
== IPA_PARAM_OP_NEW
188 || apm
->op
== IPA_PARAM_OP_SPLIT
)
190 tree ntype
= apm
->type
;
191 if (is_gimple_reg_type (ntype
)
192 && TYPE_MODE (ntype
) != BLKmode
)
194 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ntype
));
195 if (TYPE_ALIGN (ntype
) != malign
)
196 ntype
= build_aligned_type (ntype
, malign
);
198 new_types
->quick_push (ntype
);
205 /* Build and return a function type just like ORIG_TYPE but with parameter
206 types given in NEW_PARAM_TYPES - which can be NULL if, but only if,
207 ORIG_TYPE itself has NULL TREE_ARG_TYPEs. If METHOD2FUNC is true, also make
208 it a FUNCTION_TYPE instead of FUNCTION_TYPE. */
211 build_adjusted_function_type (tree orig_type
, vec
<tree
> *new_param_types
,
212 bool method2func
, bool skip_return
)
214 tree new_arg_types
= NULL
;
215 if (TYPE_ARG_TYPES (orig_type
))
217 gcc_checking_assert (new_param_types
);
218 bool last_parm_void
= (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type
)))
220 unsigned len
= new_param_types
->length ();
221 for (unsigned i
= 0; i
< len
; i
++)
222 new_arg_types
= tree_cons (NULL_TREE
, (*new_param_types
)[i
],
225 tree new_reversed
= nreverse (new_arg_types
);
229 TREE_CHAIN (new_arg_types
) = void_list_node
;
231 new_reversed
= void_list_node
;
233 new_arg_types
= new_reversed
;
236 /* Use build_distinct_type_copy to preserve as much as possible from original
237 type (debug info, attribute lists etc.). The one exception is
238 METHOD_TYPEs which must have THIS argument and when we are asked to remove
239 it, we need to build new FUNCTION_TYPE instead. */
240 tree new_type
= NULL
;
245 ret_type
= void_type_node
;
247 ret_type
= TREE_TYPE (orig_type
);
250 = build_distinct_type_copy (build_function_type (ret_type
,
252 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
256 new_type
= build_distinct_type_copy (orig_type
);
257 TYPE_ARG_TYPES (new_type
) = new_arg_types
;
259 TREE_TYPE (new_type
) = void_type_node
;
265 /* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
269 ipa_param_adjustments::get_max_base_index ()
271 unsigned adj_len
= vec_safe_length (m_adj_params
);
273 for (unsigned i
= 0; i
< adj_len
; i
++)
275 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
276 if (apm
->op
== IPA_PARAM_OP_COPY
277 && max_index
< apm
->base_index
)
278 max_index
= apm
->base_index
;
284 /* Fill SURVIVING_PARAMS with an array of bools where each one says whether a
285 parameter that originally was at that position still survives in the given
286 clone or is removed/replaced. If the final array is smaller than an index
287 of an original parameter, that parameter also did not survive. That a
288 parameter survives does not mean it has the same index as before. */
291 ipa_param_adjustments::get_surviving_params (vec
<bool> *surviving_params
)
293 unsigned adj_len
= vec_safe_length (m_adj_params
);
294 int max_index
= get_max_base_index ();
298 surviving_params
->reserve_exact (max_index
+ 1);
299 surviving_params
->quick_grow_cleared (max_index
+ 1);
300 for (unsigned i
= 0; i
< adj_len
; i
++)
302 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
303 if (apm
->op
== IPA_PARAM_OP_COPY
)
304 (*surviving_params
)[apm
->base_index
] = true;
308 /* Fill NEW_INDICES with new indices of each surviving parameter or -1 for
309 those which do not survive. Any parameter outside of lenght of the vector
310 does not survive. There is currently no support for a parameter to be
311 copied to two distinct new parameters. */
314 ipa_param_adjustments::get_updated_indices (vec
<int> *new_indices
)
316 unsigned adj_len
= vec_safe_length (m_adj_params
);
317 int max_index
= get_max_base_index ();
321 unsigned res_len
= max_index
+ 1;
322 new_indices
->reserve_exact (res_len
);
323 for (unsigned i
= 0; i
< res_len
; i
++)
324 new_indices
->quick_push (-1);
325 for (unsigned i
= 0; i
< adj_len
; i
++)
327 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
328 if (apm
->op
== IPA_PARAM_OP_COPY
)
329 (*new_indices
)[apm
->base_index
] = i
;
333 /* Return the original index for the given new parameter index. Return a
334 negative number if not available. */
337 ipa_param_adjustments::get_original_index (int newidx
)
339 const ipa_adjusted_param
*adj
= &(*m_adj_params
)[newidx
];
340 if (adj
->op
!= IPA_PARAM_OP_COPY
)
342 return adj
->base_index
;
345 /* Return true if the first parameter (assuming there was one) survives the
346 transformation intact and remains the first one. */
349 ipa_param_adjustments::first_param_intact_p ()
351 return (!vec_safe_is_empty (m_adj_params
)
352 && (*m_adj_params
)[0].op
== IPA_PARAM_OP_COPY
353 && (*m_adj_params
)[0].base_index
== 0);
356 /* Return true if we have to change what has formerly been a method into a
360 ipa_param_adjustments::method2func_p (tree orig_type
)
362 return ((TREE_CODE (orig_type
) == METHOD_TYPE
) && !first_param_intact_p ());
365 /* Given function type OLD_TYPE, return a new type derived from it after
366 performing all atored modifications. TYPE_ORIGINAL_P should be true when
367 OLD_TYPE refers to the type before any IPA transformations, as opposed to a
368 type that can be an intermediate one in between various IPA
372 ipa_param_adjustments::build_new_function_type (tree old_type
,
373 bool type_original_p
)
375 auto_vec
<tree
,16> new_param_types
, *new_param_types_p
;
376 if (prototype_p (old_type
))
378 auto_vec
<tree
, 16> otypes
;
379 push_function_arg_types (&otypes
, old_type
);
380 fill_vector_of_new_param_types (&new_param_types
, &otypes
, m_adj_params
,
382 new_param_types_p
= &new_param_types
;
385 new_param_types_p
= NULL
;
387 return build_adjusted_function_type (old_type
, new_param_types_p
,
388 method2func_p (old_type
), m_skip_return
);
391 /* Build variant of function decl ORIG_DECL which has no return value if
392 M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
393 this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
394 DECL_ARGUMENTS list are not processed now, since they are linked by
395 TREE_CHAIN directly and not accessible in LTO during WPA. The caller is
396 responsible for eliminating them when clones are properly materialized. */
399 ipa_param_adjustments::adjust_decl (tree orig_decl
)
401 tree new_decl
= copy_node (orig_decl
);
402 tree orig_type
= TREE_TYPE (orig_decl
);
403 if (prototype_p (orig_type
)
404 || (m_skip_return
&& !VOID_TYPE_P (TREE_TYPE (orig_type
))))
406 tree new_type
= build_new_function_type (orig_type
, false);
407 TREE_TYPE (new_decl
) = new_type
;
409 if (method2func_p (orig_type
))
410 DECL_VINDEX (new_decl
) = NULL_TREE
;
412 /* When signature changes, we need to clear builtin info. */
413 if (fndecl_built_in_p (new_decl
))
414 set_decl_built_in_function (new_decl
, NOT_BUILT_IN
, 0);
416 DECL_VIRTUAL_P (new_decl
) = 0;
417 DECL_LANG_SPECIFIC (new_decl
) = NULL
;
419 /* Drop MALLOC attribute for a void function. */
421 DECL_IS_MALLOC (new_decl
) = 0;
426 /* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
427 transformations. Return true if EXPR has an interesting form and fill in
428 *BASE_P and *UNIT_OFFSET_P with the appropriate info. */
431 isra_get_ref_base_and_offset (tree expr
, tree
*base_p
, unsigned *unit_offset_p
)
433 HOST_WIDE_INT offset
, size
;
436 = get_ref_base_and_extent_hwi (expr
, &offset
, &size
, &reverse
);
437 if (!base
|| size
< 0)
440 if ((offset
% BITS_PER_UNIT
) != 0)
443 if (TREE_CODE (base
) == MEM_REF
)
445 poly_int64 plmoff
= mem_ref_offset (base
).force_shwi ();
447 bool is_cst
= plmoff
.is_constant (&moff
);
450 offset
+= moff
* BITS_PER_UNIT
;
451 base
= TREE_OPERAND (base
, 0);
454 if (offset
< 0 || (offset
/ BITS_PER_UNIT
) > UINT_MAX
)
458 *unit_offset_p
= offset
/ BITS_PER_UNIT
;
462 /* Return true if EXPR describes a transitive split (i.e. one that happened for
463 both the caller and the callee) as recorded in PERFORMED_SPLITS. In that
464 case, store index of the respective record in PERFORMED_SPLITS into
465 *SM_IDX_P and the unit offset from all handled components in EXPR into
469 transitive_split_p (vec
<ipa_param_performed_split
, va_gc
> *performed_splits
,
470 tree expr
, unsigned *sm_idx_p
, unsigned *unit_offset_p
)
473 if (!isra_get_ref_base_and_offset (expr
, &base
, unit_offset_p
))
476 if (TREE_CODE (base
) == SSA_NAME
)
478 base
= SSA_NAME_VAR (base
);
483 unsigned len
= vec_safe_length (performed_splits
);
484 for (unsigned i
= 0 ; i
< len
; i
++)
486 ipa_param_performed_split
*sm
= &(*performed_splits
)[i
];
487 if (sm
->dummy_decl
== base
)
496 /* Structure to hold declarations representing transitive IPA-SRA splits. In
497 essence, if we need to pass UNIT_OFFSET of a parameter which originally has
498 number BASE_INDEX, we should pass down REPL. */
500 struct transitive_split_map
504 unsigned unit_offset
;
507 /* If call STMT contains any parameters representing transitive splits as
508 described by PERFORMED_SPLITS, return the number of extra parameters that
509 were addded during clone materialization and fill in INDEX_MAP with adjusted
510 indices of corresponding original parameters and TRANS_MAP with description
511 of all transitive replacement descriptions. Otherwise return zero. */
514 init_transitive_splits (vec
<ipa_param_performed_split
, va_gc
> *performed_splits
,
515 gcall
*stmt
, vec
<unsigned> *index_map
,
516 auto_vec
<transitive_split_map
> *trans_map
)
518 unsigned phony_arguments
= 0;
519 unsigned stmt_idx
= 0, base_index
= 0;
520 unsigned nargs
= gimple_call_num_args (stmt
);
521 while (stmt_idx
< nargs
)
523 unsigned unit_offset_delta
;
524 tree base_arg
= gimple_call_arg (stmt
, stmt_idx
);
526 if (phony_arguments
> 0)
527 index_map
->safe_push (stmt_idx
);
531 if (transitive_split_p (performed_splits
, base_arg
, &sm_idx
,
534 if (phony_arguments
== 0)
535 /* We have optimistically avoided constructing index_map do far but
536 now it is clear it will be necessary, so let's create the easy
537 bit we skipped until now. */
538 for (unsigned k
= 0; k
< stmt_idx
; k
++)
539 index_map
->safe_push (k
);
541 tree dummy
= (*performed_splits
)[sm_idx
].dummy_decl
;
542 for (unsigned j
= sm_idx
; j
< performed_splits
->length (); j
++)
544 ipa_param_performed_split
*caller_split
545 = &(*performed_splits
)[j
];
546 if (caller_split
->dummy_decl
!= dummy
)
549 tree arg
= gimple_call_arg (stmt
, stmt_idx
);
550 struct transitive_split_map tsm
;
552 tsm
.base_index
= base_index
;
553 if (caller_split
->unit_offset
>= unit_offset_delta
)
556 = (caller_split
->unit_offset
- unit_offset_delta
);
557 trans_map
->safe_push (tsm
);
566 return phony_arguments
;
569 /* Modify actual arguments of a function call in statement STMT, assuming it
570 calls CALLEE_DECL. CALLER_ADJ must be the description of parameter
571 adjustments of the caller or NULL if there are none. Return the new
572 statement that replaced the old one. When invoked, cfun and
573 current_function_decl have to be set to the caller. */
576 ipa_param_adjustments::modify_call (gcall
*stmt
,
577 vec
<ipa_param_performed_split
,
578 va_gc
> *performed_splits
,
579 tree callee_decl
, bool update_references
)
581 unsigned len
= vec_safe_length (m_adj_params
);
582 auto_vec
<tree
, 16> vargs (len
);
583 tree old_decl
= gimple_call_fndecl (stmt
);
584 unsigned old_nargs
= gimple_call_num_args (stmt
);
585 auto_vec
<bool, 16> kept (old_nargs
);
586 kept
.quick_grow_cleared (old_nargs
);
588 auto_vec
<unsigned, 16> index_map
;
589 auto_vec
<transitive_split_map
> trans_map
;
590 bool transitive_remapping
= false;
592 if (performed_splits
)
594 unsigned removed
= init_transitive_splits (performed_splits
,
595 stmt
, &index_map
, &trans_map
);
598 transitive_remapping
= true;
599 old_nargs
-= removed
;
603 cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
604 if (update_references
)
605 current_node
->remove_stmt_references (stmt
);
607 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
608 gimple_stmt_iterator prev_gsi
= gsi
;
609 gsi_prev (&prev_gsi
);
610 for (unsigned i
= 0; i
< len
; i
++)
612 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
613 if (apm
->op
== IPA_PARAM_OP_COPY
)
615 unsigned index
= apm
->base_index
;
616 if (index
>= old_nargs
)
617 /* Can happen if the original call has argument mismatch,
620 if (transitive_remapping
)
621 index
= index_map
[apm
->base_index
];
623 tree arg
= gimple_call_arg (stmt
, index
);
625 vargs
.quick_push (arg
);
630 /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
631 If we ever want to support it during WPA IPA stage, we'll need a
632 mechanism to call into the IPA passes that introduced them. Currently
633 we simply mandate that IPA infrastructure understands all argument
634 modifications. Remember, edge redirection/modification is done only
635 once, not in steps for each pass modifying the callee like clone
637 gcc_assert (apm
->op
== IPA_PARAM_OP_SPLIT
);
639 /* We have to handle transitive changes differently using the maps we
640 have created before. So look into them first. */
641 tree repl
= NULL_TREE
;
642 for (unsigned j
= 0; j
< trans_map
.length (); j
++)
643 if (trans_map
[j
].base_index
== apm
->base_index
644 && trans_map
[j
].unit_offset
== apm
->unit_offset
)
646 repl
= trans_map
[j
].repl
;
651 vargs
.quick_push (repl
);
655 unsigned index
= apm
->base_index
;
656 if (index
>= old_nargs
)
657 /* Can happen if the original call has argument mismatch, ignore. */
659 if (transitive_remapping
)
660 index
= index_map
[apm
->base_index
];
661 tree base
= gimple_call_arg (stmt
, index
);
663 /* We create a new parameter out of the value of the old one, we can
664 do the following kind of transformations:
666 - A scalar passed by reference, potentially as a part of a larger
667 aggregate, is converted to a scalar passed by value.
669 - A part of an aggregate is passed instead of the whole aggregate. */
671 location_t loc
= gimple_location (stmt
);
673 bool deref_base
= false;
674 unsigned int deref_align
= 0;
675 if (TREE_CODE (base
) != ADDR_EXPR
676 && is_gimple_reg_type (TREE_TYPE (base
)))
678 /* Detect type mismatches in calls in invalid programs and make a
679 poor attempt to gracefully convert them so that we don't ICE. */
680 if (!POINTER_TYPE_P (TREE_TYPE (base
)))
681 base
= force_value_to_type (ptr_type_node
, base
);
683 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
688 if (TREE_CODE (base
) == ADDR_EXPR
)
690 base
= TREE_OPERAND (base
, 0);
696 tree prev_base
= base
;
697 poly_int64 base_offset
;
698 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
700 /* Aggregate arguments can have non-invariant addresses. */
703 base
= build_fold_addr_expr (prev_base
);
704 off
= build_int_cst (apm
->alias_ptr_type
, apm
->unit_offset
);
706 else if (TREE_CODE (base
) == MEM_REF
)
711 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
713 off
= build_int_cst (apm
->alias_ptr_type
,
714 base_offset
+ apm
->unit_offset
);
715 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
717 base
= TREE_OPERAND (base
, 0);
721 off
= build_int_cst (apm
->alias_ptr_type
,
722 base_offset
+ apm
->unit_offset
);
723 base
= build_fold_addr_expr (base
);
727 tree type
= apm
->type
;
729 unsigned HOST_WIDE_INT misalign
;
738 get_pointer_alignment_1 (base
, &align
, &misalign
);
739 /* All users must make sure that we can be optimistic when it
740 comes to alignment in this case (by inspecting the final users
741 of these new parameters). */
742 if (TYPE_ALIGN (type
) > align
)
743 align
= TYPE_ALIGN (type
);
746 += (offset_int::from (wi::to_wide (off
), SIGNED
).to_short_addr ()
748 misalign
= misalign
& (align
- 1);
750 align
= least_bit_hwi (misalign
);
751 if (align
< TYPE_ALIGN (type
))
752 type
= build_aligned_type (type
, align
);
753 base
= force_gimple_operand_gsi (&gsi
, base
,
754 true, NULL
, true, GSI_SAME_STMT
);
755 tree expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
756 REF_REVERSE_STORAGE_ORDER (expr
) = apm
->reverse
;
757 /* If expr is not a valid gimple call argument emit
758 a load into a temporary. */
759 if (is_gimple_reg_type (TREE_TYPE (expr
)))
761 gimple
*tem
= gimple_build_assign (NULL_TREE
, expr
);
762 if (gimple_in_ssa_p (cfun
))
764 gimple_set_vuse (tem
, gimple_vuse (stmt
));
765 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
768 expr
= create_tmp_reg (TREE_TYPE (expr
));
769 gimple_assign_set_lhs (tem
, expr
);
770 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
772 vargs
.quick_push (expr
);
775 if (m_always_copy_start
>= 0)
776 for (unsigned i
= m_always_copy_start
; i
< old_nargs
; i
++)
777 vargs
.safe_push (gimple_call_arg (stmt
, i
));
779 /* For optimized away parameters, add on the caller side
781 DEBUG D#X => parm_Y(D)
782 stmts and associate D#X with parm in decl_debug_args_lookup
783 vector to say for debug info that if parameter parm had been passed,
784 it would have value parm_Y(D). */
785 if (MAY_HAVE_DEBUG_BIND_STMTS
&& old_decl
&& callee_decl
)
787 vec
<tree
, va_gc
> **debug_args
= NULL
;
789 cgraph_node
*callee_node
= cgraph_node::get (callee_decl
);
791 /* FIXME: we don't seem to be able to insert debug args before clone
792 is materialized. Materializing them early leads to extra memory
794 if (callee_node
->clone_of
)
795 callee_node
->get_untransformed_body ();
796 for (tree old_parm
= DECL_ARGUMENTS (old_decl
);
797 old_parm
&& i
< old_nargs
&& ((int) i
) < m_always_copy_start
;
798 old_parm
= DECL_CHAIN (old_parm
), i
++)
800 if (!is_gimple_reg (old_parm
) || kept
[i
])
802 tree origin
= DECL_ORIGIN (old_parm
);
804 if (transitive_remapping
)
805 arg
= gimple_call_arg (stmt
, index_map
[i
]);
807 arg
= gimple_call_arg (stmt
, i
);
809 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
811 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
814 if (TREE_CODE (arg
) == SSA_NAME
815 && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg
))
817 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg
)))
818 && useless_type_conversion_p (TREE_TYPE (origin
),
822 arg
= fold_convert_loc (gimple_location (stmt
),
823 TREE_TYPE (origin
), arg
);
825 if (debug_args
== NULL
)
826 debug_args
= decl_debug_args_insert (callee_decl
);
828 tree ddecl
= NULL_TREE
;
829 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
832 ddecl
= (**debug_args
)[ix
+ 1];
837 ddecl
= make_node (DEBUG_EXPR_DECL
);
838 DECL_ARTIFICIAL (ddecl
) = 1;
839 TREE_TYPE (ddecl
) = TREE_TYPE (origin
);
840 SET_DECL_MODE (ddecl
, DECL_MODE (origin
));
842 vec_safe_push (*debug_args
, origin
);
843 vec_safe_push (*debug_args
, ddecl
);
845 gimple
*def_temp
= gimple_build_debug_bind (ddecl
,
846 unshare_expr (arg
), stmt
);
847 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
851 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
853 fprintf (dump_file
, "replacing stmt:");
854 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0);
857 gcall
*new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
859 tree ssa_to_remove
= NULL
;
860 if (tree lhs
= gimple_call_lhs (stmt
))
863 gimple_call_set_lhs (new_stmt
, lhs
);
864 else if (TREE_CODE (lhs
) == SSA_NAME
)
866 /* LHS should now by a default-def SSA. Unfortunately default-def
867 SSA_NAMEs need a backing variable (or at least some code examining
868 SSAs assumes it is non-NULL). So we either have to re-use the
869 decl we have at hand or introdice a new one. */
870 tree repl
= create_tmp_var (TREE_TYPE (lhs
), "removed_return");
871 repl
= get_or_create_ssa_default_def (cfun
, repl
);
872 SSA_NAME_IS_DEFAULT_DEF (repl
) = true;
876 FOR_EACH_IMM_USE_STMT (using_stmt
, ui
, lhs
)
878 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
880 SET_USE (use_p
, repl
);
882 update_stmt (using_stmt
);
888 gimple_set_block (new_stmt
, gimple_block (stmt
));
889 if (gimple_has_location (stmt
))
890 gimple_set_location (new_stmt
, gimple_location (stmt
));
891 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
892 gimple_call_copy_flags (new_stmt
, stmt
);
893 if (gimple_in_ssa_p (cfun
))
894 gimple_move_vops (new_stmt
, stmt
);
896 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
898 fprintf (dump_file
, "with stmt:");
899 print_gimple_stmt (dump_file
, new_stmt
, 0);
900 fprintf (dump_file
, "\n");
902 gsi_replace (&gsi
, new_stmt
, true);
904 release_ssa_name (ssa_to_remove
);
905 if (update_references
)
908 current_node
->record_stmt_references (gsi_stmt (gsi
));
911 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
915 /* Dump information contained in the object in textual form to F. */
918 ipa_param_adjustments::dump (FILE *f
)
920 fprintf (f
, " m_always_copy_start: %i\n", m_always_copy_start
);
921 ipa_dump_adjusted_parameters (f
, m_adj_params
);
923 fprintf (f
, " Will SKIP return.\n");
926 /* Dump information contained in the object in textual form to stderr. */
929 ipa_param_adjustments::debug ()
934 /* Register that REPLACEMENT should replace parameter described in APM and
935 optionally as DUMMY to mark transitive splits across calls. */
938 ipa_param_body_adjustments::register_replacement (ipa_adjusted_param
*apm
,
942 gcc_checking_assert (apm
->op
== IPA_PARAM_OP_SPLIT
943 || apm
->op
== IPA_PARAM_OP_NEW
);
944 gcc_checking_assert (!apm
->prev_clone_adjustment
);
945 ipa_param_body_replacement psr
;
946 psr
.base
= m_oparms
[apm
->prev_clone_index
];
947 psr
.repl
= replacement
;
949 psr
.unit_offset
= apm
->unit_offset
;
950 m_replacements
.safe_push (psr
);
953 /* Copy or not, as appropriate given m_id and decl context, a pre-existing
954 PARM_DECL T so that it can be included in the parameters of the modified
958 ipa_param_body_adjustments::carry_over_param (tree t
)
963 new_parm
= remap_decl (t
, m_id
);
964 if (TREE_CODE (new_parm
) != PARM_DECL
)
965 new_parm
= m_id
->copy_decl (t
, m_id
);
967 else if (DECL_CONTEXT (t
) != m_fndecl
)
969 new_parm
= copy_node (t
);
970 DECL_CONTEXT (new_parm
) = m_fndecl
;
977 /* Common initialization performed by all ipa_param_body_adjustments
978 constructors. OLD_FNDECL is the declaration we take original arguments
979 from, (it may be the same as M_FNDECL). VARS, if non-NULL, is a pointer to
980 a chained list of new local variables. TREE_MAP is the IPA-CP produced
981 mapping of trees to constants.
983 The function is rather long but it really onlu initializes all data members
984 of the class. It creates new param DECLs, finds their new types, */
987 ipa_param_body_adjustments::common_initialization (tree old_fndecl
,
989 vec
<ipa_replace_map
*,
992 push_function_arg_decls (&m_oparms
, old_fndecl
);
993 auto_vec
<tree
,16> otypes
;
994 if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl
)) != NULL_TREE
)
995 push_function_arg_types (&otypes
, TREE_TYPE (old_fndecl
));
998 auto_vec
<tree
,16> oparms
;
999 push_function_arg_decls (&oparms
, old_fndecl
);
1000 unsigned ocount
= oparms
.length ();
1001 otypes
.reserve_exact (ocount
);
1002 for (unsigned i
= 0; i
< ocount
; i
++)
1003 otypes
.quick_push (TREE_TYPE (oparms
[i
]));
1005 fill_vector_of_new_param_types (&m_new_types
, &otypes
, m_adj_params
, true);
1007 auto_vec
<bool, 16> kept
;
1008 kept
.reserve_exact (m_oparms
.length ());
1009 kept
.quick_grow_cleared (m_oparms
.length ());
1010 auto_vec
<tree
, 16> isra_dummy_decls
;
1011 isra_dummy_decls
.reserve_exact (m_oparms
.length ());
1012 isra_dummy_decls
.quick_grow_cleared (m_oparms
.length ());
1014 unsigned adj_len
= vec_safe_length (m_adj_params
);
1015 m_method2func
= ((TREE_CODE (TREE_TYPE (m_fndecl
)) == METHOD_TYPE
)
1017 || (*m_adj_params
)[0].op
!= IPA_PARAM_OP_COPY
1018 || (*m_adj_params
)[0].base_index
!= 0));
1020 /* The main job of the this function is to go over the vector of adjusted
1021 parameters and create declarations or find corresponding old ones and push
1022 them to m_new_decls. For IPA-SRA replacements it also creates
1023 corresponding m_id->dst_node->clone.performed_splits entries. */
1025 m_new_decls
.reserve_exact (adj_len
);
1026 for (unsigned i
= 0; i
< adj_len
; i
++)
1028 ipa_adjusted_param
*apm
= &(*m_adj_params
)[i
];
1029 unsigned prev_index
= apm
->prev_clone_index
;
1031 if (apm
->op
== IPA_PARAM_OP_COPY
1032 || apm
->prev_clone_adjustment
)
1034 kept
[prev_index
] = true;
1035 new_parm
= carry_over_param (m_oparms
[prev_index
]);
1036 m_new_decls
.quick_push (new_parm
);
1038 else if (apm
->op
== IPA_PARAM_OP_NEW
1039 || apm
->op
== IPA_PARAM_OP_SPLIT
)
1041 tree new_type
= m_new_types
[i
];
1042 gcc_checking_assert (new_type
);
1043 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
1045 const char *prefix
= ipa_param_prefixes
[apm
->param_prefix_index
];
1046 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
1047 DECL_ARTIFICIAL (new_parm
) = 1;
1048 DECL_ARG_TYPE (new_parm
) = new_type
;
1049 DECL_CONTEXT (new_parm
) = m_fndecl
;
1050 TREE_USED (new_parm
) = 1;
1051 DECL_IGNORED_P (new_parm
) = 1;
1052 layout_decl (new_parm
, 0);
1053 m_new_decls
.quick_push (new_parm
);
1055 if (apm
->op
== IPA_PARAM_OP_SPLIT
)
1057 m_split_modifications_p
= true;
1062 if (!isra_dummy_decls
[prev_index
])
1064 dummy_decl
= copy_decl_to_var (m_oparms
[prev_index
],
1066 /* Any attempt to remap this dummy in this particular
1067 instance of clone materialization should yield
1069 insert_decl_map (m_id
, dummy_decl
, dummy_decl
);
1071 DECL_CHAIN (dummy_decl
) = *vars
;
1073 isra_dummy_decls
[prev_index
] = dummy_decl
;
1076 dummy_decl
= isra_dummy_decls
[prev_index
];
1078 register_replacement (apm
, new_parm
, dummy_decl
);
1079 ipa_param_performed_split ps
;
1080 ps
.dummy_decl
= dummy_decl
;
1081 ps
.unit_offset
= apm
->unit_offset
;
1082 vec_safe_push (clone_info::get_create
1083 (m_id
->dst_node
)->performed_splits
, ps
);
1086 register_replacement (apm
, new_parm
);
1094 /* As part of body modifications, we will also have to replace remaining uses
1095 of remaining uses of removed PARM_DECLs (which do not however use the
1096 initial value) with their VAR_DECL copies.
1098 We do this differently with and without m_id. With m_id, we rely on its
1099 mapping and create a replacement straight away. Without it, we have our
1100 own mechanism for which we have to populate m_removed_decls vector. Just
1101 don't mix them, that is why you should not call
1102 replace_removed_params_ssa_names or perform_cfun_body_modifications when
1103 you construct with ID not equal to NULL. */
1105 unsigned op_len
= m_oparms
.length ();
1106 for (unsigned i
= 0; i
< op_len
; i
++)
1111 if (!m_id
->decl_map
->get (m_oparms
[i
]))
1113 /* TODO: Perhaps at least aggregate-type params could re-use
1114 their isra_dummy_decl here? */
1115 tree var
= copy_decl_to_var (m_oparms
[i
], m_id
);
1116 insert_decl_map (m_id
, m_oparms
[i
], var
);
1117 /* Declare this new variable. */
1118 DECL_CHAIN (var
) = *vars
;
1124 m_removed_decls
.safe_push (m_oparms
[i
]);
1125 m_removed_map
.put (m_oparms
[i
], m_removed_decls
.length () - 1);
1129 if (!MAY_HAVE_DEBUG_STMTS
)
1132 /* Finally, when generating debug info, we fill vector m_reset_debug_decls
1133 with removed parameters declarations. We do this in order to re-map their
1134 debug bind statements and create debug decls for them. */
1138 /* Do not output debuginfo for parameter declarations as if they vanished
1139 when they were in fact replaced by a constant. */
1140 auto_vec
<int, 16> index_mapping
;
1141 bool need_remap
= false;
1142 clone_info
*info
= clone_info::get (m_id
->src_node
);
1144 if (m_id
&& info
&& info
->param_adjustments
)
1146 ipa_param_adjustments
*prev_adjustments
= info
->param_adjustments
;
1147 prev_adjustments
->get_updated_indices (&index_mapping
);
1151 for (unsigned i
= 0; i
< tree_map
->length (); i
++)
1153 int parm_num
= (*tree_map
)[i
]->parm_num
;
1154 gcc_assert (parm_num
>= 0);
1156 parm_num
= index_mapping
[parm_num
];
1157 kept
[parm_num
] = true;
1161 for (unsigned i
= 0; i
< op_len
; i
++)
1162 if (!kept
[i
] && is_gimple_reg (m_oparms
[i
]))
1163 m_reset_debug_decls
.safe_push (m_oparms
[i
]);
1166 /* Constructor of ipa_param_body_adjustments from a simple list of
1167 modifications to parameters listed in ADJ_PARAMS which will prepare ground
1168 for modification of parameters of fndecl. Return value of the function will
1169 not be removed and the object will assume it does not run as a part of
1170 tree-function_versioning. */
1172 ipa_param_body_adjustments
1173 ::ipa_param_body_adjustments (vec
<ipa_adjusted_param
, va_gc
> *adj_params
,
1175 : m_adj_params (adj_params
), m_adjustments (NULL
), m_reset_debug_decls (),
1176 m_split_modifications_p (false), m_fndecl (fndecl
), m_id (NULL
),
1177 m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1178 m_removed_decls (), m_removed_map (), m_method2func (false)
1180 common_initialization (fndecl
, NULL
, NULL
);
1183 /* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
1184 ADJUSTMENTS which will prepare ground for modification of parameters of
1185 fndecl. The object will assume it does not run as a part of
1186 tree-function_versioning. */
1188 ipa_param_body_adjustments
1189 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1191 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1192 m_reset_debug_decls (), m_split_modifications_p (false), m_fndecl (fndecl
),
1193 m_id (NULL
), m_oparms (), m_new_decls (), m_new_types (),
1194 m_replacements (), m_removed_decls (), m_removed_map (),
1195 m_method2func (false)
1197 common_initialization (fndecl
, NULL
, NULL
);
1200 /* Constructor of ipa_param_body_adjustments which sets it up as a part of
1201 running tree_function_versioning. Planned modifications to the function are
1202 in ADJUSTMENTS. FNDECL designates the new function clone which is being
1203 modified. OLD_FNDECL is the function of which FNDECL is a clone (and which
1204 at the time of invocation still share DECL_ARGUMENTS). ID is the
1205 copy_body_data structure driving the wholy body copying process. VARS is a
1206 pointer to the head of the list of new local variables, TREE_MAP is the map
1207 that drives tree substitution in the cloning process. */
1209 ipa_param_body_adjustments
1210 ::ipa_param_body_adjustments (ipa_param_adjustments
*adjustments
,
1211 tree fndecl
, tree old_fndecl
,
1212 copy_body_data
*id
, tree
*vars
,
1213 vec
<ipa_replace_map
*, va_gc
> *tree_map
)
1214 : m_adj_params (adjustments
->m_adj_params
), m_adjustments (adjustments
),
1215 m_reset_debug_decls (), m_split_modifications_p (false), m_fndecl (fndecl
),
1216 m_id (id
), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
1217 m_removed_decls (), m_removed_map (), m_method2func (false)
1219 common_initialization (old_fndecl
, vars
, tree_map
);
1222 /* Chain new param decls up and return them. */
1225 ipa_param_body_adjustments::get_new_param_chain ()
1228 tree
*link
= &result
;
1230 unsigned len
= vec_safe_length (m_adj_params
);
1231 for (unsigned i
= 0; i
< len
; i
++)
1233 tree new_decl
= m_new_decls
[i
];
1235 link
= &DECL_CHAIN (new_decl
);
1241 /* Modify the function parameters FNDECL and its type according to the plan in
1242 ADJUSTMENTS. This function needs to be called when the decl has not already
1243 been processed with ipa_param_adjustments::adjust_decl, otherwise just
1244 seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough. */
1247 ipa_param_body_adjustments::modify_formal_parameters ()
1249 tree orig_type
= TREE_TYPE (m_fndecl
);
1250 DECL_ARGUMENTS (m_fndecl
) = get_new_param_chain ();
1252 /* When signature changes, we need to clear builtin info. */
1253 if (fndecl_built_in_p (m_fndecl
))
1254 set_decl_built_in_function (m_fndecl
, NOT_BUILT_IN
, 0);
1256 /* At this point, removing return value is only implemented when going
1257 through tree_function_versioning, not when modifying function body
1259 gcc_assert (!m_adjustments
|| !m_adjustments
->m_skip_return
);
1260 tree new_type
= build_adjusted_function_type (orig_type
, &m_new_types
,
1261 m_method2func
, false);
1263 TREE_TYPE (m_fndecl
) = new_type
;
1264 DECL_VIRTUAL_P (m_fndecl
) = 0;
1265 DECL_LANG_SPECIFIC (m_fndecl
) = NULL
;
1267 DECL_VINDEX (m_fndecl
) = NULL_TREE
;
1270 /* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
1273 ipa_param_body_replacement
*
1274 ipa_param_body_adjustments::lookup_replacement_1 (tree base
,
1275 unsigned unit_offset
)
1277 unsigned int len
= m_replacements
.length ();
1278 for (unsigned i
= 0; i
< len
; i
++)
1280 ipa_param_body_replacement
*pbr
= &m_replacements
[i
];
1282 if (pbr
->base
== base
1283 && (pbr
->unit_offset
== unit_offset
))
1289 /* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
1290 and return it, assuming it is known it does not hold value by reference or
1291 in reverse storage order. */
1294 ipa_param_body_adjustments::lookup_replacement (tree base
, unsigned unit_offset
)
1296 ipa_param_body_replacement
*pbr
= lookup_replacement_1 (base
, unit_offset
);
1302 /* If T is an SSA_NAME, return NULL if it is not a default def or
1303 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
1304 the base variable is always returned, regardless if it is a default
1305 def. Return T if it is not an SSA_NAME. */
1308 get_ssa_base_param (tree t
, bool ignore_default_def
)
1310 if (TREE_CODE (t
) == SSA_NAME
)
1312 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
1313 return SSA_NAME_VAR (t
);
1320 /* Given an expression, return the structure describing how it should be
1321 replaced if it accesses a part of a split parameter or NULL otherwise.
1323 Do not free the result, it will be deallocated when the object is destroyed.
1325 If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
1326 which are default definitions, if set, consider all SSA_NAMEs of
1329 ipa_param_body_replacement
*
1330 ipa_param_body_adjustments::get_expr_replacement (tree expr
,
1331 bool ignore_default_def
)
1334 unsigned unit_offset
;
1336 if (!isra_get_ref_base_and_offset (expr
, &base
, &unit_offset
))
1339 base
= get_ssa_base_param (base
, ignore_default_def
);
1340 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
1342 return lookup_replacement_1 (base
, unit_offset
);
1345 /* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
1346 (which includes it being split or replaced), return a new variable that
1347 should be used for any SSA names that will remain in the function that
1348 previously belonged to OLD_DECL. */
1351 ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl
)
1353 unsigned *idx
= m_removed_map
.get (old_decl
);
1358 if (TREE_CODE (m_removed_decls
[*idx
]) == PARM_DECL
)
1360 gcc_assert (m_removed_decls
[*idx
] == old_decl
);
1361 repl
= copy_var_decl (old_decl
, DECL_NAME (old_decl
),
1362 TREE_TYPE (old_decl
));
1363 m_removed_decls
[*idx
] = repl
;
1366 repl
= m_removed_decls
[*idx
];
1370 /* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
1371 parameter which is to be removed because its value is not used, create a new
1372 SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
1373 original with it and return it. If there is no need to re-map, return NULL.
1374 ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments. */
1377 ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name
,
1381 if (TREE_CODE (old_name
) != SSA_NAME
)
1384 tree decl
= SSA_NAME_VAR (old_name
);
1385 if (decl
== NULL_TREE
1386 || TREE_CODE (decl
) != PARM_DECL
)
1389 tree repl
= get_replacement_ssa_base (decl
);
1393 tree new_name
= make_ssa_name (repl
, stmt
);
1394 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name
)
1395 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name
);
1397 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1399 fprintf (dump_file
, "replacing an SSA name of a removed param ");
1400 print_generic_expr (dump_file
, old_name
);
1401 fprintf (dump_file
, " with ");
1402 print_generic_expr (dump_file
, new_name
);
1403 fprintf (dump_file
, "\n");
1406 replace_uses_by (old_name
, new_name
);
1410 /* If the expression *EXPR_P should be replaced, do so. CONVERT specifies
1411 whether the function should care about type incompatibility of the current
1412 and new expressions. If it is false, the function will leave
1413 incompatibility issues to the caller - note that when the function
1414 encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
1415 their bases instead of the expressions themselves and then also performs any
1416 necessary conversions. */
1419 ipa_param_body_adjustments::modify_expression (tree
*expr_p
, bool convert
)
1421 tree expr
= *expr_p
;
1423 if (TREE_CODE (expr
) == BIT_FIELD_REF
1424 || TREE_CODE (expr
) == IMAGPART_EXPR
1425 || TREE_CODE (expr
) == REALPART_EXPR
)
1427 expr_p
= &TREE_OPERAND (expr
, 0);
1432 ipa_param_body_replacement
*pbr
= get_expr_replacement (expr
, false);
1436 tree repl
= pbr
->repl
;
1437 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1439 fprintf (dump_file
, "About to replace expr ");
1440 print_generic_expr (dump_file
, expr
);
1441 fprintf (dump_file
, " with ");
1442 print_generic_expr (dump_file
, repl
);
1443 fprintf (dump_file
, "\n");
1446 if (convert
&& !useless_type_conversion_p (TREE_TYPE (expr
),
1449 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (expr
), repl
);
1457 /* If the assignment statement STMT contains any expressions that need to
1458 replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
1459 potential type incompatibilities. If any conversion sttements have to be
1460 pre-pended to STMT, they will be added to EXTRA_STMTS. Return true iff the
1461 statement was modified. */
1464 ipa_param_body_adjustments::modify_assignment (gimple
*stmt
,
1465 gimple_seq
*extra_stmts
)
1467 tree
*lhs_p
, *rhs_p
;
1470 if (!gimple_assign_single_p (stmt
))
1473 rhs_p
= gimple_assign_rhs1_ptr (stmt
);
1474 lhs_p
= gimple_assign_lhs_ptr (stmt
);
1476 any
= modify_expression (lhs_p
, false);
1477 any
|= modify_expression (rhs_p
, false);
1479 && !useless_type_conversion_p (TREE_TYPE (*lhs_p
), TREE_TYPE (*rhs_p
)))
1481 if (TREE_CODE (*rhs_p
) == CONSTRUCTOR
)
1483 /* V_C_Es of constructors can cause trouble (PR 42714). */
1484 if (is_gimple_reg_type (TREE_TYPE (*lhs_p
)))
1485 *rhs_p
= build_zero_cst (TREE_TYPE (*lhs_p
));
1487 *rhs_p
= build_constructor (TREE_TYPE (*lhs_p
),
1492 tree new_rhs
= fold_build1_loc (gimple_location (stmt
),
1493 VIEW_CONVERT_EXPR
, TREE_TYPE (*lhs_p
),
1495 tree tmp
= force_gimple_operand (new_rhs
, extra_stmts
, true,
1497 gimple_assign_set_rhs1 (stmt
, tmp
);
1505 /* Data passed to remap_split_decl_to_dummy through walk_tree. */
1507 struct simple_tree_swap_info
1509 /* Change FROM to TO. */
1511 /* And set DONE to true when doing so. */
1515 /* Simple remapper to remap a split parameter to the same expression based on a
1516 special dummy decl so that edge redirections can detect transitive splitting
1520 remap_split_decl_to_dummy (tree
*tp
, int *walk_subtrees
, void *data
)
1524 if (DECL_P (t
) || TREE_CODE (t
) == SSA_NAME
)
1526 struct simple_tree_swap_info
*swapinfo
1527 = (struct simple_tree_swap_info
*) data
;
1528 if (t
== swapinfo
->from
1529 || (TREE_CODE (t
) == SSA_NAME
1530 && SSA_NAME_VAR (t
) == swapinfo
->from
))
1533 swapinfo
->done
= true;
1537 else if (TYPE_P (t
))
1545 /* If the call statement pointed at by STMT_P contains any expressions that
1546 need to replaced with a different one as noted by ADJUSTMENTS, do so. f the
1547 statement needs to be rebuilt, do so. Return true if any modifications have
1550 If the method is invoked as a part of IPA clone materialization and if any
1551 parameter split is transitive, i.e. it applies to the functin that is being
1552 modified and also to the callee of the statement, replace the parameter
1553 passed to old callee with an equivalent expression based on a dummy decl
1554 followed by PARM_DECLs representing the actual replacements. The actual
1555 replacements will be then converted into SSA_NAMEs and then
1556 ipa_param_adjustments::modify_call will find the appropriate ones and leave
1557 only those in the call. */
1560 ipa_param_body_adjustments::modify_call_stmt (gcall
**stmt_p
)
1562 gcall
*stmt
= *stmt_p
;
1563 auto_vec
<unsigned, 4> pass_through_args
;
1564 auto_vec
<unsigned, 4> pass_through_pbr_indices
;
1566 if (m_split_modifications_p
&& m_id
)
1568 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1570 tree t
= gimple_call_arg (stmt
, i
);
1571 gcc_assert (TREE_CODE (t
) != BIT_FIELD_REF
1572 && TREE_CODE (t
) != IMAGPART_EXPR
1573 && TREE_CODE (t
) != REALPART_EXPR
);
1576 unsigned unit_offset
;
1577 if (!isra_get_ref_base_and_offset (t
, &base
, &unit_offset
))
1580 bool by_ref
= false;
1581 if (TREE_CODE (base
) == SSA_NAME
)
1583 if (!SSA_NAME_IS_DEFAULT_DEF (base
))
1585 base
= SSA_NAME_VAR (base
);
1586 gcc_checking_assert (base
);
1589 if (TREE_CODE (base
) != PARM_DECL
)
1592 bool base_among_replacements
= false;
1593 unsigned j
, repl_list_len
= m_replacements
.length ();
1594 for (j
= 0; j
< repl_list_len
; j
++)
1596 ipa_param_body_replacement
*pbr
= &m_replacements
[j
];
1597 if (pbr
->base
== base
)
1599 base_among_replacements
= true;
1603 if (!base_among_replacements
)
1606 /* We still have to distinguish between an end-use that we have to
1607 transform now and a pass-through, which happens in the following
1610 /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
1611 &MEM_REF[ssa_name + offset], we will also have to detect that case
1614 if (TREE_CODE (t
) == SSA_NAME
1615 && SSA_NAME_IS_DEFAULT_DEF (t
)
1617 && TREE_CODE (SSA_NAME_VAR (t
)) == PARM_DECL
)
1619 /* This must be a by_reference pass-through. */
1620 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t
)));
1621 pass_through_args
.safe_push (i
);
1622 pass_through_pbr_indices
.safe_push (j
);
1624 else if (!by_ref
&& AGGREGATE_TYPE_P (TREE_TYPE (t
)))
1626 /* Currently IPA-SRA guarantees the aggregate access type
1627 exactly matches in this case. So if it does not match, it is
1628 a pass-through argument that will be sorted out at edge
1629 redirection time. */
1630 ipa_param_body_replacement
*pbr
1631 = lookup_replacement_1 (base
, unit_offset
);
1634 || (TYPE_MAIN_VARIANT (TREE_TYPE (t
))
1635 != TYPE_MAIN_VARIANT (TREE_TYPE (pbr
->repl
))))
1637 pass_through_args
.safe_push (i
);
1638 pass_through_pbr_indices
.safe_push (j
);
1644 unsigned nargs
= gimple_call_num_args (stmt
);
1645 if (!pass_through_args
.is_empty ())
1647 auto_vec
<tree
, 16> vargs
;
1648 unsigned pt_idx
= 0;
1649 for (unsigned i
= 0; i
< nargs
; i
++)
1651 if (pt_idx
< pass_through_args
.length ()
1652 && i
== pass_through_args
[pt_idx
])
1654 unsigned j
= pass_through_pbr_indices
[pt_idx
];
1656 tree base
= m_replacements
[j
].base
;
1658 /* Map base will get mapped to the special transitive-isra marker
1660 struct simple_tree_swap_info swapinfo
;
1661 swapinfo
.from
= base
;
1662 swapinfo
.to
= m_replacements
[j
].dummy
;
1663 swapinfo
.done
= false;
1664 tree arg
= gimple_call_arg (stmt
, i
);
1665 walk_tree (&arg
, remap_split_decl_to_dummy
, &swapinfo
, NULL
);
1666 gcc_assert (swapinfo
.done
);
1667 vargs
.safe_push (arg
);
1668 /* Now let's push all replacements pertaining to this parameter
1669 so that all gimple register ones get correct SSA_NAMES. Edge
1670 redirection will weed out the dummy argument as well as all
1671 unused replacements later. */
1672 unsigned int repl_list_len
= m_replacements
.length ();
1673 for (; j
< repl_list_len
; j
++)
1675 if (m_replacements
[j
].base
!= base
)
1677 vargs
.safe_push (m_replacements
[j
].repl
);
1682 tree t
= gimple_call_arg (stmt
, i
);
1683 modify_expression (&t
, true);
1684 vargs
.safe_push (t
);
1687 gcall
*new_stmt
= gimple_build_call_vec (gimple_call_fn (stmt
), vargs
);
1688 if (gimple_has_location (stmt
))
1689 gimple_set_location (new_stmt
, gimple_location (stmt
));
1690 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
1691 gimple_call_copy_flags (new_stmt
, stmt
);
1692 if (tree lhs
= gimple_call_lhs (stmt
))
1694 modify_expression (&lhs
, false);
1695 /* Avoid adjusting SSA_NAME_DEF_STMT of a SSA lhs, SSA names
1696 have not yet been remapped. */
1697 *gimple_call_lhs_ptr (new_stmt
) = lhs
;
1703 /* Otherwise, no need to rebuild the statement, let's just modify arguments
1704 and the LHS if/as appropriate. */
1705 bool modified
= false;
1706 for (unsigned i
= 0; i
< nargs
; i
++)
1708 tree
*t
= gimple_call_arg_ptr (stmt
, i
);
1709 modified
|= modify_expression (t
, true);
1712 if (gimple_call_lhs (stmt
))
1714 tree
*t
= gimple_call_lhs_ptr (stmt
);
1715 modified
|= modify_expression (t
, false);
1721 /* If the statement STMT contains any expressions that need to replaced with a
1722 different one as noted by ADJUSTMENTS, do so. Handle any potential type
1723 incompatibilities. If any conversion sttements have to be pre-pended to
1724 STMT, they will be added to EXTRA_STMTS. Return true iff the statement was
1728 ipa_param_body_adjustments::modify_gimple_stmt (gimple
**stmt
,
1729 gimple_seq
*extra_stmts
)
1731 bool modified
= false;
1734 switch (gimple_code (*stmt
))
1737 t
= gimple_return_retval_ptr (as_a
<greturn
*> (*stmt
));
1738 if (m_adjustments
&& m_adjustments
->m_skip_return
)
1740 else if (*t
!= NULL_TREE
)
1741 modified
|= modify_expression (t
, true);
1745 modified
|= modify_assignment (*stmt
, extra_stmts
);
1749 modified
|= modify_call_stmt ((gcall
**) stmt
);
1754 gasm
*asm_stmt
= as_a
<gasm
*> (*stmt
);
1755 for (unsigned i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
1757 t
= &TREE_VALUE (gimple_asm_input_op (asm_stmt
, i
));
1758 modified
|= modify_expression (t
, true);
1760 for (unsigned i
= 0; i
< gimple_asm_noutputs (asm_stmt
); i
++)
1762 t
= &TREE_VALUE (gimple_asm_output_op (asm_stmt
, i
));
1763 modified
|= modify_expression (t
, false);
1775 /* Traverse body of the current function and perform the requested adjustments
1776 on its statements. Return true iff the CFG has been changed. */
1779 ipa_param_body_adjustments::modify_cfun_body ()
1781 bool cfg_changed
= false;
1784 FOR_EACH_BB_FN (bb
, cfun
)
1786 gimple_stmt_iterator gsi
;
1788 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1790 gphi
*phi
= as_a
<gphi
*> (gsi_stmt (gsi
));
1791 tree new_lhs
, old_lhs
= gimple_phi_result (phi
);
1792 new_lhs
= replace_removed_params_ssa_names (old_lhs
, phi
);
1795 gimple_phi_set_result (phi
, new_lhs
);
1796 release_ssa_name (old_lhs
);
1800 gsi
= gsi_start_bb (bb
);
1801 while (!gsi_end_p (gsi
))
1803 gimple
*stmt
= gsi_stmt (gsi
);
1804 gimple
*stmt_copy
= stmt
;
1805 gimple_seq extra_stmts
= NULL
;
1806 bool modified
= modify_gimple_stmt (&stmt
, &extra_stmts
);
1807 if (stmt
!= stmt_copy
)
1809 gcc_checking_assert (modified
);
1810 gsi_replace (&gsi
, stmt
, false);
1812 if (!gimple_seq_empty_p (extra_stmts
))
1813 gsi_insert_seq_before (&gsi
, extra_stmts
, GSI_SAME_STMT
);
1817 FOR_EACH_SSA_DEF_OPERAND (defp
, stmt
, iter
, SSA_OP_DEF
)
1819 tree old_def
= DEF_FROM_PTR (defp
);
1820 if (tree new_def
= replace_removed_params_ssa_names (old_def
,
1823 SET_DEF (defp
, new_def
);
1824 release_ssa_name (old_def
);
1832 if (maybe_clean_eh_stmt (stmt
)
1833 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
1843 /* Call gimple_debug_bind_reset_value on all debug statements describing
1844 gimple register parameters that are being removed or replaced. */
1847 ipa_param_body_adjustments::reset_debug_stmts ()
1850 gimple_stmt_iterator
*gsip
= NULL
, gsi
;
1852 if (MAY_HAVE_DEBUG_STMTS
&& single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun
)))
1854 gsi
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
1857 len
= m_reset_debug_decls
.length ();
1858 for (i
= 0; i
< len
; i
++)
1860 imm_use_iterator ui
;
1863 tree name
, vexpr
, copy
= NULL_TREE
;
1864 use_operand_p use_p
;
1865 tree decl
= m_reset_debug_decls
[i
];
1867 gcc_checking_assert (is_gimple_reg (decl
));
1868 name
= ssa_default_def (cfun
, decl
);
1871 FOR_EACH_IMM_USE_STMT (stmt
, ui
, name
)
1873 if (gimple_clobber_p (stmt
))
1875 gimple_stmt_iterator cgsi
= gsi_for_stmt (stmt
);
1876 unlink_stmt_vdef (stmt
);
1877 gsi_remove (&cgsi
, true);
1878 release_defs (stmt
);
1881 /* All other users must have been removed by function body
1883 gcc_assert (is_gimple_debug (stmt
));
1884 if (vexpr
== NULL
&& gsip
!= NULL
)
1886 vexpr
= make_node (DEBUG_EXPR_DECL
);
1887 def_temp
= gimple_build_debug_source_bind (vexpr
, decl
, NULL
);
1888 DECL_ARTIFICIAL (vexpr
) = 1;
1889 TREE_TYPE (vexpr
) = TREE_TYPE (name
);
1890 SET_DECL_MODE (vexpr
, DECL_MODE (decl
));
1891 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
1895 FOR_EACH_IMM_USE_ON_STMT (use_p
, ui
)
1896 SET_USE (use_p
, vexpr
);
1899 gimple_debug_bind_reset_value (stmt
);
1902 /* Create a VAR_DECL for debug info purposes. */
1903 if (!DECL_IGNORED_P (decl
))
1905 copy
= build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
1906 VAR_DECL
, DECL_NAME (decl
),
1908 if (DECL_PT_UID_SET_P (decl
))
1909 SET_DECL_PT_UID (copy
, DECL_PT_UID (decl
));
1910 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (decl
);
1911 TREE_READONLY (copy
) = TREE_READONLY (decl
);
1912 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (decl
);
1913 DECL_NOT_GIMPLE_REG_P (copy
) = DECL_NOT_GIMPLE_REG_P (decl
);
1914 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (decl
);
1915 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (decl
);
1916 DECL_ABSTRACT_ORIGIN (copy
) = DECL_ORIGIN (decl
);
1917 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
1918 SET_DECL_RTL (copy
, 0);
1919 TREE_USED (copy
) = 1;
1920 DECL_CONTEXT (copy
) = current_function_decl
;
1921 add_local_decl (cfun
, copy
);
1923 = BLOCK_VARS (DECL_INITIAL (current_function_decl
));
1924 BLOCK_VARS (DECL_INITIAL (current_function_decl
)) = copy
;
1926 if (gsip
!= NULL
&& copy
&& target_for_debug_bind (decl
))
1928 gcc_assert (TREE_CODE (decl
) == PARM_DECL
);
1930 def_temp
= gimple_build_debug_bind (copy
, vexpr
, NULL
);
1932 def_temp
= gimple_build_debug_source_bind (copy
, decl
,
1934 gsi_insert_before (gsip
, def_temp
, GSI_SAME_STMT
);
1939 /* Perform all necessary body changes to change signature, body and debug info
1940 of fun according to adjustments passed at construction. Return true if CFG
1941 was changed in any way. The main entry point for modification of standalone
1942 functions that is not part of IPA clone materialization. */
1945 ipa_param_body_adjustments::perform_cfun_body_modifications ()
1948 modify_formal_parameters ();
1949 cfg_changed
= modify_cfun_body ();
1950 reset_debug_stmts ();