]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
-fuse-caller-save - Enable for ARM
authorRadovan Obradovic <robradovic@mips.com>
Wed, 18 Jun 2014 15:50:59 +0000 (15:50 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Wed, 18 Jun 2014 15:50:59 +0000 (15:50 +0000)
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

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/fuse-caller-save.c [new file with mode: 0644]

index f6124cde470a15bef7ef589264e653ccd2d41a95..b0c9ed83ba0e67fb522817e4d5709568ccacd7ec 100644 (file)
@@ -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.
index 74645ee1d2453d1f60c07d25b1161bfa6e81f956..524fd83c05a9cb29fa65738011367bb53b1ff547 100644 (file)
@@ -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);
index ffe8e2105ab9b200b9553e38a9f6003f4cbbd12b..d293b5b24f41bd75a59f04ff5032d756232a1df0 100644 (file)
@@ -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;
 \f
 /* 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.  */
index 6ae240e8b6ec127bdde5dfe8953fc574a6854040..42c12c8f87f2349eafa0e71eba187f7d9d521e78 100644 (file)
       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;
   }"
 )
 
     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;
   }"
 )
   [(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" "")
   "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
 
     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" "")
   "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
 
     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;
   }"
 )
 
index 52c4bef538fc7a563418fc73264b429404a936bb..f41f3dfe06911446ed72e46bcb337eff5c929f49 100644 (file)
@@ -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 (file)
index 0000000..5fa8998
--- /dev/null
@@ -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 } } } } */