re PR target/38052 (genautomata segfaults when -O2 is enabled)
gcc/ PR target/38052 * config/mips/mips.c (mips_cfun_call_saved_reg_p) (mips_cfun_might_clobber_call_saved_reg_p): New functions, split out from... (mips_save_reg_p): ...here. Always consult TARGET_CALL_SAVED_GP rather than call_really_used_regs when handling $gp. From-SVN: r141926
This commit is contained in:
parent
8d9d917290
commit
7cc003b5c2
@ -1,3 +1,12 @@
|
||||
2008-11-16 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
PR target/38052
|
||||
* config/mips/mips.c (mips_cfun_call_saved_reg_p)
|
||||
(mips_cfun_might_clobber_call_saved_reg_p): New functions,
|
||||
split out from...
|
||||
(mips_save_reg_p): ...here. Always consult TARGET_CALL_SAVED_GP
|
||||
rather than call_really_used_regs when handling $gp.
|
||||
|
||||
2008-11-16 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
PR target/38052
|
||||
|
@ -8433,48 +8433,85 @@ mips_global_pointer (void)
|
||||
return GLOBAL_POINTER_REGNUM;
|
||||
}
|
||||
|
||||
/* Return true if the current function should treat register REGNO
|
||||
as call-saved. */
|
||||
|
||||
static bool
|
||||
mips_cfun_call_saved_reg_p (unsigned int regno)
|
||||
{
|
||||
/* call_insns preserve $28 unless they explicitly say otherwise,
|
||||
so call_really_used_regs[] treats $28 as call-saved. However,
|
||||
we want the ABI property rather than the default call_insn
|
||||
property here. */
|
||||
return (regno == GLOBAL_POINTER_REGNUM
|
||||
? TARGET_CALL_SAVED_GP
|
||||
: !call_really_used_regs[regno]);
|
||||
}
|
||||
|
||||
/* Return true if the function body might clobber register REGNO.
|
||||
We know that REGNO is call-saved. */
|
||||
|
||||
static bool
|
||||
mips_cfun_might_clobber_call_saved_reg_p (unsigned int regno)
|
||||
{
|
||||
/* Some functions should be treated as clobbering all call-saved
|
||||
registers. */
|
||||
if (crtl->saves_all_registers)
|
||||
return true;
|
||||
|
||||
/* DF handles cases where a register is explicitly referenced in
|
||||
the rtl. Incoming values are passed in call-clobbered registers,
|
||||
so we can assume that any live call-saved register is set within
|
||||
the function. */
|
||||
if (df_regs_ever_live_p (regno))
|
||||
return true;
|
||||
|
||||
/* Check for registers that are clobbered by FUNCTION_PROFILER.
|
||||
These clobbers are not explicit in the rtl. */
|
||||
if (crtl->profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno))
|
||||
return true;
|
||||
|
||||
/* If we're using a call-saved global pointer, the function's
|
||||
prologue will need to set it up. */
|
||||
if (cfun->machine->global_pointer == regno)
|
||||
return true;
|
||||
|
||||
/* The function's prologue will need to set the frame pointer if
|
||||
frame_pointer_needed. */
|
||||
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
|
||||
return true;
|
||||
|
||||
/* If a MIPS16 function returns a value in FPRs, its epilogue
|
||||
will need to call an external libgcc routine. This yet-to-be
|
||||
generated call_insn will clobber $31. */
|
||||
if (regno == GP_REG_FIRST + 31 && mips16_cfun_returns_in_fpr_p ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if the current function must save register REGNO. */
|
||||
|
||||
static bool
|
||||
mips_save_reg_p (unsigned int regno)
|
||||
{
|
||||
/* We need to save $gp if TARGET_CALL_SAVED_GP and if we have not
|
||||
chosen a call-clobbered substitute. */
|
||||
if (TARGET_CALL_SAVED_GP
|
||||
&& regno == GLOBAL_POINTER_REGNUM
|
||||
&& cfun->machine->global_pointer == regno)
|
||||
return true;
|
||||
if (mips_cfun_call_saved_reg_p (regno))
|
||||
{
|
||||
if (mips_cfun_might_clobber_call_saved_reg_p (regno))
|
||||
return true;
|
||||
|
||||
/* Check call-saved registers. */
|
||||
if ((crtl->saves_all_registers || df_regs_ever_live_p (regno))
|
||||
&& !call_really_used_regs[regno])
|
||||
return true;
|
||||
/* Save both registers in an FPR pair if either one is used. This is
|
||||
needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
|
||||
register to be used without the even register. */
|
||||
if (FP_REG_P (regno)
|
||||
&& MAX_FPRS_PER_FMT == 2
|
||||
&& mips_cfun_might_clobber_call_saved_reg_p (regno + 1))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Save both registers in an FPR pair if either one is used. This is
|
||||
needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd
|
||||
register to be used without the even register. */
|
||||
if (FP_REG_P (regno)
|
||||
&& MAX_FPRS_PER_FMT == 2
|
||||
&& df_regs_ever_live_p (regno + 1)
|
||||
&& !call_really_used_regs[regno + 1])
|
||||
return true;
|
||||
|
||||
/* We need to save the old frame pointer before setting up a new one. */
|
||||
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
|
||||
return true;
|
||||
|
||||
/* Check for registers that must be saved for FUNCTION_PROFILER. */
|
||||
if (crtl->profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno))
|
||||
return true;
|
||||
|
||||
/* We need to save the incoming return address if it is ever clobbered
|
||||
within the function, if __builtin_eh_return is being used to set a
|
||||
different return address, or if a stub is being used to return a
|
||||
value in FPRs. */
|
||||
if (regno == GP_REG_FIRST + 31
|
||||
&& (df_regs_ever_live_p (regno)
|
||||
|| crtl->calls_eh_return
|
||||
|| mips16_cfun_returns_in_fpr_p ()))
|
||||
/* We need to save the incoming return address if __builtin_eh_return
|
||||
is being used to set a different return address. */
|
||||
if (regno == GP_REG_FIRST + 31 && crtl->calls_eh_return)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user