mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 02:54:11 +08:00
re PR rtl-optimization/9771 ([x86] wrong ebp optimisation)
PR rtl-optimization/9771 * regclass.c (CALL_REALLY_USED_REGNO_P): New macro to eliminate conditional compilation in init_reg_sets_1. (init_reg_sets_1): Let global_regs[i] take priority over the frame (but not stack) pointer exceptions to regs_invalidated_by_call. (globalize_reg): Globalizing a fixed register may need to update regs_invalidated_by_call. * gcc.dg/pr9771-1.c: New test case. From-SVN: r87516
This commit is contained in:
parent
1810f6edaa
commit
f6ae6c51df
@ -1,3 +1,13 @@
|
||||
2004-09-14 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR rtl-optimization/9771
|
||||
* regclass.c (CALL_REALLY_USED_REGNO_P): New macro to eliminate
|
||||
conditional compilation in init_reg_sets_1.
|
||||
(init_reg_sets_1): Let global_regs[i] take priority over the frame
|
||||
(but not stack) pointer exceptions to regs_invalidated_by_call.
|
||||
(globalize_reg): Globalizing a fixed register may need to update
|
||||
regs_invalidated_by_call.
|
||||
|
||||
2004-09-14 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
PR tree-optimization/15262
|
||||
|
@ -104,6 +104,13 @@ static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
|
||||
char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
|
||||
#endif
|
||||
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
#define CALL_REALLY_USED_REGNO_P(X) call_really_used_regs[X]
|
||||
#else
|
||||
#define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X]
|
||||
#endif
|
||||
|
||||
|
||||
/* Indexed by hard register number, contains 1 for registers that are
|
||||
fixed use or call used registers that cannot hold quantities across
|
||||
calls even if we are willing to save and restore them. call fixed
|
||||
@ -454,7 +461,11 @@ init_reg_sets_1 (void)
|
||||
If we are generating PIC code, the PIC offset table register is
|
||||
preserved across calls, though the target can override that. */
|
||||
|
||||
if (i == STACK_POINTER_REGNUM || i == FRAME_POINTER_REGNUM)
|
||||
if (i == STACK_POINTER_REGNUM)
|
||||
;
|
||||
else if (global_regs[i])
|
||||
SET_HARD_REG_BIT (regs_invalidated_by_call, i);
|
||||
else if (i == FRAME_POINTER_REGNUM)
|
||||
;
|
||||
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
||||
else if (i == HARD_FRAME_POINTER_REGNUM)
|
||||
@ -468,13 +479,7 @@ init_reg_sets_1 (void)
|
||||
else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
|
||||
;
|
||||
#endif
|
||||
else if (0
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
|| call_really_used_regs[i]
|
||||
#else
|
||||
|| call_used_regs[i]
|
||||
#endif
|
||||
|| global_regs[i])
|
||||
else if (CALL_REALLY_USED_REGNO_P (i))
|
||||
SET_HARD_REG_BIT (regs_invalidated_by_call, i);
|
||||
}
|
||||
|
||||
@ -800,6 +805,12 @@ globalize_reg (int i)
|
||||
|
||||
global_regs[i] = 1;
|
||||
|
||||
/* If we're globalizing the frame pointer, we need to set the
|
||||
appropriate regs_invalidated_by_call bit, even if it's already
|
||||
set in fixed_regs. */
|
||||
if (i != STACK_POINTER_REGNUM)
|
||||
SET_HARD_REG_BIT (regs_invalidated_by_call, i);
|
||||
|
||||
/* If already fixed, nothing else to do. */
|
||||
if (fixed_regs[i])
|
||||
return;
|
||||
@ -813,7 +824,6 @@ globalize_reg (int i)
|
||||
SET_HARD_REG_BIT (fixed_reg_set, i);
|
||||
SET_HARD_REG_BIT (call_used_reg_set, i);
|
||||
SET_HARD_REG_BIT (call_fixed_reg_set, i);
|
||||
SET_HARD_REG_BIT (regs_invalidated_by_call, i);
|
||||
}
|
||||
|
||||
/* Now the data and code for the `regclass' pass, which happens
|
||||
|
@ -1,3 +1,8 @@
|
||||
2004-09-14 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR rtl-optimization/9771
|
||||
* gcc.dg/pr9771-1.c: New test case.
|
||||
|
||||
2004-09-14 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
PR tree-optimization/15262
|
||||
|
43
gcc/testsuite/gcc.dg/pr9771-1.c
Normal file
43
gcc/testsuite/gcc.dg/pr9771-1.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* PR rtl-optimization/9771 */
|
||||
/* { dg-do run { target i?86-*-* } } */
|
||||
/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */
|
||||
|
||||
extern void abort(void);
|
||||
extern void exit(int);
|
||||
|
||||
register long *B asm ("ebp");
|
||||
|
||||
long x = 10;
|
||||
long y = 20;
|
||||
|
||||
void bar(void)
|
||||
{
|
||||
B = &y;
|
||||
}
|
||||
|
||||
void foo()
|
||||
{
|
||||
long *adr = B;
|
||||
long save = *adr;
|
||||
|
||||
*adr = 123;
|
||||
|
||||
bar();
|
||||
|
||||
*adr = save;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
B = &x;
|
||||
|
||||
foo();
|
||||
|
||||
if (x != 10 || y != 20)
|
||||
abort();
|
||||
|
||||
/* We can't return, as our caller may assume %ebp is preserved! */
|
||||
/* We could save/restore it (like foo), but its easier to exit. */
|
||||
exit(0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user