This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Stack alignment
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: rth at redhat dot com (Richard Henderson)
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Feb 2003 14:52:17 -0500 (EST)
- Subject: [PATCH]: Stack alignment
> > When STACK_BOUNDARY is set to 64, there is one fill word in the frame
> > as a result of the starting frame offset and the need to align it to a
> > STACK_BOUNDARY. If STACK_BOUNDARY were set to 512, we would have 15
> > fill words.
>
> Eh? Is the stack pointer aligned or not?
This turned out to be totally wrong. Here is the actual problem.
Reload aligns the stack in each iteration. It uses a default alignment
value of BIGGEST_ALIGNMENT. If STARTING_FRAME_OFFSET % BIGGEST_ALIGNMENT
is not zero, the rounding in assign_stack_temp_for_type will cause the
frame size to be non-zero. As a result, you will never have a non-empty
frame and code for doing the stack adjustments needs to be emitted in
the prologue and epilogue.
The enclosed patch changes assign_stack_temp_for_type to only do the
reload alignment when the current frame size is not zero. With this
fix, I can save eight bytes in the stack offset on the 64-bit PA ports.
It has been tested with no regressions on hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11.
Ok for trunk and 3.3? The reason for installing on 3.3 is that I
would like to revert the change that I made to STARTING_FRAME_OFFSET
on the 64-bit ports when I found that we never had a non-empty frame.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2003-02-17 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* function.c (assign_stack_temp_for_type): Don't create a non-zero
frame when doing a stack alignment if the current frame size is zero.
Index: function.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/function.c,v
retrieving revision 1.399
diff -u -3 -p -r1.399 function.c
--- function.c 1 Feb 2003 18:59:44 -0000 1.399
+++ function.c 17 Feb 2003 17:06:06 -0000
@@ -564,16 +564,28 @@ assign_stack_local_1 (mode, size, align,
frame_off = STARTING_FRAME_OFFSET % frame_alignment;
frame_phase = frame_off ? frame_alignment - frame_off : 0;
- /* Round frame offset to that alignment.
- We must be careful here, since FRAME_OFFSET might be negative and
- division with a negative dividend isn't as well defined as we might
- like. So we instead assume that ALIGNMENT is a power of two and
- use logical operations which are unambiguous. */
+ /* Round the frame offset to the specified alignment unless the
+ frame size is zero and this is a frame alignment request. When
+ STARTING_FRAME_OFFSET is non-zero, we don't want a frame alignment
+ request to create a frame if one doesn't already exist. */
+ if (function->x_frame_offset
+ || mode != BLKmode
+ || size != 0)
+ {
+ /* We must be careful here, since FRAME_OFFSET might be negative and
+ division with a negative dividend isn't as well defined as we might
+ like. So we instead assume that ALIGNMENT is a power of two and
+ use logical operations which are unambiguous. */
#ifdef FRAME_GROWS_DOWNWARD
- function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
+ function->x_frame_offset
+ = (FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment)
+ + frame_phase);
#else
- function->x_frame_offset = CEIL_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
+ function->x_frame_offset
+ = (CEIL_ROUND (function->x_frame_offset - frame_phase, alignment)
+ + frame_phase);
#endif
+ }
/* On a big-endian machine, if we are allocating more space than we will use,
use the least significant bytes of those that are allocated. */