diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-09-06 21:57:57 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-09-06 21:57:57 +0200 |
commit | 73109af7527b8c42510b1144cc2118a175960903 (patch) | |
tree | 978465120a74b359693836e943442478555e6466 /gcc | |
parent | 60a23e2e02d5fafd887891c0fd910f7fdc760055 (diff) | |
download | gcc-73109af7527b8c42510b1144cc2118a175960903.zip gcc-73109af7527b8c42510b1144cc2118a175960903.tar.gz gcc-73109af7527b8c42510b1144cc2118a175960903.tar.bz2 |
re PR target/22362 (static function calls and global register variables)
PR target/22362
* config/i386/i386.c (ix86_function_regparm): Make sure automatic regparm
for internal functions doesn't use registers used by global registers
variables. Use fewer register parameters if there are global register
variables.
* gcc.target/i386/pr22362.c: New test.
From-SVN: r103964
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr22362.c | 25 |
4 files changed, 57 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f93ae7..9c60317 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-09-06 Jakub Jelinek <jakub@redhat.com> + + PR target/22362 + * config/i386/i386.c (ix86_function_regparm): Make sure automatic regparm + for internal functions doesn't use registers used by global registers + variables. Use fewer register parameters if there are global register + variables. + 2005-09-06 Olivier Hainque <hainque@adacore.com> Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5d2db43..2325efd 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2148,12 +2148,29 @@ ix86_function_regparm (tree type, tree decl) struct cgraph_local_info *i = cgraph_local_info (decl); if (i && i->local) { + int local_regparm, globals = 0, regno; + + /* Make sure no regparm register is taken by a global register + variable. */ + for (local_regparm = 0; local_regparm < 3; local_regparm++) + if (global_regs[local_regparm]) + break; /* We can't use regparm(3) for nested functions as these use static chain pointer in third argument. */ - if (DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl)) - regparm = 2; - else - regparm = 3; + if (local_regparm == 3 + && DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl)) + local_regparm = 2; + /* Each global register variable increases register preassure, + so the more global reg vars there are, the smaller regparm + optimization use, unless requested by the user explicitly. */ + for (regno = 0; regno < 6; regno++) + if (global_regs[regno]) + globals++; + local_regparm + = globals < local_regparm ? local_regparm - globals : 0; + + if (local_regparm > regparm) + regparm = local_regparm; } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 31dfd85..b76b34b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-09-06 Jakub Jelinek <jakub@redhat.com> + PR target/22362 + * gcc.target/i386/pr22362.c: New test. + PR rtl-optimization/23098 * gcc.target/i386/pr23098.c: Add dg-require-effective-target ilp32. diff --git a/gcc/testsuite/gcc.target/i386/pr22362.c b/gcc/testsuite/gcc.target/i386/pr22362.c new file mode 100644 index 0000000..a7c78b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr22362.c @@ -0,0 +1,25 @@ +/* PR target/22362 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target ilp32 } */ + +register unsigned int reg0 __asm__ ("esi"); +register unsigned int reg1 __asm__ ("edi"); +register unsigned int reg2 __asm__ ("ebx"); + +static unsigned int +__attribute__((noinline)) +foo (unsigned long *x, void *y, void *z) +{ + int i; + + for (i = 5; i > 0; i--) + x[i] = (unsigned long) foo ((unsigned long *) x[i], y, z); + return 0; +} + +unsigned int +bar (void) +{ + return foo (0, 0, 0); +} |