public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Thomas Preud'homme" <thomas.preudhomme@arm.com>
To: <gcc-patches@gcc.gnu.org>
Subject: [PATCH, ARM] Fix PR64453: live high register not saved in function prolog with -Os
Date: Wed, 14 Jan 2015 10:38:00 -0000	[thread overview]
Message-ID: <000001d02fe3$c12d7d90$438878b0$@arm.com> (raw)

When compiling for size, live high registers are not saved in function prolog in ARM backend in Thumb mode. The problem comes from arm_conditional_register_usage setting call_used_regs for all high register to avoid them being allocated. However, this cause prolog to not save these register even if they are used. This patch marks high registers as really needing to be saved in prolog if live, no matter what is the content of call_used_regs.

ChangeLog entries are as follows:

gcc/ChangeLog

2015-01-12 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.


gcc/testsuite/ChangeLog

2014-12-31 Thomas Preud'homme thomas.preudhomme@arm.com

    * gcc.target/arm/pr64453.c: New.


diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0ec526b..fcc14c2 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -18989,6 +18989,14 @@ output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
   fputs ("\"\n", stream);
 }
 

+/* 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.  */
 
@@ -19049,7 +19057,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.  */
@@ -19212,7 +19220,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
@@ -19245,7 +19253,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;
     }
 
@@ -27185,8 +27193,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;
     }
 
diff --git a/gcc/testsuite/gcc.target/arm/pr64453.c b/gcc/testsuite/gcc.target/arm/pr64453.c
new file mode 100644
index 0000000..17155af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr64453.c
@@ -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" } } */

Tested by compiling an arm-none-eabi GCC cross-compiler and running the testsuite on QEMU emulating Cortex-M0 without any regression.

Is this ok for trunk?

Best regards,

Thomas



             reply	other threads:[~2015-01-14 10:20 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-14 10:38 Thomas Preud'homme [this message]
2015-01-14 11:38 ` Ramana Radhakrishnan
2015-01-23  9:32   ` Thomas Preud'homme
2015-02-17  8:07     ` Ramana Radhakrishnan
2015-03-03  9:35       ` Thomas Preud'homme
2015-03-03  9:44         ` Thomas Preud'homme
2015-03-04  2:09         ` Thomas Preud'homme

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='000001d02fe3$c12d7d90$438878b0$@arm.com' \
    --to=thomas.preudhomme@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).