Simplify frame layout for stack probing
authorWilco Dijkstra <wdijkstr@arm.com>
Thu, 26 Oct 2017 16:40:25 +0000 (16:40 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Thu, 26 Oct 2017 16:40:25 +0000 (16:40 +0000)
This patch makes some changes to the frame layout in order to simplify
stack probing.  We want to use the save of LR as a probe in any non-leaf
function.  With shrinkwrapping we may only save LR before a call, so it
is useful to define a fixed location in the callee-saves. So force LR at
the bottom of the callee-saves even with -fomit-frame-pointer.

Also remove a rarely used frame layout that saves the callee-saves first
with -fomit-frame-pointer.  Doing so allows the store of LR to be used as
a valid stack probe in all frames.

    gcc/
* config/aarch64/aarch64.c (aarch64_layout_frame):
        Ensure LR is always stored at the bottom of the callee-saves.
        Remove rarely used frame layout which saves callee-saves at top of
        frame, so the store of LR can be used as a valid probe in all cases.

From-SVN: r254112

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index 7e0417ba60ca72842b9093917e5417adb40c2945..f32a30b7730e195b39c741c5dd80b7ad418505a4 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-26  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_layout_frame):
+       Ensure LR is always stored at the bottom of the callee-saves.
+       Remove rarely used frame layout which saves callee-saves at top of
+       frame, so the store of LR can be used as a valid probe in all cases.
+
 2017-10-26  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_legitimize_address_displacement):
index 83630fce1cce85b4d5beece2fa303ab09b9ac4dd..ed97e2d5de11e34f8b724ca5fd29c426e296e883 100644 (file)
@@ -2885,7 +2885,8 @@ aarch64_frame_pointer_required (void)
 
 /* Mark the registers that need to be saved by the callee and calculate
    the size of the callee-saved registers area and frame record (both FP
-   and LR may be omitted).  */
+   and LR may be omitted).  If the function is not a leaf, ensure LR is
+   saved at the bottom of the callee-save area.  */
 static void
 aarch64_layout_frame (void)
 {
@@ -2936,7 +2937,14 @@ aarch64_layout_frame (void)
       cfun->machine->frame.wb_candidate1 = R29_REGNUM;
       cfun->machine->frame.reg_offset[R30_REGNUM] = UNITS_PER_WORD;
       cfun->machine->frame.wb_candidate2 = R30_REGNUM;
-      offset += 2 * UNITS_PER_WORD;
+      offset = 2 * UNITS_PER_WORD;
+    }
+  else if (!crtl->is_leaf)
+    {
+      /* Ensure LR is saved at the bottom of the callee-saves.  */
+      cfun->machine->frame.reg_offset[R30_REGNUM] = 0;
+      cfun->machine->frame.wb_candidate1 = R30_REGNUM;
+      offset = UNITS_PER_WORD;
     }
 
   /* Now assign stack slots for them.  */
@@ -3035,20 +3043,6 @@ aarch64_layout_frame (void)
       cfun->machine->frame.final_adjust
        = cfun->machine->frame.frame_size - cfun->machine->frame.callee_adjust;
     }
-  else if (!frame_pointer_needed
-          && varargs_and_saved_regs_size < max_push_offset)
-    {
-      /* Frame with large local area and outgoing arguments (this pushes the
-        callee-saves first, followed by the locals and outgoing area):
-        stp reg1, reg2, [sp, -varargs_and_saved_regs_size]!
-        stp reg3, reg4, [sp, 16]
-        sub sp, sp, frame_size - varargs_and_saved_regs_size  */
-      cfun->machine->frame.callee_adjust = varargs_and_saved_regs_size;
-      cfun->machine->frame.final_adjust
-       = cfun->machine->frame.frame_size - cfun->machine->frame.callee_adjust;
-      cfun->machine->frame.hard_fp_offset = cfun->machine->frame.callee_adjust;
-      cfun->machine->frame.locals_offset = cfun->machine->frame.hard_fp_offset;
-    }
   else
     {
       /* Frame with large local area and outgoing arguments using frame pointer: