Support using multiple registers to hold the frame pointer
authorKwok Cheung Yeung <kcy@codesourcery.com>
Thu, 7 Nov 2019 00:07:04 +0000 (00:07 +0000)
committerKwok Cheung Yeung <kcy@gcc.gnu.org>
Thu, 7 Nov 2019 00:07:04 +0000 (00:07 +0000)
When multiple hard registers are required to hold the frame pointer,
ensure that the registers after the first are marked as non-allocatable,
live and eliminable as well.

2019-11-07  Kwok Cheung Yeung  <kcy@codesourcery.com>

gcc/
* ira.c (setup_alloc_regs): Setup no_unit_alloc_regs for
frame pointer in multiple registers.
(ira_setup_eliminable_regset): Setup eliminable_regset,
ira_no_alloc_regs and regs_ever_live for frame pointer in
multiple registers.

From-SVN: r277895

gcc/ChangeLog
gcc/ira.c

index c3dc5b333dfdbbaa7910f8b7abb87d01eb9c93c2..f5ef703927dd36c2db0629698d1694b3b265ab12 100644 (file)
@@ -1,3 +1,11 @@
+2019-11-07  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       * ira.c (setup_alloc_regs): Setup no_unit_alloc_regs for
+       frame pointer in multiple registers.
+       (ira_setup_eliminable_regset): Setup eliminable_regset,
+       ira_no_alloc_regs and regs_ever_live for frame pointer in
+       multiple registers.
+
 2019-11-06  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * config/rs6000/vsx.md (xxswapd_<mode>): Add support for V2DF and
index 9f8da67539cfca3720cdcd7ac8342332d2ec5626..5df995364dd94a33c5dd6fa6d7a011a636e240d8 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -515,7 +515,8 @@ setup_alloc_regs (bool use_hard_frame_p)
 #endif
   no_unit_alloc_regs = fixed_nonglobal_reg_set;
   if (! use_hard_frame_p)
-    SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+    add_to_hard_reg_set (&no_unit_alloc_regs, Pmode,
+                        HARD_FRAME_POINTER_REGNUM);
   setup_class_hard_regs ();
 }
 
@@ -2248,6 +2249,7 @@ ira_setup_eliminable_regset (void)
 {
   int i;
   static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
+  int fp_reg_count = hard_regno_nregs (HARD_FRAME_POINTER_REGNUM, Pmode);
 
   /* Setup is_leaf as frame_pointer_required may use it.  This function
      is called by sched_init before ira if scheduling is enabled.  */
@@ -2276,7 +2278,8 @@ ira_setup_eliminable_regset (void)
        frame pointer in LRA.  */
 
   if (frame_pointer_needed)
-    df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true);
+    for (i = 0; i < fp_reg_count; i++)
+      df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true);
     
   ira_no_alloc_regs = no_unit_alloc_regs;
   CLEAR_HARD_REG_SET (eliminable_regset);
@@ -2306,17 +2309,21 @@ ira_setup_eliminable_regset (void)
     }
   if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
     {
-      if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
-       {
-         SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
-         if (frame_pointer_needed)
-           SET_HARD_REG_BIT (ira_no_alloc_regs, HARD_FRAME_POINTER_REGNUM);
-       }
-      else if (frame_pointer_needed)
-       error ("%s cannot be used in %<asm%> here",
-              reg_names[HARD_FRAME_POINTER_REGNUM]);
-      else
-       df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true);
+      for (i = 0; i < fp_reg_count; i++)
+       if (!TEST_HARD_REG_BIT (crtl->asm_clobbers,
+                               HARD_FRAME_POINTER_REGNUM + i))
+         {
+           SET_HARD_REG_BIT (eliminable_regset,
+                             HARD_FRAME_POINTER_REGNUM + i);
+           if (frame_pointer_needed)
+             SET_HARD_REG_BIT (ira_no_alloc_regs,
+                               HARD_FRAME_POINTER_REGNUM + i);
+         }
+       else if (frame_pointer_needed)
+         error ("%s cannot be used in %<asm%> here",
+                reg_names[HARD_FRAME_POINTER_REGNUM + i]);
+       else
+         df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true);
     }
 }