Commit 26e288ba by Tom de Vries

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
parent f5168e47
...@@ -225,6 +225,7 @@ static int final_addr_vec_align (rtx); ...@@ -225,6 +225,7 @@ static int final_addr_vec_align (rtx);
#endif #endif
static int align_fuzz (rtx, rtx, int, unsigned); static int align_fuzz (rtx, rtx, int, unsigned);
static void collect_fn_hard_reg_usage (void); static void collect_fn_hard_reg_usage (void);
static tree get_call_fndecl (rtx);
/* Initialize data in final at the beginning of a compilation. */ /* Initialize data in final at the beginning of a compilation. */
...@@ -4746,6 +4747,16 @@ make_pass_clean_state (gcc::context *ctxt) ...@@ -4746,6 +4747,16 @@ make_pass_clean_state (gcc::context *ctxt)
return new pass_clean_state (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. */ /* Collect hard register usage for the current function. */
static void static void
...@@ -4771,7 +4782,8 @@ collect_fn_hard_reg_usage (void) ...@@ -4771,7 +4782,8 @@ collect_fn_hard_reg_usage (void)
if (!NONDEBUG_INSN_P (insn)) if (!NONDEBUG_INSN_P (insn))
continue; continue;
if (CALL_P (insn)) if (CALL_P (insn)
&& !self_recursive_call_p (insn))
{ {
if (!get_call_reg_set_usage (insn, &insn_used_regs, if (!get_call_reg_set_usage (insn, &insn_used_regs,
call_used_reg_set)) call_used_reg_set))
......
/* { dg-do compile } */
/* { dg-options "-O2 -fuse-caller-save -fomit-frame-pointer -fno-optimize-sibling-calls" } */
/* { dg-additional-options "-mregparm=1" { target ia32 } } */
/* Test -fuse-caller-save optimization on self-recursive function. */
static int __attribute__((noinline))
bar (int x)
{
if (x > 4)
return bar (x - 3);
return 0;
}
int __attribute__((noinline))
foo (int y)
{
return y + bar (y);
}
int
main (void)
{
return !(foo (5) == 13);
}
/* Verify that no registers where saved on stack. */
/* { dg-final { scan-assembler-not "\.cfi_offset" } } */
/* Verify that bar is self-recursive. */
/* { dg-final { scan-assembler-times "call\tbar" 2 } } */
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