diff options
author | vries <vries@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-24 09:34:15 +0000 |
---|---|---|
committer | vries <vries@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-24 09:34:15 +0000 |
commit | 2e3b0d0fde7879de7ccc1f2f2e76bb8ab4f3743a (patch) | |
tree | 12104592791a836124a5fa50178055b2071db3fd | |
parent | 2cc49064f6255da8ca63b3897ac371fe2fc322cc (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/calls.c | 21 | ||||
-rw-r--r-- | gcc/combine.c | 1 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 9 | ||||
-rw-r--r-- | gcc/reg-notes.def | 5 |
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) |