summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-24 09:34:15 +0000
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-24 09:34:15 +0000
commit2e3b0d0fde7879de7ccc1f2f2e76bb8ab4f3743a (patch)
tree12104592791a836124a5fa50178055b2071db3fd
parent2cc49064f6255da8ca63b3897ac371fe2fc322cc (diff)
downloadgcc-2e3b0d0fde7879de7ccc1f2f2e76bb8ab4f3743a.tar.gz
-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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209744 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/calls.c21
-rw-r--r--gcc/combine.c1
-rw-r--r--gcc/emit-rtl.c9
-rw-r--r--gcc/reg-notes.def5
5 files changed, 45 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index edf0467334d..662e08377ee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,15 @@
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.
+
+2014-04-24 Radovan Obradovic <robradovic@mips.com>
+ Tom de Vries <tom@codesourcery.com>
+
* common.opt (fuse-caller-save): New option.
2014-04-24 Tejas Belagod <tejas.belagod@arm.com>
diff --git a/gcc/calls.c b/gcc/calls.c
index f0c92ddc018..e798c7a0349 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3178,6 +3178,19 @@ expand_call (tree exp, rtx target, int ignore)
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
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
of the argument setup we probably clobbered our call address.
In that case we can't do sibcalls. */
@@ -4205,6 +4218,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
valreg,
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. */
if (!pcc_struct_value
&& TYPE_MODE (tfom) != BLKmode
diff --git a/gcc/combine.c b/gcc/combine.c
index 9a78c064945..e051f5e4d1f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13269,6 +13269,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
case REG_NORETURN:
case REG_SETJMP:
case REG_TM:
+ case REG_CALL_DECL:
/* These notes must remain with the call. It should not be
possible for both I2 and I3 to be a call. */
if (CALL_P (i3))
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4736f8d0dcc..e3fd0a5132b 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3427,6 +3427,7 @@ try_split (rtx pat, rtx trial, int last)
int probability;
rtx insn_last, insn;
int njumps = 0;
+ rtx call_insn = NULL_RTX;
/* We're not good at redistributing frame information. */
if (RTX_FRAME_RELATED_P (trial))
@@ -3499,6 +3500,9 @@ try_split (rtx pat, rtx trial, int last)
{
rtx next, *p;
+ gcc_assert (call_insn == NULL_RTX);
+ call_insn = insn;
+
/* Add the old CALL_INSN_FUNCTION_USAGE to whatever the
target may have explicitly specified. */
p = &CALL_INSN_FUNCTION_USAGE (insn);
@@ -3571,6 +3575,11 @@ try_split (rtx pat, rtx trial, int last)
fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));
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:
break;
}
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index 31cd171b542..831fe82272a 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -211,3 +211,8 @@ REG_NOTE (ARGS_SIZE)
that the return value of a call can be used to reinitialize a
pseudo reg. */
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)