diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-03-11 22:12:33 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-03-11 22:12:33 +0100 |
commit | 9bfaf89d4f07272d60824efcbcbdb2d7f1dd4d6e (patch) | |
tree | aac00dcd74a4bb14c38abd88b8fbe9ad9b4c2d6b | |
parent | 8a9ceef2cc5783e9920cb48e8eb68c21c9244a29 (diff) | |
download | gcc-9bfaf89d4f07272d60824efcbcbdb2d7f1dd4d6e.zip gcc-9bfaf89d4f07272d60824efcbcbdb2d7f1dd4d6e.tar.gz gcc-9bfaf89d4f07272d60824efcbcbdb2d7f1dd4d6e.tar.bz2 |
re PR target/39137 (-mpreferred-stack-boundary=2 causes lots of dynamic realign)
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
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 34 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 13 | ||||
-rw-r--r-- | gcc/defaults.h | 5 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/stackalign/longlong-1.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/stackalign/longlong-2.c | 33 |
9 files changed, 127 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 838bd34..c4cccf2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c73bba7..4bfdc5f 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -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; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e7dd5be..9a34912 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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. */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index f2f4448..8035e84 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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. */ diff --git a/gcc/defaults.h b/gcc/defaults.h index fbb13ac..217c0d9 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -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 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b4fcc2d..f4680b6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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;}. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af958c3..f8a7b2d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..225d0c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/longlong-1.c @@ -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 index 0000000..027d2ad --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/stackalign/longlong-2.c @@ -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); +} |