* [SH] Miscellaneous changes for LRA.

From-SVN: r218889
This commit is contained in:
Kaz Kojima 2014-12-19 04:49:16 +00:00
parent 106a52b7bf
commit fc1fcfa0b6
6 changed files with 93 additions and 3 deletions

View File

@ -1,3 +1,17 @@
2014-12-19 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/predicates.md (general_movsrc_operand): Allow only
valid plus address expressions.
(general_movdst_operand): Likewise.
(t_reg_operand): Allow (zero_extend (reg t)).
* config/sh/sh-protos.h (sh_hard_regno_caller_save_mode): Declare.
* config/sh/sh.c (sh_hard_regno_caller_save_mode): New function.
(sh_secondary_reload): Return NO_REGS instead of FPUL_REGS in one
case.
* config/sh/sh.h (HARD_REGNO_CALLER_SAVE_MODE): Define.
* config/sh/sh.md (untyped_call): Clobber function value
registers before call.
2014-12-19 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh.c (sh_lra_p): New function.

View File

@ -510,7 +510,25 @@
&& GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
return false;
if ((mode == QImode || mode == HImode)
if (GET_CODE (x) == PLUS)
{
rtx y = XEXP (x, 0);
if (! REG_P (y)
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
return false;
y = XEXP (x, 1);
if (! REG_P (y)
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
&& ! CONST_INT_P (y))
return false;
}
/* LRA will try to satisfy the constraints for the memory displacements
and thus we must not reject invalid displacements in the predicate,
or else LRA will bail out.
FIXME: maybe remove this check completely? */
if (!lra_in_progress && (mode == QImode || mode == HImode)
&& GET_CODE (x) == PLUS
&& REG_P (XEXP (x, 0))
&& CONST_INT_P (XEXP (x, 1)))
@ -595,7 +613,25 @@
&& GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
return false;
if ((mode == QImode || mode == HImode)
if (GET_CODE (x) == PLUS)
{
rtx y = XEXP (x, 0);
if (! REG_P (y)
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))))
return false;
y = XEXP (x, 1);
if (! REG_P (y)
&& ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))
&& ! CONST_INT_P (y))
return false;
}
/* LRA will try to satisfy the constraints for the memory displacements
and thus we must not reject invalid displacements in the predicate,
or else LRA will bail out.
FIXME: maybe remove this check completely? */
if (!lra_in_progress && (mode == QImode || mode == HImode)
&& GET_CODE (x) == PLUS
&& REG_P (XEXP (x, 0))
&& CONST_INT_P (XEXP (x, 1)))
@ -1117,6 +1153,8 @@
case ZERO_EXTEND:
case SIGN_EXTEND:
if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG)
return true;
return GET_CODE (XEXP (op, 0)) == SUBREG
&& REG_P (SUBREG_REG (XEXP (op, 0)))
&& REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;

View File

@ -262,5 +262,7 @@ extern int sh2a_get_function_vector_number (rtx);
extern bool sh2a_is_function_vector_call (rtx);
extern void sh_fix_range (const char *);
extern bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
machine_mode);
extern bool sh_can_use_simple_return_p (void);
#endif /* ! GCC_SH_PROTOS_H */

View File

@ -12186,6 +12186,26 @@ sh_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
return true;
}
/* Specify the modes required to caller save a given hard regno.
choose_hard_reg_mode chooses mode based on HARD_REGNO_MODE_OK
and returns ?Imode for float regs when sh_hard_regno_mode_ok
permits integer modes on them. That makes LRA's split process
unhappy. See PR55212.
*/
machine_mode
sh_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
machine_mode mode)
{
if (FP_REGISTER_P (regno)
&& (mode == SFmode
|| mode == SCmode
|| ((mode == DFmode || mode == DCmode)
&& ((regno - FIRST_FP_REG) & 1) == 0)))
return mode;
return choose_hard_reg_mode (regno, nregs, false);
}
/* Return the class of registers for which a mode change from FROM to TO
is invalid. */
bool
@ -13183,7 +13203,7 @@ sh_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
{
if (rclass == FPUL_REGS)
return GENERAL_REGS;
return FPUL_REGS;
return NO_REGS; // LRA wants NO_REGS here, it used to be FPUL_REGS;
}
if ((rclass == TARGET_REGS
|| (TARGET_SHMEDIA && rclass == SIBCALL_REGS))

View File

@ -905,6 +905,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
&& (GET_MODE_SIZE (MODE2) <= 4)) \
: ((MODE1) != SFmode && (MODE2) != SFmode))))
/* Specify the modes required to caller save a given hard regno. */
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
sh_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE))
/* A C expression that is nonzero if hard register NEW_REG can be
considered for use as a rename register for OLD_REG register */
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \

View File

@ -10055,6 +10055,18 @@ label:
(match_operand 2 "" "")])]
"(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
{
if (! TARGET_SHMEDIA)
{
/* RA does not know that the call sets the function value registers.
We avoid problems by claiming that those registers are clobbered
at this point. */
for (int i = 0; i < XVECLEN (operands[2], 0); i++)
{
rtx set = XVECEXP (operands[2], 0, i);
emit_clobber (SET_SRC (set));
}
}
emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
for (int i = 0; i < XVECLEN (operands[2], 0); i++)