i386: Don't use frame pointer without stack access
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 10 Aug 2017 15:29:05 +0000 (15:29 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 10 Aug 2017 15:29:05 +0000 (08:29 -0700)
When there is no stack access, there is no need to use frame pointer
even if -fno-omit-frame-pointer is used and caller's frame pointer is
unchanged.

gcc/

PR target/81736
* config/i386/i386.c (ix86_finalize_stack_realign_flags): Renamed
to ...
(ix86_finalize_stack_frame_flags): This.  Also clear
frame_pointer_needed if -fno-omit-frame-pointer is used without
stack access.
(ix86_expand_prologue): Replace ix86_finalize_stack_realign_flags
with ix86_finalize_stack_frame_flags.
(ix86_expand_epilogue): Likewise.
(ix86_expand_split_stack_prologue): Likewise.
* doc/invoke.texi: Add a note for -fno-omit-frame-pointer.

gcc/testsuite/

PR target/81736
* gcc.target/i386/pr81736-1.c: New test.
* gcc.target/i386/pr81736-2.c: Likewise.
* gcc.target/i386/pr81736-3.c: Likewise.
* gcc.target/i386/pr81736-4.c: Likewise.
* gcc.target/i386/pr81736-5.c: Likewise.
* gcc.target/i386/pr81736-6.c: Likewise.
* gcc.target/i386/pr81736-7.c: Likewise.

From-SVN: r251028

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr81736-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr81736-7.c [new file with mode: 0644]

index 1694c21e4977f1bfd4fc976fdc54c70307442b4f..95d07f6de140bfa211564ff0f860b26e2fe8f4cf 100644 (file)
@@ -1,3 +1,17 @@
+2017-08-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/81736
+       * config/i386/i386.c (ix86_finalize_stack_realign_flags): Renamed
+       to ...
+       (ix86_finalize_stack_frame_flags): This.  Also clear
+       frame_pointer_needed if -fno-omit-frame-pointer is used without
+       stack access.
+       (ix86_expand_prologue): Replace ix86_finalize_stack_realign_flags
+       with ix86_finalize_stack_frame_flags.
+       (ix86_expand_epilogue): Likewise.
+       (ix86_expand_split_stack_prologue): Likewise.
+       * doc/invoke.texi: Add a note for -fno-omit-frame-pointer.
+
 2017-08-10  Martin Liska  <mliska@suse.cz>
 
        PR c++/81355
index 3f8519777f7c5eb6e0daf61534efadc373fe711f..85aa4d4fbf5b622223d4b8af6e593f321327291a 100644 (file)
@@ -14179,10 +14179,11 @@ output_probe_stack_range (rtx reg, rtx end)
   return "";
 }
 
-/* Finalize stack_realign_needed flag, which will guide prologue/epilogue
-   to be generated in correct form.  */
+/* Finalize stack_realign_needed and frame_pointer_needed flags, which
+   will guide prologue/epilogue to be generated in correct form.  */
+
 static void
-ix86_finalize_stack_realign_flags (void)
+ix86_finalize_stack_frame_flags (void)
 {
   /* Check if stack realign is really needed after reload, and
      stores result in cfun */
@@ -14205,13 +14206,13 @@ ix86_finalize_stack_realign_flags (void)
     }
 
   /* If the only reason for frame_pointer_needed is that we conservatively
-     assumed stack realignment might be needed, but in the end nothing that
-     needed the stack alignment had been spilled, clear frame_pointer_needed
-     and say we don't need stack realignment.  */
-  if (stack_realign
+     assumed stack realignment might be needed or -fno-omit-frame-pointer
+     is used, but in the end nothing that needed the stack alignment had
+     been spilled nor stack access, clear frame_pointer_needed and say we
+     don't need stack realignment.  */
+  if ((stack_realign || !flag_omit_frame_pointer)
       && frame_pointer_needed
       && crtl->is_leaf
-      && flag_omit_frame_pointer
       && crtl->sp_is_unchanging
       && !ix86_current_function_calls_tls_descriptor
       && !crtl->accesses_prior_frames
@@ -14402,7 +14403,7 @@ ix86_expand_prologue (void)
   if (ix86_function_naked (current_function_decl))
     return;
 
-  ix86_finalize_stack_realign_flags ();
+  ix86_finalize_stack_frame_flags ();
 
   /* DRAP should not coexist with stack_realign_fp */
   gcc_assert (!(crtl->drap_reg && stack_realign_fp));
@@ -15266,7 +15267,7 @@ ix86_expand_epilogue (int style)
       return;
     }
 
-  ix86_finalize_stack_realign_flags ();
+  ix86_finalize_stack_frame_flags ();
   frame = m->frame;
 
   m->fs.sp_realigned = stack_realign_fp;
@@ -15801,7 +15802,7 @@ ix86_expand_split_stack_prologue (void)
 
   gcc_assert (flag_split_stack && reload_completed);
 
-  ix86_finalize_stack_realign_flags ();
+  ix86_finalize_stack_frame_flags ();
   frame = cfun->machine->frame;
   allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
 
index cc0f5a00a4f25a43b11ef297a39554cfcf869c48..3753d8a992b3290b4a0884defe21858f94d0ba79 100644 (file)
@@ -7366,6 +7366,10 @@ size) for 32-bit GNU/Linux x86 and 32-bit Darwin x86 targets is
 @option{-fomit-frame-pointer}.  You can configure GCC with the
 @option{--enable-frame-pointer} configure option to change the default.
 
+Note that @option{-fno-omit-frame-pointer} doesn't force a new stack
+frame for all functions if it isn't otherwise needed, and hence doesn't
+guarantee a new frame pointer for all functions.
+
 Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
 
 @item -foptimize-sibling-calls
index ac131e5ba22ffc202f828e46cf70b939cdafb7a0..0c5ac58bdc9a32645d17ca40ca9f9020592562f9 100644 (file)
@@ -1,3 +1,14 @@
+2017-08-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/81736
+       * gcc.target/i386/pr81736-1.c: New test.
+       * gcc.target/i386/pr81736-2.c: Likewise.
+       * gcc.target/i386/pr81736-3.c: Likewise.
+       * gcc.target/i386/pr81736-4.c: Likewise.
+       * gcc.target/i386/pr81736-5.c: Likewise.
+       * gcc.target/i386/pr81736-6.c: Likewise.
+       * gcc.target/i386/pr81736-7.c: Likewise.
+
 2017-08-10  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * gcc.target/powerpc/fold-vec-msum-short.c: Fix typo.
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-1.c b/gcc/testsuite/gcc.target/i386/pr81736-1.c
new file mode 100644 (file)
index 0000000..92c7bc9
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+extern int i;
+
+int
+foo (void)
+{
+  return i;
+}
+
+/* No need to use a frame pointer.  */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-2.c b/gcc/testsuite/gcc.target/i386/pr81736-2.c
new file mode 100644 (file)
index 0000000..a372087
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+int
+#ifndef __x86_64__
+__attribute__((regparm(3)))
+#endif
+foo (int i)
+{
+  return i;
+}
+
+/* No need to use a frame pointer.  */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-3.c b/gcc/testsuite/gcc.target/i386/pr81736-3.c
new file mode 100644 (file)
index 0000000..c3bde7d
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+void
+foo (void)
+{
+  asm ("# " : : : "ebx");
+}
+
+/* Need to use a frame pointer.  */
+/* { dg-final { scan-assembler "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-4.c b/gcc/testsuite/gcc.target/i386/pr81736-4.c
new file mode 100644 (file)
index 0000000..25f5001
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+int
+foo (int i1, int i2, int i3, int i4, int i5, int i6, int i7)
+{
+  return i7;
+}
+
+/* Need to use a frame pointer.  */
+/* { dg-final { scan-assembler "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-5.c b/gcc/testsuite/gcc.target/i386/pr81736-5.c
new file mode 100644 (file)
index 0000000..e1602cf
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -mavx" } */
+
+typedef int v8si __attribute__ ((vector_size (32)));
+
+void
+#ifndef __x86_64__
+__attribute__((regparm(3)))
+#endif
+foo (v8si *out_start, v8si *out_end, v8si *regions)
+{
+  v8si base = regions[3];
+  *out_start = base;
+  *out_end = base;
+}
+
+/* No need to use a frame pointer.  */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */
+/* Verify no dynamic realignment is performed.  */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-6.c b/gcc/testsuite/gcc.target/i386/pr81736-6.c
new file mode 100644 (file)
index 0000000..6198574
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+struct foo
+{
+  int head;
+} a;
+
+int
+bar (void)
+{
+  return a.head != 0;
+}
+
+/* No need to use a frame pointer.  */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81736-7.c b/gcc/testsuite/gcc.target/i386/pr81736-7.c
new file mode 100644 (file)
index 0000000..f947886
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+extern int foo (void);
+
+int
+bar (void)
+{
+  return foo ();
+}
+
+/* No need to use a frame pointer.  */
+/* { dg-final { scan-assembler-not "%\[re\]bp" } } */