Message ID | 20230831082024.314097-2-hongyu.wang@intel.com |
---|---|
State | New |
Headers | show |
Series | Support Intel APX EGPR | expand |
On Thu, Aug 31, 2023 at 10:20 AM Hongyu Wang <hongyu.wang@intel.com> wrote: > > From: Kong Lingling <lingling.kong@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. 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 >
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.wang@intel.com> wrote: > > > > From: Kong Lingling <lingling.kong@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 > >
On 9/1/23 05:07, Hongyu Wang wrote: > 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.wang@intel.com> wrote: >>> From: Kong Lingling <lingling.kong@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. > > I think the approach proposed by Intel developers is better. In some way we already use such approach when we pass memory mode to get the base reg class. Although we could use different memory constraints for different modes when the possible base reg differs for some memory modes. Using special memory constraints probably can be implemented too (I understand attractiveness of such approach for readability of the machine description). But in my opinion it will require much bigger work in IRA/LRA/reload. It also significantly slow down RA as we need to process insn constraints for processing each memory in many places (e.g. for calculation of reg classes and costs in IRA). Still I think there will be a few cases for this approach resulting in a bigger probability of assigning hard reg out of specific base reg class and this will result in additional reloads. So the approach proposed by Intel is ok for me. Although if x86 maintainers are strongly against this approach and the changes in x86 machine dependent code and Intel developers implement Uros approach, I am ready to review this. But still I prefer the current Intel developers approach for reasons I mentioned above.
On Wed, Sep 6, 2023 at 9:43 PM Vladimir Makarov <vmakarov@redhat.com> wrote: > > > On 9/1/23 05:07, Hongyu Wang wrote: > > 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.wang@intel.com> wrote: > >>> From: Kong Lingling <lingling.kong@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. > > > > > I think the approach proposed by Intel developers is better. In some way > we already use such approach when we pass memory mode to get the base > reg class. Although we could use different memory constraints for > different modes when the possible base reg differs for some memory > modes. > > Using special memory constraints probably can be implemented too (I > understand attractiveness of such approach for readability of the > machine description). But in my opinion it will require much bigger > work in IRA/LRA/reload. It also significantly slow down RA as we need > to process insn constraints for processing each memory in many places > (e.g. for calculation of reg classes and costs in IRA). Still I think > there will be a few cases for this approach resulting in a bigger > probability of assigning hard reg out of specific base reg class and > this will result in additional reloads. > > So the approach proposed by Intel is ok for me. Although if x86 maintainers > are strongly against this approach and the changes in x86 machine > dependent code and Intel developers implement Uros approach, I am > ready to review this. But still I prefer the current Intel developers > approach for reasons I mentioned above. My above proposal is more or less a wish from a target maintainer PoV. Ideally, we would have a bunch of different memory constraints, and a target hook that returns corresponding BASE/INDEX reg classes. However, I have no idea about the complexity of the implementation in the infrastructure part of the compiler. Uros.
On 9/7/23 02:23, Uros Bizjak wrote: > On Wed, Sep 6, 2023 at 9:43 PM Vladimir Makarov <vmakarov@redhat.com> wrote: >> >> On 9/1/23 05:07, Hongyu Wang wrote: >>> >> I think the approach proposed by Intel developers is better. In some way >> we already use such approach when we pass memory mode to get the base >> reg class. Although we could use different memory constraints for >> different modes when the possible base reg differs for some memory >> modes. >> >> Using special memory constraints probably can be implemented too (I >> understand attractiveness of such approach for readability of the >> machine description). But in my opinion it will require much bigger >> work in IRA/LRA/reload. It also significantly slow down RA as we need >> to process insn constraints for processing each memory in many places >> (e.g. for calculation of reg classes and costs in IRA). Still I think >> there will be a few cases for this approach resulting in a bigger >> probability of assigning hard reg out of specific base reg class and >> this will result in additional reloads. >> >> So the approach proposed by Intel is ok for me. Although if x86 maintainers >> are strongly against this approach and the changes in x86 machine >> dependent code and Intel developers implement Uros approach, I am >> ready to review this. But still I prefer the current Intel developers >> approach for reasons I mentioned above. > My above proposal is more or less a wish from a target maintainer PoV. > Ideally, we would have a bunch of different memory constraints, and a > target hook that returns corresponding BASE/INDEX reg classes. > However, I have no idea about the complexity of the implementation in > the infrastructure part of the compiler. > Basically, it needs introducing new hooks which return base and index classes from special memory constraints. When we process memory in an insn (a lot of places in IRA, LRA,reload) we should consider all possible memory insn constraints, take intersection of basic and index reg classes for the constraints and use them instead of the default base and reg classes. The required functionality is absent in reload too. I would say that it is a moderate size project (1-2 months for me). It still requires to introduce new hooks and I guess there are few cases when we will still assign hard regs out of desirable base class for address pseudos and this will results in generation of additional reload insns. It also means much more additional changes in RA source code and x86 machine dependent files. Probably, with this approach there will be also edge cases when we need to solve new PRs because of LRA failures to generate the correct code but I believe they can be solved. Therefore I lean toward the current Intel approach when to get base reg class we pass the insn as a parameter additionally to memory mode.
On 8/31/23 04:20, Hongyu Wang wrote: > @@ -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 I'd prefer more general description of 'insn' argument for the macros. Something like that: @code{insn} can be used to define an insn-specific base register class.
Vladimir Makarov via Gcc-patches <gcc-patches@gcc.gnu.org> 于2023年9月9日周六 01:04写道: > > > On 8/31/23 04:20, Hongyu Wang wrote: > > @@ -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 > > I'd prefer more general description of 'insn' argument for the macros. > Something like that: > > @code{insn} can be used to define an insn-specific base register class. > Sure, will adjust in the V2 patch. Also, currently we reuse the old macro MODE_CODE_BASE_REG_CLASS, do you think we need a new macro like INSN_BASE_REG_CLASS as other parameters are actually unused? Then we don't need to change other targets like avr/gcn.
On 9/10/23 00:49, Hongyu Wang wrote: > Vladimir Makarov via Gcc-patches <gcc-patches@gcc.gnu.org> 于2023年9月9日周六 01:04写道: >> >> On 8/31/23 04:20, Hongyu Wang wrote: >>> @@ -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 >> I'd prefer more general description of 'insn' argument for the macros. >> Something like that: >> >> @code{insn} can be used to define an insn-specific base register class. >> > Sure, will adjust in the V2 patch. > Also, currently we reuse the old macro MODE_CODE_BASE_REG_CLASS, do > you think we need a new macro like INSN_BASE_REG_CLASS as other > parameters are actually unused? Then we don't need to change other > targets like avr/gcn. > I thought about this too. Using new macros would be definitely worth to add, especially when you are already adding INSN_INDEX_REG_CLASS. The names INSN_BASE_REG_CLASS instead of MODE_CODE_BASE_REG_CLASS and REGNO_OK_FOR_INSN_BASE_P instead of REGNO_MODE_CODE_OK_FOR_BASE_P are ok for me too. When you submit the v2 patch, I'll review the RA part as soon as possible (actually I already looked at this) and most probably give my approval for the RA part because I prefer you current approach for RA instead of introducing new memory constraints.
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)];
From: Kong Lingling <lingling.kong@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. 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(-)