Uros Bizjak via Gcc-patches <gcc-patches@gcc.gnu.org> 于2023年8月31日周四 18:16写道: > > On Thu, Aug 31, 2023 at 10:20 AM Hongyu Wang <hongyu.w...@intel.com> wrote: > > > > From: Kong Lingling <lingling.k...@intel.com> > > > > Current reload infrastructure does not support selective base_reg_class > > for backend insn. Add insn argument to base_reg_class for > > lra/reload usage. > > I don't think this is the correct approach. Ideally, a memory > constraint should somehow encode its BASE/INDEX register class. > Instead of passing "insn", simply a different constraint could be used > in the constraint string of the relevant insn.
We tried constraint only at the beginning, but then we found the reload infrastructure does not work like that. The BASE/INDEX reg classes are determined before choosing alternatives, in process_address under curr_insn_transform. Process_address creates the mem operand according to the BASE/INDEX reg class. Then, the memory operand constraint check will evaluate the mem op with targetm.legitimate_address_p. If we want to make use of EGPR in base/index we need to either extend BASE/INDEX reg class in the backend, or, for specific insns, add a target hook to tell reload that the extended reg class with EGPR can be used to construct memory operand. CC'd Vladimir as git send-mail failed to add recipient. > > Uros. > > > > gcc/ChangeLog: > > > > * addresses.h (base_reg_class): Add insn argument. > > Pass to MODE_CODE_BASE_REG_CLASS. > > (regno_ok_for_base_p_1): Add insn argument. > > Pass to REGNO_MODE_CODE_OK_FOR_BASE_P. > > (regno_ok_for_base_p): Add insn argument and parse to > > ok_for_base_p_1. > > * config/avr/avr.h (MODE_CODE_BASE_REG_CLASS): Add insn argument. > > (REGNO_MODE_CODE_OK_FOR_BASE_P): Ditto. > > * config/gcn/gcn.h (MODE_CODE_BASE_REG_CLASS): Ditto. > > (REGNO_MODE_CODE_OK_FOR_BASE_P): Ditto. > > * config/rl78/rl78.h (REGNO_MODE_CODE_OK_FOR_BASE_P): Ditto. > > (MODE_CODE_BASE_REG_CLASS): Ditto. > > * doc/tm.texi: Add insn argument for MODE_CODE_BASE_REG_CLASS > > and REGNO_MODE_CODE_OK_FOR_BASE_P. > > * doc/tm.texi.in: Ditto. > > * lra-constraints.cc (process_address_1): Pass insn to > > base_reg_class. > > (curr_insn_transform): Ditto. > > * reload.cc (find_reloads): Ditto. > > (find_reloads_address): Ditto. > > (find_reloads_address_1): Ditto. > > (find_reloads_subreg_address): Ditto. > > * reload1.cc (maybe_fix_stack_asms): Ditto. > > --- > > gcc/addresses.h | 15 +++++++++------ > > gcc/config/avr/avr.h | 5 +++-- > > gcc/config/gcn/gcn.h | 4 ++-- > > gcc/config/rl78/rl78.h | 6 ++++-- > > gcc/doc/tm.texi | 8 ++++++-- > > gcc/doc/tm.texi.in | 8 ++++++-- > > gcc/lra-constraints.cc | 15 +++++++++------ > > gcc/reload.cc | 30 ++++++++++++++++++------------ > > gcc/reload1.cc | 2 +- > > 9 files changed, 58 insertions(+), 35 deletions(-) > > > > diff --git a/gcc/addresses.h b/gcc/addresses.h > > index 3519c241c6d..08b100cfe6d 100644 > > --- a/gcc/addresses.h > > +++ b/gcc/addresses.h > > @@ -28,11 +28,12 @@ inline enum reg_class > > base_reg_class (machine_mode mode ATTRIBUTE_UNUSED, > > addr_space_t as ATTRIBUTE_UNUSED, > > enum rtx_code outer_code ATTRIBUTE_UNUSED, > > - enum rtx_code index_code ATTRIBUTE_UNUSED) > > + enum rtx_code index_code ATTRIBUTE_UNUSED, > > + rtx_insn *insn ATTRIBUTE_UNUSED = NULL) > > { > > #ifdef MODE_CODE_BASE_REG_CLASS > > return MODE_CODE_BASE_REG_CLASS (MACRO_MODE (mode), as, outer_code, > > - index_code); > > + index_code, insn); > > #else > > #ifdef MODE_BASE_REG_REG_CLASS > > if (index_code == REG) > > @@ -56,11 +57,12 @@ ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED, > > machine_mode mode ATTRIBUTE_UNUSED, > > addr_space_t as ATTRIBUTE_UNUSED, > > enum rtx_code outer_code ATTRIBUTE_UNUSED, > > - enum rtx_code index_code ATTRIBUTE_UNUSED) > > + enum rtx_code index_code ATTRIBUTE_UNUSED, > > + rtx_insn* insn ATTRIBUTE_UNUSED = NULL) > > { > > #ifdef REGNO_MODE_CODE_OK_FOR_BASE_P > > return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, MACRO_MODE (mode), as, > > - outer_code, index_code); > > + outer_code, index_code, insn); > > #else > > #ifdef REGNO_MODE_OK_FOR_REG_BASE_P > > if (index_code == REG) > > @@ -79,12 +81,13 @@ ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED, > > > > inline bool > > regno_ok_for_base_p (unsigned regno, machine_mode mode, addr_space_t as, > > - enum rtx_code outer_code, enum rtx_code index_code) > > + enum rtx_code outer_code, enum rtx_code index_code, > > + rtx_insn* insn = NULL) > > { > > if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0) > > regno = reg_renumber[regno]; > > > > - return ok_for_base_p_1 (regno, mode, as, outer_code, index_code); > > + return ok_for_base_p_1 (regno, mode, as, outer_code, index_code, insn); > > } > > > > #endif /* GCC_ADDRESSES_H */ > > diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h > > index 8e7e00db13b..1d090fe0838 100644 > > --- a/gcc/config/avr/avr.h > > +++ b/gcc/config/avr/avr.h > > @@ -280,12 +280,13 @@ enum reg_class { > > > > #define REGNO_REG_CLASS(R) avr_regno_reg_class(R) > > > > -#define MODE_CODE_BASE_REG_CLASS(mode, as, outer_code, index_code) \ > > +#define MODE_CODE_BASE_REG_CLASS(mode, as, outer_code, index_code, insn) > > \ > > avr_mode_code_base_reg_class (mode, as, outer_code, index_code) > > > > #define INDEX_REG_CLASS NO_REGS > > > > -#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, as, outer_code, > > index_code) \ > > +#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, as, outer_code, \ > > + index_code, insn) \ > > avr_regno_mode_code_ok_for_base_p (num, mode, as, outer_code, index_code) > > > > #define REGNO_OK_FOR_INDEX_P(NUM) 0 > > diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h > > index 4ff9a5d4d12..b56702a77fd 100644 > > --- a/gcc/config/gcn/gcn.h > > +++ b/gcc/config/gcn/gcn.h > > @@ -437,9 +437,9 @@ enum reg_class > > 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 }} > > > > #define REGNO_REG_CLASS(REGNO) gcn_regno_reg_class (REGNO) > > -#define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX) \ > > +#define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX, INSN) \ > > gcn_mode_code_base_reg_class (MODE, AS, OUTER, INDEX) > > -#define REGNO_MODE_CODE_OK_FOR_BASE_P(NUM, MODE, AS, OUTER, INDEX) \ > > +#define REGNO_MODE_CODE_OK_FOR_BASE_P(NUM, MODE, AS, OUTER, INDEX, INSN) \ > > gcn_regno_mode_code_ok_for_base_p (NUM, MODE, AS, OUTER, INDEX) > > #define INDEX_REG_CLASS VGPR_REGS > > #define REGNO_OK_FOR_INDEX_P(regno) regno_ok_for_index_p (regno) > > diff --git a/gcc/config/rl78/rl78.h b/gcc/config/rl78/rl78.h > > index 7a7c6a44ba2..d0ed9162292 100644 > > --- a/gcc/config/rl78/rl78.h > > +++ b/gcc/config/rl78/rl78.h > > @@ -375,10 +375,12 @@ enum reg_class > > > > #define REGNO_OK_FOR_INDEX_P(regno) REGNO_OK_FOR_BASE_P (regno) > > > > -#define REGNO_MODE_CODE_OK_FOR_BASE_P(regno, mode, address_space, > > outer_code, index_code) \ > > +#define REGNO_MODE_CODE_OK_FOR_BASE_P(regno, mode, address_space, > > outer_code, \ > > + index_code, insn) > > \ > > rl78_regno_mode_code_ok_for_base_p (regno, mode, address_space, > > outer_code, index_code) > > > > -#define MODE_CODE_BASE_REG_CLASS(mode, address_space, outer_code, > > index_code) \ > > +#define MODE_CODE_BASE_REG_CLASS(mode, address_space, outer_code, > > index_code, \ > > + insn) > > \ > > rl78_mode_code_base_reg_class (mode, address_space, outer_code, > > index_code) > > > > #define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \ > > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi > > index d0d47b0d471..a4239e3de10 100644 > > --- a/gcc/doc/tm.texi > > +++ b/gcc/doc/tm.texi > > @@ -2533,7 +2533,7 @@ register address. You should define this macro if > > base plus index > > addresses have different requirements than other base register uses. > > @end defmac > > > > -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, > > @var{outer_code}, @var{index_code}) > > +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, > > @var{outer_code}, @var{index_code}, @var{insn}) > > A C expression whose value is the register class to which a valid > > base register for a memory reference in mode @var{mode} to address > > space @var{address_space} must belong. @var{outer_code} and > > @var{index_code} > > @@ -2542,6 +2542,8 @@ the code of the immediately enclosing expression > > (@code{MEM} for the top level > > of an address, @code{ADDRESS} for something that occurs in an > > @code{address_operand}). @var{index_code} is the code of the corresponding > > index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} > > otherwise. > > +@code{insn} indicates insn specific base register class should be subset > > +of the original base register class. > > @end defmac > > > > @defmac INDEX_REG_CLASS > > @@ -2579,7 +2581,7 @@ Use of this macro is deprecated; please use the more > > general > > @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. > > @end defmac > > > > -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, > > @var{address_space}, @var{outer_code}, @var{index_code}) > > +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, > > @var{address_space}, @var{outer_code}, @var{index_code}, @var{insn}) > > A C expression which is nonzero if register number @var{num} is > > suitable for use as a base register in operand addresses, accessing > > memory in mode @var{mode} in address space @var{address_space}. > > @@ -2592,6 +2594,8 @@ address, @code{ADDRESS} for something that occurs in > > an > > corresponding index expression if @var{outer_code} is @code{PLUS}; > > @code{SCRATCH} otherwise. The mode may be @code{VOIDmode} for addresses > > that appear outside a @code{MEM}, i.e., as an @code{address_operand}. > > +@code{insn} indicates insn specific base register class should be subset > > +of the original base register class. > > @end defmac > > > > @defmac REGNO_OK_FOR_INDEX_P (@var{num}) > > diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in > > index 4ac96dc357d..72898f3adba 100644 > > --- a/gcc/doc/tm.texi.in > > +++ b/gcc/doc/tm.texi.in > > @@ -2128,7 +2128,7 @@ register address. You should define this macro if > > base plus index > > addresses have different requirements than other base register uses. > > @end defmac > > > > -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, > > @var{outer_code}, @var{index_code}) > > +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, > > @var{outer_code}, @var{index_code}, @var{insn}) > > A C expression whose value is the register class to which a valid > > base register for a memory reference in mode @var{mode} to address > > space @var{address_space} must belong. @var{outer_code} and > > @var{index_code} > > @@ -2137,6 +2137,8 @@ the code of the immediately enclosing expression > > (@code{MEM} for the top level > > of an address, @code{ADDRESS} for something that occurs in an > > @code{address_operand}). @var{index_code} is the code of the corresponding > > index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} > > otherwise. > > +@code{insn} indicates insn specific base register class should be subset > > +of the original base register class. > > @end defmac > > > > @defmac INDEX_REG_CLASS > > @@ -2174,7 +2176,7 @@ Use of this macro is deprecated; please use the more > > general > > @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. > > @end defmac > > > > -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, > > @var{address_space}, @var{outer_code}, @var{index_code}) > > +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, > > @var{address_space}, @var{outer_code}, @var{index_code}, @var{insn}) > > A C expression which is nonzero if register number @var{num} is > > suitable for use as a base register in operand addresses, accessing > > memory in mode @var{mode} in address space @var{address_space}. > > @@ -2187,6 +2189,8 @@ address, @code{ADDRESS} for something that occurs in > > an > > corresponding index expression if @var{outer_code} is @code{PLUS}; > > @code{SCRATCH} otherwise. The mode may be @code{VOIDmode} for addresses > > that appear outside a @code{MEM}, i.e., as an @code{address_operand}. > > +@code{insn} indicates insn specific base register class should be subset > > +of the original base register class. > > @end defmac > > > > @defmac REGNO_OK_FOR_INDEX_P (@var{num}) > > diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc > > index c718bedff32..9e7915ce934 100644 > > --- a/gcc/lra-constraints.cc > > +++ b/gcc/lra-constraints.cc > > @@ -3672,7 +3672,7 @@ process_address_1 (int nop, bool check_only_p, > > REGNO (*ad.base_term)) != NULL_RTX) > > ? after : NULL), > > base_reg_class (ad.mode, ad.as, ad.base_outer_code, > > - get_index_code (&ad))))) > > + get_index_code (&ad), curr_insn)))) > > { > > change_p = true; > > if (ad.base_term2 != NULL) > > @@ -3722,7 +3722,8 @@ process_address_1 (int nop, bool check_only_p, > > rtx_insn *last = get_last_insn (); > > int code = -1; > > enum reg_class cl = base_reg_class (ad.mode, ad.as, > > - SCRATCH, SCRATCH); > > + SCRATCH, SCRATCH, > > + curr_insn); > > rtx addr = *ad.inner; > > > > new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, NULL, "addr"); > > @@ -3785,7 +3786,8 @@ process_address_1 (int nop, bool check_only_p, > > /* index * scale + disp => new base + index * scale, > > case (1) above. */ > > enum reg_class cl = base_reg_class (ad.mode, ad.as, PLUS, > > - GET_CODE (*ad.index)); > > + GET_CODE (*ad.index), > > + curr_insn); > > > > lra_assert (INDEX_REG_CLASS != NO_REGS); > > new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, NULL, "disp"); > > @@ -3846,7 +3848,7 @@ process_address_1 (int nop, bool check_only_p, > > *ad.base_term = XEXP (SET_SRC (set), 0); > > *ad.disp_term = XEXP (SET_SRC (set), 1); > > cl = base_reg_class (ad.mode, ad.as, ad.base_outer_code, > > - get_index_code (&ad)); > > + get_index_code (&ad), curr_insn); > > regno = REGNO (*ad.base_term); > > if (regno >= FIRST_PSEUDO_REGISTER > > && cl != lra_get_allocno_class (regno)) > > @@ -3890,7 +3892,8 @@ process_address_1 (int nop, bool check_only_p, > > else > > { > > enum reg_class cl = base_reg_class (ad.mode, ad.as, > > - SCRATCH, SCRATCH); > > + SCRATCH, SCRATCH, > > + curr_insn); > > rtx addr = *ad.inner; > > > > new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, NULL, "addr"); > > @@ -4639,7 +4642,7 @@ curr_insn_transform (bool check_only_p) > > > > push_to_sequence (before); > > rclass = base_reg_class (GET_MODE (op), MEM_ADDR_SPACE (op), > > - MEM, SCRATCH); > > + MEM, SCRATCH, curr_insn); > > if (GET_RTX_CLASS (code) == RTX_AUTOINC) > > new_reg = emit_inc (rclass, *loc, *loc, > > /* This value does not matter for MODIFY. > > */ > > diff --git a/gcc/reload.cc b/gcc/reload.cc > > index 2126bdd117c..72f7e27af15 100644 > > --- a/gcc/reload.cc > > +++ b/gcc/reload.cc > > @@ -3321,7 +3321,7 @@ find_reloads (rtx_insn *insn, int replace, int > > ind_levels, int live_known, > > were handled in find_reloads_address. */ > > this_alternative[i] > > = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, > > - ADDRESS, SCRATCH); > > + ADDRESS, SCRATCH, insn); > > win = 1; > > badop = 0; > > break; > > @@ -3508,7 +3508,7 @@ find_reloads (rtx_insn *insn, int replace, int > > ind_levels, int live_known, > > the address into a base register. */ > > this_alternative[i] > > = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, > > - ADDRESS, SCRATCH); > > + ADDRESS, SCRATCH, insn); > > badop = 0; > > break; > > > > @@ -4018,7 +4018,7 @@ find_reloads (rtx_insn *insn, int replace, int > > ind_levels, int live_known, > > operand_reloadnum[i] > > = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, > > &XEXP (recog_data.operand[i], 0), (rtx*) 0, > > - base_reg_class (VOIDmode, as, MEM, SCRATCH), > > + base_reg_class (VOIDmode, as, MEM, SCRATCH, > > insn), > > address_mode, > > VOIDmode, 0, 0, i, RELOAD_OTHER); > > rld[operand_reloadnum[i]].inc > > @@ -4897,7 +4897,8 @@ find_reloads_address (machine_mode mode, rtx > > *memrefloc, rtx ad, > > if (reg_equiv_constant (regno) != 0) > > { > > find_reloads_address_part (reg_equiv_constant (regno), loc, > > - base_reg_class (mode, as, MEM, > > SCRATCH), > > + base_reg_class (mode, as, MEM, > > + SCRATCH, insn), > > GET_MODE (ad), opnum, type, > > ind_levels); > > return 1; > > } > > @@ -4966,7 +4967,7 @@ find_reloads_address (machine_mode mode, rtx > > *memrefloc, rtx ad, > > > > /* If we do not have one of the cases above, we must do the reload. > > */ > > push_reload (ad, NULL_RTX, loc, (rtx*) 0, > > - base_reg_class (mode, as, MEM, SCRATCH), > > + base_reg_class (mode, as, MEM, SCRATCH, insn), > > GET_MODE (ad), VOIDmode, 0, 0, opnum, type); > > return 1; > > } > > @@ -5123,7 +5124,8 @@ find_reloads_address (machine_mode mode, rtx > > *memrefloc, rtx ad, > > reload the sum into a base reg. > > That will at least work. */ > > find_reloads_address_part (ad, loc, > > - base_reg_class (mode, as, MEM, > > SCRATCH), > > + base_reg_class (mode, as, MEM, > > + SCRATCH, insn), > > GET_MODE (ad), opnum, type, > > ind_levels); > > } > > return ! removed_and; > > @@ -5203,7 +5205,7 @@ find_reloads_address (machine_mode mode, rtx > > *memrefloc, rtx ad, > > op_index == 0 ? addend : offset_reg); > > *loc = ad; > > > > - cls = base_reg_class (mode, as, MEM, GET_CODE (addend)); > > + cls = base_reg_class (mode, as, MEM, GET_CODE (addend), insn); > > find_reloads_address_part (XEXP (ad, op_index), > > &XEXP (ad, op_index), cls, > > GET_MODE (ad), opnum, type, > > ind_levels); > > @@ -5261,7 +5263,8 @@ find_reloads_address (machine_mode mode, rtx > > *memrefloc, rtx ad, > > } > > > > find_reloads_address_part (ad, loc, > > - base_reg_class (mode, as, MEM, SCRATCH), > > + base_reg_class (mode, as, MEM, > > + SCRATCH, insn), > > address_mode, opnum, type, ind_levels); > > return ! removed_and; > > } > > @@ -5513,7 +5516,8 @@ find_reloads_address_1 (machine_mode mode, > > addr_space_t as, > > if (context == 1) > > context_reg_class = INDEX_REG_CLASS; > > else > > - context_reg_class = base_reg_class (mode, as, outer_code, index_code); > > + context_reg_class = base_reg_class (mode, as, outer_code, index_code, > > + insn); > > > > switch (code) > > { > > @@ -5738,7 +5742,8 @@ find_reloads_address_1 (machine_mode mode, > > addr_space_t as, > > reloadnum = push_reload (tem, tem, &XEXP (x, 0), > > &XEXP (op1, 0), > > base_reg_class (mode, as, > > - code, index_code), > > + code, index_code, > > + insn), > > GET_MODE (x), GET_MODE (x), 0, > > 0, opnum, RELOAD_OTHER); > > > > @@ -5756,7 +5761,8 @@ find_reloads_address_1 (machine_mode mode, > > addr_space_t as, > > reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0), > > &XEXP (op1, 0), &XEXP (x, 0), > > base_reg_class (mode, as, > > - code, index_code), > > + code, index_code, > > + insn), > > GET_MODE (x), GET_MODE (x), 0, 0, > > opnum, RELOAD_OTHER); > > > > @@ -6216,7 +6222,7 @@ find_reloads_subreg_address (rtx x, int opnum, enum > > reload_type type, > > { > > push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0, > > base_reg_class (GET_MODE (tem), MEM_ADDR_SPACE (tem), > > - MEM, SCRATCH), > > + MEM, SCRATCH, insn), > > GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0, opnum, type); > > reloaded = 1; > > } > > diff --git a/gcc/reload1.cc b/gcc/reload1.cc > > index 9ba822d1ff7..f41f4a4de22 100644 > > --- a/gcc/reload1.cc > > +++ b/gcc/reload1.cc > > @@ -1382,7 +1382,7 @@ maybe_fix_stack_asms (void) > > if (insn_extra_address_constraint (cn)) > > cls = (int) reg_class_subunion[cls] > > [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, > > - ADDRESS, SCRATCH)]; > > + ADDRESS, SCRATCH, > > chain->insn)]; > > else > > cls = (int) reg_class_subunion[cls] > > [reg_class_for_constraint (cn)]; > > -- > > 2.31.1 > >