-fuse-caller-save - Enable for MIPS
2014-05-29 Radovan Obradovic <robradovic@mips.com> Tom de Vries <tom@codesourcery.com> * config/mips/mips.h (POST_CALL_TMP_REG): Define. * config/mips/mips.c (mips_emit_call_insn): Add POST_CALL_TMP_REG clobber. (mips_split_call): Use POST_CALL_TMP_REG. (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true. * gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo options. * gcc.target/mips/fuse-caller-save.h: New include file. * gcc.target/mips/fuse-caller-save.c: New test. * gcc.target/mips/fuse-caller-save-mips16.c: Same. * gcc.target/mips/fuse-caller-save-micromips.c: Same. Co-Authored-By: Tom de Vries <tom@codesourcery.com> From-SVN: r211049
This commit is contained in:
parent
41455f8918
commit
c2db3f3d39
9 changed files with 109 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
|||
2014-05-29 Radovan Obradovic <robradovic@mips.com>
|
||||
Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* config/mips/mips.h (POST_CALL_TMP_REG): Define.
|
||||
* config/mips/mips.c (mips_emit_call_insn): Add POST_CALL_TMP_REG
|
||||
clobber.
|
||||
(mips_split_call): Use POST_CALL_TMP_REG.
|
||||
(TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.
|
||||
|
||||
2014-05-29 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* final.c (collect_fn_hard_reg_usage): Guard variable declaration
|
||||
|
|
|
@ -2848,6 +2848,15 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
|
|||
gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
|
||||
emit_insn (gen_update_got_version ());
|
||||
}
|
||||
|
||||
if (TARGET_MIPS16
|
||||
&& TARGET_EXPLICIT_RELOCS
|
||||
&& TARGET_CALL_CLOBBERED_GP)
|
||||
{
|
||||
rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
|
||||
clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
|
||||
}
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
|
@ -7104,10 +7113,8 @@ mips_split_call (rtx insn, rtx call_pattern)
|
|||
{
|
||||
emit_call_insn (call_pattern);
|
||||
if (!find_reg_note (insn, REG_NORETURN, 0))
|
||||
/* Pick a temporary register that is suitable for both MIPS16 and
|
||||
non-MIPS16 code. $4 and $5 are used for returning complex double
|
||||
values in soft-float code, so $6 is the first suitable candidate. */
|
||||
mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
|
||||
mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode,
|
||||
POST_CALL_TMP_REG));
|
||||
}
|
||||
|
||||
/* Return true if a call to DECL may need to use JALX. */
|
||||
|
@ -19143,6 +19150,9 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
|
|||
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
|
||||
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
|
||||
|
||||
#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
|
||||
#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-mips.h"
|
||||
|
|
|
@ -2175,6 +2175,13 @@ enum reg_class
|
|||
#define FP_ARG_FIRST (FP_REG_FIRST + 12)
|
||||
#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
|
||||
|
||||
/* Temporary register that is used when restoring $gp after a call. $4 and $5
|
||||
are used for returning complex double values in soft-float code, so $6 is the
|
||||
first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use
|
||||
$gp itself as the temporary. */
|
||||
#define POST_CALL_TMP_REG \
|
||||
(TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM)
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
We have no FP argument registers when soft-float. When FP registers
|
||||
are 32 bits, we can't directly reference the odd numbered ones. */
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2014-05-29 Radovan Obradovic <robradovic@mips.com>
|
||||
Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
|
||||
options.
|
||||
* gcc.target/mips/fuse-caller-save.h: New include file.
|
||||
* gcc.target/mips/fuse-caller-save.c: New test.
|
||||
* gcc.target/mips/fuse-caller-save-mips16.c: Same.
|
||||
* gcc.target/mips/fuse-caller-save-micromips.c: Same.
|
||||
|
||||
2014-05-29 Evgeny Stupachenko <evstupac@gmail.com>
|
||||
|
||||
* gcc.dg/vect/pr52252-ld.c: Fix target and options for the test.
|
||||
|
|
17
gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
Normal file
17
gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-fuse-caller-save (-mmicromips)" } */
|
||||
/* At -O0 and -O1, the register allocator behaves more conservatively, and
|
||||
the fuse-caller-save optimization doesnt' trigger. */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
|
||||
/* Testing -fuse-caller-save optimization option. */
|
||||
|
||||
#define ATTRIBUTE MICROMIPS
|
||||
#include "fuse-caller-save.h"
|
||||
|
||||
/* Check that there are only 2 stack-saves: r31 in main and foo. */
|
||||
|
||||
/* Check that there only 2 sw/sd. */
|
||||
/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
|
||||
|
||||
/* Check that the first caller-save register is unused. */
|
||||
/* { dg-final { scan-assembler-not "\\\$16" } } */
|
17
gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c
Normal file
17
gcc/testsuite/gcc.target/mips/fuse-caller-save-mips16.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-fuse-caller-save (-mips16)" } */
|
||||
/* At -O0 and -O1, the register allocator behaves more conservatively, and
|
||||
the fuse-caller-save optimization doesnt' trigger. */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
|
||||
/* Testing -fuse-caller-save optimization option. */
|
||||
|
||||
#define ATTRIBUTE MIPS16
|
||||
#include "fuse-caller-save.h"
|
||||
|
||||
/* Check that there are only 2 stack-saves: r31 in main and foo. */
|
||||
|
||||
/* Check that there only 2 sw/sd. */
|
||||
/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
|
||||
|
||||
/* Check that the first caller-save register is unused. */
|
||||
/* { dg-final { scan-assembler-not "\\\$16" } } */
|
17
gcc/testsuite/gcc.target/mips/fuse-caller-save.c
Normal file
17
gcc/testsuite/gcc.target/mips/fuse-caller-save.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-fuse-caller-save" } */
|
||||
/* At -O0 and -O1, the register allocator behaves more conservatively, and
|
||||
the fuse-caller-save optimization doesnt' trigger. */
|
||||
/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */
|
||||
/* Testing -fuse-caller-save optimization option. */
|
||||
|
||||
#define ATTRIBUTE NOCOMPRESSION
|
||||
#include "fuse-caller-save.h"
|
||||
|
||||
/* Check that there are only 2 stack-saves: r31 in main and foo. */
|
||||
|
||||
/* Check that there only 2 sw/sd. */
|
||||
/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } } */
|
||||
|
||||
/* Check that the first caller-save register is unused. */
|
||||
/* { dg-final { scan-assembler-not "\\\$16" } } */
|
17
gcc/testsuite/gcc.target/mips/fuse-caller-save.h
Normal file
17
gcc/testsuite/gcc.target/mips/fuse-caller-save.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
static int __attribute__((noinline)) ATTRIBUTE
|
||||
bar (int x)
|
||||
{
|
||||
return x + 3;
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) ATTRIBUTE
|
||||
foo (int y)
|
||||
{
|
||||
return y + bar (y);
|
||||
}
|
||||
|
||||
int ATTRIBUTE
|
||||
main (void)
|
||||
{
|
||||
return !(foo (5) == 13);
|
||||
}
|
|
@ -305,6 +305,7 @@ foreach option {
|
|||
tree-vectorize
|
||||
unroll-all-loops
|
||||
unroll-loops
|
||||
use-caller-save
|
||||
} {
|
||||
lappend mips_option_groups $option "-f(no-|)$option"
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue