From: Tom de Vries Date: Wed, 9 Jul 2014 21:03:44 +0000 (+0000) Subject: Enable fuse-caller-save on self-recursive functions X-Git-Tag: releases/gcc-5.1.0~6430 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=26e288bab56e529b3249c580ad31da4f0e77d76f;p=thirdparty%2Fgcc.git Enable fuse-caller-save on self-recursive functions 2014-07-09 Tom de Vries * 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 --- diff --git a/gcc/final.c b/gcc/final.c index cf2a2789db1c..304ae2ab6eed 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)) diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save-rec.c b/gcc/testsuite/gcc.target/i386/fuse-caller-save-rec.c new file mode 100644 index 000000000000..b30a0b4dbb14 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save-rec.c @@ -0,0 +1,32 @@ +/* { 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 } } */ +