Patchwork [AArch64] Make omit-frame-pointer work correctly

login
register
mail settings
Submitter Ian Bolton
Date March 28, 2013, 5:55 p.m.
Message ID <000001ce2bdd$80cf0220$826d0660$@bolton@arm.com>
Download mbox | patch
Permalink /patch/232156/
State New
Headers show

Comments

Ian Bolton - March 28, 2013, 5:55 p.m.
Currently, if you compile with -fomit-frame-pointer, the frame record
and frame pointer are still maintained (i.e. There is no way to get
the behaviour you are asking for!).

This patch fixes that.  It also makes sure that if you ask for no frame
pointers in leaf functions then they are not generated there unless LR
gets clobbered in the leaf for some reason.  (I have testcases here to
check for that.)

OK to commit to trunk?

Cheers,
Ian



2013-03-28  Ian Bolton  <ian.bolton@arm.com>

gcc/
        * config/aarch64/aarch64.md (aarch64_can_eliminate): Only keep
        frame record when required.

testsuite/
        * gcc.target/aarch64/inc/asm-adder-clobber-lr.c: New test.
        * gcc.target/aarch64/inc/asm-adder-no-clobber-lr.c: Likewise.
        * gcc.target/aarch64/test-framepointer-1.c: Likewise.
        * gcc.target/aarch64/test-framepointer-2.c: Likewise.
        * gcc.target/aarch64/test-framepointer-3.c: Likewise.
        * gcc.target/aarch64/test-framepointer-4.c: Likewise.
        * gcc.target/aarch64/test-framepointer-5.c: Likewise.
        * gcc.target/aarch64/test-framepointer-6.c: Likewise.
        * gcc.target/aarch64/test-framepointer-7.c: Likewise.
        * gcc.target/aarch64/test-framepointer-8.c: Likewise.
Marcus Shawcroft - March 28, 2013, 6:38 p.m.
On 28/03/13 17:55, Ian Bolton wrote:
> Currently, if you compile with -fomit-frame-pointer, the frame record
> and frame pointer are still maintained (i.e. There is no way to get
> the behaviour you are asking for!).
>
> This patch fixes that.  It also makes sure that if you ask for no frame
> pointers in leaf functions then they are not generated there unless LR
> gets clobbered in the leaf for some reason.  (I have testcases here to
> check for that.)
>
> OK to commit to trunk?
>
> Cheers,
> Ian
>
>
>
> 2013-03-28  Ian Bolton  <ian.bolton@arm.com>
>
> gcc/
>          * config/aarch64/aarch64.md (aarch64_can_eliminate): Only keep
>          frame record when required.
>
> testsuite/
>          * gcc.target/aarch64/inc/asm-adder-clobber-lr.c: New test.
>          * gcc.target/aarch64/inc/asm-adder-no-clobber-lr.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-1.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-2.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-3.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-4.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-5.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-6.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-7.c: Likewise.
>          * gcc.target/aarch64/test-framepointer-8.c: Likewise.
>

OK
/Marcus

Patch

Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-2.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-no-clobber-lr.c"
+
+/* omit-frame-pointer is TRUE.
+   omit-leaf-frame-pointer is false, but irrelevant due to omit-frame-pointer.
+   LR is not being clobbered in the leaf.
+
+   Since we asked to have no frame pointers anywhere, we expect no frame
+   record in main or the leaf.  */
+
+/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-6.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-clobber-lr.c"
+
+/* omit-frame-pointer is TRUE.
+   omit-leaf-frame-pointer is false, but irrelevant due to omit-frame-pointer.
+   LR is being clobbered in the leaf.
+
+   Since we asked to have no frame pointers anywhere, we expect no frame
+   record in main or the leaf.  */
+
+/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-3.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-no-clobber-lr.c"
+
+/* omit-frame-pointer is TRUE.
+   omit-leaf-frame-pointer is true, but irrelevant due to omit-frame-pointer.
+   LR is not being clobbered in the leaf.
+
+   Since we asked to have no frame pointers anywhere, we expect no frame
+   record in main or the leaf.  */
+
+/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-7.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-clobber-lr.c"
+
+/* omit-frame-pointer is TRUE.
+   omit-leaf-frame-pointer is true, but irrelevant due to omit-frame-pointer.
+   LR is being clobbered in the leaf.
+
+   Since we asked to have no frame pointers anywhere, we expect no frame
+   record in main or the leaf.  */
+
+/* { dg-final { scan-assembler-not "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/asm-adder-clobber-lr.c	(revision 0)
@@ -0,0 +1,24 @@ 
+extern void abort (void);
+
+int
+adder (int a, int b)
+{
+  int result;
+  __asm__ ("add %w0,%w1,%w2" : "=r"(result) : "r"(a), "r"(b) : "x30");
+  return result;
+}
+
+int
+main (int argc, char** argv)
+{
+  int i;
+  int total = argc;
+  for (i = 0; i < 20; i++)
+    total = adder (total, i);
+
+  if (total != (190 + argc))
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-4.c	(revision 0)
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-no-clobber-lr.c"
+
+/* omit-frame-pointer is FALSE.
+   omit-leaf-frame-pointer is TRUE.
+   LR is not being clobbered in the leaf.
+
+   Unless we are removing all frame records, it's OK to remove the frame
+   record for a leaf where LR is not clobbered.  Therefore, we expect a
+   frame record only in main.  */
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-8.c	(revision 0)
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-clobber-lr.c"
+
+/* omit-frame-pointer is FALSE.
+   omit-leaf-frame-pointer is TRUE.
+   LR is being clobbered in the leaf.
+
+   Unless we are removing all frame records (which we aren't), it's
+   not OK to remove the frame record for a leaf where LR is clobbered.
+   Therefore, we expect a frame record in main and leaf.  */
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-1.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-no-clobber-lr.c"
+
+/* omit-frame-pointer is FALSE.
+   omit-leaf-frame-pointer is FALSE.
+   LR is not being clobbered in the leaf.
+
+   With no frame pointer omissions, we expect a frame record
+   for main and the leaf.  */
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/test-framepointer-5.c	(revision 0)
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-inline --save-temps" } */
+
+#include "asm-adder-clobber-lr.c"
+
+/* omit-frame-pointer is FALSE.
+   omit-leaf-frame-pointer is FALSE.
+   LR is being clobbered in the leaf.
+
+   With no frame pointer omissions, we expect a frame record for main
+   and the leaf.  */
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
Index: gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c	(revision 0)
+++ gcc/testsuite/gcc.target/aarch64/asm-adder-no-clobber-lr.c	(revision 0)
@@ -0,0 +1,24 @@ 
+extern void abort (void);
+
+int
+adder (int a, int b)
+{
+  int result;
+  __asm__ ("add %w0,%w1,%w2" : "=r"(result) : "r"(a), "r"(b) : );
+  return result;
+}
+
+int
+main (int argc, char** argv)
+{
+  int i;
+  int total = argc;
+  for (i = 0; i < 20; i++)
+    total = adder (total, i);
+
+  if (total != (190 + argc))
+    abort ();
+
+  return 0;
+}
+
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	(revision 197202)
+++ gcc/config/aarch64/aarch64.c	(working copy)
@@ -3879,14 +3879,21 @@  aarch64_can_eliminate (const int from, c
     }
   else
     {
-      /* If we decided that we didn't need a frame pointer but then used
-	 LR in the function, then we do need a frame pointer after all, so
-	 prevent this elimination to ensure a frame pointer is used.  */
-
+      /* If we decided that we didn't need a leaf frame pointer but then used
+	 LR in the function, then we'll want a frame pointer after all, so
+	 prevent this elimination to ensure a frame pointer is used.
+
+	 NOTE: the original value of flag_omit_frame_pointer gets trashed
+	 IFF flag_omit_leaf_frame_pointer is true, so we check the value
+	 of faked_omit_frame_pointer here (which is true when we always
+	 wish to keep non-leaf frame pointers but only wish to keep leaf frame
+	 pointers when LR is clobbered).  */
       if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM
-	  && df_regs_ever_live_p (LR_REGNUM))
+	  && df_regs_ever_live_p (LR_REGNUM)
+	  && faked_omit_frame_pointer)
 	return false;
     }
+
   return true;
 }