[gcc/devel/autopar_devel] arm: Add support for interrupt routines to reg_needs_saving_p

Giuliano Belinassi giulianob@gcc.gnu.org
Sat Aug 22 21:17:04 GMT 2020


https://gcc.gnu.org/g:6fce8cb4f81f19c9225824040fdfbdf7f1a7be67

commit 6fce8cb4f81f19c9225824040fdfbdf7f1a7be67
Author: Christophe Lyon <christophe.lyon@linaro.org>
Date:   Mon May 4 13:42:03 2020 +0000

    arm: Add support for interrupt routines to reg_needs_saving_p
    
    reg_needs_saving_p is only used when dealing with non-interrupt
    routines, but it makes sense to extend it to support that context too,
    and make arm_compute_save_reg0_reg12_mask use it.
    
    Save only live registers for non-leaf functions, but assume a callee
    could clobber any register.
    
    2020-05-15  Christophe Lyon  <christophe.lyon@linaro.org>
    
            gcc/
            * config/arm/arm.c (reg_needs_saving_p): Add support for interrupt
            routines.
            (arm_compute_save_reg0_reg12_mask): Use reg_needs_saving_p.

Diff:
---
 gcc/ChangeLog        |  6 ++++++
 gcc/config/arm/arm.c | 28 +++++++++++++++++++++-------
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 592ca9bfd31..fb7ee99fa28 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-15  Christophe Lyon  <christophe.lyon@linaro.org>
+
+        * config/arm/arm.c (reg_needs_saving_p): Add support for interrupt
+        routines.
+        (arm_compute_save_reg0_reg12_mask): Use reg_needs_saving_p.
+
 2020-05-15  Tobias Burnus  <tobias@codesourcery.com>
 
 	PR middle-end/94635
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 3dab6145987..349918a9bfa 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4188,14 +4188,29 @@ arm_trampoline_adjust_address (rtx addr)
   return addr;
 }
 
-/* Return 1 if REG needs to be saved.   */
+/* Return 1 if REG needs to be saved. For interrupt handlers, this
+   includes call-clobbered registers too.  If this is a leaf function
+   we can just examine the registers used by the RTL, but otherwise we
+   have to assume that whatever function is called might clobber
+   anything, and so we have to save all the call-clobbered registers
+   as well.  */
 static inline bool reg_needs_saving_p (unsigned reg)
 {
-  if (!df_regs_ever_live_p (reg)
-      || call_used_or_fixed_reg_p (reg))
-    return false;
+  unsigned long func_type = arm_current_func_type ();
+
+  if (IS_INTERRUPT (func_type))
+    if (df_regs_ever_live_p (reg)
+	/* Save call-clobbered core registers.  */
+	|| (! crtl->is_leaf && call_used_or_fixed_reg_p (reg) && reg < FIRST_VFP_REGNUM))
+      return true;
+    else
+      return false;
   else
-    return true;
+    if (!df_regs_ever_live_p (reg)
+	|| call_used_or_fixed_reg_p (reg))
+      return false;
+    else
+      return true;
 }
 
 /* Return 1 if it is possible to return using a single instruction.
@@ -20677,8 +20692,7 @@ arm_compute_save_reg0_reg12_mask (void)
 	max_reg = 12;
 
       for (reg = 0; reg <= max_reg; reg++)
-	if (df_regs_ever_live_p (reg)
-	    || (! crtl->is_leaf && call_used_or_fixed_reg_p (reg)))
+	if (reg_needs_saving_p (reg))
 	  save_reg_mask |= (1 << reg);
 
       /* Also save the pic base register if necessary.  */


More information about the Gcc-cvs mailing list