diff options
author | Radovan Obradovic <robradovic@mips.com> | 2014-06-18 15:50:59 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2014-06-18 15:50:59 +0000 |
commit | 7a32d6c491b450dfe86263ef28a9947cd57d09b6 (patch) | |
tree | c149e1e97b535742e7eb05f673e0816661351dc5 /gcc | |
parent | 4b9fcb37ba51b6806d9a38b27ebd7e057e8d46e9 (diff) | |
download | gcc-7a32d6c491b450dfe86263ef28a9947cd57d09b6.zip gcc-7a32d6c491b450dfe86263ef28a9947cd57d09b6.tar.gz gcc-7a32d6c491b450dfe86263ef28a9947cd57d09b6.tar.bz2 |
-fuse-caller-save - Enable for ARM
2014-06-18 Radovan Obradovic <robradovic@mips.com>
Tom de Vries <tom@codesourcery.com>
* config/arm/arm-protos.h (arm_emit_call_insn): Add bool parameter.
* config/arm/arm.c (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS):
Redefine to true.
(arm_emit_call_insn): Add and use sibcall parameter. Add IP and CC
clobbers to CALL_INSN_FUNCTION_USAGE.
(define_expand "sibcall_internal")
(define_expand "sibcall_value_internal"): New.
(define_expand "call", define_expand "call_value"): Add argument to
arm_emit_call_insn.
(define_expand "sibcall"): Use sibcall_internal and arm_emit_call_insn.
(define_expand "sibcall_value"): Use sibcall_value_internal and
arm_emit_call_insn.
* gcc.target/arm/fuse-caller-save.c: New test.
Co-Authored-By: Tom de Vries <tom@codesourcery.com>
From-SVN: r211798
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 16 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/fuse-caller-save.c | 25 |
6 files changed, 90 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f6124cd..b0c9ed8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2014-06-18 Radovan Obradovic <robradovic@mips.com> + Tom de Vries <tom@codesourcery.com> + + * config/arm/arm-protos.h (arm_emit_call_insn): Add bool parameter. + * config/arm/arm.c (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): + Redefine to true. + (arm_emit_call_insn): Add and use sibcall parameter. Add IP and CC + clobbers to CALL_INSN_FUNCTION_USAGE. + (define_expand "sibcall_internal") + (define_expand "sibcall_value_internal"): New. + (define_expand "call", define_expand "call_value"): Add argument to + arm_emit_call_insn. + (define_expand "sibcall"): Use sibcall_internal and arm_emit_call_insn. + (define_expand "sibcall_value"): Use sibcall_value_internal and + arm_emit_call_insn. + 2014-06-18 Charles Baylis <charles.baylis@linaro.org> * config/arm/bpabi.c (__gnu_uldivmod_helper): Remove. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 74645ee..524fd83 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -126,7 +126,7 @@ extern int arm_const_double_inline_cost (rtx); extern bool arm_const_double_by_parts (rtx); extern bool arm_const_double_by_immediates (rtx); extern const char *fp_immediate_constant (rtx); -extern void arm_emit_call_insn (rtx, rtx); +extern void arm_emit_call_insn (rtx, rtx, bool); extern const char *output_call (rtx *); extern const char *output_call_mem (rtx *); void arm_emit_movpair (rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ffe8e21..d293b5b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -685,6 +685,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P #define TARGET_CONST_NOT_OK_FOR_DEBUG_P arm_const_not_ok_for_debug_p +#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS +#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -17615,7 +17618,7 @@ vfp_emit_fstmd (int base_reg, int count) the call target. */ void -arm_emit_call_insn (rtx pat, rtx addr) +arm_emit_call_insn (rtx pat, rtx addr, bool sibcall) { rtx insn; @@ -17626,6 +17629,7 @@ arm_emit_call_insn (rtx pat, rtx addr) to the instruction's CALL_INSN_FUNCTION_USAGE. */ if (TARGET_VXWORKS_RTP && flag_pic + && !sibcall && GET_CODE (addr) == SYMBOL_REF && (SYMBOL_REF_DECL (addr) ? !targetm.binds_local_p (SYMBOL_REF_DECL (addr)) @@ -17634,6 +17638,16 @@ arm_emit_call_insn (rtx pat, rtx addr) require_pic_register (); use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg); } + + if (TARGET_AAPCS_BASED) + { + /* For AAPCS, IP and CC can be clobbered by veneers inserted by the + linker. We need to add these to allow setting + TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS to true. */ + rtx *fusage = &CALL_INSN_FUNCTION_USAGE (insn); + clobber_reg (fusage, gen_rtx_REG (word_mode, IP_REGNUM)); + clobber_reg (fusage, gen_rtx_REG (word_mode, CC_REGNUM)); + } } /* Output a 'call' insn. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 6ae240e..42c12c8 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7561,7 +7561,7 @@ XEXP (operands[0], 0) = force_reg (Pmode, callee); pat = gen_call_internal (operands[0], operands[1], operands[2]); - arm_emit_call_insn (pat, XEXP (operands[0], 0)); + arm_emit_call_insn (pat, XEXP (operands[0], 0), false); DONE; }" ) @@ -7640,7 +7640,7 @@ pat = gen_call_value_internal (operands[0], operands[1], operands[2], operands[3]); - arm_emit_call_insn (pat, XEXP (operands[1], 0)); + arm_emit_call_insn (pat, XEXP (operands[1], 0), false); DONE; }" ) @@ -7730,6 +7730,12 @@ [(set_attr "type" "call")] ) +(define_expand "sibcall_internal" + [(parallel [(call (match_operand 0 "memory_operand" "") + (match_operand 1 "general_operand" "")) + (return) + (use (match_operand 2 "" ""))])]) + ;; We may also be able to do sibcalls for Thumb, but it's much harder... (define_expand "sibcall" [(parallel [(call (match_operand 0 "memory_operand" "") @@ -7739,6 +7745,8 @@ "TARGET_32BIT" " { + rtx pat; + if ((!REG_P (XEXP (operands[0], 0)) && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF @@ -7747,9 +7755,20 @@ if (operands[2] == NULL_RTX) operands[2] = const0_rtx; + + pat = gen_sibcall_internal (operands[0], operands[1], operands[2]); + arm_emit_call_insn (pat, operands[0], true); + DONE; }" ) +(define_expand "sibcall_value_internal" + [(parallel [(set (match_operand 0 "" "") + (call (match_operand 1 "memory_operand" "") + (match_operand 2 "general_operand" ""))) + (return) + (use (match_operand 3 "" ""))])]) + (define_expand "sibcall_value" [(parallel [(set (match_operand 0 "" "") (call (match_operand 1 "memory_operand" "") @@ -7759,6 +7778,8 @@ "TARGET_32BIT" " { + rtx pat; + if ((!REG_P (XEXP (operands[1], 0)) && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF @@ -7767,6 +7788,11 @@ if (operands[3] == NULL_RTX) operands[3] = const0_rtx; + + pat = gen_sibcall_value_internal (operands[0], operands[1], + operands[2], operands[3]); + arm_emit_call_insn (pat, operands[1], true); + DONE; }" ) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 52c4bef..f41f3df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-18 Radovan Obradovic <robradovic@mips.com> + Tom de Vries <tom@codesourcery.com> + + * gcc.target/arm/fuse-caller-save.c: New test. + 2014-06-18 Richard Biener <rguenther@suse.de> * tree-pass.h (make_pass_dce_loop): Remove. diff --git a/gcc/testsuite/gcc.target/arm/fuse-caller-save.c b/gcc/testsuite/gcc.target/arm/fuse-caller-save.c new file mode 100644 index 0000000..5fa8998 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fuse-caller-save.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fuse-caller-save" } */ +/* Testing -fuse-caller-save optimization option. */ + +static int __attribute__((noinline)) +bar (int x) +{ + return x + 3; +} + +int __attribute__((noinline)) +foo (int y) +{ + return y + bar (y); +} + +int +main (void) +{ + return !(foo (5) == 13); +} + +/* For thumb1, r3 is considered likely spilled, and treated differently in + ira_build_conflicts, which inhibits the fuse-caller-save optimization. */ +/* { dg-final { scan-assembler-times "mov\tr3, r0" 1 { target { ! arm_thumb1 } } } } */ |