sh.c (calc_live_regs): If the return address pointer is live, force pr live.

* sh.c (calc_live_regs): If the return address pointer is live,
	force pr live.
	(sh5_schedule_saves): Exclude PR_MEDIA_REG from being a temp register
	for saves / restores.
	(sh_expand_epilogue): If sh_media_register_for_return returns a
	register number, flag the instructions that restores PR_MEDIA_REG
	as possibly dead.
	Remove dead update of offset.
	(sh_get_pr_initial_val): Use UNSPEC_RA if we don't know yet if
	we can use the result of get_hard_reg_initial_val.
	* sh.md (UNSPEC_RA): New constant.
	(movsi_i_lowpart+1): Changed into a define_insn_and_split, named:
	(load_ra).  Handle UNSPEC_RA.
	(sibcall_media): Use PR_MEDIA_REG.

From-SVN: r70234
This commit is contained in:
J"orn Rennecke 2003-08-07 22:40:07 +00:00 committed by Joern Rennecke
parent 7160c99da0
commit 7d73a2bae9
3 changed files with 61 additions and 18 deletions

View File

@ -1,5 +1,20 @@
2003-08-07 J"orn Rennecke <joern.rennecke@superh.com>
* sh.c (calc_live_regs): If the return address pointer is live,
force pr live.
(sh5_schedule_saves): Exclude PR_MEDIA_REG from being a temp register
for saves / restores.
(sh_expand_epilogue): If sh_media_register_for_return returns a
register number, flag the instructions that restores PR_MEDIA_REG
as possibly dead.
Remove dead update of offset.
(sh_get_pr_initial_val): Use UNSPEC_RA if we don't know yet if
we can use the result of get_hard_reg_initial_val.
* sh.md (UNSPEC_RA): New constant.
(movsi_i_lowpart+1): Changed into a define_insn_and_split, named:
(load_ra). Handle UNSPEC_RA.
(sibcall_media): Use PR_MEDIA_REG.
* sh.h (CALL_USED_REGISTERS): Include PR_REG and PR_MEDIA_REG.
* sh.c (calc_live_regs): Use sh_pr_n_sets to determine if pr
needs saving on SHmedia.

View File

@ -4848,6 +4848,8 @@ calc_live_regs (live_regs_mask)
the initial value can become the PR_MEDIA_REG hard register, as seen for
execute/20010122-1.c:test9. */
if (TARGET_SHMEDIA)
/* ??? this function is called from initial_elimination_offset, hence we
can't use the result of sh_media_register_for_return here. */
pr_live = sh_pr_n_sets ();
else
{
@ -4856,6 +4858,10 @@ calc_live_regs (live_regs_mask)
? (GET_CODE (pr_initial) != REG
|| REGNO (pr_initial) != (PR_REG))
: regs_ever_live[PR_REG]);
/* For Shcompact, if not optimizing, we end up with a memory reference
using the return address pointer for __builtin_return_address even
though there is no actual need to put the PR register on the stack. */
pr_live |= regs_ever_live[RETURN_ADDRESS_POINTER_REGNUM];
}
/* Force PR to be live if the prologue has to call the SHmedia
argument decoder or register saver. */
@ -5027,7 +5033,7 @@ sh5_schedule_saves (HARD_REG_SET *live_regs_mask, save_schedule *schedule,
if (! current_function_interrupt)
for (i = FIRST_GENERAL_REG; tmpx < MAX_TEMPS && i <= LAST_GENERAL_REG; i++)
if (call_used_regs[i] && ! fixed_regs[i]
if (call_used_regs[i] && ! fixed_regs[i] && i != PR_MEDIA_REG
&& ! FUNCTION_ARG_REGNO_P (i)
&& i != FIRST_RET_REG
&& ! (current_function_needs_context && i == STATIC_CHAIN_REGNUM)
@ -5169,6 +5175,9 @@ sh_expand_prologue ()
rtx insn = emit_move_insn (gen_rtx_REG (DImode, tr),
gen_rtx_REG (DImode, PR_MEDIA_REG));
/* ??? We should suppress saving pr when we don't need it, but this
is tricky because of builtin_return_address. */
/* If this function only exits with sibcalls, this copy
will be flagged as dead. */
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
@ -5552,7 +5561,7 @@ sh_expand_epilogue ()
save_schedule schedule;
save_entry *entry;
int *tmp_pnt;
entry = sh5_schedule_saves (&live_regs_mask, &schedule, d_rounding);
offset_base = -entry[1].offset + d_rounding;
tmp_pnt = schedule.temps;
@ -5660,8 +5669,11 @@ sh_expand_epilogue ()
}
insn = emit_move_insn (reg_rtx, mem_rtx);
offset += GET_MODE_SIZE (mode);
if (reg == PR_MEDIA_REG && sh_media_register_for_return () >= 0)
/* This is dead, unless we return with a sibcall. */
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
const0_rtx,
REG_NOTES (insn));
}
if (entry->offset + offset_base != d + d_rounding)
@ -8835,17 +8847,29 @@ scavenge_reg (HARD_REG_SET *s)
rtx
sh_get_pr_initial_val (void)
{
rtx val;
/* ??? Unfortunately, get_hard_reg_initial_val doesn't always work for the
PR register on SHcompact, because it might be clobbered by the prologue.
We don't know if that's the case before rtl generation is finished. */
We check first if that is known to be the case. */
if (TARGET_SHCOMPACT
&& (rtx_equal_function_value_matters
|| (current_function_args_info.call_cookie
& ~ CALL_COOKIE_RET_TRAMP (1))
&& ((current_function_args_info.call_cookie
& ~ CALL_COOKIE_RET_TRAMP (1))
|| current_function_has_nonlocal_label))
return gen_rtx_MEM (SImode, return_address_pointer_rtx);
return
get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
/* If we haven't finished rtl generation, there might be a nonlocal label
that we haven't seen yet.
??? get_hard_reg_initial_val fails if it is called while no_new_pseudos
is set, unless it has been called before for the same register. And even
then, we end in trouble if we didn't use the register in the same
basic block before. So call get_hard_reg_initial_val now and wrap it
in an unspec if we might need to replace it. */
val
= get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
if (TARGET_SHCOMPACT && rtx_equal_function_value_matters)
return gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_RA);
return val;
}
#include "gt-sh.h"

View File

@ -142,6 +142,7 @@
(UNSPEC_DTPOFF 23)
(UNSPEC_GOTTPOFF 24)
(UNSPEC_TPOFF 25)
(UNSPEC_RA 26)
;; These are used with unspec_volatile.
(UNSPECV_BLOCKAGE 0)
@ -3471,16 +3472,18 @@
fake %1,%0"
[(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
(define_split
(define_insn_and_split "load_ra"
[(set (match_operand:SI 0 "general_movdst_operand" "")
(mem:SI (reg:SI RAP_REG)))]
"TARGET_SHCOMPACT
&& ! rtx_equal_function_value_matters
&& ! ((current_function_args_info.call_cookie
& ~ CALL_COOKIE_RET_TRAMP (1))
|| current_function_has_nonlocal_label)"
(unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
"TARGET_SHCOMPACT"
"#"
"&& ! rtx_equal_function_value_matters"
[(set (match_dup 0) (match_dup 1))]
"operands[1] = sh_get_pr_initial_val ();")
"
{
if (current_function_has_nonlocal_label)
operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
}")
(define_insn "*movsi_media"
[(set (match_operand:SI 0 "general_movdst_operand"
@ -6174,6 +6177,7 @@
(define_insn "sibcall_media"
[(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
(match_operand 1 "" ""))
(use (reg:SI PR_MEDIA_REG))
(return)]
"TARGET_SHMEDIA"
"blink %0, r63"