From: Kong Lingling <lingling.k...@intel.com>

Current reload infrastructure does not support selective base_reg_class
for backend insn. Add new macros with insn parameters to base_reg_class
for lra/reload usage.

gcc/ChangeLog:

        * addresses.h (base_reg_class): Add insn argument and new macro
        INSN_BASE_REG_CLASS.
        (regno_ok_for_base_p_1): Add insn argument and new macro
        REGNO_OK_FOR_INSN_BASE_P.
        (regno_ok_for_base_p): Add insn argument and parse to ok_for_base_p_1.
        * doc/tm.texi: Document INSN_BASE_REG_CLASS and
        REGNO_OK_FOR_INSN_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.

Co-authored-by: Hongyu Wang <hongyu.w...@intel.com>
Co-authored-by: Hongtao Liu <hongtao....@intel.com>
---
 gcc/addresses.h        | 19 +++++++++++++++----
 gcc/doc/tm.texi        | 14 ++++++++++++++
 gcc/doc/tm.texi.in     | 14 ++++++++++++++
 gcc/lra-constraints.cc | 15 +++++++++------
 gcc/reload.cc          | 30 ++++++++++++++++++------------
 gcc/reload1.cc         |  2 +-
 6 files changed, 71 insertions(+), 23 deletions(-)

diff --git a/gcc/addresses.h b/gcc/addresses.h
index 3519c241c6d..2c92927bd51 100644
--- a/gcc/addresses.h
+++ b/gcc/addresses.h
@@ -28,8 +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 INSN_BASE_REG_CLASS
+  return INSN_BASE_REG_CLASS (insn);
+#else
 #ifdef MODE_CODE_BASE_REG_CLASS
   return MODE_CODE_BASE_REG_CLASS (MACRO_MODE (mode), as, outer_code,
                                   index_code);
@@ -44,6 +48,7 @@ base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
   return BASE_REG_CLASS;
 #endif
 #endif
+#endif
 }
 
 /* Wrapper function to unify target macros REGNO_MODE_CODE_OK_FOR_BASE_P,
@@ -56,8 +61,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_OK_FOR_INSN_BASE_P
+  return REGNO_OK_FOR_INSN_BASE_P (regno, insn);
+#else
 #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);
@@ -72,6 +81,7 @@ ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED,
   return REGNO_OK_FOR_BASE_P (regno);
 #endif
 #endif
+#endif
 }
 
 /* Wrapper around ok_for_base_p_1, for use after register allocation is
@@ -79,12 +89,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/doc/tm.texi b/gcc/doc/tm.texi
index b0779724d30..5b1e2a11f89 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2568,6 +2568,13 @@ of an address, @code{ADDRESS} for something that occurs 
in an
 index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise.
 @end defmac
 
+@defmac INSN_BASE_REG_CLASS (@var{insn})
+A C expression whose value is the register class to which a valid
+base register for a specified @var{insn} must belong. This macro is
+used when some backend insns may have limited usage of base register
+compared with other insns.
+@end defmac
+
 @defmac INDEX_REG_CLASS
 A macro whose definition is the name of the class to which a valid
 index register must belong.  An index register is one used in an
@@ -2618,6 +2625,13 @@ corresponding index expression if @var{outer_code} is 
@code{PLUS};
 that appear outside a @code{MEM}, i.e., as an @code{address_operand}.
 @end defmac
 
+@defmac REGNO_OK_FOR_INSN_BASE_P (@var{num}, @var{insn})
+A C expression which is nonzero if register number @var{num} is
+suitable for use as a base register in operand addresses for a specified
+@var{insn}. This macro is used when some backend insn may have limited
+usage of base register compared with other insns.
+@end defmac
+
 @defmac REGNO_OK_FOR_INDEX_P (@var{num})
 A C expression which is nonzero if register number @var{num} is
 suitable for use as an index register in operand addresses.  It may be
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index d3e18955628..f6e63ad8871 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -2150,6 +2150,13 @@ of an address, @code{ADDRESS} for something that occurs 
in an
 index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise.
 @end defmac
 
+@defmac INSN_BASE_REG_CLASS (@var{insn})
+A C expression whose value is the register class to which a valid
+base register for a specified @var{insn} must belong. This macro is
+used when some backend insns may have limited usage of base register
+compared with other insns.
+@end defmac
+
 @defmac INDEX_REG_CLASS
 A macro whose definition is the name of the class to which a valid
 index register must belong.  An index register is one used in an
@@ -2200,6 +2207,13 @@ corresponding index expression if @var{outer_code} is 
@code{PLUS};
 that appear outside a @code{MEM}, i.e., as an @code{address_operand}.
 @end defmac
 
+@defmac REGNO_OK_FOR_INSN_BASE_P (@var{num}, @var{insn})
+A C expression which is nonzero if register number @var{num} is
+suitable for use as a base register in operand addresses for a specified
+@var{insn}. This macro is used when some backend insn may have limited
+usage of base register compared with other insns.
+@end defmac
+
 @defmac REGNO_OK_FOR_INDEX_P (@var{num})
 A C expression which is nonzero if register number @var{num} is
 suitable for use as an index register in operand addresses.  It may be
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 3aaa4906999..6dc77af86cd 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -3681,7 +3681,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)
@@ -3731,7 +3731,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");
@@ -3794,7 +3795,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");
@@ -3855,7 +3857,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))
@@ -3899,7 +3901,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");
@@ -4649,7 +4652,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

Reply via email to