Commit f6ae6c51 by Roger Sayle Committed by Roger Sayle

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
parent 1810f6ed
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> 2004-09-14 Diego Novillo <dnovillo@redhat.com>
PR tree-optimization/15262 PR tree-optimization/15262
......
...@@ -104,6 +104,13 @@ static const char initial_call_used_regs[] = CALL_USED_REGISTERS; ...@@ -104,6 +104,13 @@ static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS; char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
#endif #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 /* Indexed by hard register number, contains 1 for registers that are
fixed use or call used registers that cannot hold quantities across fixed use or call used registers that cannot hold quantities across
calls even if we are willing to save and restore them. call fixed calls even if we are willing to save and restore them. call fixed
...@@ -454,7 +461,11 @@ init_reg_sets_1 (void) ...@@ -454,7 +461,11 @@ init_reg_sets_1 (void)
If we are generating PIC code, the PIC offset table register is If we are generating PIC code, the PIC offset table register is
preserved across calls, though the target can override that. */ 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 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
else if (i == HARD_FRAME_POINTER_REGNUM) else if (i == HARD_FRAME_POINTER_REGNUM)
...@@ -468,13 +479,7 @@ init_reg_sets_1 (void) ...@@ -468,13 +479,7 @@ init_reg_sets_1 (void)
else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
; ;
#endif #endif
else if (0 else if (CALL_REALLY_USED_REGNO_P (i))
#ifdef CALL_REALLY_USED_REGISTERS
|| call_really_used_regs[i]
#else
|| call_used_regs[i]
#endif
|| global_regs[i])
SET_HARD_REG_BIT (regs_invalidated_by_call, i); SET_HARD_REG_BIT (regs_invalidated_by_call, i);
} }
...@@ -800,6 +805,12 @@ globalize_reg (int i) ...@@ -800,6 +805,12 @@ globalize_reg (int i)
global_regs[i] = 1; 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 already fixed, nothing else to do. */
if (fixed_regs[i]) if (fixed_regs[i])
return; return;
...@@ -813,7 +824,6 @@ globalize_reg (int i) ...@@ -813,7 +824,6 @@ globalize_reg (int i)
SET_HARD_REG_BIT (fixed_reg_set, i); SET_HARD_REG_BIT (fixed_reg_set, i);
SET_HARD_REG_BIT (call_used_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 (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 /* Now the data and code for the `regclass' pass, which happens
......
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> 2004-09-14 Diego Novillo <dnovillo@redhat.com>
PR tree-optimization/15262 PR tree-optimization/15262
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment