aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-21 06:58:16 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-21 06:58:16 +0000
commitf075bd950c5ad3e2baeb3d8f82fe962efc8e4f7a (patch)
tree8b895dc76d9b5a9544b28dcb10c3ac925ccea4dd /gcc/cfgexpand.c
parent7ee216163faf80d2a55f1c08abb971b7da34a793 (diff)
downloadgcc-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.c64
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;