Commit 4f660b15 by Radovan Obradovic Committed by Tom de Vries

-fuse-caller-save - Add new reg-note REG_CALL_DECL

2014-04-24  Radovan Obradovic  <robradovic@mips.com>
            Tom de Vries  <tom@codesourcery.com>

	* reg-notes.def (REG_NOTE (CALL_DECL)): New reg-note REG_CALL_DECL.
	* calls.c (expand_call, emit_library_call_value_1): Add REG_CALL_DECL
	reg-note.
	* combine.c (distribute_notes): Handle REG_CALL_DECL reg-note.
	* emit-rtl.c (try_split): Same.

Co-Authored-By: Tom de Vries <tom@codesourcery.com>

From-SVN: r209744
parent d996e61a
2014-04-24 Radovan Obradovic <robradovic@mips.com> 2014-04-24 Radovan Obradovic <robradovic@mips.com>
Tom de Vries <tom@codesourcery.com> Tom de Vries <tom@codesourcery.com>
* reg-notes.def (REG_NOTE (CALL_DECL)): New reg-note REG_CALL_DECL.
* calls.c (expand_call, emit_library_call_value_1): Add REG_CALL_DECL
reg-note.
* combine.c (distribute_notes): Handle REG_CALL_DECL reg-note.
* emit-rtl.c (try_split): Same.
2014-04-24 Radovan Obradovic <robradovic@mips.com>
Tom de Vries <tom@codesourcery.com>
* common.opt (fuse-caller-save): New option. * common.opt (fuse-caller-save): New option.
2014-04-24 Tejas Belagod <tejas.belagod@arm.com> 2014-04-24 Tejas Belagod <tejas.belagod@arm.com>
......
...@@ -3178,6 +3178,19 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -3178,6 +3178,19 @@ expand_call (tree exp, rtx target, int ignore)
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags, args_so_far); flags, args_so_far);
if (flag_use_caller_save)
{
rtx last, datum = NULL_RTX;
if (fndecl != NULL_TREE)
{
datum = XEXP (DECL_RTL (fndecl), 0);
gcc_assert (datum != NULL_RTX
&& GET_CODE (datum) == SYMBOL_REF);
}
last = last_call_insn ();
add_reg_note (last, REG_CALL_DECL, datum);
}
/* If the call setup or the call itself overlaps with anything /* If the call setup or the call itself overlaps with anything
of the argument setup we probably clobbered our call address. of the argument setup we probably clobbered our call address.
In that case we can't do sibcalls. */ In that case we can't do sibcalls. */
...@@ -4205,6 +4218,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, ...@@ -4205,6 +4218,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
valreg, valreg,
old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far); old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);
if (flag_use_caller_save)
{
rtx last, datum = orgfun;
gcc_assert (GET_CODE (datum) == SYMBOL_REF);
last = last_call_insn ();
add_reg_note (last, REG_CALL_DECL, datum);
}
/* Right-shift returned value if necessary. */ /* Right-shift returned value if necessary. */
if (!pcc_struct_value if (!pcc_struct_value
&& TYPE_MODE (tfom) != BLKmode && TYPE_MODE (tfom) != BLKmode
......
...@@ -13269,6 +13269,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, ...@@ -13269,6 +13269,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
case REG_NORETURN: case REG_NORETURN:
case REG_SETJMP: case REG_SETJMP:
case REG_TM: case REG_TM:
case REG_CALL_DECL:
/* These notes must remain with the call. It should not be /* These notes must remain with the call. It should not be
possible for both I2 and I3 to be a call. */ possible for both I2 and I3 to be a call. */
if (CALL_P (i3)) if (CALL_P (i3))
......
...@@ -3427,6 +3427,7 @@ try_split (rtx pat, rtx trial, int last) ...@@ -3427,6 +3427,7 @@ try_split (rtx pat, rtx trial, int last)
int probability; int probability;
rtx insn_last, insn; rtx insn_last, insn;
int njumps = 0; int njumps = 0;
rtx call_insn = NULL_RTX;
/* We're not good at redistributing frame information. */ /* We're not good at redistributing frame information. */
if (RTX_FRAME_RELATED_P (trial)) if (RTX_FRAME_RELATED_P (trial))
...@@ -3499,6 +3500,9 @@ try_split (rtx pat, rtx trial, int last) ...@@ -3499,6 +3500,9 @@ try_split (rtx pat, rtx trial, int last)
{ {
rtx next, *p; rtx next, *p;
gcc_assert (call_insn == NULL_RTX);
call_insn = insn;
/* Add the old CALL_INSN_FUNCTION_USAGE to whatever the /* Add the old CALL_INSN_FUNCTION_USAGE to whatever the
target may have explicitly specified. */ target may have explicitly specified. */
p = &CALL_INSN_FUNCTION_USAGE (insn); p = &CALL_INSN_FUNCTION_USAGE (insn);
...@@ -3571,6 +3575,11 @@ try_split (rtx pat, rtx trial, int last) ...@@ -3571,6 +3575,11 @@ try_split (rtx pat, rtx trial, int last)
fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0))); fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));
break; break;
case REG_CALL_DECL:
gcc_assert (call_insn != NULL_RTX);
add_reg_note (call_insn, REG_NOTE_KIND (note), XEXP (note, 0));
break;
default: default:
break; break;
} }
......
...@@ -211,3 +211,8 @@ REG_NOTE (ARGS_SIZE) ...@@ -211,3 +211,8 @@ REG_NOTE (ARGS_SIZE)
that the return value of a call can be used to reinitialize a that the return value of a call can be used to reinitialize a
pseudo reg. */ pseudo reg. */
REG_NOTE (RETURNED) REG_NOTE (RETURNED)
/* Used to mark a call with the function decl called by the call.
The decl might not be available in the call due to splitting of the call
insn. This note is a SYMBOL_REF. */
REG_NOTE (CALL_DECL)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment