re PR target/64453 (Live high register not saved in function prolog on ARM with -Os)
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Wed, 14 Jan 2015 11:51:40 +0000 (11:51 +0000)
committerThomas Preud'homme <thopre01@gcc.gnu.org>
Wed, 14 Jan 2015 11:51:40 +0000 (11:51 +0000)
2015-01-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>

    gcc/
    PR target/64453
    * config/arm/arm.c (callee_saved_reg_p): Define.
    (arm_compute_save_reg0_reg12_mask): Use callee_saved_reg_p to check if
    register is callee saved instead of !call_used_regs[reg].
    (thumb1_compute_save_reg_mask): Likewise.

    gcc/testsuite/
    PR target/64453
    * gcc.target/arm/pr64453.c: New.

From-SVN: r219592

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr64453.c [new file with mode: 0644]

index 96ef507517b6f4efb34e02661574557f60330694..4472ed2b6b3c92acfdab7c83ff35355b57bdf346 100644 (file)
@@ -1,3 +1,11 @@
+2015-01-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR target/64453
+       * config/arm/arm.c (callee_saved_reg_p): Define.
+       (arm_compute_save_reg0_reg12_mask): Use callee_saved_reg_p to check if
+       register is callee saved instead of !call_used_regs[reg].
+       (thumb1_compute_save_reg_mask): Likewise.
+
 2015-01-14  Hale Wang  <hale.wang@arm.com>
 
        * config/arm/arm.c: Tune the max_cond_insns/branch_cost for
index 1a1901179122beba8c2b986e248dc98348e7c437..237211a1f6dbc96f3c8bc0a37a6d94332c0abf29 100644 (file)
@@ -19033,6 +19033,14 @@ output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
   fputs ("\"\n", stream);
 }
 \f
+/* Whether a register is callee saved or not.  This is necessary because high
+   registers are marked as caller saved when optimizing for size on Thumb-1
+   targets despite being callee saved in order to avoid using them.  */
+#define callee_saved_reg_p(reg) \
+  (!call_used_regs[reg] \
+   || (TARGET_THUMB1 && optimize_size \
+       && reg >= FIRST_HI_REGNUM && reg <= LAST_HI_REGNUM))
+
 /* Compute the register save mask for registers 0 through 12
    inclusive.  This code is used by arm_compute_save_reg_mask.  */
 
@@ -19093,7 +19101,7 @@ arm_compute_save_reg0_reg12_mask (void)
       /* In the normal case we only need to save those registers
         which are call saved and which are used by this function.  */
       for (reg = 0; reg <= 11; reg++)
-       if (df_regs_ever_live_p (reg) && ! call_used_regs[reg])
+       if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg))
          save_reg_mask |= (1 << reg);
 
       /* Handle the frame pointer as a special case.  */
@@ -19257,7 +19265,7 @@ thumb1_compute_save_reg_mask (void)
 
   mask = 0;
   for (reg = 0; reg < 12; reg ++)
-    if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
+    if (df_regs_ever_live_p (reg) && callee_saved_reg_p (reg))
       mask |= 1 << reg;
 
   if (flag_pic
@@ -19290,7 +19298,7 @@ thumb1_compute_save_reg_mask (void)
       if (reg * UNITS_PER_WORD <= (unsigned) arm_size_return_regs ())
        reg = LAST_LO_REGNUM;
 
-      if (! call_used_regs[reg])
+      if (callee_saved_reg_p (reg))
        mask |= 1 << reg;
     }
 
@@ -27230,8 +27238,7 @@ arm_conditional_register_usage (void)
       /* When optimizing for size on Thumb-1, it's better not
         to use the HI regs, because of the overhead of
         stacking them.  */
-      for (regno = FIRST_HI_REGNUM;
-          regno <= LAST_HI_REGNUM; ++regno)
+      for (regno = FIRST_HI_REGNUM; regno <= LAST_HI_REGNUM; ++regno)
        fixed_regs[regno] = call_used_regs[regno] = 1;
     }
 
index e2929d3d42fe69c256a751b61259efc9a6ffe1a4..6429922d59f0bf852fb62a252ae8a7e5e8f9691b 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR target/64453
+       * gcc.target/arm/pr64453.c: New.
+
 2015-01-14  Richard Biener  <rguenther@suse.de>
 
        PR lto/64415
diff --git a/gcc/testsuite/gcc.target/arm/pr64453.c b/gcc/testsuite/gcc.target/arm/pr64453.c
new file mode 100644 (file)
index 0000000..17155af
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-mthumb -Os " }  */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+void save_regs () {
+  __asm volatile ("" ::: "r8");
+}
+
+/* { dg-final { scan-assembler "\tmov\tr., r8" } } */