re PR rtl-optimization/9771 ([x86] wrong ebp optimisation)
authorRoger Sayle <roger@eyesopen.com>
Tue, 14 Sep 2004 22:52:41 +0000 (22:52 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 14 Sep 2004 22:52:41 +0000 (22:52 +0000)
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

gcc/ChangeLog
gcc/regclass.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr9771-1.c [new file with mode: 0644]

index eb5533dbddcd08863f603b8caa14e81a4a3b8d4f..2ce328f08b6e2a21bbd04f6dcb0b09f99ccc1906 100644 (file)
@@ -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
index a73d8865bac3ba11f0f435918de97c7392513d3c..3d5a5f8dddd92e14b85499c0c9519c11af5c1d97 100644 (file)
@@ -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);
 }
 \f
 /* Now the data and code for the `regclass' pass, which happens
index 6ac93c8b42f8a980e59246d3c5c2d72944e9c0a2..a8f7e5d393e62a2a0d731d7606e161e1594226fd 100644 (file)
@@ -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
diff --git a/gcc/testsuite/gcc.dg/pr9771-1.c b/gcc/testsuite/gcc.dg/pr9771-1.c
new file mode 100644 (file)
index 0000000..1e3bc03
--- /dev/null
@@ -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);
+}
+