diff options
author | Richard Henderson <rth@redhat.com> | 2012-08-02 20:28:36 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2012-08-02 20:28:36 -0700 |
commit | 34831f3e27748ea41fe976de0e9a2ead29059878 (patch) | |
tree | b5d9d7cd2065f71046fd8b930903596b2c603b72 /gcc/explow.c | |
parent | 6e48db73ed88eeb3e1025b28aa49c4f5ee4f3a76 (diff) | |
download | gcc-34831f3e27748ea41fe976de0e9a2ead29059878.zip gcc-34831f3e27748ea41fe976de0e9a2ead29059878.tar.gz gcc-34831f3e27748ea41fe976de0e9a2ead29059878.tar.bz2 |
Revert "PR 34548"
This reverts commit 190051.
From-SVN: r190110
Diffstat (limited to 'gcc/explow.c')
-rw-r--r-- | gcc/explow.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/gcc/explow.c b/gcc/explow.c index c7581b0..1cfe93b 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -1173,6 +1173,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align, { HOST_WIDE_INT stack_usage_size = -1; rtx final_label, final_target, target; + unsigned extra_align = 0; bool must_align; /* If we're asking for zero bytes, it doesn't matter what we point @@ -1236,40 +1237,58 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align, else if (size_align < BITS_PER_UNIT) size_align = BITS_PER_UNIT; + /* We can't attempt to minimize alignment necessary, because we don't + know the final value of preferred_stack_boundary yet while executing + this code. */ + if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY) + crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; + /* We will need to ensure that the address we return is aligned to - REQUIRED_ALIGN. If that alignment is no larger than - PREFERRED_STACK_BOUNDARY, we can handle everything without an - explicit alignment. */ - if (required_align <= PREFERRED_STACK_BOUNDARY) + REQUIRED_ALIGN. If STACK_DYNAMIC_OFFSET is defined, we don't + always know its final value at this point in the compilation (it + might depend on the size of the outgoing parameter lists, for + example), so we must align the value to be returned in that case. + (Note that STACK_DYNAMIC_OFFSET will have a default nonzero value if + STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined). + We must also do an alignment operation on the returned value if + the stack pointer alignment is less strict than REQUIRED_ALIGN. + + If we have to align, we must leave space in SIZE for the hole + that might result from the alignment operation. */ + + must_align = (crtl->preferred_stack_boundary < required_align); + if (must_align) { - if (crtl->preferred_stack_boundary < required_align) - crtl->preferred_stack_boundary = required_align; - if (crtl->max_dynamic_stack_alignment < required_align) - crtl->max_dynamic_stack_alignment = required_align; - must_align = false; + if (required_align > PREFERRED_STACK_BOUNDARY) + extra_align = PREFERRED_STACK_BOUNDARY; + else if (required_align > STACK_BOUNDARY) + extra_align = STACK_BOUNDARY; + else + extra_align = BITS_PER_UNIT; } - else - { - unsigned extra, extra_align; - crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; - crtl->max_dynamic_stack_alignment = PREFERRED_STACK_BOUNDARY; + /* ??? STACK_POINTER_OFFSET is always defined now. */ +#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET) + must_align = true; + extra_align = BITS_PER_UNIT; +#endif - extra_align = PREFERRED_STACK_BOUNDARY; - extra = (required_align - extra_align) / BITS_PER_UNIT; + if (must_align) + { + unsigned extra = (required_align - extra_align) / BITS_PER_UNIT; size = plus_constant (Pmode, size, extra); size = force_operand (size, NULL_RTX); if (flag_stack_usage_info) stack_usage_size += extra; + if (extra && size_align > extra_align) size_align = extra_align; - must_align = true; } /* Round the size to a multiple of the required stack alignment. - Since the stack is presumed to be rounded before this allocation, + Since the stack if presumed to be rounded before this allocation, this will maintain the required alignment. If the stack grows downward, we could save an insn by subtracting |