* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103964
138bc75d-0d04-0410-961f-
82ee72b054a4
+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>
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;
}
}
}
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.
--- /dev/null
+/* 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);
+}