diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-21 06:58:16 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-21 06:58:16 +0000 |
commit | f075bd950c5ad3e2baeb3d8f82fe962efc8e4f7a (patch) | |
tree | 8b895dc76d9b5a9544b28dcb10c3ac925ccea4dd /gcc/cfgexpand.c | |
parent | 7ee216163faf80d2a55f1c08abb971b7da34a793 (diff) | |
download | gcc-f075bd950c5ad3e2baeb3d8f82fe962efc8e4f7a.zip gcc-f075bd950c5ad3e2baeb3d8f82fe962efc8e4f7a.tar.gz gcc-f075bd950c5ad3e2baeb3d8f82fe962efc8e4f7a.tar.bz2 |
poly_int: frame allocations
This patch converts the frame allocation code (mostly in function.c)
to use poly_int64 rather than HOST_WIDE_INT for frame offsets and
sizes.
2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* function.h (frame_space): Change start and length from HOST_WIDE_INT
to poly_int64.
(get_frame_size): Return the size as a poly_int64 rather than a
HOST_WIDE_INT.
(frame_offset_overflow): Take the offset as a poly_int64 rather
than a HOST_WIDE_INT.
(assign_stack_local_1, assign_stack_local, assign_stack_temp_for_type)
(assign_stack_temp): Likewise for the size.
* function.c (get_frame_size): Return a poly_int64 rather than
a HOST_WIDE_INT.
(frame_offset_overflow): Take the offset as a poly_int64 rather
than a HOST_WIDE_INT.
(try_fit_stack_local): Take the start, length and size as poly_int64s
rather than HOST_WIDE_INTs. Return the offset as a poly_int64_pod
rather than a HOST_WIDE_INT.
(add_frame_space): Take the start and end as poly_int64s rather than
HOST_WIDE_INTs.
(assign_stack_local_1, assign_stack_local, assign_stack_temp_for_type)
(assign_stack_temp): Likewise for the size.
(temp_slot): Change size, base_offset and full_size from HOST_WIDE_INT
to poly_int64.
(find_temp_slot_from_address): Handle polynomial offsets.
(combine_temp_slots): Likewise.
* emit-rtl.h (rtl_data::x_frame_offset): Change from HOST_WIDE_INT
to poly_int64.
* cfgexpand.c (alloc_stack_frame_space): Return the offset as a
poly_int64 rather than a HOST_WIDE_INT.
(expand_one_stack_var_at): Take the offset as a poly_int64 rather
than a HOST_WIDE_INT.
(expand_stack_vars, expand_one_stack_var_1, expand_used_vars): Handle
polynomial frame offsets.
* config/m32r/m32r-protos.h (m32r_compute_frame_size): Take the size
as a poly_int64 rather than an int.
* config/m32r/m32r.c (m32r_compute_frame_size): Likewise.
* config/v850/v850-protos.h (compute_frame_size): Likewise.
* config/v850/v850.c (compute_frame_size): Likewise.
* config/xtensa/xtensa-protos.h (compute_frame_size): Likewise.
* config/xtensa/xtensa.c (compute_frame_size): Likewise.
* config/pa/pa-protos.h (pa_compute_frame_size): Likewise.
* config/pa/pa.c (pa_compute_frame_size): Likewise.
* explow.h (get_dynamic_stack_base): Take the offset as a poly_int64
rather than a HOST_WIDE_INT.
* explow.c (get_dynamic_stack_base): Likewise.
* final.c (final_start_function): Use the constant lower bound
of the frame size for -Wframe-larger-than.
* ira.c (do_reload): Adjust for new get_frame_size return type.
* lra.c (lra): Likewise.
* reload1.c (reload): Likewise.
* config/avr/avr.c (avr_asm_function_end_prologue): Likewise.
* config/pa/pa.h (EXIT_IGNORE_STACK): Likewise.
* rtlanal.c (get_initial_register_offset): Return the offset as
a poly_int64 rather than a HOST_WIDE_INT.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255917
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index e616ec1..32c48ac 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -389,22 +389,23 @@ align_base (HOST_WIDE_INT base, unsigned HOST_WIDE_INT align, bool align_up) /* Allocate SIZE bytes at byte alignment ALIGN from the stack frame. Return the frame offset. */ -static HOST_WIDE_INT +static poly_int64 alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align) { - HOST_WIDE_INT offset, new_frame_offset; + poly_int64 offset, new_frame_offset; if (FRAME_GROWS_DOWNWARD) { new_frame_offset - = align_base (frame_offset - frame_phase - size, - align, false) + frame_phase; + = aligned_lower_bound (frame_offset - frame_phase - size, + align) + frame_phase; offset = new_frame_offset; } else { new_frame_offset - = align_base (frame_offset - frame_phase, align, true) + frame_phase; + = aligned_upper_bound (frame_offset - frame_phase, + align) + frame_phase; offset = new_frame_offset; new_frame_offset += size; } @@ -980,13 +981,13 @@ dump_stack_var_partition (void) static void expand_one_stack_var_at (tree decl, rtx base, unsigned base_align, - HOST_WIDE_INT offset) + poly_int64 offset) { unsigned align; rtx x; /* If this fails, we've overflowed the stack frame. Error nicely? */ - gcc_assert (offset == trunc_int_for_mode (offset, Pmode)); + gcc_assert (known_eq (offset, trunc_int_for_mode (offset, Pmode))); x = plus_constant (Pmode, base, offset); x = gen_rtx_MEM (TREE_CODE (decl) == SSA_NAME @@ -1000,7 +1001,7 @@ expand_one_stack_var_at (tree decl, rtx base, unsigned base_align, important, we'll simply use the alignment that is already set. */ if (base == virtual_stack_vars_rtx) offset -= frame_phase; - align = least_bit_hwi (offset); + align = known_alignment (offset); align *= BITS_PER_UNIT; if (align == 0 || align > base_align) align = base_align; @@ -1094,7 +1095,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) { rtx base; unsigned base_align, alignb; - HOST_WIDE_INT offset; + poly_int64 offset; i = stack_vars_sorted[si]; @@ -1119,13 +1120,16 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT) { base = virtual_stack_vars_rtx; - if ((asan_sanitize_stack_p ()) - && pred) + /* ASAN description strings don't yet have a syntax for expressing + polynomial offsets. */ + HOST_WIDE_INT prev_offset; + if (asan_sanitize_stack_p () + && pred + && frame_offset.is_constant (&prev_offset)) { - HOST_WIDE_INT prev_offset - = align_base (frame_offset, - MAX (alignb, ASAN_RED_ZONE_SIZE), - !FRAME_GROWS_DOWNWARD); + prev_offset = align_base (prev_offset, + MAX (alignb, ASAN_RED_ZONE_SIZE), + !FRAME_GROWS_DOWNWARD); tree repr_decl = NULL_TREE; offset = alloc_stack_frame_space (stack_vars[i].size @@ -1133,7 +1137,10 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) MAX (alignb, ASAN_RED_ZONE_SIZE)); data->asan_vec.safe_push (prev_offset); - data->asan_vec.safe_push (offset + stack_vars[i].size); + /* Allocating a constant amount of space from a constant + starting offset must give a constant result. */ + data->asan_vec.safe_push ((offset + stack_vars[i].size) + .to_constant ()); /* Find best representative of the partition. Prefer those with DECL_NAME, even better satisfying asan_protect_stack_decl predicate. */ @@ -1179,7 +1186,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) space. */ if (large_size > 0 && ! large_allocation_done) { - HOST_WIDE_INT loffset; + poly_int64 loffset; rtx large_allocsize; large_allocsize = GEN_INT (large_size); @@ -1282,7 +1289,8 @@ set_parm_rtl (tree parm, rtx x) static void expand_one_stack_var_1 (tree var) { - HOST_WIDE_INT size, offset; + HOST_WIDE_INT size; + poly_int64 offset; unsigned byte_align; if (TREE_CODE (var) == SSA_NAME) @@ -2218,9 +2226,12 @@ expand_used_vars (void) in addition to phase 1 and 2. */ expand_stack_vars (asan_decl_phase_3, &data); - if (!data.asan_vec.is_empty ()) + /* ASAN description strings don't yet have a syntax for expressing + polynomial offsets. */ + HOST_WIDE_INT prev_offset; + if (!data.asan_vec.is_empty () + && frame_offset.is_constant (&prev_offset)) { - HOST_WIDE_INT prev_offset = frame_offset; HOST_WIDE_INT offset, sz, redzonesz; redzonesz = ASAN_RED_ZONE_SIZE; sz = data.asan_vec[0] - prev_offset; @@ -2229,8 +2240,10 @@ expand_used_vars (void) && sz + ASAN_RED_ZONE_SIZE >= (int) data.asan_alignb) redzonesz = ((sz + ASAN_RED_ZONE_SIZE + data.asan_alignb - 1) & ~(data.asan_alignb - HOST_WIDE_INT_1)) - sz; - offset - = alloc_stack_frame_space (redzonesz, ASAN_RED_ZONE_SIZE); + /* Allocating a constant amount of space from a constant + starting offset must give a constant result. */ + offset = (alloc_stack_frame_space (redzonesz, ASAN_RED_ZONE_SIZE) + .to_constant ()); data.asan_vec.safe_push (prev_offset); data.asan_vec.safe_push (offset); /* Leave space for alignment if STRICT_ALIGNMENT. */ @@ -2275,9 +2288,10 @@ expand_used_vars (void) if (STACK_ALIGNMENT_NEEDED) { HOST_WIDE_INT align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; - if (!FRAME_GROWS_DOWNWARD) - frame_offset += align - 1; - frame_offset &= -align; + if (FRAME_GROWS_DOWNWARD) + frame_offset = aligned_lower_bound (frame_offset, align); + else + frame_offset = aligned_upper_bound (frame_offset, align); } return var_end_seq; |