From: Richard Sandiford Date: Sat, 11 Nov 2023 17:28:58 +0000 (+0000) Subject: mode-switching: Pass the set of live registers to the after hook X-Git-Tag: basepoints/gcc-15~4777 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=93d65f39bc5c3dc318deb6da0e3633f3a4c6c34d;p=thirdparty%2Fgcc.git mode-switching: Pass the set of live registers to the after hook This patch passes the set of live hard registers to the after hook, like the previous one did for the needed hook. gcc/ * target.def (mode_switching.after): Add a regs_live parameter. * doc/tm.texi: Regenerate. * config/epiphany/epiphany-protos.h (epiphany_mode_after): Update accordingly. * config/epiphany/epiphany.cc (epiphany_mode_needed): Likewise. (epiphany_mode_after): Likewise. * config/i386/i386.cc (ix86_mode_after): Likewise. * config/riscv/riscv.cc (riscv_mode_after): Likewise. * config/sh/sh.cc (sh_mode_after): Likewise. * mode-switching.cc (optimize_mode_switching): Likewise. --- diff --git a/gcc/config/epiphany/epiphany-protos.h b/gcc/config/epiphany/epiphany-protos.h index ef49a1e06a4a..ff8987ea99ea 100644 --- a/gcc/config/epiphany/epiphany-protos.h +++ b/gcc/config/epiphany/epiphany-protos.h @@ -46,8 +46,9 @@ extern void epiphany_insert_mode_switch_use (rtx_insn *insn, int, int); extern void epiphany_expand_set_fp_mode (rtx *operands); #ifdef HARD_CONST extern int epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET); +extern int epiphany_mode_after (int entity, int last_mode, rtx_insn *insn, + HARD_REG_SET); #endif -extern int epiphany_mode_after (int entity, int last_mode, rtx_insn *insn); extern bool epiphany_epilogue_uses (int regno); extern bool epiphany_optimize_mode_switching (int entity); extern bool epiphany_is_interrupt_p (tree); diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc index 60a9b49d8a48..68e748c688e9 100644 --- a/gcc/config/epiphany/epiphany.cc +++ b/gcc/config/epiphany/epiphany.cc @@ -2437,7 +2437,7 @@ epiphany_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET) return 2; case EPIPHANY_MSW_ENTITY_ROUND_KNOWN: if (recog_memoized (insn) == CODE_FOR_set_fp_mode) - mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn); + mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn, {}); /* Fall through. */ case EPIPHANY_MSW_ENTITY_NEAREST: case EPIPHANY_MSW_ENTITY_TRUNC: @@ -2498,7 +2498,8 @@ epiphany_mode_entry_exit (int entity, bool exit) } int -epiphany_mode_after (int entity, int last_mode, rtx_insn *insn) +epiphany_mode_after (int entity, int last_mode, rtx_insn *insn, + HARD_REG_SET) { /* We have too few call-saved registers to hope to keep the masks across calls. */ diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index a041e87d363d..2c80fd8ebf3f 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -15109,7 +15109,7 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn) /* Return the mode that an insn results in. */ static int -ix86_mode_after (int entity, int mode, rtx_insn *insn) +ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET) { switch (entity) { diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 750eaf90ea2a..ecee7eb4727c 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -9527,7 +9527,7 @@ riscv_frm_mode_after (rtx_insn *insn, int mode) /* Return the mode that an insn results in. */ static int -riscv_mode_after (int entity, int mode, rtx_insn *insn) +riscv_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET) { switch (entity) { diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc index c363490e8526..6ec2eecf7546 100644 --- a/gcc/config/sh/sh.cc +++ b/gcc/config/sh/sh.cc @@ -196,7 +196,7 @@ static HOST_WIDE_INT rounded_frame_size (int); static bool sh_frame_pointer_required (void); static void sh_emit_mode_set (int, int, int, HARD_REG_SET); static int sh_mode_needed (int, rtx_insn *, HARD_REG_SET); -static int sh_mode_after (int, int, rtx_insn *); +static int sh_mode_after (int, int, rtx_insn *, HARD_REG_SET); static int sh_mode_entry (int); static int sh_mode_exit (int); static int sh_mode_priority (int entity, int n); @@ -12537,7 +12537,8 @@ sh_mode_needed (int entity ATTRIBUTE_UNUSED, rtx_insn *insn, HARD_REG_SET) } static int -sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn) +sh_mode_after (int entity ATTRIBUTE_UNUSED, int mode, rtx_insn *insn, + HARD_REG_SET) { if (TARGET_HITACHI && recog_memoized (insn) >= 0 && get_attr_fp_set (insn) != FP_SET_NONE) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 144b3f88c376..b730b5bf658d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10423,12 +10423,14 @@ such requirement. @var{regs_live} contains the set of hard registers that are live before @var{insn}. @end deftypefn -@deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn}) +@deftypefn {Target Hook} int TARGET_MODE_AFTER (int @var{entity}, int @var{mode}, rtx_insn *@var{insn}, HARD_REG_SET @var{regs_live}) @var{entity} is an integer specifying a mode-switched entity. If this hook is defined, it is evaluated for every @var{insn} during mode switching. It returns the mode that @var{entity} is in after @var{insn} has been executed. @var{mode} is the mode that @var{entity} was in before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}. +@var{regs_live} is the set of hard registers that are live after @var{insn} +has been executed. @var{mode} is equal to the number of modes defined for @var{entity} if the mode before @var{insn} is unknown. The hook should likewise return diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc index c5fe90ba449d..7a5c4993d653 100644 --- a/gcc/mode-switching.cc +++ b/gcc/mode-switching.cc @@ -632,10 +632,6 @@ optimize_mode_switching (void) last_mode = mode; } - if (targetm.mode_switching.after) - last_mode = targetm.mode_switching.after (e, last_mode, - insn); - /* Update LIVE_NOW. */ for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_DEAD) @@ -645,6 +641,10 @@ optimize_mode_switching (void) for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_UNUSED) reg_dies (XEXP (link, 0), &live_now); + + if (targetm.mode_switching.after) + last_mode = targetm.mode_switching.after (e, last_mode, + insn, live_now); } } diff --git a/gcc/target.def b/gcc/target.def index 50bad184acaf..9b14c037d3f3 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -7042,6 +7042,8 @@ If this hook is defined, it is evaluated for every @var{insn} during mode\n\ switching. It returns the mode that @var{entity} is in after @var{insn}\n\ has been executed. @var{mode} is the mode that @var{entity} was in\n\ before @var{insn} was executed, taking account of @var{TARGET_MODE_NEEDED}.\n\ +@var{regs_live} is the set of hard registers that are live after @var{insn}\n\ +has been executed.\n\ \n\ @var{mode} is equal to the number of modes defined for @var{entity}\n\ if the mode before @var{insn} is unknown. The hook should likewise return\n\ @@ -7049,7 +7051,7 @@ the number of modes if it does not know what mode @var{entity} has after\n\ @var{insn}.\n\ \n\ Not defining the hook is equivalent to returning @var{mode}.", - int, (int entity, int mode, rtx_insn *insn), NULL) + int, (int entity, int mode, rtx_insn *insn, HARD_REG_SET regs_live), NULL) DEFHOOK (entry,