From 73109af7527b8c42510b1144cc2118a175960903 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 6 Sep 2005 21:57:57 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386.c | 25 +++++++++++++++++++++---- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr22362.c | 25 +++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr22362.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f93ae7218c..9c603172c66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-09-06 Jakub Jelinek + + 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 Eric Botcazou diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5d2db431b81..2325efd1aa5 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 31dfd8580a4..b76b34bd009 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-09-06 Jakub Jelinek + 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 00000000000..a7c78b12f84 --- /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); +} -- 2.30.2