aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@arm.com>2014-04-25 17:00:33 +0000
committerYufeng Zhang <yufeng@gcc.gnu.org>2014-04-25 17:00:33 +0000
commit10432733a5534e0116b0b1770139a56ae2ab01fe (patch)
tree90f35fa09214aa4563cf77cbd2ffc558975d270c
parent4ec21835cbed3f28c7939dcc72795c28dc6dc46a (diff)
downloadgcc-10432733a5534e0116b0b1770139a56ae2ab01fe.zip
gcc-10432733a5534e0116b0b1770139a56ae2ab01fe.tar.gz
gcc-10432733a5534e0116b0b1770139a56ae2ab01fe.tar.bz2
[ARM] Enable tail call optimization for long call
gcc/ * config/arm/predicates.md (call_insn_operand): Add long_call check. * config/arm/arm.md (sibcall, sibcall_value): Force the address to reg for long_call. * config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call restriction. gcc/testsuite * gcc.target/arm/tail-long-call.c: New test. From-SVN: r209808
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm.c5
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/arm/predicates.md3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/tail-long-call.c12
6 files changed, 34 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d08a417..7de7be5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2014-04-25 Jiong Wang <jiong.wang@arm.com>
+
+ * config/arm/predicates.md (call_insn_operand): Add long_call check.
+ * config/arm/arm.md (sibcall, sibcall_value): Force the address to
+ reg for long_call.
+ * config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call
+ restriction.
+
2014-04-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.c (arm_cortex_a8_tune): Initialise
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index de457a3..16fc7ed 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6217,11 +6217,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl))
return false;
- /* Cannot tail-call to long calls, since these are out of range of
- a branch instruction. */
- if (decl && arm_is_long_call_p (decl))
- return false;
-
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8a949b9..97753ce 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9367,8 +9367,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[0], 0))
- && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[0], 0))
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
if (operands[2] == NULL_RTX)
@@ -9385,8 +9387,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[1], 0)) &&
- (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[1], 0))
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
if (operands[3] == NULL_RTX)
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 6273e88..d74fcb3 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -681,5 +681,6 @@
(match_code "reg" "0")))
(define_predicate "call_insn_operand"
- (ior (match_code "symbol_ref")
+ (ior (and (match_code "symbol_ref")
+ (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))"))
(match_operand 0 "s_register_operand")))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0d65bef..88681c8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-25 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/arm/tail-long-call.c: New test.
+
2014-04-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/60930
diff --git a/gcc/testsuite/gcc.target/arm/tail-long-call.c b/gcc/testsuite/gcc.target/arm/tail-long-call.c
new file mode 100644
index 0000000..9b27468
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/tail-long-call.c
@@ -0,0 +1,12 @@
+/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */
+/* { dg-options "-O2 -march=armv5te -marm" } */
+/* { dg-final { scan-assembler "bx" } } */
+/* { dg-final { scan-assembler-not "blx" } } */
+
+int lcal (int) __attribute__ ((long_call));
+
+int
+dec (int a)
+{
+ return lcal (a);
+}