diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-21 07:01:00 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-21 07:01:00 +0000 |
commit | a20c5714c689bf1c0c7a2d2589b4df0eaa4635fb (patch) | |
tree | 69d2a02e7942089893a7b94124db1ea69c6816a0 /gcc/function.c | |
parent | e6715081eddeb808bc2c8f2fa84b2f436d86a0e5 (diff) | |
download | gcc-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.c | 51 |
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; } } } |