target.def (class_likely_spilled_p): New hook.

* 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.

From-SVN: r163779
This commit is contained in:
Anatoly Sokolov 2010-09-02 18:29:37 +04:00 committed by Anatoly Sokolov
parent 844022b747
commit 07b8f0a812
18 changed files with 148 additions and 64 deletions

View File

@ -1,3 +1,31 @@
2010-09-02 Anatoly Sokolov <aesok@post.ru>
* 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.
2010-09-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44937

View File

@ -1900,7 +1900,7 @@ avoid_likely_spilled_reg (rtx x)
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,

View File

@ -2137,12 +2137,12 @@ cant_combine_insn_p (rtx insn)
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 @@ likely_spilled_retval_p (rtx insn)
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;

View File

@ -26218,6 +26218,32 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
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.
@ -31736,6 +31762,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#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

View File

@ -1440,34 +1440,6 @@ enum reg_class
: (((((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) \

View File

@ -2286,7 +2286,7 @@ hash_rtx_cb (const_rtx x, enum machine_mode mode,
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 @@ hash_rtx_cb (const_rtx x, enum machine_mode mode,
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;

View File

@ -2858,6 +2858,24 @@ Do not define this macro if you do not define
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 which returns @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

View File

@ -2858,6 +2858,24 @@ Do not define this macro if you do not define
is @code{BITS_PER_WORD} bits wide is correct for your machine.
@end defmac
@hook TARGET_CLASS_LIKELY_SPILLED_P
A target hook which returns @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

View File

@ -864,7 +864,8 @@ ira_build_conflicts (void)
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
{

View File

@ -2363,7 +2363,7 @@ update_equiv_regs (void)
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

View File

@ -387,7 +387,7 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
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)])

View File

@ -73,13 +73,13 @@ static int fixup_match_2 (rtx, rtx, rtx, rtx);
/* 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 @@ find_matches (rtx insn, struct match *matchp)
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;
}

View File

@ -227,12 +227,6 @@ extern int caller_save_needed;
#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) \

View File

@ -121,9 +121,14 @@ a register with any other reload. */
/* 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
@ -438,7 +443,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
|| (! 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 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
|| (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 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
&& 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 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& 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 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
{
/* 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))
{

View File

@ -2401,7 +2401,7 @@ get_rgn_sched_max_insns_priority (void)
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 @@ sets_likely_spilled_1 (rtx x, const_rtx pat, void *data)
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 @@ add_branch_dependences (rtx head, rtx tail)
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))

View File

@ -1971,6 +1971,12 @@ DEFHOOK
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

View File

@ -1220,4 +1220,16 @@ default_profile_before_prologue (void)
#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"

View File

@ -152,3 +152,4 @@ extern int default_register_move_cost (enum machine_mode, reg_class_t,
reg_class_t);
extern bool default_profile_before_prologue (void);
extern bool default_class_likely_spilled_p (reg_class_t);