aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-09-06 21:57:57 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2005-09-06 21:57:57 +0200
commit73109af7527b8c42510b1144cc2118a175960903 (patch)
tree978465120a74b359693836e943442478555e6466
parent60a23e2e02d5fafd887891c0fd910f7fdc760055 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c25
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr22362.c25
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);
+}