Commit 7a32d6c4 by Radovan Obradovic Committed by Tom de Vries

-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
parent 4b9fcb37
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.
......
......@@ -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);
......
......@@ -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. */
......
......@@ -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;
}"
)
......
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.
......
/* { 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 } } } } */
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