public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <richard.guenther@gmail.com>
To: "Kewen.Lin" <linkw@linux.ibm.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
	Richard Sandiford <richard.sandiford@arm.com>
Subject: Re: [PATCH 1/3] targhooks: Extend legitimate_address_p with code_helper [PR110248]
Date: Fri, 30 Jun 2023 10:56:43 +0200	[thread overview]
Message-ID: <CAFiYyc2=jQBTtmPePwS=y3O+eso3iCZ3uSeUO2iHugfWURiq1Q@mail.gmail.com> (raw)
In-Reply-To: <7928a68a-cb83-3cd7-eacd-63e3f7c2445c@linux.ibm.com>

On Fri, Jun 30, 2023 at 7:38 AM Kewen.Lin <linkw@linux.ibm.com> wrote:
>
> Hi,
>
> As PR110248 shows, some middle-end passes like IVOPTs can
> query the target hook legitimate_address_p with some
> artificially constructed rtx to determine whether some
> addressing modes are supported by target for some gimple
> statement.  But for now the existing legitimate_address_p
> only checks the given mode, it's unable to distinguish
> some special cases unfortunately, for example, for LEN_LOAD
> ifn on Power port, we would expand it with lxvl hardware
> insn, which only supports one register to hold the address
> (the other register is holding the length), that is we
> don't support base (reg) + index (reg) addressing mode for
> sure.  But hook legitimate_address_p only considers the
> given mode which would be some vector mode for LEN_LOAD
> ifn, and we do support base + index addressing mode for
> normal vector load and store insns, so the hook will return
> true for the query unexpectedly.
>
> This patch is to introduce one extra argument of type
> code_helper for hook legitimate_address_p, it makes targets
> able to handle some special case like what's described
> above.  The subsequent patches will show how to leverage
> the new code_helper argument.
>
> I didn't separate those target specific adjustments to
> their own patches, since those changes are no function
> changes.  One typical change is to add one unnamed argument
> with default ERROR_MARK, some ports need to include tree.h
> in their {port}-protos.h since the hook is used in some
> machine description files.  I've cross-built a corresponding
> cc1 successfully for at least one triple of each affected
> target so I believe they are safe.  But feel free to correct
> me if separating is needed for the review of this patch.
>
> Besides, it's bootstrapped and regtested on
> x86_64-redhat-linux and powerpc64{,le}-linux-gnu.
>
> Is it ok for trunk?

Is defaulting the arguments in the targets necessary for
the middle-end or only for direct uses in the targets?

It looks OK in general but please give others some time to
comment.

Thanks,
Richard.

> BR,
> Kewen
> ------
>         PR tree-optimization/110248
>
> gcc/ChangeLog:
>
>         * coretypes.h (class code_helper): Add forward declaration.
>         * doc/tm.texi: Regenerate.
>         * lra-constraints.cc (valid_address_p): Call target hook
>         targetm.addr_space.legitimate_address_p with an extra parameter
>         ERROR_MARK as its prototype changes.
>         * recog.cc (memory_address_addr_space_p): Likewise.
>         * reload.cc (strict_memory_address_addr_space_p): Likewise.
>         * target.def (legitimate_address_p, addr_space.legitimate_address_p):
>         Extend with one more argument of type code_helper, update the
>         documentation accordingly.
>         * targhooks.cc (default_legitimate_address_p): Adjust for the
>         new code_helper argument.
>         (default_addr_space_legitimate_address_p): Likewise.
>         * targhooks.h (default_legitimate_address_p): Likewise.
>         (default_addr_space_legitimate_address_p): Likewise.
>         * config/aarch64/aarch64.cc (aarch64_legitimate_address_hook_p): Adjust
>         with extra unnamed code_helper argument with default ERROR_MARK.
>         * config/alpha/alpha.cc (alpha_legitimate_address_p): Likewise.
>         * config/arc/arc.cc (arc_legitimate_address_p): Likewise.
>         * config/arm/arm-protos.h (arm_legitimate_address_p): Likewise.
>         (tree.h): New include for tree_code ERROR_MARK.
>         * config/arm/arm.cc (arm_legitimate_address_p): Adjust with extra
>         unnamed code_helper argument with default ERROR_MARK.
>         * config/avr/avr.cc (avr_addr_space_legitimate_address_p): Likewise.
>         * config/bfin/bfin.cc (bfin_legitimate_address_p): Likewise.
>         * config/bpf/bpf.cc (bpf_legitimate_address_p): Likewise.
>         * config/c6x/c6x.cc (c6x_legitimate_address_p): Likewise.
>         * config/cris/cris-protos.h (cris_legitimate_address_p): Likewise.
>         (tree.h): New include for tree_code ERROR_MARK.
>         * config/cris/cris.cc (cris_legitimate_address_p): Adjust with extra
>         unnamed code_helper argument with default ERROR_MARK.
>         * config/csky/csky.cc (csky_legitimate_address_p): Likewise.
>         * config/epiphany/epiphany.cc (epiphany_legitimate_address_p):
>         Likewise.
>         * config/frv/frv.cc (frv_legitimate_address_p): Likewise.
>         * config/ft32/ft32.cc (ft32_addr_space_legitimate_address_p): Likewise.
>         * config/gcn/gcn.cc (gcn_addr_space_legitimate_address_p): Likewise.
>         * config/h8300/h8300.cc (h8300_legitimate_address_p): Likewise.
>         * config/i386/i386.cc (ix86_legitimate_address_p): Likewise.
>         * config/ia64/ia64.cc (ia64_legitimate_address_p): Likewise.
>         * config/iq2000/iq2000.cc (iq2000_legitimate_address_p): Likewise.
>         * config/lm32/lm32.cc (lm32_legitimate_address_p): Likewise.
>         * config/loongarch/loongarch.cc (loongarch_legitimate_address_p):
>         Likewise.
>         * config/m32c/m32c.cc (m32c_legitimate_address_p): Likewise.
>         (m32c_addr_space_legitimate_address_p): Likewise.
>         * config/m32r/m32r.cc (m32r_legitimate_address_p): Likewise.
>         * config/m68k/m68k.cc (m68k_legitimate_address_p): Likewise.
>         * config/mcore/mcore.cc (mcore_legitimate_address_p): Likewise.
>         * config/microblaze/microblaze-protos.h (tree.h): New include for
>         tree_code ERROR_MARK.
>         (microblaze_legitimate_address_p): Adjust with extra unnamed
>         code_helper argument with default ERROR_MARK.
>         * config/microblaze/microblaze.cc (microblaze_legitimate_address_p):
>         Likewise.
>         * config/mips/mips.cc (mips_legitimate_address_p): Likewise.
>         * config/mmix/mmix.cc (mmix_legitimate_address_p): Likewise.
>         * config/mn10300/mn10300.cc (mn10300_legitimate_address_p): Likewise.
>         * config/moxie/moxie.cc (moxie_legitimate_address_p): Likewise.
>         * config/msp430/msp430.cc (msp430_legitimate_address_p): Likewise.
>         (msp430_addr_space_legitimate_address_p): Adjust with extra code_helper
>         argument with default ERROR_MARK and adjust the call to function
>         msp430_legitimate_address_p.
>         * config/nds32/nds32.cc (nds32_legitimate_address_p): Adjust with extra
>         unnamed code_helper argument with default ERROR_MARK.
>         * config/nios2/nios2.cc (nios2_legitimate_address_p): Likewise.
>         * config/nvptx/nvptx.cc (nvptx_legitimate_address_p): Likewise.
>         * config/or1k/or1k.cc (or1k_legitimate_address_p): Likewise.
>         * config/pa/pa.cc (pa_legitimate_address_p): Likewise.
>         * config/pdp11/pdp11.cc (pdp11_legitimate_address_p): Likewise.
>         * config/pru/pru.cc (pru_addr_space_legitimate_address_p): Likewise.
>         * config/riscv/riscv.cc (riscv_legitimate_address_p): Likewise.
>         * config/rl78/rl78-protos.h (rl78_as_legitimate_address): Likewise.
>         (tree.h): New include for tree_code ERROR_MARK.
>         * config/rl78/rl78.cc (rl78_as_legitimate_address): Adjust with
>         extra unnamed code_helper argument with default ERROR_MARK.
>         * config/rs6000/rs6000.cc (rs6000_legitimate_address_p): Likewise.
>         (rs6000_debug_legitimate_address_p): Adjust with extra code_helper
>         argument and adjust the call to function rs6000_legitimate_address_p.
>         * config/rx/rx.cc (rx_is_legitimate_address): Adjust with extra
>         unnamed code_helper argument with default ERROR_MARK.
>         * config/s390/s390.cc (s390_legitimate_address_p): Likewise.
>         * config/sh/sh.cc (sh_legitimate_address_p): Likewise.
>         * config/sparc/sparc.cc (sparc_legitimate_address_p): Likewise.
>         * config/v850/v850.cc (v850_legitimate_address_p): Likewise.
>         * config/vax/vax.cc (vax_legitimate_address_p): Likewise.
>         * config/visium/visium.cc (visium_legitimate_address_p): Likewise.
>         * config/xtensa/xtensa.cc (xtensa_legitimate_address_p): Likewise.
>         * config/stormy16/stormy16-protos.h (xstormy16_legitimate_address_p):
>         Likewise.
>         (tree.h): New include for tree_code ERROR_MARK.
>         * config/stormy16/stormy16.cc (xstormy16_legitimate_address_p):
>         Adjust with extra unnamed code_helper argument with default
>         ERROR_MARK.
> ---
>  gcc/config/aarch64/aarch64.cc             |  3 ++-
>  gcc/config/alpha/alpha.cc                 |  3 ++-
>  gcc/config/arc/arc.cc                     |  3 ++-
>  gcc/config/arm/arm-protos.h               |  4 +++-
>  gcc/config/arm/arm.cc                     |  2 +-
>  gcc/config/avr/avr.cc                     |  4 ++--
>  gcc/config/bfin/bfin.cc                   |  3 ++-
>  gcc/config/bpf/bpf.cc                     |  3 ++-
>  gcc/config/c6x/c6x.cc                     |  3 ++-
>  gcc/config/cris/cris-protos.h             |  5 ++++-
>  gcc/config/cris/cris.cc                   |  2 +-
>  gcc/config/csky/csky.cc                   |  3 ++-
>  gcc/config/epiphany/epiphany.cc           |  3 ++-
>  gcc/config/frv/frv.cc                     |  5 +++--
>  gcc/config/ft32/ft32.cc                   |  3 ++-
>  gcc/config/gcn/gcn.cc                     |  2 +-
>  gcc/config/h8300/h8300.cc                 |  3 ++-
>  gcc/config/i386/i386.cc                   |  3 ++-
>  gcc/config/ia64/ia64.cc                   |  7 ++++---
>  gcc/config/iq2000/iq2000.cc               |  6 ++++--
>  gcc/config/lm32/lm32.cc                   |  7 ++++---
>  gcc/config/loongarch/loongarch.cc         |  3 ++-
>  gcc/config/m32c/m32c.cc                   | 15 +++++++++------
>  gcc/config/m32r/m32r.cc                   |  5 +++--
>  gcc/config/m68k/m68k.cc                   |  5 +++--
>  gcc/config/mcore/mcore.cc                 |  5 +++--
>  gcc/config/microblaze/microblaze-protos.h |  5 ++++-
>  gcc/config/microblaze/microblaze.cc       |  3 ++-
>  gcc/config/mips/mips.cc                   |  3 ++-
>  gcc/config/mmix/mmix.cc                   |  6 ++++--
>  gcc/config/mn10300/mn10300.cc             |  3 ++-
>  gcc/config/moxie/moxie.cc                 |  3 ++-
>  gcc/config/msp430/msp430.cc               |  8 +++++---
>  gcc/config/nds32/nds32.cc                 |  3 ++-
>  gcc/config/nios2/nios2.cc                 |  5 +++--
>  gcc/config/nvptx/nvptx.cc                 |  2 +-
>  gcc/config/or1k/or1k.cc                   |  3 ++-
>  gcc/config/pa/pa.cc                       |  5 +++--
>  gcc/config/pdp11/pdp11.cc                 |  4 ++--
>  gcc/config/pru/pru.cc                     |  3 ++-
>  gcc/config/riscv/riscv.cc                 |  3 ++-
>  gcc/config/rl78/rl78-protos.h             |  6 +++++-
>  gcc/config/rl78/rl78.cc                   |  3 ++-
>  gcc/config/rs6000/rs6000.cc               | 12 +++++++-----
>  gcc/config/rx/rx.cc                       |  3 ++-
>  gcc/config/s390/s390.cc                   |  3 ++-
>  gcc/config/sh/sh.cc                       |  5 +++--
>  gcc/config/sparc/sparc.cc                 |  6 ++++--
>  gcc/config/stormy16/stormy16-protos.h     |  5 +++--
>  gcc/config/stormy16/stormy16.cc           |  4 ++--
>  gcc/config/v850/v850.cc                   |  3 ++-
>  gcc/config/vax/vax.cc                     |  5 +++--
>  gcc/config/visium/visium.cc               |  5 +++--
>  gcc/config/xtensa/xtensa.cc               |  7 ++++---
>  gcc/coretypes.h                           |  1 +
>  gcc/doc/tm.texi                           | 18 +++++++++++++-----
>  gcc/lra-constraints.cc                    |  3 ++-
>  gcc/recog.cc                              |  3 ++-
>  gcc/reload.cc                             |  3 ++-
>  gcc/target.def                            | 18 +++++++++++++-----
>  gcc/targhooks.cc                          |  8 +++++---
>  gcc/targhooks.h                           |  6 +++---
>  62 files changed, 190 insertions(+), 106 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 644ebdebc0e..2dfb811ec4f 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -11182,7 +11182,8 @@ aarch64_classify_symbolic_expression (rtx x)
>  /* Return TRUE if X is a legitimate address for accessing memory in
>     mode MODE.  */
>  static bool
> -aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p)
> +aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p,
> +                                  code_helper = ERROR_MARK)
>  {
>    struct aarch64_address_info addr;
>
> diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc
> index 360b50e20d4..0367f117c21 100644
> --- a/gcc/config/alpha/alpha.cc
> +++ b/gcc/config/alpha/alpha.cc
> @@ -844,7 +844,8 @@ alpha_linkage_symbol_p (const char *symname)
>     low-order three bits; this is an "unaligned" access.  */
>
>  static bool
> -alpha_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +alpha_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                           code_helper = ERROR_MARK)
>  {
>    /* If this is an ldq_u type address, discard the outer AND.  */
>    if (mode == DImode
> diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
> index fef8a504f77..266ba8b00bb 100644
> --- a/gcc/config/arc/arc.cc
> +++ b/gcc/config/arc/arc.cc
> @@ -6715,7 +6715,8 @@ arc_legitimate_constant_p (machine_mode mode, rtx x)
>  }
>
>  static bool
> -arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +arc_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                         code_helper = ERROR_MARK)
>  {
>    if (RTX_OK_FOR_BASE_P (x, strict))
>       return true;
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 7d73c66a15d..2257aa2c1c0 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -23,6 +23,7 @@
>  #define GCC_ARM_PROTOS_H
>
>  #include "sbitmap.h"
> +#include "tree.h" /* For ERROR_MARK.  */
>
>  rtl_opt_pass *make_pass_insert_bti (gcc::context *ctxt);
>
> @@ -83,7 +84,8 @@ extern int arm_split_constant (RTX_CODE, machine_mode, rtx,
>  extern int legitimate_pic_operand_p (rtx);
>  extern rtx legitimize_pic_address (rtx, machine_mode, rtx, rtx, bool);
>  extern rtx legitimize_tls_address (rtx, rtx);
> -extern bool arm_legitimate_address_p (machine_mode, rtx, bool);
> +extern bool arm_legitimate_address_p (machine_mode, rtx, bool,
> +                                     code_helper = ERROR_MARK);
>  extern int arm_legitimate_address_outer_p (machine_mode, rtx, RTX_CODE, int);
>  extern int thumb_legitimate_offset_p (machine_mode, HOST_WIDE_INT);
>  extern int thumb1_legitimate_address_p (machine_mode, rtx, int);
> diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
> index 38f0839de1c..6e933c80183 100644
> --- a/gcc/config/arm/arm.cc
> +++ b/gcc/config/arm/arm.cc
> @@ -9171,7 +9171,7 @@ thumb_legitimate_offset_p (machine_mode mode, HOST_WIDE_INT val)
>  }
>
>  bool
> -arm_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +arm_legitimate_address_p (machine_mode mode, rtx x, bool strict_p, code_helper)
>  {
>    if (TARGET_ARM)
>      return arm_legitimate_address_outer_p (mode, x, SET, strict_p);
> diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
> index 0447641a8e9..fa42602f877 100644
> --- a/gcc/config/avr/avr.cc
> +++ b/gcc/config/avr/avr.cc
> @@ -13431,8 +13431,8 @@ avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
>  /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'.  */
>
>  static bool
> -avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
> -                                     bool strict, addr_space_t as)
> +avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                                    addr_space_t as, code_helper = ERROR_MARK)
>  {
>    bool ok = false;
>
> diff --git a/gcc/config/bfin/bfin.cc b/gcc/config/bfin/bfin.cc
> index 4320ec26722..5718babb6b2 100644
> --- a/gcc/config/bfin/bfin.cc
> +++ b/gcc/config/bfin/bfin.cc
> @@ -2718,7 +2718,8 @@ bfin_valid_reg_p (unsigned int regno, int strict, machine_mode mode,
>  */
>
>  static bool
> -bfin_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +bfin_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                          code_helper = ERROR_MARK)
>  {
>    switch (GET_CODE (x)) {
>    case REG:
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index e0324e1e0e0..a16275c2810 100644
> --- a/gcc/config/bpf/bpf.cc
> +++ b/gcc/config/bpf/bpf.cc
> @@ -668,7 +668,8 @@ bpf_address_base_p (rtx x, bool strict)
>  static bool
>  bpf_legitimate_address_p (machine_mode mode,
>                           rtx x,
> -                         bool strict)
> +                         bool strict,
> +                         code_helper = ERROR_MARK)
>  {
>    switch (GET_CODE (x))
>      {
> diff --git a/gcc/config/c6x/c6x.cc b/gcc/config/c6x/c6x.cc
> index 0c9cb821f28..72e8b4c5345 100644
> --- a/gcc/config/c6x/c6x.cc
> +++ b/gcc/config/c6x/c6x.cc
> @@ -2444,7 +2444,8 @@ c6x_legitimate_address_p_1 (machine_mode mode, rtx x, bool strict,
>  }
>
>  static bool
> -c6x_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +c6x_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                         code_helper = ERROR_MARK)
>  {
>    return c6x_legitimate_address_p_1 (mode, x, strict, false);
>  }
> diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h
> index 666e04f9eee..58555943986 100644
> --- a/gcc/config/cris/cris-protos.h
> +++ b/gcc/config/cris/cris-protos.h
> @@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
>
>  /* Prototypes for the CRIS port.  */
>
> +#include "tree.h" /* For ERROR_MARK.  */
> +
>  extern bool cris_simple_epilogue (void);
>  #ifdef RTX_CODE
>  extern const char *cris_op_str (rtx);
> @@ -34,7 +36,8 @@ extern bool cris_base_or_autoincr_p (const_rtx, bool);
>  extern bool cris_bdap_index_p (const_rtx, bool);
>  extern void cris_reduce_compare (rtx *, rtx *, rtx *);
>  extern bool cris_biap_index_p (const_rtx, bool);
> -extern bool cris_legitimate_address_p (machine_mode, rtx, bool);
> +extern bool cris_legitimate_address_p (machine_mode, rtx, bool,
> +                                      code_helper = ERROR_MARK);
>  extern bool cris_store_multiple_op_p (rtx);
>  extern bool cris_movem_load_rest_p (rtx);
>  extern void cris_asm_output_symbol_ref (FILE *, rtx);
> diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
> index 7fca2af085a..edd2b898a6c 100644
> --- a/gcc/config/cris/cris.cc
> +++ b/gcc/config/cris/cris.cc
> @@ -1537,7 +1537,7 @@ cris_biap_index_p (const_rtx x, bool strict)
>  /* Worker function for TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  bool
> -cris_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +cris_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    const_rtx x1, x2;
>
> diff --git a/gcc/config/csky/csky.cc b/gcc/config/csky/csky.cc
> index b4ee3b273a4..731f47cb2c0 100644
> --- a/gcc/config/csky/csky.cc
> +++ b/gcc/config/csky/csky.cc
> @@ -3186,7 +3186,8 @@ csky_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
>     be recognized.  */
>
>  static bool
> -csky_legitimate_address_p (machine_mode mode, rtx addr, bool strict_p)
> +csky_legitimate_address_p (machine_mode mode, rtx addr, bool strict_p,
> +                          code_helper = ERROR_MARK)
>  {
>    enum rtx_code code = GET_CODE (addr);
>
> diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
> index 60a2845d6d1..a5460dbf97f 100644
> --- a/gcc/config/epiphany/epiphany.cc
> +++ b/gcc/config/epiphany/epiphany.cc
> @@ -2053,7 +2053,8 @@ epiphany_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn,
>       || RTX_OK_FOR_OFFSET_P (MODE, XEXP (X, 1))))
>
>  static bool
> -epiphany_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +epiphany_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                              code_helper = ERROR_MARK)
>  {
>  #define REG_OK_FOR_BASE_P(X) \
>    (strict ? GPR_P (REGNO (X)) : GPR_AP_OR_PSEUDO_P (REGNO (X)))
> diff --git a/gcc/config/frv/frv.cc b/gcc/config/frv/frv.cc
> index 2dbaa75f3dc..03976ba7b71 100644
> --- a/gcc/config/frv/frv.cc
> +++ b/gcc/config/frv/frv.cc
> @@ -261,7 +261,8 @@ static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
>  /* Forward references */
>
>  static void frv_option_override                        (void);
> -static bool frv_legitimate_address_p           (machine_mode, rtx, bool);
> +static bool frv_legitimate_address_p (machine_mode, rtx, bool,
> +                                     code_helper = ERROR_MARK);
>  static int frv_default_flags_for_cpu           (void);
>  static FRV_INLINE bool frv_small_data_reloc_p  (rtx, int);
>  static void frv_print_operand                  (FILE *, rtx, int);
> @@ -3396,7 +3397,7 @@ frv_legitimate_address_p_1 (machine_mode mode,
>  }
>
>  bool
> -frv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +frv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p, code_helper)
>  {
>    return frv_legitimate_address_p_1 (mode, x, strict_p, FALSE, FALSE);
>  }
> diff --git a/gcc/config/ft32/ft32.cc b/gcc/config/ft32/ft32.cc
> index 806ab769f79..059243d2a3d 100644
> --- a/gcc/config/ft32/ft32.cc
> +++ b/gcc/config/ft32/ft32.cc
> @@ -856,7 +856,8 @@ reg_ok_for_base_p (rtx r, bool strict)
>
>  static bool
>  ft32_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> -                                      addr_space_t as ATTRIBUTE_UNUSED)
> +                                     addr_space_t as ATTRIBUTE_UNUSED,
> +                                     code_helper = ERROR_MARK)
>  {
>    int max_offset = TARGET_FT32B ? 16384 : 128;
>
> diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
> index 02f4dedec42..f6cff659703 100644
> --- a/gcc/config/gcn/gcn.cc
> +++ b/gcc/config/gcn/gcn.cc
> @@ -1654,7 +1654,7 @@ gcn_global_address_p (rtx addr)
>
>  static bool
>  gcn_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> -                                    addr_space_t as)
> +                                    addr_space_t as, code_helper = ERROR_MARK)
>  {
>    /* All vector instructions need to work on addresses in registers.  */
>    if (!TARGET_GCN5_PLUS && (vgpr_vector_mode_p (mode) && !REG_P (x)))
> diff --git a/gcc/config/h8300/h8300.cc b/gcc/config/h8300/h8300.cc
> index cdf74c1acbd..4bbb1b711e8 100644
> --- a/gcc/config/h8300/h8300.cc
> +++ b/gcc/config/h8300/h8300.cc
> @@ -5312,7 +5312,8 @@ h8300_rtx_ok_for_base_p (rtx x, int strict)
>     CONSTANT_ADDRESS.  */
>
>  static bool
> -h8300_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +h8300_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                           code_helper = ERROR_MARK)
>  {
>    /* The register indirect addresses like @er0 is always valid.  */
>    if (h8300_rtx_ok_for_base_p (x, strict))
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 0761965344b..7226b3e5fd3 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -11010,7 +11010,8 @@ ix86_validate_address_register (rtx op)
>     be recognized.  */
>
>  static bool
> -ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
> +ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
> +                          code_helper = ERROR_MARK)
>  {
>    struct ix86_address parts;
>    rtx base, index, disp;
> diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
> index 92f34dd1ee7..c241e1a50fc 100644
> --- a/gcc/config/ia64/ia64.cc
> +++ b/gcc/config/ia64/ia64.cc
> @@ -313,7 +313,8 @@ static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
>  static bool ia64_scalar_mode_supported_p (scalar_mode mode);
>  static bool ia64_vector_mode_supported_p (machine_mode mode);
>  static bool ia64_legitimate_constant_p (machine_mode, rtx);
> -static bool ia64_legitimate_address_p (machine_mode, rtx, bool);
> +static bool ia64_legitimate_address_p (machine_mode, rtx, bool,
> +                                      code_helper = ERROR_MARK);
>  static bool ia64_cannot_force_const_mem (machine_mode, rtx);
>  static const char *ia64_mangle_type (const_tree);
>  static const char *ia64_invalid_conversion (const_tree, const_tree);
> @@ -1024,8 +1025,8 @@ ia64_legitimate_address_disp (const_rtx reg, const_rtx disp, bool strict)
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -ia64_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
> -                          rtx x, bool strict)
> +ia64_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
> +                          bool strict, code_helper)
>  {
>    if (ia64_legitimate_address_reg (x, strict))
>      return true;
> diff --git a/gcc/config/iq2000/iq2000.cc b/gcc/config/iq2000/iq2000.cc
> index 733fecac2b7..54404e8d05a 100644
> --- a/gcc/config/iq2000/iq2000.cc
> +++ b/gcc/config/iq2000/iq2000.cc
> @@ -170,7 +170,8 @@ static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
>  static unsigned int iq2000_function_arg_boundary (machine_mode,
>                                                   const_tree);
>  static void iq2000_va_start          (tree, rtx);
> -static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
> +static bool iq2000_legitimate_address_p (machine_mode, rtx, bool,
> +                                        code_helper = ERROR_MARK);
>  static bool iq2000_can_eliminate      (const int, const int);
>  static void iq2000_asm_trampoline_template (FILE *);
>  static void iq2000_trampoline_init    (rtx, tree, rtx);
> @@ -304,7 +305,8 @@ iq2000_reg_mode_ok_for_base_p (rtx reg,
>     function is called during reload.  */
>
>  bool
> -iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
> +iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict,
> +                            code_helper)
>  {
>    if (TARGET_DEBUG_A_MODE)
>      {
> diff --git a/gcc/config/lm32/lm32.cc b/gcc/config/lm32/lm32.cc
> index 6528358009d..9d65d66719c 100644
> --- a/gcc/config/lm32/lm32.cc
> +++ b/gcc/config/lm32/lm32.cc
> @@ -69,8 +69,8 @@ static void lm32_setup_incoming_varargs (cumulative_args_t cum,
>  static bool lm32_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
>                             int *total, bool speed);
>  static bool lm32_can_eliminate (const int, const int);
> -static bool
> -lm32_legitimate_address_p (machine_mode mode, rtx x, bool strict);
> +static bool lm32_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                                      code_helper = ERROR_MARK);
>  static HOST_WIDE_INT lm32_compute_frame_size (int size);
>  static void lm32_option_override (void);
>  static rtx lm32_function_arg (cumulative_args_t, const function_arg_info &);
> @@ -1192,7 +1192,8 @@ lm32_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -lm32_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
> +lm32_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
> +                          bool strict, code_helper)
>  {
>     /* (rM) */
>    if (strict && REG_P (x) && STRICT_REG_OK_FOR_BASE_P (x))
> diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
> index 5b8b93eb24b..86d58784113 100644
> --- a/gcc/config/loongarch/loongarch.cc
> +++ b/gcc/config/loongarch/loongarch.cc
> @@ -2096,7 +2096,8 @@ loongarch_classify_address (struct loongarch_address_info *info, rtx x,
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -loongarch_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +loongarch_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
> +                               code_helper = ERROR_MARK)
>  {
>    struct loongarch_address_info addr;
>
> diff --git a/gcc/config/m32c/m32c.cc b/gcc/config/m32c/m32c.cc
> index 65971d62990..e18efc3c7f2 100644
> --- a/gcc/config/m32c/m32c.cc
> +++ b/gcc/config/m32c/m32c.cc
> @@ -75,8 +75,11 @@ static int m32c_comp_type_attributes (const_tree, const_tree);
>  static bool m32c_fixed_condition_code_regs (unsigned int *, unsigned int *);
>  static struct machine_function *m32c_init_machine_status (void);
>  static void m32c_insert_attributes (tree, tree *);
> -static bool m32c_legitimate_address_p (machine_mode, rtx, bool);
> -static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool, addr_space_t);
> +static bool m32c_legitimate_address_p (machine_mode, rtx, bool,
> +                                      code_helper = ERROR_MARK);
> +static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool,
> +                                                 addr_space_t,
> +                                                 code_helper = ERROR_MARK);
>  static rtx m32c_function_arg (cumulative_args_t, const function_arg_info &);
>  static bool m32c_pass_by_reference (cumulative_args_t,
>                                     const function_arg_info &);
> @@ -1648,7 +1651,7 @@ m32c_trampoline_init (rtx m_tramp, tree fndecl, rtx chainval)
>  #undef TARGET_LEGITIMATE_ADDRESS_P
>  #define TARGET_LEGITIMATE_ADDRESS_P m32c_legitimate_address_p
>  bool
> -m32c_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +m32c_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    int mode_adjust;
>    if (CONSTANT_P (x))
> @@ -1966,8 +1969,8 @@ m32c_addr_space_address_mode (addr_space_t addrspace)
>  #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
>    m32c_addr_space_legitimate_address_p
>  static bool
> -m32c_addr_space_legitimate_address_p (machine_mode mode, rtx x,
> -                                     bool strict, addr_space_t as)
> +m32c_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                                     addr_space_t as, code_helper ch)
>  {
>    if (as == ADDR_SPACE_FAR)
>      {
> @@ -2048,7 +2051,7 @@ m32c_addr_space_legitimate_address_p (machine_mode mode, rtx x,
>    else if (as != ADDR_SPACE_GENERIC)
>      gcc_unreachable ();
>
> -  return m32c_legitimate_address_p (mode, x, strict);
> +  return m32c_legitimate_address_p (mode, x, strict, ch);
>  }
>
>  /* Like m32c_legitimate_address, except with named address support.  */
> diff --git a/gcc/config/m32r/m32r.cc b/gcc/config/m32r/m32r.cc
> index 155a248459b..63a1798da3d 100644
> --- a/gcc/config/m32r/m32r.cc
> +++ b/gcc/config/m32r/m32r.cc
> @@ -66,7 +66,8 @@ static void  m32r_option_override (void);
>  static void  init_reg_tables (void);
>  static void  block_move_call (rtx, rtx, rtx);
>  static int   m32r_is_insn (rtx);
> -static bool  m32r_legitimate_address_p (machine_mode, rtx, bool);
> +static bool  m32r_legitimate_address_p (machine_mode, rtx, bool,
> +                                       code_helper = ERROR_MARK);
>  static rtx   m32r_legitimize_address (rtx, rtx, machine_mode);
>  static bool  m32r_mode_dependent_address_p (const_rtx, addr_space_t);
>  static tree  m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
> @@ -2913,7 +2914,7 @@ m32r_store_preinc_predec_p (machine_mode mode, const_rtx x, bool strict)
>  /* Implement  TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -m32r_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +m32r_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    if (m32r_rtx_ok_for_base_p (x, strict)
>        || m32r_legitimate_offset_addres_p (mode, x, strict)
> diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
> index 03db2b6a936..145a92d8710 100644
> --- a/gcc/config/m68k/m68k.cc
> +++ b/gcc/config/m68k/m68k.cc
> @@ -158,7 +158,8 @@ static int m68k_sched_first_cycle_multipass_dfa_lookahead (void);
>
>  static bool m68k_can_eliminate (const int, const int);
>  static void m68k_conditional_register_usage (void);
> -static bool m68k_legitimate_address_p (machine_mode, rtx, bool);
> +static bool m68k_legitimate_address_p (machine_mode, rtx, bool,
> +                                      code_helper = ERROR_MARK);
>  static void m68k_option_override (void);
>  static void m68k_override_options_after_change (void);
>  static rtx find_addr_reg (rtx);
> @@ -2311,7 +2312,7 @@ m68k_decompose_address (machine_mode mode, rtx x,
>     STRICT_P says whether strict checking is needed.  */
>
>  bool
> -m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +m68k_legitimate_address_p (machine_mode mode, rtx x, bool strict_p, code_helper)
>  {
>    struct m68k_address address;
>
> diff --git a/gcc/config/mcore/mcore.cc b/gcc/config/mcore/mcore.cc
> index e933b03cdff..6f1d7af7937 100644
> --- a/gcc/config/mcore/mcore.cc
> +++ b/gcc/config/mcore/mcore.cc
> @@ -144,7 +144,8 @@ static bool       mcore_warn_func_return        (tree);
>  static void       mcore_option_override                (void);
>  static bool       mcore_legitimate_constant_p   (machine_mode, rtx);
>  static bool      mcore_legitimate_address_p    (machine_mode, rtx, bool,
> -                                                addr_space_t);
> +                                                addr_space_t,
> +                                                code_helper = ERROR_MARK);
>  static bool      mcore_hard_regno_mode_ok      (unsigned int, machine_mode);
>  static bool      mcore_modes_tieable_p         (machine_mode, machine_mode);
>
>
> @@ -3249,7 +3250,7 @@ mcore_legitimate_index_p (machine_mode mode, const_rtx op)
>
>  static bool
>  mcore_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
> -                           addr_space_t as)
> +                           addr_space_t as, code_helper)
>  {
>    gcc_assert (ADDR_SPACE_GENERIC_P (as));
>
> diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h
> index 31a6515176b..93fd8d17e3c 100644
> --- a/gcc/config/microblaze/microblaze-protos.h
> +++ b/gcc/config/microblaze/microblaze-protos.h
> @@ -22,6 +22,8 @@
>  #ifndef GCC_MICROBLAZE_PROTOS_H
>  #define GCC_MICROBLAZE_PROTOS_H
>
> +#include "tree.h"  /* For ERROR_MARK.  */
> +
>  #ifdef RTX_CODE
>  extern int pic_address_needs_scratch (rtx);
>  extern bool microblaze_constant_address_p (rtx x);
> @@ -40,7 +42,8 @@ extern int microblaze_can_use_return_insn (void);
>  extern void print_operand (FILE *, rtx, int);
>  extern void print_operand_address (FILE *, rtx);
>  extern void init_cumulative_args (CUMULATIVE_ARGS *,tree, rtx);
> -extern bool microblaze_legitimate_address_p (machine_mode, rtx, bool);
> +extern bool microblaze_legitimate_address_p (machine_mode, rtx, bool,
> +                                            code_helper = ERROR_MARK);
>  extern int microblaze_is_interrupt_variant (void);
>  extern int microblaze_is_break_handler (void);
>  extern int microblaze_break_function_p (tree func);
> diff --git a/gcc/config/microblaze/microblaze.cc b/gcc/config/microblaze/microblaze.cc
> index cbabf1af712..c9f6c4198cf 100644
> --- a/gcc/config/microblaze/microblaze.cc
> +++ b/gcc/config/microblaze/microblaze.cc
> @@ -919,7 +919,8 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
>     is called during reload.  */
>
>  bool
> -microblaze_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +microblaze_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                                code_helper)
>  {
>    struct microblaze_address_info addr;
>
> diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
> index 999127a72e7..3497d42cdf3 100644
> --- a/gcc/config/mips/mips.cc
> +++ b/gcc/config/mips/mips.cc
> @@ -2691,7 +2691,8 @@ mips_classify_address (struct mips_address_info *info, rtx x,
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -mips_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +mips_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
> +                          code_helper = ERROR_MARK)
>  {
>    struct mips_address_info addr;
>
> diff --git a/gcc/config/mmix/mmix.cc b/gcc/config/mmix/mmix.cc
> index 1d36306fdb6..34743092749 100644
> --- a/gcc/config/mmix/mmix.cc
> +++ b/gcc/config/mmix/mmix.cc
> @@ -132,7 +132,8 @@ static void mmix_target_asm_function_end_prologue (FILE *);
>  static void mmix_target_asm_function_epilogue (FILE *);
>  static reg_class_t mmix_preferred_reload_class (rtx, reg_class_t);
>  static reg_class_t mmix_preferred_output_reload_class (rtx, reg_class_t);
> -static bool mmix_legitimate_address_p (machine_mode, rtx, bool);
> +static bool mmix_legitimate_address_p (machine_mode, rtx, bool,
> +                                      code_helper = ERROR_MARK);
>  static bool mmix_legitimate_constant_p (machine_mode, rtx);
>  static void mmix_reorg (void);
>  static void mmix_asm_output_mi_thunk
> @@ -1109,7 +1110,8 @@ mmix_constant_address_p (rtx x)
>  bool
>  mmix_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
>                            rtx x,
> -                          bool strict_checking)
> +                          bool strict_checking,
> +                          code_helper)
>  {
>  #define MMIX_REG_OK(X)                                                 \
>    ((strict_checking                                                    \
> diff --git a/gcc/config/mn10300/mn10300.cc b/gcc/config/mn10300/mn10300.cc
> index a8b01a543cc..cd1de1b2d83 100644
> --- a/gcc/config/mn10300/mn10300.cc
> +++ b/gcc/config/mn10300/mn10300.cc
> @@ -1932,7 +1932,8 @@ mn10300_legitimate_pic_operand_p (rtx x)
>     function record_unscaled_index_insn_codes.  */
>
>  static bool
> -mn10300_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +mn10300_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                             code_helper = ERROR_MARK)
>  {
>    rtx base, index;
>
> diff --git a/gcc/config/moxie/moxie.cc b/gcc/config/moxie/moxie.cc
> index 2132b6e48a3..209d03077ea 100644
> --- a/gcc/config/moxie/moxie.cc
> +++ b/gcc/config/moxie/moxie.cc
> @@ -577,7 +577,8 @@ moxie_reg_ok_for_base_p (const_rtx reg, bool strict_p)
>  static bool
>  moxie_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
>                             rtx x, bool strict_p,
> -                           addr_space_t as)
> +                           addr_space_t as,
> +                           code_helper = ERROR_MARK)
>  {
>    gcc_assert (ADDR_SPACE_GENERIC_P (as));
>
> diff --git a/gcc/config/msp430/msp430.cc b/gcc/config/msp430/msp430.cc
> index 6f9c56187ee..061a9c77961 100644
> --- a/gcc/config/msp430/msp430.cc
> +++ b/gcc/config/msp430/msp430.cc
> @@ -927,7 +927,8 @@ reg_ok_for_addr (rtx r, bool strict)
>  bool
>  msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
>                              rtx x ATTRIBUTE_UNUSED,
> -                            bool strict ATTRIBUTE_UNUSED)
> +                            bool strict ATTRIBUTE_UNUSED,
> +                            code_helper = ERROR_MARK)
>  {
>    switch (GET_CODE (x))
>      {
> @@ -980,9 +981,10 @@ bool
>  msp430_addr_space_legitimate_address_p (machine_mode mode,
>                                         rtx x,
>                                         bool strict,
> -                                       addr_space_t as ATTRIBUTE_UNUSED)
> +                                       addr_space_t as ATTRIBUTE_UNUSED,
> +                                       code_helper ch = ERROR_MARK)
>  {
> -  return msp430_legitimate_address_p (mode, x, strict);
> +  return msp430_legitimate_address_p (mode, x, strict, ch);
>  }
>
>  #undef  TARGET_ASM_INTEGER
> diff --git a/gcc/config/nds32/nds32.cc b/gcc/config/nds32/nds32.cc
> index 91ed91d914f..1f8de2a514a 100644
> --- a/gcc/config/nds32/nds32.cc
> +++ b/gcc/config/nds32/nds32.cc
> @@ -2565,7 +2565,8 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
>  /* Addressing Modes.  */
>
>  static bool
> -nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict,
> +                           code_helper = ERROR_MARK)
>  {
>    if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
>      {
> diff --git a/gcc/config/nios2/nios2.cc b/gcc/config/nios2/nios2.cc
> index 936eb34ace4..b435d7475f9 100644
> --- a/gcc/config/nios2/nios2.cc
> +++ b/gcc/config/nios2/nios2.cc
> @@ -2141,8 +2141,9 @@ nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
>
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>  static bool
> -nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
> -                           rtx operand, bool strict_p)
> +nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx operand,
> +                           bool strict_p,
> +                           code_helper = ERROR_MARK)
>  {
>    switch (GET_CODE (operand))
>      {
> diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
> index e3b0304d537..49291d71a74 100644
> --- a/gcc/config/nvptx/nvptx.cc
> +++ b/gcc/config/nvptx/nvptx.cc
> @@ -2202,7 +2202,7 @@ nvptx_gen_shared_bcast (rtx reg, propagate_mask pm, unsigned rep,
>  /* Returns true if X is a valid address for use in a memory reference.  */
>
>  static bool
> -nvptx_legitimate_address_p (machine_mode, rtx x, bool)
> +nvptx_legitimate_address_p (machine_mode, rtx x, bool, code_helper)
>  {
>    enum rtx_code code = GET_CODE (x);
>
> diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc
> index ec30bc8156c..5eeed0e91be 100644
> --- a/gcc/config/or1k/or1k.cc
> +++ b/gcc/config/or1k/or1k.cc
> @@ -575,7 +575,8 @@ or1k_initial_elimination_offset (int from, int to)
>     Returns true if X is a legitimate address RTX on OpenRISC.  */
>
>  static bool
> -or1k_legitimate_address_p (machine_mode, rtx x, bool strict_p)
> +or1k_legitimate_address_p (machine_mode, rtx x, bool strict_p,
> +                          code_helper = ERROR_MARK)
>  {
>    rtx base, addend;
>
> diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
> index 0fa9e5fd632..2e906cff7ff 100644
> --- a/gcc/config/pa/pa.cc
> +++ b/gcc/config/pa/pa.cc
> @@ -196,7 +196,8 @@ static section *pa_function_section (tree, enum node_frequency, bool, bool);
>  static bool pa_cannot_force_const_mem (machine_mode, rtx);
>  static bool pa_legitimate_constant_p (machine_mode, rtx);
>  static unsigned int pa_section_type_flags (tree, const char *, int);
> -static bool pa_legitimate_address_p (machine_mode, rtx, bool);
> +static bool pa_legitimate_address_p (machine_mode, rtx, bool,
> +                                    code_helper = ERROR_MARK);
>  static bool pa_callee_copies (cumulative_args_t, const function_arg_info &);
>  static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode);
>  static bool pa_hard_regno_mode_ok (unsigned int, machine_mode);
> @@ -10787,7 +10788,7 @@ pa_section_type_flags (tree decl, const char *name, int reloc)
>     output as REG+SMALLINT.  */
>
>  static bool
> -pa_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +pa_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    if ((REG_P (x)
>         && (strict ? STRICT_REG_OK_FOR_BASE_P (x)
> diff --git a/gcc/config/pdp11/pdp11.cc b/gcc/config/pdp11/pdp11.cc
> index f6dd841f184..321837935c8 100644
> --- a/gcc/config/pdp11/pdp11.cc
> +++ b/gcc/config/pdp11/pdp11.cc
> @@ -1615,8 +1615,8 @@ pdp11_secondary_memory_needed (machine_mode, reg_class_t c1, reg_class_t c2)
>  */
>
>  static bool
> -pdp11_legitimate_address_p (machine_mode mode,
> -                           rtx operand, bool strict)
> +pdp11_legitimate_address_p (machine_mode mode, rtx operand, bool strict,
> +                           code_helper = ERROR_MARK)
>  {
>      rtx xfoob;
>
> diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc
> index e855bbb8195..6e8112be64a 100644
> --- a/gcc/config/pru/pru.cc
> +++ b/gcc/config/pru/pru.cc
> @@ -1466,7 +1466,8 @@ int pru_symref2ioregno (rtx op)
>  /* Implement TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P.  */
>  static bool
>  pru_addr_space_legitimate_address_p (machine_mode mode, rtx operand,
> -                                    bool strict_p, addr_space_t as)
> +                                    bool strict_p, addr_space_t as,
> +                                    code_helper = ERROR_MARK)
>  {
>    if (as == ADDR_SPACE_REGIO)
>      {
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 280aa0b33b9..31e2b9bccc2 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1163,7 +1163,8 @@ riscv_classify_address (struct riscv_address_info *info, rtx x,
>  /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
>
>  static bool
> -riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
> +riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
> +                           code_helper = ERROR_MARK)
>  {
>    struct riscv_address_info addr;
>
> diff --git a/gcc/config/rl78/rl78-protos.h b/gcc/config/rl78/rl78-protos.h
> index 7d474ffc130..813459ad8b6 100644
> --- a/gcc/config/rl78/rl78-protos.h
> +++ b/gcc/config/rl78/rl78-protos.h
> @@ -18,6 +18,9 @@
>     along with GCC; see the file COPYING3.  If not see
>     <http://www.gnu.org/licenses/>.  */
>
>
> +
> +#include "tree.h"  /* For ERROR_MARK.  */
> +
>  const char *    rl78_addsi3_internal (rtx *, unsigned int);
>  void           rl78_emit_eh_epilogue (rtx);
>  void           rl78_expand_compare (rtx *);
> @@ -33,7 +36,8 @@ int           rl78_far_p (rtx x);
>  bool           rl78_hl_b_c_addr_p (rtx);
>  int            rl78_initial_elimination_offset (int, int);
>  bool           rl78_as_legitimate_address (machine_mode, rtx,
> -                                           bool, addr_space_t);
> +                                           bool, addr_space_t,
> +                                           code_helper = ERROR_MARK);
>  int            rl78_legitimize_reload_address (rtx *, machine_mode, int,int, int);
>  enum reg_class rl78_mode_code_base_reg_class (machine_mode, addr_space_t, int, int);
>  bool           rl78_peep_movhi_p (rtx *);
> diff --git a/gcc/config/rl78/rl78.cc b/gcc/config/rl78/rl78.cc
> index 9083096c4ae..0cbd6bf780a 100644
> --- a/gcc/config/rl78/rl78.cc
> +++ b/gcc/config/rl78/rl78.cc
> @@ -1143,7 +1143,8 @@ rl78_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x ATTRIBUTE
>
>  bool
>  rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
> -                           bool strict ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED)
> +                           bool strict ATTRIBUTE_UNUSED,
> +                           addr_space_t as ATTRIBUTE_UNUSED, code_helper)
>  {
>    rtx base, index, addend;
>    bool is_far_addr = false;
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 546c353029b..efc54528b23 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -1109,7 +1109,8 @@ struct processor_costs ppca2_cost = {
>  static tree (*rs6000_veclib_handler) (combined_fn, tree, tree);
>
>
>
> -static bool rs6000_debug_legitimate_address_p (machine_mode, rtx, bool);
> +static bool rs6000_debug_legitimate_address_p (machine_mode, rtx, bool,
> +                                              code_helper = ERROR_MARK);
>  static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
>  static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
>  static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
> @@ -9854,7 +9855,8 @@ use_toc_relative_ref (rtx sym, machine_mode mode)
>     because adjacent memory cells are accessed by adding word-sized offsets
>     during assembly output.  */
>  static bool
> -rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
> +rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict,
> +                            code_helper = ERROR_MARK)
>  {
>    bool reg_offset_p = reg_offset_addressing_ok_p (mode);
>    bool quad_offset_p = mode_supports_dq_form (mode);
> @@ -9957,10 +9959,10 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
>
>  /* Debug version of rs6000_legitimate_address_p.  */
>  static bool
> -rs6000_debug_legitimate_address_p (machine_mode mode, rtx x,
> -                                  bool reg_ok_strict)
> +rs6000_debug_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict,
> +                                  code_helper ch)
>  {
> -  bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
> +  bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict, ch);
>    fprintf (stderr,
>            "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
>            "strict = %d, reload = %s, code = %s\n",
> diff --git a/gcc/config/rx/rx.cc b/gcc/config/rx/rx.cc
> index 726b00a3193..245c6a4413d 100644
> --- a/gcc/config/rx/rx.cc
> +++ b/gcc/config/rx/rx.cc
> @@ -179,7 +179,8 @@ rx_small_data_operand (rtx op)
>
>  static bool
>  rx_is_legitimate_address (machine_mode mode, rtx x,
> -                         bool strict ATTRIBUTE_UNUSED)
> +                         bool strict ATTRIBUTE_UNUSED,
> +                         code_helper = ERROR_MARK)
>  {
>    if (RTX_OK_FOR_BASE (x, strict))
>      /* Register Indirect.  */
> diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
> index 9284477396d..5b8826162a9 100644
> --- a/gcc/config/s390/s390.cc
> +++ b/gcc/config/s390/s390.cc
> @@ -4914,7 +4914,8 @@ s390_expand_plus_operand (rtx target, rtx src,
>     STRICT specifies whether strict register checking applies.  */
>
>  static bool
> -s390_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
> +s390_legitimate_address_p (machine_mode mode, rtx addr, bool strict,
> +                          code_helper = ERROR_MARK)
>  {
>    struct s390_address ad;
>
> diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
> index 938f7aa6281..294faf7c0c3 100644
> --- a/gcc/config/sh/sh.cc
> +++ b/gcc/config/sh/sh.cc
> @@ -266,7 +266,8 @@ static reg_class_t sh_preferred_reload_class (rtx, reg_class_t);
>  static reg_class_t sh_secondary_reload (bool, rtx, reg_class_t,
>                                          machine_mode,
>                                          struct secondary_reload_info *);
> -static bool sh_legitimate_address_p (machine_mode, rtx, bool);
> +static bool sh_legitimate_address_p (machine_mode, rtx, bool,
> +                                    code_helper = ERROR_MARK);
>  static rtx sh_legitimize_address (rtx, rtx, machine_mode);
>  static rtx sh_delegitimize_address (rtx);
>  static bool sh_cannot_substitute_mem_equiv_p (rtx);
> @@ -9038,7 +9039,7 @@ sh_legitimate_index_p (machine_mode mode, rtx op, bool consider_sh2a,
>           GBR
>           GBR+disp  */
>  static bool
> -sh_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +sh_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    if (REG_P (x) && REGNO (x) == GBR_REG)
>      return true;
> diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
> index 0aade05faf5..82e57952414 100644
> --- a/gcc/config/sparc/sparc.cc
> +++ b/gcc/config/sparc/sparc.cc
> @@ -607,7 +607,8 @@ static void sparc_emit_set_const64 (rtx, rtx);
>  static void sparc_output_addr_vec (rtx);
>  static void sparc_output_addr_diff_vec (rtx);
>  static void sparc_output_deferred_case_vectors (void);
> -static bool sparc_legitimate_address_p (machine_mode, rtx, bool);
> +static bool sparc_legitimate_address_p (machine_mode, rtx, bool,
> +                                       code_helper = ERROR_MARK);
>  static bool sparc_legitimate_constant_p (machine_mode, rtx);
>  static rtx sparc_builtin_saveregs (void);
>  static int epilogue_renumber (rtx *, int);
> @@ -4529,7 +4530,8 @@ sparc_pic_register_p (rtx x)
>     ordinarily.  This changes a bit when generating PIC.  */
>
>  static bool
> -sparc_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
> +sparc_legitimate_address_p (machine_mode mode, rtx addr, bool strict,
> +                           code_helper)
>  {
>    rtx rs1 = NULL, rs2 = NULL, imm1 = NULL;
>
> diff --git a/gcc/config/stormy16/stormy16-protos.h b/gcc/config/stormy16/stormy16-protos.h
> index f90d88eba6f..27ae023bcb3 100644
> --- a/gcc/config/stormy16/stormy16-protos.h
> +++ b/gcc/config/stormy16/stormy16-protos.h
> @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
>  along with GCC; see the file COPYING3.  If not see
>  <http://www.gnu.org/licenses/>.  */
>
> -
> +#include "tree.h"  /* For ERROR_MARK.  */
>
>  extern struct xstormy16_stack_layout xstormy16_compute_stack_layout (void);
>  extern void xstormy16_expand_prologue (void);
> @@ -65,6 +65,7 @@ extern const char * xstormy16_output_shift (machine_mode, enum rtx_code,
>                                             rtx, rtx, rtx);
>  extern bool  xstormy16_below100_symbol (rtx, machine_mode);
>  extern bool  xstormy16_splittable_below100_operand (rtx, machine_mode);
> -extern bool xstormy16_legitimate_address_p (machine_mode, rtx, bool);
> +extern bool xstormy16_legitimate_address_p (machine_mode, rtx, bool,
> +                                           code_helper = ERROR_MARK);
>  #endif
>
> diff --git a/gcc/config/stormy16/stormy16.cc b/gcc/config/stormy16/stormy16.cc
> index cd453c2a2f7..10887153906 100644
> --- a/gcc/config/stormy16/stormy16.cc
> +++ b/gcc/config/stormy16/stormy16.cc
> @@ -795,8 +795,8 @@ xstormy16_expand_andqi3 (rtx *operands)
>    && (INTVAL (X) + (OFFSET) < 0x100 || INTVAL (X) + (OFFSET) >= 0x7F00))
>
>  bool
> -xstormy16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
> -                               rtx x, bool strict)
> +xstormy16_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
> +                               bool strict, code_helper)
>  {
>    if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0))
>      return true;
> diff --git a/gcc/config/v850/v850.cc b/gcc/config/v850/v850.cc
> index 0fb72716b17..416c2841a5c 100644
> --- a/gcc/config/v850/v850.cc
> +++ b/gcc/config/v850/v850.cc
> @@ -3030,7 +3030,8 @@ v850_rtx_ok_for_base_p (const_rtx x, bool strict_p)
>
>  static bool
>  v850_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
> -                          addr_space_t as ATTRIBUTE_UNUSED)
> +                          addr_space_t as ATTRIBUTE_UNUSED,
> +                          code_helper = ERROR_MARK)
>  {
>    gcc_assert (ADDR_SPACE_GENERIC_P (as));
>
> diff --git a/gcc/config/vax/vax.cc b/gcc/config/vax/vax.cc
> index 82a176d3bfc..df9478d881a 100644
> --- a/gcc/config/vax/vax.cc
> +++ b/gcc/config/vax/vax.cc
> @@ -46,7 +46,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "target-def.h"
>
>  static void vax_option_override (void);
> -static bool vax_legitimate_address_p (machine_mode, rtx, bool);
> +static bool vax_legitimate_address_p (machine_mode, rtx, bool,
> +                                     code_helper = ERROR_MARK);
>  static void vax_file_start (void);
>  static void vax_init_libfuncs (void);
>  static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
> @@ -1902,7 +1903,7 @@ indexable_address_p (rtx xfoo0, rtx xfoo1, machine_mode mode, bool strict)
>     The MODE argument is the machine mode for the MEM expression
>     that wants to use this address.  */
>  bool
> -vax_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +vax_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    rtx xfoo0, xfoo1;
>
> diff --git a/gcc/config/visium/visium.cc b/gcc/config/visium/visium.cc
> index 48a61744db6..5fadbc80be0 100644
> --- a/gcc/config/visium/visium.cc
> +++ b/gcc/config/visium/visium.cc
> @@ -194,7 +194,8 @@ static rtx_insn *visium_md_asm_adjust (vec<rtx> &, vec<rtx> &,
>
>  static bool visium_legitimate_constant_p (machine_mode, rtx);
>
> -static bool visium_legitimate_address_p (machine_mode, rtx, bool);
> +static bool visium_legitimate_address_p (machine_mode, rtx, bool,
> +                                        code_helper = ERROR_MARK);
>
>  static bool visium_print_operand_punct_valid_p (unsigned char);
>  static void visium_print_operand (FILE *, rtx, int);
> @@ -1818,7 +1819,7 @@ rtx_ok_for_offset_p (machine_mode mode, rtx op)
>     kind of register is required.  */
>
>  static bool
> -visium_legitimate_address_p (machine_mode mode, rtx x, bool strict)
> +visium_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
>  {
>    rtx base;
>    unsigned int regno;
> diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
> index dd35e63c094..897cf7363f4 100644
> --- a/gcc/config/xtensa/xtensa.cc
> +++ b/gcc/config/xtensa/xtensa.cc
> @@ -123,7 +123,8 @@ static bool xtensa_mode_dependent_address_p (const_rtx, addr_space_t);
>  static bool xtensa_return_in_msb (const_tree);
>  static void printx (FILE *, signed int);
>  static rtx xtensa_builtin_saveregs (void);
> -static bool xtensa_legitimate_address_p (machine_mode, rtx, bool);
> +static bool xtensa_legitimate_address_p (machine_mode, rtx, bool,
> +                                        code_helper = ERROR_MARK);
>  static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
>                                                         int) ATTRIBUTE_UNUSED;
>  static section *xtensa_select_rtx_section (machine_mode, rtx,
> @@ -2296,9 +2297,9 @@ xtensa_emit_sibcall (int callop, rtx *operands)
>    return result;
>  }
>
> -
>  bool
> -xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
> +xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict,
> +                            code_helper)
>  {
>    /* Allow constant pool addresses.  */
>    if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
> diff --git a/gcc/coretypes.h b/gcc/coretypes.h
> index ca8837cef67..3e9a2f19e27 100644
> --- a/gcc/coretypes.h
> +++ b/gcc/coretypes.h
> @@ -99,6 +99,7 @@ typedef const union tree_node *const_tree;
>  struct gimple;
>  typedef gimple *gimple_seq;
>  struct gimple_stmt_iterator;
> +class code_helper;
>
>  /* Forward decls for leaf gimple subclasses (for individual gimple codes).
>     Keep this in the same order as the corresponding codes in gimple.def.  */
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 95ba56e05ae..e4d0cc43f41 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -5853,9 +5853,16 @@ the maximum number that @code{TARGET_LEGITIMATE_ADDRESS_P} would ever
>  accept.
>  @end defmac
>
> -@deftypefn {Target Hook} bool TARGET_LEGITIMATE_ADDRESS_P (machine_mode @var{mode}, rtx @var{x}, bool @var{strict})
> +@deftypefn {Target Hook} bool TARGET_LEGITIMATE_ADDRESS_P (machine_mode @var{mode}, rtx @var{x}, bool @var{strict}, code_helper @var{ch})
>  A function that returns whether @var{x} (an RTX) is a legitimate memory
>  address on the target machine for a memory operand of mode @var{mode}.
> +If @var{ch} is not @code{ERROR_MARK}, it can be called from middle-end to
> +determine if it is valid to use @var{x} as a memory operand for RTX insn
> +which is generated for the given code_helper @var{ch}.  For example,
> +assuming the given @var{ch} is IFN_LEN_LOAD, on some target its underlying
> +hardware instructions support fewer addressing modes than what are for the
> +normal vector load and store, then with this @var{ch} target can know the
> +actual use context and return more exact result.
>
>  Legitimate addresses are defined in two variants: a strict variant and a
>  non-strict one.  The @var{strict} parameter chooses which variant is
> @@ -10992,11 +10999,12 @@ version of this hook returns true for the modes returned by either the
>  target hooks for the given address space.
>  @end deftypefn
>
> -@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P (machine_mode @var{mode}, rtx @var{exp}, bool @var{strict}, addr_space_t @var{as})
> +@deftypefn {Target Hook} bool TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P (machine_mode @var{mode}, rtx @var{exp}, bool @var{strict}, addr_space_t @var{as}, code_helper @var{ch})
>  Define this to return true if @var{exp} is a valid address for mode
> -@var{mode} in the named address space @var{as}.  The @var{strict}
> -parameter says whether strict addressing is in effect after reload has
> -finished.  This target hook is the same as the
> +@var{mode} in the named address space @var{as} with the use context
> +@var{ch}.  The @var{strict} parameter says whether strict addressing
> +is in effect after reload has finished.  The @var{ch} indicates what
> +context @var{exp} will be used for.  This target hook is the same as the
>  @code{TARGET_LEGITIMATE_ADDRESS_P} target hook, except that it includes
>  explicit named address space support.
>  @end deftypefn
> diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
> index 4dc2d70c402..cb9cbac5bb3 100644
> --- a/gcc/lra-constraints.cc
> +++ b/gcc/lra-constraints.cc
> @@ -336,7 +336,8 @@ valid_address_p (machine_mode mode ATTRIBUTE_UNUSED,
>   win:
>    return 1;
>  #else
> -  return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
> +  return targetm.addr_space.legitimate_address_p (mode, addr, 0, as,
> +                                                 ERROR_MARK);
>  #endif
>  }
>
> diff --git a/gcc/recog.cc b/gcc/recog.cc
> index 37432087812..692c258def6 100644
> --- a/gcc/recog.cc
> +++ b/gcc/recog.cc
> @@ -1813,7 +1813,8 @@ memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
>   win:
>    return true;
>  #else
> -  return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
> +  return targetm.addr_space.legitimate_address_p (mode, addr, 0, as,
> +                                                 ERROR_MARK);
>  #endif
>  }
>
> diff --git a/gcc/reload.cc b/gcc/reload.cc
> index d079bc120d5..0be21f7b61e 100644
> --- a/gcc/reload.cc
> +++ b/gcc/reload.cc
> @@ -2172,7 +2172,8 @@ strict_memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
>   win:
>    return true;
>  #else
> -  return targetm.addr_space.legitimate_address_p (mode, addr, 1, as);
> +  return targetm.addr_space.legitimate_address_p (mode, addr, 1, as,
> +                                                 ERROR_MARK);
>  #endif
>  }
>
>
> diff --git a/gcc/target.def b/gcc/target.def
> index 7d684296c17..a500aeb6714 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -2897,6 +2897,13 @@ DEFHOOK
>  (legitimate_address_p,
>   "A function that returns whether @var{x} (an RTX) is a legitimate memory\n\
>  address on the target machine for a memory operand of mode @var{mode}.\n\
> +If @var{ch} is not @code{ERROR_MARK}, it can be called from middle-end to\n\
> +determine if it is valid to use @var{x} as a memory operand for RTX insn\n\
> +which is generated for the given code_helper @var{ch}.  For example,\n\
> +assuming the given @var{ch} is IFN_LEN_LOAD, on some target its underlying\n\
> +hardware instructions support fewer addressing modes than what are for the\n\
> +normal vector load and store, then with this @var{ch} target can know the\n\
> +actual use context and return more exact result.\n\
>  \n\
>  Legitimate addresses are defined in two variants: a strict variant and a\n\
>  non-strict one.  The @var{strict} parameter chooses which variant is\n\
> @@ -2957,7 +2964,7 @@ that case and the non-strict variant otherwise.\n\
>  \n\
>  Using the hook is usually simpler because it limits the number of\n\
>  files that are recompiled when changes are made.",
> - bool, (machine_mode mode, rtx x, bool strict),
> + bool, (machine_mode mode, rtx x, bool strict, code_helper ch),
>   default_legitimate_address_p)
>
>  /* True if the given constant can be put into an object_block.  */
> @@ -3348,12 +3355,13 @@ target hooks for the given address space.",
>  DEFHOOK
>  (legitimate_address_p,
>   "Define this to return true if @var{exp} is a valid address for mode\n\
> -@var{mode} in the named address space @var{as}.  The @var{strict}\n\
> -parameter says whether strict addressing is in effect after reload has\n\
> -finished.  This target hook is the same as the\n\
> +@var{mode} in the named address space @var{as} with the use context\n\
> +@var{ch}.  The @var{strict} parameter says whether strict addressing\n\
> +is in effect after reload has finished.  The @var{ch} indicates what\n\
> +context @var{exp} will be used for.  This target hook is the same as the\n\
>  @code{TARGET_LEGITIMATE_ADDRESS_P} target hook, except that it includes\n\
>  explicit named address space support.",
> - bool, (machine_mode mode, rtx exp, bool strict, addr_space_t as),
> + bool, (machine_mode mode, rtx exp, bool strict, addr_space_t as, code_helper ch),
>   default_addr_space_legitimate_address_p)
>
>  /* Return an updated address to convert an invalid pointer to a named
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index e190369f87a..4ef53267e50 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -99,7 +99,8 @@ along with GCC; see the file COPYING3.  If not see
>  bool
>  default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
>                               rtx addr ATTRIBUTE_UNUSED,
> -                             bool strict ATTRIBUTE_UNUSED)
> +                             bool strict ATTRIBUTE_UNUSED,
> +                             code_helper ATTRIBUTE_UNUSED)
>  {
>  #ifdef GO_IF_LEGITIMATE_ADDRESS
>    /* Defer to the old implementation using a goto.  */
> @@ -1680,9 +1681,10 @@ target_default_pointer_address_modes_p (void)
>  bool
>  default_addr_space_legitimate_address_p (machine_mode mode, rtx mem,
>                                          bool strict,
> -                                        addr_space_t as ATTRIBUTE_UNUSED)
> +                                        addr_space_t as ATTRIBUTE_UNUSED,
> +                                        code_helper code)
>  {
> -  return targetm.legitimate_address_p (mode, mem, strict);
> +  return targetm.legitimate_address_p (mode, mem, strict, code);
>  }
>
>  /* Named address space version of LEGITIMIZE_ADDRESS.
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 1a0db8dddd5..761225512b7 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -20,7 +20,7 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_TARGHOOKS_H
>  #define GCC_TARGHOOKS_H
>
> -extern bool default_legitimate_address_p (machine_mode, rtx, bool);
> +extern bool default_legitimate_address_p (machine_mode, rtx, bool, code_helper);
>
>  extern void default_external_libcall (rtx);
>  extern rtx default_legitimize_address (rtx, rtx, machine_mode);
> @@ -202,8 +202,8 @@ extern scalar_int_mode default_addr_space_pointer_mode (addr_space_t);
>  extern scalar_int_mode default_addr_space_address_mode (addr_space_t);
>  extern bool default_addr_space_valid_pointer_mode (scalar_int_mode,
>                                                    addr_space_t);
> -extern bool default_addr_space_legitimate_address_p (machine_mode, rtx,
> -                                                    bool, addr_space_t);
> +extern bool default_addr_space_legitimate_address_p (machine_mode, rtx, bool,
> +                                                    addr_space_t, code_helper);
>  extern rtx default_addr_space_legitimize_address (rtx, rtx, machine_mode,
>                                                   addr_space_t);
>  extern bool default_addr_space_subset_p (addr_space_t, addr_space_t);
> --
> 2.39.3

  parent reply	other threads:[~2023-06-30  8:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-30  5:37 Kewen.Lin
2023-06-30  5:46 ` [PATCH 2/3] ivopts: Call valid_mem_ref_p " Kewen.Lin
2023-06-30  8:58   ` Richard Biener
2023-08-14  7:53   ` Jan-Benedict Glaw
2023-08-14  8:47     ` Kewen.Lin
2023-08-15  3:20       ` Hans-Peter Nilsson
2023-06-30  5:57 ` [PATCH 3/3] rs6000: Teach legitimate_address_p about LEN_{LOAD,STORE} [PR110248] Kewen.Lin
2023-06-30  8:56 ` Richard Biener [this message]
2023-06-30  9:13   ` [PATCH 1/3] targhooks: Extend legitimate_address_p with code_helper [PR110248] Kewen.Lin
2023-08-07 10:15     ` Kewen.Lin
2023-08-07 11:58       ` Richard Biener

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='CAFiYyc2=jQBTtmPePwS=y3O+eso3iCZ3uSeUO2iHugfWURiq1Q@mail.gmail.com' \
    --to=richard.guenther@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=linkw@linux.ibm.com \
    --cc=richard.sandiford@arm.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).