re PR target/39137 (-mpreferred-stack-boundary=2 causes lots of dynamic realign)
authorJakub Jelinek <jakub@redhat.com>
Wed, 11 Mar 2009 21:12:33 +0000 (22:12 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 11 Mar 2009 21:12:33 +0000 (22:12 +0100)
PR target/39137
* cfgexpand.c (get_decl_align_unit): Use LOCAL_DECL_ALIGNMENT
macro.
* defaults.h (LOCAL_DECL_ALIGNMENT): Define if not yet defined.
* config/i386/i386.h (LOCAL_DECL_ALIGNMENT): Define.
* config/i386/i386.c (ix86_local_alignment): For
-m32 -mpreferred-stack-boundary=2 use 32-bit alignment for
long long variables on the stack to avoid dynamic realignment.
Allow the first argument to be a decl rather than type.
* doc/tm.texi (LOCAL_DECL_ALIGNMENT): Document.

* gcc.target/i386/stackalign/longlong-1.c: New test.
* gcc.target/i386/stackalign/longlong-2.c: New test.

From-SVN: r144792

gcc/ChangeLog
gcc/cfgexpand.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/stackalign/longlong-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/stackalign/longlong-2.c [new file with mode: 0644]

index 838bd3407bf2680862bb9c075a9d3fae26d0e2b0..c4cccf25b44ccc92c2f4da2901b9c6fc4c390ea1 100644 (file)
@@ -1,3 +1,16 @@
+2009-03-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/39137
+       * cfgexpand.c (get_decl_align_unit): Use LOCAL_DECL_ALIGNMENT
+       macro.
+       * defaults.h (LOCAL_DECL_ALIGNMENT): Define if not yet defined.
+       * config/i386/i386.h (LOCAL_DECL_ALIGNMENT): Define.
+       * config/i386/i386.c (ix86_local_alignment): For
+       -m32 -mpreferred-stack-boundary=2 use 32-bit alignment for
+       long long variables on the stack to avoid dynamic realignment.
+       Allow the first argument to be a decl rather than type.
+       * doc/tm.texi (LOCAL_DECL_ALIGNMENT): Document.
+
 2009-03-11  Nick Clifton  <nickc@redhat.com>
 
        PR target/5362
index c73bba7d9a9c0cf25366c5e8b15c07d8e600f5c8..4bfdc5fed74aaa3815e66cbf7ff2b33b33cd794d 100644 (file)
@@ -488,8 +488,7 @@ get_decl_align_unit (tree decl)
 {
   unsigned int align;
 
-  align = DECL_ALIGN (decl);
-  align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
+  align = LOCAL_DECL_ALIGNMENT (decl);
 
   if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
     align = MAX_SUPPORTED_STACK_ALIGNMENT;
index e7dd5bebaec72f31d44a005548956e386b3833ca..9a34912c313b3a3cb78fdee2bc6c314956c0bde8 100644 (file)
@@ -19347,15 +19347,39 @@ ix86_data_alignment (tree type, int align)
   return align;
 }
 
-/* Compute the alignment for a local variable or a stack slot.  TYPE is
-   the data type, MODE is the widest mode available and ALIGN is the
-   alignment that the object would ordinarily have.  The value of this
-   macro is used instead of that alignment to align the object.  */
+/* Compute the alignment for a local variable or a stack slot.  EXP is
+   the data type or decl itself, MODE is the widest mode available and
+   ALIGN is the alignment that the object would ordinarily have.  The
+   value of this macro is used instead of that alignment to align the
+   object.  */
 
 unsigned int
-ix86_local_alignment (tree type, enum machine_mode mode,
+ix86_local_alignment (tree exp, enum machine_mode mode,
                      unsigned int align)
 {
+  tree type, decl;
+
+  if (exp && DECL_P (exp))
+    {
+      type = TREE_TYPE (exp);
+      decl = exp;
+    }
+  else
+    {
+      type = exp;
+      decl = NULL;
+    }
+
+  /* Don't do dynamic stack realignment for long long objects with
+     -mpreferred-stack-boundary=2.  */
+  if (!TARGET_64BIT
+      && align == 64
+      && ix86_preferred_stack_boundary < 64
+      && (mode == DImode || (type && TYPE_MODE (type) == DImode))
+      && (!type || !TYPE_USER_ALIGN (type))
+      && (!decl || !DECL_USER_ALIGN (decl)))
+    align = 32;
+
   /* If TYPE is NULL, we are allocating a stack slot for caller-save
      register in MODE.  We will return the largest alignment of XF
      and DF.  */
index f2f4448d15e716fe97dc74462b4c517fd5ce9bd1..8035e84a2f82d67e68e10a6be9031ba6d606677a 100644 (file)
@@ -791,6 +791,19 @@ enum target_cpu_default
 #define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \
   ix86_local_alignment ((TYPE), (MODE), (ALIGN))
 
+/* If defined, a C expression to compute the alignment for a local
+   variable DECL.
+
+   If this macro is not defined, then
+   LOCAL_ALIGNMENT (TREE_TYPE (DECL), DECL_ALIGN (DECL)) will be used.
+
+   One use of this macro is to increase alignment of medium-size
+   data to make it all fit in fewer cache lines.  */
+
+#define LOCAL_DECL_ALIGNMENT(DECL) \
+  ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL))
+
+
 /* If defined, a C expression that gives the alignment boundary, in
    bits, of an argument with the specified mode and type.  If it is
    not defined, `PARM_BOUNDARY' is used for all arguments.  */
index fbb13accc0864103d53f7147273070f64890e2d4..217c0d94a56c43154f90ffe03a0b46724ac756df 100644 (file)
@@ -944,6 +944,11 @@ along with GCC; see the file COPYING3.  If not see
   ((TYPE) ? LOCAL_ALIGNMENT ((TYPE), (ALIGN)) : (ALIGN))
 #endif
 
+#ifndef LOCAL_DECL_ALIGNMENT
+#define LOCAL_DECL_ALIGNMENT(DECL) \
+  LOCAL_ALIGNMENT (TREE_TYPE (DECL), DECL_ALIGN (DECL))
+#endif
+
 /* Alignment value for attribute ((aligned)).  */
 #ifndef ATTRIBUTE_ALIGNED_VALUE
 #define ATTRIBUTE_ALIGNED_VALUE BIGGEST_ALIGNMENT
index b4fcc2de94db2085f108063621ec38658dc0e589..f4680b69391b4e5c6bea9bd5033fcfad585ffdb1 100644 (file)
@@ -1215,6 +1215,18 @@ This macro is to set alignment of stack slot to the maximum alignment
 of all possible modes which the slot may have.
 @end defmac
 
+@defmac LOCAL_DECL_ALIGNMENT (@var{decl})
+If defined, a C expression to compute the alignment for a local
+variable @var{decl}.
+
+If this macro is not defined, then
+@code{LOCAL_ALIGNMENT (TREE_TYPE (@var{decl}), DECL_ALIGN (@var{decl}))}
+is used.
+
+One use of this macro is to increase alignment of medium-size data to
+make it all fit in fewer cache lines.
+@end defmac
+
 @defmac EMPTY_FIELD_BOUNDARY
 Alignment in bits to be given to a structure bit-field that follows an
 empty field such as @code{int : 0;}.
index af958c33701e76e2e09a88e2c5a0762ba6a3b488..f8a7b2dc8c3bfe760fc57c994393e0c8f8a20e8c 100644 (file)
@@ -1,3 +1,9 @@
+2009-03-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/39137
+       * gcc.target/i386/stackalign/longlong-1.c: New test.
+       * gcc.target/i386/stackalign/longlong-2.c: New test.
+
 2009-03-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        * g++.old-deja/g++.jason/thunk2.C: Skip on SPU.
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/longlong-1.c b/gcc/testsuite/gcc.target/i386/stackalign/longlong-1.c
new file mode 100644 (file)
index 0000000..225d0c5
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/39137 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=2" } */
+/* Make sure dynamic stack realignment isn't performed just because there
+   are long long variables.  */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[^\\n\]*-8,\[^\\n\]*sp" } } */
+
+void fn (void *);
+
+void f1 (void)
+{
+  unsigned long long a;
+  fn (&a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/longlong-2.c b/gcc/testsuite/gcc.target/i386/stackalign/longlong-2.c
new file mode 100644 (file)
index 0000000..027d2ad
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -mpreferred-stack-boundary=2" } */
+/* { dg-final { scan-assembler-times "and\[lq\]?\[^\\n\]*-8,\[^\\n\]*sp" 2 } } */ 
+/* { dg-final { scan-assembler-times "and\[lq\]?\[^\\n\]*-16,\[^\\n\]*sp" 2 } } */ 
+
+void fn (void *);
+
+void f2 (void)
+{
+  unsigned long long a __attribute__((aligned (8)));
+  fn (&a);
+}
+
+void f3 (void)
+{
+  typedef unsigned long long L __attribute__((aligned (8)));
+  L a;
+  fn (&a);
+}
+
+void f4 (void)
+{
+  unsigned long long a __attribute__((aligned (16)));
+  fn (&a);
+}
+
+void f5 (void)
+{
+  typedef unsigned long long L __attribute__((aligned (16)));
+  L a;
+  fn (&a);
+}