diff options
author | Kwok Cheung Yeung <kcy@codesourcery.com> | 2019-11-07 00:07:04 +0000 |
---|---|---|
committer | Kwok Cheung Yeung <kcy@gcc.gnu.org> | 2019-11-07 00:07:04 +0000 |
commit | ff33d18785b1190441742b27fb89bb970c8b9258 (patch) | |
tree | 550dfd60b511c26ceb38535232227e59225ef6c5 | |
parent | 7b88f66de61f4533bbd7ae0124c4260c2959f1e0 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ira.c | 33 |
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 @@ -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); } } |