diff options
author | Tom de Vries <vries@gcc.gnu.org> | 2014-07-09 21:03:44 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2014-07-09 21:03:44 +0000 |
commit | 26e288bab56e529b3249c580ad31da4f0e77d76f (patch) | |
tree | 8f870b283ee2ce1cc19e7bdf8ea4acb72ccad8dc /gcc/final.c | |
parent | f5168e47a83d6afcab6afa176da2ba466c383dbb (diff) | |
download | gcc-26e288bab56e529b3249c580ad31da4f0e77d76f.zip gcc-26e288bab56e529b3249c580ad31da4f0e77d76f.tar.gz gcc-26e288bab56e529b3249c580ad31da4f0e77d76f.tar.bz2 |
Enable fuse-caller-save on self-recursive functions
2014-07-09 Tom de Vries <tom@codesourcery.com>
* final.c (get_call_fndecl): Declare.
(self_recursive_call_p): New function.
(collect_fn_hard_reg_usage): Handle self-recursive function calls.
* gcc.target/i386/fuse-caller-save-rec.c: New test.
From-SVN: r212409
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/gcc/final.c b/gcc/final.c index cf2a278..304ae2a 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -225,6 +225,7 @@ static int final_addr_vec_align (rtx); #endif static int align_fuzz (rtx, rtx, int, unsigned); static void collect_fn_hard_reg_usage (void); +static tree get_call_fndecl (rtx); /* Initialize data in final at the beginning of a compilation. */ @@ -4746,6 +4747,16 @@ make_pass_clean_state (gcc::context *ctxt) return new pass_clean_state (ctxt); } +/* Return true if INSN is a call to the the current function. */ + +static bool +self_recursive_call_p (rtx insn) +{ + tree fndecl = get_call_fndecl (insn); + return (fndecl == current_function_decl + && decl_binds_to_current_def_p (fndecl)); +} + /* Collect hard register usage for the current function. */ static void @@ -4771,7 +4782,8 @@ collect_fn_hard_reg_usage (void) if (!NONDEBUG_INSN_P (insn)) continue; - if (CALL_P (insn)) + if (CALL_P (insn) + && !self_recursive_call_p (insn)) { if (!get_call_reg_set_usage (insn, &insn_used_regs, call_used_reg_set)) |