aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-21 07:01:00 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-21 07:01:00 +0000
commita20c5714c689bf1c0c7a2d2589b4df0eaa4635fb (patch)
tree69d2a02e7942089893a7b94124db1ea69c6816a0 /gcc/function.c
parente6715081eddeb808bc2c8f2fa84b2f436d86a0e5 (diff)
downloadgcc-a20c5714c689bf1c0c7a2d2589b4df0eaa4635fb.zip
gcc-a20c5714c689bf1c0c7a2d2589b4df0eaa4635fb.tar.gz
gcc-a20c5714c689bf1c0c7a2d2589b4df0eaa4635fb.tar.bz2
poly_int: argument sizes
This patch changes various bits of state related to argument sizes so that they have type poly_int64 rather than HOST_WIDE_INT. This includes: - incoming_args::pops_args and incoming_args::size - rtl_data::outgoing_args_size - pending_stack_adjust - stack_pointer_delta - stack_usage::pushed_stack_size - args_size::constant It also changes TARGET_RETURN_POPS_ARGS so that the size of the arguments passed in and the size returned by the hook are both poly_int64s. 2017-12-21 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * target.def (return_pops_args): Treat both the input and output sizes as poly_int64s rather than HOST_WIDE_INTS. * targhooks.h (default_return_pops_args): Update accordingly. * targhooks.c (default_return_pops_args): Likewise. * doc/tm.texi: Regenerate. * emit-rtl.h (incoming_args): Change pops_args, size and outgoing_args_size from int to poly_int64_pod. * function.h (expr_status): Change x_pending_stack_adjust and x_stack_pointer_delta from int to poly_int64. (args_size::constant): Change from HOST_WIDE_INT to poly_int64. (ARGS_SIZE_RTX): Update accordingly. * calls.c (highest_outgoing_arg_in_use): Change from int to unsigned int. (stack_usage_watermark, stored_args_watermark): New variables. (stack_region_maybe_used_p, mark_stack_region_used): New functions. (emit_call_1): Change the stack_size and rounded_stack_size parameters from HOST_WIDE_INT to poly_int64. Track n_popped as a poly_int64. (save_fixed_argument_area): Check stack_usage_watermark. (initialize_argument_information): Change old_pending_adj from a HOST_WIDE_INT * to a poly_int64_pod *. (compute_argument_block_size): Return the size as a poly_int64 rather than an int. (finalize_must_preallocate): Track polynomial argument sizes. (compute_argument_addresses): Likewise. (internal_arg_pointer_based_exp): Track polynomial offsets. (mem_overlaps_already_clobbered_arg_p): Rename to... (mem_might_overlap_already_clobbered_arg_p): ...this and take the size as a poly_uint64 rather than an unsigned HOST_WIDE_INT. Check stored_args_used_watermark. (load_register_parameters): Update accordingly. (check_sibcall_argument_overlap_1): Likewise. (combine_pending_stack_adjustment_and_call): Take the unadjusted args size as a poly_int64 rather than an int. Return a bool indicating whether the optimization was possible and return the new adjustment by reference. (check_sibcall_argument_overlap): Track polynomail argument sizes. Update stored_args_watermark. (can_implement_as_sibling_call_p): Handle polynomial argument sizes. (expand_call): Likewise. Maintain stack_usage_watermark and stored_args_watermark. Update calls to combine_pending_stack_adjustment_and_call. (emit_library_call_value_1): Handle polynomial argument sizes. Call stack_region_maybe_used_p and mark_stack_region_used. Maintain stack_usage_watermark. (store_one_arg): Likewise. Update call to mem_overlaps_already_clobbered_arg_p. * config/arm/arm.c (arm_output_function_prologue): Add a cast to HOST_WIDE_INT. * config/avr/avr.c (avr_outgoing_args_size): Likewise. * config/microblaze/microblaze.c (microblaze_function_prologue): Likewise. * config/cr16/cr16.c (cr16_return_pops_args): Update for new TARGET_RETURN_POPS_ARGS interface. (cr16_compute_frame, cr16_initial_elimination_offset): Add casts to HOST_WIDE_INT. * config/ft32/ft32.c (ft32_compute_frame): Likewise. * config/i386/i386.c (ix86_return_pops_args): Update for new TARGET_RETURN_POPS_ARGS interface. (ix86_expand_split_stack_prologue): Add a cast to HOST_WIDE_INT. * config/moxie/moxie.c (moxie_compute_frame): Likewise. * config/m68k/m68k.c (m68k_return_pops_args): Update for new TARGET_RETURN_POPS_ARGS interface. * config/vax/vax.c (vax_return_pops_args): Likewise. * config/pa/pa.h (STACK_POINTER_OFFSET): Add a cast to poly_int64. (EXIT_IGNORE_STACK): Update reference to crtl->outgoing_args_size. * config/arm/arm.h (CALLER_INTERWORKING_SLOT_SIZE): Likewise. * config/powerpcspe/aix.h (STACK_DYNAMIC_OFFSET): Likewise. * config/powerpcspe/darwin.h (STACK_DYNAMIC_OFFSET): Likewise. * config/powerpcspe/powerpcspe.h (STACK_DYNAMIC_OFFSET): Likewise. * config/rs6000/aix.h (STACK_DYNAMIC_OFFSET): Likewise. * config/rs6000/darwin.h (STACK_DYNAMIC_OFFSET): Likewise. * config/rs6000/rs6000.h (STACK_DYNAMIC_OFFSET): Likewise. * dojump.h (saved_pending_stack_adjust): Change x_pending_stack_adjust and x_stack_pointer_delta from int to poly_int64. * dojump.c (do_pending_stack_adjust): Update accordingly. * explow.c (allocate_dynamic_stack_space): Handle polynomial stack_pointer_deltas. * function.c (STACK_DYNAMIC_OFFSET): Add a cast to poly_int64. (pad_to_arg_alignment): Track polynomial offsets. (assign_parm_find_stack_rtl): Likewise. (assign_parms, locate_and_pad_parm): Handle polynomial argument sizes. * toplev.c (output_stack_usage): Update reference to current_function_pushed_stack_size. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r255921
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/gcc/function.c b/gcc/function.c
index e479b1e..c752062 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1407,7 +1407,7 @@ static poly_int64 cfa_offset;
: 0) + (STACK_POINTER_OFFSET))
#else
#define STACK_DYNAMIC_OFFSET(FNDECL) \
-((ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0) \
+ ((ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : poly_int64 (0)) \
+ (STACK_POINTER_OFFSET))
#endif
#endif
@@ -2727,12 +2727,15 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
is TARGET_FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're
intentionally forcing upward padding. Otherwise we have to come
up with a guess at the alignment based on OFFSET_RTX. */
+ poly_int64 offset;
if (data->locate.where_pad != PAD_DOWNWARD || data->entry_parm)
align = boundary;
- else if (CONST_INT_P (offset_rtx))
+ else if (poly_int_rtx_p (offset_rtx, &offset))
{
- align = INTVAL (offset_rtx) * BITS_PER_UNIT | boundary;
- align = least_bit_hwi (align);
+ align = least_bit_hwi (boundary);
+ unsigned int offset_align = known_alignment (offset) * BITS_PER_UNIT;
+ if (offset_align != 0)
+ align = MIN (align, offset_align);
}
set_mem_align (stack_parm, align);
@@ -3894,14 +3897,15 @@ assign_parms (tree fndecl)
/* Adjust function incoming argument size for alignment and
minimum length. */
- crtl->args.size = MAX (crtl->args.size, all.reg_parm_stack_space);
- crtl->args.size = CEIL_ROUND (crtl->args.size,
- PARM_BOUNDARY / BITS_PER_UNIT);
+ crtl->args.size = upper_bound (crtl->args.size, all.reg_parm_stack_space);
+ crtl->args.size = aligned_upper_bound (crtl->args.size,
+ PARM_BOUNDARY / BITS_PER_UNIT);
if (ARGS_GROW_DOWNWARD)
{
crtl->args.arg_offset_rtx
- = (all.stack_args_size.var == 0 ? GEN_INT (-all.stack_args_size.constant)
+ = (all.stack_args_size.var == 0
+ ? gen_int_mode (-all.stack_args_size.constant, Pmode)
: expand_expr (size_diffop (all.stack_args_size.var,
size_int (-all.stack_args_size.constant)),
NULL_RTX, VOIDmode, EXPAND_NORMAL));
@@ -4141,15 +4145,19 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
{
if (reg_parm_stack_space > 0)
{
- if (initial_offset_ptr->var)
+ if (initial_offset_ptr->var
+ || !ordered_p (initial_offset_ptr->constant,
+ reg_parm_stack_space))
{
initial_offset_ptr->var
= size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
ssize_int (reg_parm_stack_space));
initial_offset_ptr->constant = 0;
}
- else if (initial_offset_ptr->constant < reg_parm_stack_space)
- initial_offset_ptr->constant = reg_parm_stack_space;
+ else
+ initial_offset_ptr->constant
+ = ordered_max (initial_offset_ptr->constant,
+ reg_parm_stack_space);
}
}
@@ -4276,9 +4284,9 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
struct args_size *alignment_pad)
{
tree save_var = NULL_TREE;
- HOST_WIDE_INT save_constant = 0;
+ poly_int64 save_constant = 0;
int boundary_in_bytes = boundary / BITS_PER_UNIT;
- HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET;
+ poly_int64 sp_offset = STACK_POINTER_OFFSET;
#ifdef SPARC_STACK_BOUNDARY_HACK
/* ??? The SPARC port may claim a STACK_BOUNDARY higher than
@@ -4299,7 +4307,10 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
if (boundary > BITS_PER_UNIT)
{
- if (offset_ptr->var)
+ int misalign;
+ if (offset_ptr->var
+ || !known_misalignment (offset_ptr->constant + sp_offset,
+ boundary_in_bytes, &misalign))
{
tree sp_offset_tree = ssize_int (sp_offset);
tree offset = size_binop (PLUS_EXPR,
@@ -4320,13 +4331,13 @@ pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
}
else
{
- offset_ptr->constant = -sp_offset +
- (ARGS_GROW_DOWNWARD
- ? FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes)
- : CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes));
+ if (ARGS_GROW_DOWNWARD)
+ offset_ptr->constant -= misalign;
+ else
+ offset_ptr->constant += -misalign & (boundary_in_bytes - 1);
- if (boundary > PARM_BOUNDARY)
- alignment_pad->constant = offset_ptr->constant - save_constant;
+ if (boundary > PARM_BOUNDARY)
+ alignment_pad->constant = offset_ptr->constant - save_constant;
}
}
}