aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKwok Cheung Yeung <kcy@codesourcery.com>2019-11-07 00:07:04 +0000
committerKwok Cheung Yeung <kcy@gcc.gnu.org>2019-11-07 00:07:04 +0000
commitff33d18785b1190441742b27fb89bb970c8b9258 (patch)
tree550dfd60b511c26ceb38535232227e59225ef6c5
parent7b88f66de61f4533bbd7ae0124c4260c2959f1e0 (diff)
downloadgcc-ff33d18785b1190441742b27fb89bb970c8b9258.zip
gcc-ff33d18785b1190441742b27fb89bb970c8b9258.tar.gz
gcc-ff33d18785b1190441742b27fb89bb970c8b9258.tar.bz2
Support using multiple registers to hold the frame pointer
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ira.c33
2 files changed, 28 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c3dc5b3..f5ef703 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ira.c b/gcc/ira.c
index 9f8da67..5df9953 100644
--- 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);
}
}