This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Reload & stack alignments


This bug concerns things like leaf functions that allocate unnecessary stack frames. For instance, on rs6000 with -maltivec:
void Foo () {}
becomes:
Foo:
stwu 1,-16(1)
addi 1,1,16
blr


The reason turns out to be the alignment code in reload and powerpc's non-zero initial STARTING_FRAME_OFFSET value (because of RS6000_SAVE_AREA). The initial value is 64 bits (for non-aix, non-darwin ABIs). With -maltivec (or unconditionally with Vxworks) the stack alignment is 128 bits. Thus this bit of code in reload
/* Round size of stack frame to stack_alignment_needed. This
must be done here because the stack size may be a part of the
offset computation for register elimination, and there might
have been new stack slots created in the last iteration of
this loop. */
if (cfun->stack_alignment_needed)
assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
ends up allocating some stack frame.


AFAICT, there's no reason to align the stack at the beginning of reload's loop. It can be aligned at the end of the loop -- and then only need be when the current frame size is non-zero.

This patch does that, with the result that the above leaf function allocates no stack frame, and in general stack frames on rs6000 are 8 bytes smaller.

It seems to me that the real problem is that GCC doesn't track an 'alignment padding' slot that ideally would sit between the top of local variables and the bottom of the backend's spill slots. Instead it aligns those two regions separately, resulting in unnecessary padding. Fixing that looks to be involved :(

tested on rs6000-wrs-vxworks, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-12-18  Nathan Sidwell  <nathan@codesourcery.com>

	* reload1.c (reload): Realign stack after it changes size.

	* gcc.dg/rs6000-leaf.c: New.

Index: testsuite/gcc.dg/rs6000-leaf.c
===================================================================
--- testsuite/gcc.dg/rs6000-leaf.c	(revision 0)
+++ testsuite/gcc.dg/rs6000-leaf.c	(revision 0)
@@ -0,0 +1,8 @@
+/* { dg-do compile { target rs6000-*-* } }  */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "\tstwu 1,-\[0-9\]*(1)\n" } } */
+
+int Leaf (int i)
+{
+  return i + 1;
+}
Index: reload1.c
===================================================================
--- reload1.c	(revision 120001)
+++ reload1.c	(working copy)
@@ -888,16 +888,8 @@ reload (rtx first, int global)
     {
       int something_changed;
       int did_spill;
-
       HOST_WIDE_INT starting_frame_size;
 
-      /* Round size of stack frame to stack_alignment_needed.  This must be done
-	 here because the stack size may be a part of the offset computation
-	 for register elimination, and there might have been new stack slots
-	 created in the last iteration of this loop.  */
-      if (cfun->stack_alignment_needed)
-        assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
-
       starting_frame_size = get_frame_size ();
 
       set_initial_elim_offsets ();
@@ -964,6 +956,20 @@ reload (rtx first, int global)
       /* If we allocated another stack slot, redo elimination bookkeeping.  */
       if (starting_frame_size != get_frame_size ())
 	continue;
+      if (starting_frame_size && cfun->stack_alignment_needed)
+	{
+	  /* If we have a stack frame, we must align it now.  The
+	     stack size may be a part of the offset computation for
+	     register elimination.  So if this changes the stack size,
+	     then repeat the elimination bookkeeping.  We don't
+	     realign when there is no stack, as that will cause a
+	     stack frame when none is needed should
+	     STARTING_FRAME_OFFSET not be already aligned to
+	     STACK_BOUNDARY.  */
+	  assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
+	  if (starting_frame_size != get_frame_size ())
+	    continue;
+	}
 
       if (caller_save_needed)
 	{

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]