This is the mail archive of the gcc@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]

FRAME_GROWS_DOWNWARD and expand_stack_vars


I am working on FRAME_GROWS_DOWNWARD for MIPS and I am seeing two performance
issues with the code generated.  The first one has to do with the order how
expand_stack_vars places locals on the stack.

Consider this function (simplified from CSiBE's
replaypc-0.4.0.preproc:find-GOPs):

  f ()
  {
    char buf[32768];
    int i;
    g (&buf, &i);
  }

expand_stack_vars allocates variables in increasing order of their size.  So
with !FRAME_GROWS_DOWNWARD smaller variables are closer to the stack pointer
making it more likely that they can be accesses with base + offset addressing.

With FRAME_GROWS_DOWNWARD the opposite happens so computing the address of
variable i now takes multiple instructions.

To fix this we can change the allocation with FRAME_GROWS_DOWNWARD (see the
patch below).  However, I can see that on some targets for example if the hard
frame pointer is used and it points somewhere above or at the local variables
(unlike on MIPS) then you'd still want the original order.  So maybe this
should really be controlled by another backend knob.

Comments?

Adam

        * cfgexpand.c (expand_stack_vars): Expand variables in decreasing
        order of their size if FRAME_GROWS_DOWNWARD.

Index: cfgexpand.c
===================================================================
--- cfgexpand.c	(revision 142249)
+++ cfgexpand.c	(working copy)
@@ -901,7 +901,13 @@ expand_stack_vars (bool (*pred) (tree))
     {
       HOST_WIDE_INT offset;
 
-      i = stack_vars_sorted[si];
+      /* If the frame grows downward allocate larger object first, away from
+	 the stack pointer.  We have a better chance this way to access more
+	 locals with base + offset addressing.  */
+      if (FRAME_GROWS_DOWNWARD)
+	i = stack_vars_sorted[n - 1 - si];
+      else
+	i = stack_vars_sorted[si];
 
       /* Skip variables that aren't partition representatives, for now.  */
       if (stack_vars[i].representative != i)


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