From: Richard Sandiford <richard.sandiford@arm.com>
To: Alexandre Oliva via Gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Alexandre Oliva <oliva@adacore.com>
Subject: Re: try multi dest registers in default_zero_call_used_regs
Date: Thu, 31 Mar 2022 13:10:20 +0100 [thread overview]
Message-ID: <mpt4k3exqz7.fsf@arm.com> (raw)
In-Reply-To: <orczi75965.fsf@lxoliva.fsfla.org> (Alexandre Oliva via Gcc-patches's message of "Sun, 27 Mar 2022 19:21:06 -0300")
Alexandre Oliva via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> When the mode of regno_reg_rtx is not hard_regno_mode_ok for the
> target, try grouping the register with subsequent ones. This enables
> s16 to s31 and their hidden pairs to be zeroed with the default logic
> on some arm variants.
>
> Regstrapped on x86_64-linux-gnu, also tested on an affected arm
> configuration. Ok to install?
>
>
> for gcc/ChangeLog
>
> * targhooks.c (default_zero_call_used_regs): Attempt to group
> regs that the target refuses to use in their natural modes.
Thanks for doing this. Some comments below…
> ---
> gcc/targhooks.cc | 79 ++++++++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 70 insertions(+), 9 deletions(-)
>
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index fc49235eb38ee..bdaab9c63c7ee 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -1035,16 +1035,45 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
> if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
> {
> rtx_insn *last_insn = get_last_insn ();
> - machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
> + rtx regno_rtx = regno_reg_rtx[regno];
> + machine_mode mode = GET_MODE (regno_rtx);
> +
> + /* If the natural mode doesn't work, try some wider mode. */
> + if (!targetm.hard_regno_mode_ok (regno, mode))
> + {
> + for (int nregs = 2;
> + regno + nregs <= FIRST_PSEUDO_REGISTER
> + && TEST_HARD_REG_BIT (need_zeroed_hardregs,
> + regno + nregs - 1);
> + nregs++)
> + {
> + mode = choose_hard_reg_mode (regno, nregs, 0);
I like the idea, but it would be good to avoid the large:
FIRST_PSEUDO_REGISTER * FIRST_PSEUDO_REGISTER * NUM_MACHINE_MODES
constant factor. How about if init_reg_modes_target recorded the
maximum value of x_hard_regno_nregs?
> + if (mode == E_VOIDmode)
> + continue;
> + gcc_checking_assert (targetm.hard_regno_mode_ok (regno, mode));
> + regno_rtx = gen_rtx_REG (mode, regno);
> + break;
> + }
> + if (mode != GET_MODE (regno_rtx)
> + || regno_rtx == regno_reg_rtx[regno])
> + {
> + SET_HARD_REG_BIT (failed, regno);
> + continue;
> + }
> + }
> +
> rtx zero = CONST0_RTX (mode);
> - rtx_insn *insn = emit_move_insn (regno_reg_rtx[regno], zero);
> + rtx_insn *insn = emit_move_insn (regno_rtx, zero);
> if (!valid_insn_p (insn))
> {
> SET_HARD_REG_BIT (failed, regno);
> delete_insns_since (last_insn);
> }
> else
> - progress = true;
> + {
> + progress = true;
> + regno += hard_regno_nregs (regno, mode) - 1;
> + }
> }
>
> /* Now retry with copies from zeroed registers, as long as we've
> @@ -1060,7 +1089,34 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
> for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> if (TEST_HARD_REG_BIT (retrying, regno))
> {
> - machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
> + rtx regno_rtx = regno_reg_rtx[regno];
> + machine_mode mode = GET_MODE (regno_rtx);
> +
> + /* If the natural mode doesn't work, try some wider mode. */
> + if (!targetm.hard_regno_mode_ok (regno, mode))
> + {
> + for (int nregs = 2;
> + regno + nregs <= FIRST_PSEUDO_REGISTER
> + && TEST_HARD_REG_BIT (need_zeroed_hardregs,
> + regno + nregs - 1);
> + nregs++)
> + {
> + mode = choose_hard_reg_mode (regno, nregs, 0);
> + if (mode == E_VOIDmode)
> + continue;
> + gcc_checking_assert (targetm.hard_regno_mode_ok (regno,
> + mode));
> + regno_rtx = gen_rtx_REG (mode, regno);
> + break;
> + }
> + if (mode != GET_MODE (regno_rtx)
> + || regno_rtx == regno_reg_rtx[regno])
> + {
> + SET_HARD_REG_BIT (failed, regno);
> + continue;
> + }
> + }
> +
This seems big enough to be worth splitting out into a helper, rather
than repeating. That should also simplify the failure detection:
the helper can return nonnull on success and null on failure.
> bool success = false;
> /* Look for a source. */
> for (unsigned int src = 0; src < FIRST_PSEUDO_REGISTER; src++)
> @@ -1086,8 +1142,10 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
>
> /* SRC is usable, try to copy from it. */
> rtx_insn *last_insn = get_last_insn ();
> - rtx zsrc = gen_rtx_REG (mode, src);
> - rtx_insn *insn = emit_move_insn (regno_reg_rtx[regno], zsrc);
> + rtx src_rtx = (mode == GET_MODE (regno_reg_rtx[src])
> + ? regno_reg_rtx[src]
> + : gen_rtx_REG (mode, src));
Is this needed? The original gen_rtx_REG (mode, src) seems OK.
Thanks,
Richard
> + rtx_insn *insn = emit_move_insn (regno_rtx, src_rtx);
> if (!valid_insn_p (insn))
> /* It didn't work, remove any inserts. We'll look
> for another SRC. */
> @@ -1100,13 +1158,16 @@ default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
> }
> }
>
> - /* If nothing worked for REGNO this round, marked it to be
> + /* If nothing worked for REGNO this round, mark it to be
> retried if we get another round. */
> if (!success)
> SET_HARD_REG_BIT (failed, regno);
> else
> - /* Take note so as to enable another round if needed. */
> - progress = true;
> + {
> + /* Take note so as to enable another round if needed. */
> + progress = true;
> + regno += hard_regno_nregs (regno, mode) - 1;
> + }
> }
> }
next prev parent reply other threads:[~2022-03-31 12:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-27 22:21 Alexandre Oliva
2022-03-31 12:10 ` Richard Sandiford [this message]
2022-04-01 5:56 ` Alexandre Oliva
2022-04-04 12:29 ` Richard Sandiford
2022-04-05 4:26 ` Alexandre Oliva
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=mpt4k3exqz7.fsf@arm.com \
--to=richard.sandiford@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=oliva@adacore.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).