diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2021-03-11 03:38:34 +0100 |
---|---|---|
committer | Hans-Peter Nilsson <hp@axis.com> | 2021-03-11 03:43:48 +0100 |
commit | aa27696b798b34730f5266cac2adba9178ebc3ae (patch) | |
tree | c31b33844b404d76ff180b28c60c192c48c1a3eb /gcc/config/cris | |
parent | e9800852067503ed0fe4efbfcac5f172b8596ee6 (diff) | |
download | gcc-aa27696b798b34730f5266cac2adba9178ebc3ae.tar.gz |
cris: define HARD_FRAME_POINTER_REGNUM
Beware, tm.texi doesn't tell the whole story: a defined
HARD_FRAME_POINTER_REGNUM (different to FRAME_POINTER_REGNUM) is
supposed to make work easier for reload, being able to easily
tell actual frame-pointer-related addresses from those that
happen to use the same register or something to that effect.
On reasonable code the performance effect is barely measurable.
Looking at libgcc changes for -march=v10, the effect (where
noticeable) is mostly indeterminate churn. Instances where it's
not just insns moved around at no obvious effect: one more insn
for addvdi3, subvdi3; two insns more in floatdisf; three insns
shorter fixunsdfdi. Some of those seem related to pairing r8
with r9. The only effect on coremark is an infinitesimal
positive effect from a three(!) cycles total (from the 15 calls)
faster execution paths in vfprintf_r. Local microbenchmarks
give similar results. With that in mind and not forgetting that
expectations in the register allocator and reload leaning
towards HARD_FRAME_POINTER_REGNUM defined (and different to)
FRAME_POINTER_REGNUM or to wit, "all the kids do it", why not.
Note that the offset at elimination really is 0.
gcc:
* config/cris/cris.h (HARD_FRAME_POINTER_REGNUM): Define.
Change FRAME_POINTER_REGNUM to correspond to a new faked
register faked_fp, part of GENNONACR_REGS like faked_ap.
(CRIS_FAKED_REGS_CONTENTS): New helper macro.
(FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS):
(REG_ALLOC_ORDER, REG_CLASS_CONTENTS, REGNO_OK_FOR_BASE_P)
(ELIMINABLE_REGS, REGISTER_NAMES): Adjust accordingly.
* config/cris/cris.md (CRIS_FP_REGNUM): Renumber to new faked
register.
(CRIS_REAL_FP_REGNUM): New constant.
* config/cris/cris.c (cris_reg_saved_in_regsave_area): Check
for HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM.
(cris_initial_elimination_offset): Handle elimination changes
to HARD_FRAME_POINTER_REGNUM instead of FRAME_POINTER_REGNUM
and add one from FRAME_POINTER_REGNUM to
HARD_FRAME_POINTER_REGNUM.
(cris_expand_prologue, cris_expand_epilogue): Emit code for
hard_frame_pointer_rtx instead of frame_pointer_rtx.
Diffstat (limited to 'gcc/config/cris')
-rw-r--r-- | gcc/config/cris/cris.c | 16 | ||||
-rw-r--r-- | gcc/config/cris/cris.h | 35 | ||||
-rw-r--r-- | gcc/config/cris/cris.md | 5 |
3 files changed, 36 insertions, 20 deletions
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 42f0a529f65..d9213d7ffb6 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -864,7 +864,7 @@ cris_reg_saved_in_regsave_area (unsigned int regno) return (((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))) - && (regno != FRAME_POINTER_REGNUM || !frame_pointer_needed) + && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed) && regno != CRIS_SRP_REGNUM) || (crtl->calls_eh_return && (regno == EH_RETURN_DATA_REGNO (0) @@ -1445,7 +1445,7 @@ cris_initial_elimination_offset (int fromreg, int toreg) int ap_fp_offset = 4 + (return_address_on_stack ? 4 : 0); if (fromreg == ARG_POINTER_REGNUM - && toreg == FRAME_POINTER_REGNUM) + && toreg == HARD_FRAME_POINTER_REGNUM) return ap_fp_offset; /* Between the frame pointer and the stack are only "normal" stack @@ -1459,6 +1459,10 @@ cris_initial_elimination_offset (int fromreg, int toreg) && toreg == STACK_POINTER_REGNUM) return ap_fp_offset + fp_sp_offset - 4; + if (fromreg == FRAME_POINTER_REGNUM + && toreg == HARD_FRAME_POINTER_REGNUM) + return 0; + gcc_unreachable (); } @@ -2749,10 +2753,10 @@ cris_expand_prologue (void) mem = gen_rtx_MEM (SImode, stack_pointer_rtx); set_mem_alias_set (mem, get_frame_alias_set ()); - insn = emit_move_insn (mem, frame_pointer_rtx); + insn = emit_move_insn (mem, hard_frame_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; - insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); + insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; framesize += 4; @@ -3015,11 +3019,11 @@ cris_expand_epilogue (void) emit_insn (gen_cris_frame_deallocated_barrier ()); - emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); + emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); mem = gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode, stack_pointer_rtx)); set_mem_alias_set (mem, get_frame_alias_set ()); - insn = emit_move_insn (frame_pointer_rtx, mem); + insn = emit_move_insn (hard_frame_pointer_rtx, mem); /* Whenever we emit insns with post-incremented addresses ourselves, we must add a post-inc note manually. */ diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 4d04ef869f3..1ab830e4d75 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -373,8 +373,8 @@ extern int cris_cpu_version; /* Node: Register Basics */ /* We count all 16 non-special registers, SRP, a faked argument - pointer register, MOF and CCR/DCCR. */ -#define FIRST_PSEUDO_REGISTER (16 + 1 + 1 + 1 + 1) + pointer register, MOF, CCR/DCCR, and the faked frame-pointer. */ +#define FIRST_PSEUDO_REGISTER (16 + 1 + 1 + 1 + 1 + 1) /* For CRIS, these are r15 (pc) and r14 (sp). Register r8 is used as a frame-pointer, but is not fixed. SRP is not included in general @@ -382,12 +382,12 @@ extern int cris_cpu_version; registers are fixed at the moment. The faked argument pointer register is fixed too. */ #define FIXED_REGISTERS \ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1} + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1} /* Register r9 is used for structure-address, r10-r13 for parameters, r10- for return values. */ #define CALL_USED_REGISTERS \ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1} + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1} /* Node: Allocation Order */ @@ -410,7 +410,8 @@ extern int cris_cpu_version; Use struct-return address first, since very few functions use structure return values so it is likely to be available. */ #define REG_ALLOC_ORDER \ - {9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 17, 16, 18, 19} + {9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 17, 16, 18, 19, \ + 20} /* Node: Leaf Functions */ @@ -451,6 +452,9 @@ enum reg_class #define CRIS_SPECIAL_REGS_CONTENTS \ ((1 << CRIS_SRP_REGNUM) | (1 << CRIS_MOF_REGNUM) | (1 << CRIS_CC0_REGNUM)) +#define CRIS_FAKED_REGS_CONTENTS \ + ((1 << CRIS_AP_REGNUM) | (1 << CRIS_FP_REGNUM)) + /* Count in the faked argument register in GENERAL_REGS. Keep out SRP. */ #define REG_CLASS_CONTENTS \ { \ @@ -464,13 +468,13 @@ enum reg_class {CRIS_SPECIAL_REGS_CONTENTS}, \ {CRIS_SPECIAL_REGS_CONTENTS \ | (1 << CRIS_ACR_REGNUM)}, \ - {(0xffff | (1 << CRIS_AP_REGNUM)) \ + {(0xffff | CRIS_FAKED_REGS_CONTENTS) \ & ~(1 << CRIS_ACR_REGNUM)}, \ - {(0xffff | (1 << CRIS_AP_REGNUM) \ + {(0xffff | CRIS_FAKED_REGS_CONTENTS \ | CRIS_SPECIAL_REGS_CONTENTS) \ & ~(1 << CRIS_ACR_REGNUM)}, \ - {0xffff | (1 << CRIS_AP_REGNUM)}, \ - {0xffff | (1 << CRIS_AP_REGNUM) \ + {0xffff | CRIS_FAKED_REGS_CONTENTS}, \ + {0xffff | CRIS_FAKED_REGS_CONTENTS \ | CRIS_SPECIAL_REGS_CONTENTS} \ } @@ -493,8 +497,10 @@ enum reg_class allocation. */ #define REGNO_OK_FOR_BASE_P(REGNO) \ ((REGNO) <= CRIS_LAST_GENERAL_REGISTER \ + || (REGNO) == FRAME_POINTER_REGNUM \ || (REGNO) == ARG_POINTER_REGNUM \ || (unsigned) reg_renumber[REGNO] <= CRIS_LAST_GENERAL_REGISTER \ + || (unsigned) reg_renumber[REGNO] == FRAME_POINTER_REGNUM \ || (unsigned) reg_renumber[REGNO] == ARG_POINTER_REGNUM) /* See REGNO_OK_FOR_BASE_P. */ @@ -580,6 +586,9 @@ enum reg_class /* Register used for frame pointer. This is also the last of the saved registers, when a frame pointer is not used. */ +#define HARD_FRAME_POINTER_REGNUM CRIS_REAL_FP_REGNUM + +/* Faked register, is always eliminated to at least CRIS_REAL_FP_REGNUM. */ #define FRAME_POINTER_REGNUM CRIS_FP_REGNUM /* Faked register, is always eliminated. We need it to eliminate @@ -596,8 +605,9 @@ enum reg_class #define ELIMINABLE_REGS \ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ - {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} + {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = cris_initial_elimination_offset (FROM, TO) @@ -818,7 +828,8 @@ struct cum_args {int regs;}; #define REGISTER_NAMES \ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ - "r9", "r10", "r11", "r12", "r13", "sp", "pc", "srp", "mof", "faked_ap", "dccr"} + "r9", "r10", "r11", "r12", "r13", "sp", "pc", "srp", \ + "mof", "faked_ap", "dccr", "faked_fp"} #define ADDITIONAL_REGISTER_NAMES \ {{"r14", 14}, {"r15", 15}} diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index 069f7e00b6d..7de0ec63fcf 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -58,13 +58,14 @@ ;; Register numbers. (define_constants [(CRIS_STATIC_CHAIN_REGNUM 7) - (CRIS_FP_REGNUM 8) + (CRIS_REAL_FP_REGNUM 8) (CRIS_SP_REGNUM 14) (CRIS_ACR_REGNUM 15) (CRIS_SRP_REGNUM 16) (CRIS_MOF_REGNUM 17) (CRIS_AP_REGNUM 18) - (CRIS_CC0_REGNUM 19)] + (CRIS_CC0_REGNUM 19) + (CRIS_FP_REGNUM 20)] ) ;; We need an attribute to define whether an instruction can be put in |