===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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
{
===================================================================
@@ -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"
===================================================================
@@ -152,3 +152,4 @@
reg_class_t);
extern bool default_profile_before_prologue (void);
+extern bool default_class_likely_spilled_p (reg_class_t);
===================================================================
@@ -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
===================================================================
@@ -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))
{
===================================================================
@@ -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) \
===================================================================
@@ -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)])
===================================================================
@@ -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;
===================================================================
@@ -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;
}
===================================================================
@@ -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,
===================================================================
@@ -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
===================================================================
@@ -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;
===================================================================
@@ -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))
===================================================================
@@ -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) \
===================================================================
@@ -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