This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Hookize CLASS_LIKELY_SPILLED_P


Hello.

  This patch turns CLASS_LIKELY_SPILLED_P macro into a hook.

  Please, whether someone can update documentation for CLASS_LIKELY_SPILLED_P
and TARGET_CLASS_LIKELY_SPILLED_P, they contain references on global.c and
local-alloc.c files which is deleted from the GCC sources.

  The patch has been bootstrapped on and regression tested on
x86_64-unknown-linux-gnu for c.

        * target.def (class_likely_spilled_p): New hook.
        * doc/tm.texi.in (TARGET_CLASS_LIKELY_SPILLED_P): Document.
        * doc/tm.texi: Regenerate.
        * targhooks.c (default_class_likely_spilled_p): New function.
        * targhooks.h (default_class_likely_spilled_p): Declare.
        * regs.h (CLASS_LIKELY_SPILLED_P): Remove.
        * combine.c: (cant_combine_insn_p, likely_spilled_retval_p): Use
        TARGET_CLASS_LIKELY_SPILLED_P target hook. Use HARD_REGISTER_P macro.
        Use fixed_reg_set instead of fixed_regs.
        * cse.c (hash_rtx_cb): Use TARGET_CLASS_LIKELY_SPILLED_P target hook.
        * calls.c (avoid_likely_spilled_reg): Ditto.
        * ira-conflicts.c: (ira_build_conflicts): Ditto.
        * ira.c (update_equiv_regs): Ditto.
        * mode-switching.c (create_pre_exit): Ditto.
        * regmove.c (find_matches): Ditto.
        (regclass_compatible_p): Use TARGET_CLASS_LIKELY_SPILLED_P target
        hook.
        * reload.c (SMALL_REGISTER_CLASS_P): Remove macro.
        (small_register_class_p): New inline function.
        (push_secondary_reload, find_reusable_reload, find_reloads): Use
        small_register_class_p instead of SMALL_REGISTER_CLASS_P.

        * config/i386/i386.h (CLASS_LIKELY_SPILLED_P): Remove.
        * config/i386/i386.c (ix86_class_likely_spilled_p): New.
        (TARGET_CLASS_LIKELY_SPILLED_P): Define.

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 163619)
+++ gcc/doc/tm.texi     (working copy)
@@ -2858,6 +2858,24 @@
 is @code{BITS_PER_WORD} bits wide is correct for your machine.
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_CLASS_LIKELY_SPILLED_P (reg_class_t @var{rclass})
+A target hook whose return @code{true} if pseudos that have been assigned
+to registers of class @var{rclass} would likely be spilled because
+registers of @var{rclass} are needed for spill registers.
+
+The default version of this target hook returns @code{true} if @var{rclass}
+has exactly one register and @code{false} otherwise.  On most machines, this
+default should be used.  Only use this target hook to some other expression
+if pseudos allocated by @file{local-alloc.c} end up in memory because their
+hard registers were needed for spill registers.  If this target hook returns
+@code{false} for those classes, those pseudos will only be allocated by
+@file{global.c}, which knows how to reallocate the pseudo to another
+register.  If there would not be another register available for reallocation,
+you should not change the implementation of this target hook since
+the only effect of such implementation would be to slow down register
+allocation.
+@end deftypefn
+
 @defmac CLASS_LIKELY_SPILLED_P (@var{class})
 A C expression whose value is nonzero if pseudos that have been assigned
 to registers of class @var{class} would likely be spilled because
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in  (revision 163619)
+++ gcc/doc/tm.texi.in  (working copy)
@@ -2858,6 +2858,24 @@
 is @code{BITS_PER_WORD} bits wide is correct for your machine.
 @end defmac
 
+@hook TARGET_CLASS_LIKELY_SPILLED_P
+A target hook whose return @code{true} if pseudos that have been assigned
+to registers of class @var{rclass} would likely be spilled because
+registers of @var{rclass} are needed for spill registers.
+
+The default version of this target hook returns @code{true} if @var{rclass}
+has exactly one register and @code{false} otherwise.  On most machines, this
+default should be used.  Only use this target hook to some other expression
+if pseudos allocated by @file{local-alloc.c} end up in memory because their
+hard registers were needed for spill registers.  If this target hook returns
+@code{false} for those classes, those pseudos will only be allocated by
+@file{global.c}, which knows how to reallocate the pseudo to another
+register.  If there would not be another register available for reallocation,
+you should not change the implementation of this target hook since
+the only effect of such implementation would be to slow down register
+allocation.
+@end deftypefn
+
 @defmac CLASS_LIKELY_SPILLED_P (@var{class})
 A C expression whose value is nonzero if pseudos that have been assigned
 to registers of class @var{class} would likely be spilled because
Index: gcc/ira-conflicts.c
===================================================================
--- gcc/ira-conflicts.c	(revision 163619)
+++ gcc/ira-conflicts.c	(working copy)
@@ -864,7 +864,8 @@
          ira_free (conflicts);
        }
     }
-  if (! CLASS_LIKELY_SPILLED_P (base_reg_class (VOIDmode, ADDRESS, SCRATCH)))
+  if (! targetm.class_likely_spilled_p (base_reg_class (VOIDmode, ADDRESS,
+                                                       SCRATCH)))
     CLEAR_HARD_REG_SET (temp_hard_reg_set);
   else
     {
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     (revision 163619)
+++ gcc/targhooks.c     (working copy)
@@ -1220,4 +1220,16 @@
 #endif
 }
 
+/* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P.  */
+
+bool
+default_class_likely_spilled_p (reg_class_t rclass)
+{
+#ifndef CLASS_LIKELY_SPILLED_P
+  return (reg_class_size[(int) rclass] == 1);
+#else
+  return CLASS_LIKELY_SPILLED_P ((enum reg_class) rclass);
+#endif
+}
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     (revision 163619)
+++ gcc/targhooks.h     (working copy)
@@ -152,3 +152,4 @@
                                       reg_class_t);
 
 extern bool default_profile_before_prologue (void);
+extern bool default_class_likely_spilled_p (reg_class_t);
Index: gcc/target.def
===================================================================
--- gcc/target.def      (revision 163619)
+++ gcc/target.def      (working copy)
@@ -1971,6 +1971,12 @@
   secondary_reload_info *sri),
  default_secondary_reload)
 
+DEFHOOK
+(class_likely_spilled_p,
+ "",
+ bool, (reg_class_t rclass),
+ default_class_likely_spilled_p)
+
 /* This target hook allows the backend to perform additional
    processing while initializing for variable expansion.  */
 DEFHOOK
Index: gcc/reload.c
===================================================================
--- gcc/reload.c        (revision 163619)
+++ gcc/reload.c        (working copy)
@@ -121,10 +121,15 @@
 
 /* True if C is a non-empty register class that has too few registers
    to be safely used as a reload target class.  */
-#define SMALL_REGISTER_CLASS_P(C) \
-  (reg_class_size [(C)] == 1 \
-   || (reg_class_size [(C)] >= 1 && CLASS_LIKELY_SPILLED_P (C)))
 
+static inline bool
+small_register_class_p (reg_class_t rclass)
+{
+  return (reg_class_size [(int) rclass] == 1
+         || (reg_class_size [(int) rclass] >= 1 
+             && targetm.class_likely_spilled_p (rclass)));
+}
+
 
 /* All reloads of the current insn are recorded here.  See reload.h for
    comments.  */
@@ -438,7 +443,7 @@
            || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
        && ((in_p && rld[s_reload].secondary_in_icode == t_icode)
            || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
-       && (SMALL_REGISTER_CLASS_P (rclass)
+       && (small_register_class_p (rclass)
            || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
                             opnum, rld[s_reload].opnum))
@@ -749,7 +754,7 @@
            || (out != 0 && MATCHES (rld[i].out, out)
                && (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (rclass)
+       && (small_register_class_p (rclass)
            || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
       return i;
@@ -775,7 +780,7 @@
                && GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
                && MATCHES (XEXP (in, 0), rld[i].in)))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (rclass)
+       && (small_register_class_p (rclass)
            || targetm.small_register_classes_for_mode_p (VOIDmode))
        && MERGABLE_RELOADS (type, rld[i].when_needed,
                             opnum, rld[i].opnum))
@@ -3588,7 +3593,7 @@
              && this_alternative[i] != NO_REGS
              && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
              && reg_class_size [(int) preferred_class[i]] > 0
-             && ! SMALL_REGISTER_CLASS_P (preferred_class[i]))
+             && ! small_register_class_p (preferred_class[i]))
            {
              if (! reg_class_subset_p (this_alternative[i],
                                        preferred_class[i]))
@@ -3646,7 +3651,7 @@
                {
                  /* If the output is in a non-empty few-regs class,
                     it's costly to reload it, so reload the input instead.  */
-                 if (SMALL_REGISTER_CLASS_P (this_alternative[i])
+                 if (small_register_class_p (this_alternative[i])
                      && (REG_P (recog_data.operand[j])
                          || GET_CODE (recog_data.operand[j]) == SUBREG))
                    {
Index: gcc/regs.h
===================================================================
--- gcc/regs.h  (revision 163619)
+++ gcc/regs.h  (working copy)
@@ -227,12 +227,6 @@
 #define CALLER_SAVE_PROFITABLE(REFS, CALLS)  (4 * (CALLS) < (REFS))
 #endif
 
-/* On most machines a register class is likely to be spilled if it
-   only has one register.  */
-#ifndef CLASS_LIKELY_SPILLED_P
-#define CLASS_LIKELY_SPILLED_P(CLASS) (reg_class_size[(int) (CLASS)] == 1)
-#endif
-
 /* Select a register mode required for caller save of hard regno REGNO.  */
 #ifndef HARD_REGNO_CALLER_SAVE_MODE
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
Index: gcc/mode-switching.c
===================================================================
--- gcc/mode-switching.c        (revision 163619)
+++ gcc/mode-switching.c        (working copy)
@@ -387,7 +387,7 @@
            gcc_assert (!nregs
                        || forced_late_switch
                        || short_block
-                       || !(CLASS_LIKELY_SPILLED_P
+                       || !(targetm.class_likely_spilled_p
                             (REGNO_REG_CLASS (ret_start)))
                        || (nregs
                            != hard_regno_nregs[ret_start][GET_MODE (ret_reg)])
Index: gcc/cse.c
===================================================================
--- gcc/cse.c   (revision 163619)
+++ gcc/cse.c   (working copy)
@@ -2286,7 +2286,7 @@
 
               On all machines, we can't record any global registers.
               Nor should we record any register that is in a small
-              class, as defined by CLASS_LIKELY_SPILLED_P.  */
+              class, as defined by TARGET_CLASS_LIKELY_SPILLED_P.  */
            bool record;
 
            if (regno >= FIRST_PSEUDO_REGISTER)
@@ -2305,7 +2305,7 @@
              record = true;
            else if (targetm.small_register_classes_for_mode_p (GET_MODE (x)))
              record = false;
-           else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
+           else if (targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno)))
              record = false;
            else
              record = true;
Index: gcc/regmove.c
===================================================================
--- gcc/regmove.c       (revision 163619)
+++ gcc/regmove.c       (working copy)
@@ -73,13 +73,13 @@
 /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
    causing too much register allocation problems.  */
 static int
-regclass_compatible_p (enum reg_class class0, enum reg_class class1)
+regclass_compatible_p (reg_class_t class0, reg_class_t class1)
 {
   return (class0 == class1
          || (reg_class_subset_p (class0, class1)
-             && ! CLASS_LIKELY_SPILLED_P (class0))
+             && ! targetm.class_likely_spilled_p (class0))
          || (reg_class_subset_p (class1, class0)
-             && ! CLASS_LIKELY_SPILLED_P (class1)));
+             && ! targetm.class_likely_spilled_p (class1)));
 }
 
 
@@ -1337,7 +1337,7 @@
          case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
          case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
          case 'C': case 'D': case 'W': case 'Y': case 'Z':
-           if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p) ))
+           if (targetm.class_likely_spilled_p (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)))
              likely_spilled[op_no] = 1;
            break;
          }
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	(revision 163619)
+++ gcc/calls.c	(working copy)
@@ -1896,7 +1896,7 @@
 
   if (REG_P (x)
       && HARD_REGISTER_P (x)
-      && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (x))))
+      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (x))))
     {
       /* Make sure that we generate a REG rather than a CONCAT.
         Moves into CONCATs can need nontrivial instructions,
Index: gcc/ira.c
===================================================================
--- gcc/ira.c   (revision 163619)
+++ gcc/ira.c   (working copy)
@@ -2363,7 +2363,7 @@
          if (!REG_P (dest)
              || (regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER
              || reg_equiv[regno].init_insns == const0_rtx
-             || (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno))
+             || (targetm.class_likely_spilled_p (reg_preferred_class (regno))
                  && MEM_P (src) && ! reg_equiv[regno].is_arg_equivalence))
            {
              /* This might be setting a SUBREG of a pseudo, a pseudo that is
Index: gcc/combine.c
===================================================================
--- gcc/combine.c       (revision 163619)
+++ gcc/combine.c       (working copy)
@@ -2137,12 +2137,12 @@
   if (GET_CODE (dest) == SUBREG)
     dest = SUBREG_REG (dest);
   if (REG_P (src) && REG_P (dest)
-      && ((REGNO (src) < FIRST_PSEUDO_REGISTER
-          && ! fixed_regs[REGNO (src)]
-          && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (src))))
-         || (REGNO (dest) < FIRST_PSEUDO_REGISTER
-             && ! fixed_regs[REGNO (dest)]
-             && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (dest))))))
+      && ((HARD_REGISTER_P (src)
+          && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src))
+          && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (src))))
+         || (HARD_REGISTER_P (dest)
+             && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dest))
+             && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dest))))))
     return 1;
 
   return 0;
@@ -2223,7 +2223,7 @@
   do
     {
       if ((mask & 1 << nregs)
-         && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno + nregs)))
+         && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno + nregs)))
        return 1;
     } while (nregs--);
   return 0;
Index: gcc/sched-rgn.c
===================================================================
--- gcc/sched-rgn.c     (revision 163619)
+++ gcc/sched-rgn.c     (working copy)
@@ -2401,7 +2401,7 @@
   return rgn_sched_info.sched_max_insns_priority;
 }
 
-/* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register.  */
+/* Determine if PAT sets a TARGET_CLASS_LIKELY_SPILLED_P register.  */
 
 static bool
 sets_likely_spilled (rtx pat)
@@ -2418,8 +2418,8 @@
 
   if (GET_CODE (pat) == SET
       && REG_P (x)
-      && REGNO (x) < FIRST_PSEUDO_REGISTER
-      && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (x))))
+      && HARD_REGISTER_P (x)
+      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (x))))
     *ret = true;
 }
 
@@ -2448,8 +2448,8 @@
 
      COND_EXEC insns cannot be moved past a branch (see e.g. PR17808).
 
-     Insns setting CLASS_LIKELY_SPILLED_P registers (usually return values)
-     are not moved before reload because we can wind up with register
+     Insns setting TARGET_CLASS_LIKELY_SPILLED_P registers (usually return
+     values) are not moved before reload because we can wind up with register
      allocation failures.  */
 
   while (tail != head && DEBUG_INSN_P (tail))
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h      (revision 163619)
+++ gcc/config/i386/i386.h      (working copy)
@@ -1447,34 +1447,6 @@
   : (((((MODE) == XFmode ? 12 : GET_MODE_SIZE (MODE)))                 \
       + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
-/* A C expression whose value is nonzero if pseudos that have been
-   assigned to registers of class CLASS would likely be spilled
-   because registers of CLASS are needed for spill registers.
-
-   The default value of this macro returns 1 if CLASS has exactly one
-   register and zero otherwise.  On most machines, this default
-   should be used.  Only define this macro to some other expression
-   if pseudo allocated by `local-alloc.c' end up in memory because
-   their hard registers were needed for spill registers.  If this
-   macro returns nonzero for those classes, those pseudos will only
-   be allocated by `global.c', which knows how to reallocate the
-   pseudo to another register.  If there would not be another
-   register available for reallocation, you should not change the
-   definition of this macro since the only effect of such a
-   definition would be to slow down register allocation.  */
-
-#define CLASS_LIKELY_SPILLED_P(CLASS)                                  \
-  (((CLASS) == AREG)                                                   \
-   || ((CLASS) == DREG)                                                        \
-   || ((CLASS) == CREG)                                                        \
-   || ((CLASS) == BREG)                                                        \
-   || ((CLASS) == AD_REGS)                                             \
-   || ((CLASS) == SIREG)                                               \
-   || ((CLASS) == DIREG)                                               \
-   || ((CLASS) == SSE_FIRST_REG)                                       \
-   || ((CLASS) == FP_TOP_REG)                                          \
-   || ((CLASS) == FP_SECOND_REG))
-
 /* Return a class of registers that cannot change FROM mode to TO mode.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 163619)
+++ gcc/config/i386/i386.c      (working copy)
@@ -26184,6 +26184,32 @@
   return NO_REGS;
 }
 
+/* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
+
+static bool
+ix86_class_likely_spilled_p (reg_class_t rclass)
+{
+  switch (rclass)
+    {
+      case AREG:
+      case DREG:
+      case CREG:
+      case BREG:
+      case AD_REGS:
+      case SIREG:
+      case DIREG:
+      case SSE_FIRST_REG:
+      case FP_TOP_REG:
+      case FP_SECOND_REG:
+       return true;
+
+      default:
+       break;
+    }
+
+  return false;
+}
+
 /* If we are copying between general and FP registers, we need a memory
    location. The same is true for SSE and MMX registers.
 
@@ -31702,6 +31728,9 @@
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
 
+#undef TARGET_CLASS_LIKELY_SPILLED_P
+#define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
+
 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   ix86_builtin_vectorization_cost


Anatoly.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]