This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, ARM] Enable sibling calls for Thumb-2
- From: Julian Brown <julian at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 15 Feb 2010 12:46:29 +0000
- Subject: [PATCH, ARM] Enable sibling calls for Thumb-2
Hi,
This patch turns on sibling calls for Thumb-2. It works in cases which
failed with earlier patches, e.g. described in the thread here:
http://gcc.gnu.org/ml/gcc-patches/2009-05/msg01291.html
Specifically,
http://gcc.gnu.org/ml/gcc-patches/2009-05/msg01317.html
The patch does not allow sibling calls to be conditional: I have a
strong suspicion that would create problems for the linker at present,
e.g. for interworking and/or long-branch stub generation. I think this
addresses, or at least sidesteps, the issue mentioned in the (removed)
comment on USE_RETURN_INSN about confusing the conditional insn counter.
Testing (cross to ARM Linux, targeting ARMv7-a/Thumb) shows a couple of
progressions. OK to apply (when we get to stage 1)?
Cheers,
Julian
ChangeLog
Julian Brown <julian@codesourcery.com>
Mark Mitchell <mark@codesourcery.com>
gcc/
* config/arm/arm.c (arm_function_ok_for_sibcall): Allow sibling
calls for Thumb-2.
(output_return_instruction): Use pop not ldmfd for Thumb-2.
* config/arm/arm.h (USE_RETURN_INSN): Enable for Thumb-2.
* config/arm/arm.md (*call_symbol, *call_value_symbol): Use for
Thumb-2.
(*call_insn, *call_value_insn): Don't use for Thumb-2.
(sibcall, sibcall_value, *sibcall_insn, *sibcall_value_insn): Use
for Thumb-2.
(return): New expander.
(*arm_return): New name for ARM return insn.
(*thumb2_return): New insn pattern.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 466981a..d450a1e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4785,8 +4785,8 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
return false;
/* Never tailcall something for which we have no decl, or if we
- are in Thumb mode. */
- if (decl == NULL || TARGET_THUMB)
+ are generating code for Thumb-1. */
+ if (decl == NULL || !TARGET_32BIT)
return false;
/* The PIC register is live on entry to VxWorks PLT entries, so we
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 26ffaf8..907f591 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1810,10 +1810,8 @@ typedef struct
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
-/* This is disabled for Thumb-2 because it will confuse the
- conditional insn counter. */
#define USE_RETURN_INSN(ISCOND) \
- (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)
+ (TARGET_32BIT ? use_return_insn (ISCOND, NULL) : 0)
/* Definitions for register eliminations.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3d0d7f2..282b538 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8625,7 +8625,7 @@
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
- "TARGET_ARM
+ "TARGET_32BIT
&& (GET_CODE (operands[0]) == SYMBOL_REF)
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
@@ -8641,7 +8641,7 @@
(match_operand:SI 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
- "TARGET_ARM
+ "TARGET_32BIT
&& (GET_CODE (operands[1]) == SYMBOL_REF)
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
@@ -8656,7 +8656,7 @@
(match_operand:SI 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
- "TARGET_THUMB
+ "TARGET_THUMB1
&& GET_CODE (operands[0]) == SYMBOL_REF
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"bl\\t%a0"
@@ -8670,7 +8670,7 @@
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
- "TARGET_THUMB
+ "TARGET_THUMB1
&& GET_CODE (operands[1]) == SYMBOL_REF
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"bl\\t%a1"
@@ -8684,7 +8684,7 @@
(match_operand 1 "general_operand" ""))
(return)
(use (match_operand 2 "" ""))])]
- "TARGET_ARM"
+ "TARGET_32BIT"
"
{
if (operands[2] == NULL_RTX)
@@ -8698,7 +8698,7 @@
(match_operand 2 "general_operand" "")))
(return)
(use (match_operand 3 "" ""))])]
- "TARGET_ARM"
+ "TARGET_32BIT"
"
{
if (operands[3] == NULL_RTX)
@@ -8711,7 +8711,7 @@
(match_operand 1 "" ""))
(return)
(use (match_operand 2 "" ""))]
- "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
+ "TARGET_32BIT && GET_CODE (operands[0]) == SYMBOL_REF"
"*
return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
"
@@ -8724,15 +8724,20 @@
(match_operand 2 "" "")))
(return)
(use (match_operand 3 "" ""))]
- "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
+ "TARGET_32BIT && GET_CODE (operands[1]) == SYMBOL_REF"
"*
return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
"
[(set_attr "type" "call")]
)
+(define_expand "return"
+ [(return)]
+ "TARGET_32BIT && USE_RETURN_INSN (FALSE)"
+ "")
+
;; Often the return insn will be the same as loading from memory, so set attr
-(define_insn "return"
+(define_insn "*arm_return"
[(return)]
"TARGET_ARM && USE_RETURN_INSN (FALSE)"
"*
@@ -8749,6 +8754,19 @@
(set_attr "predicable" "yes")]
)
+;; Note: this is not predicable, to avoid issues with linker-generated
+;; interworking stubs.
+(define_insn "*thumb2_return"
+ [(return)]
+ "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)"
+ "*
+ {
+ return output_return_instruction (const_true_rtx, TRUE, FALSE);
+ }"
+ [(set_attr "type" "load1")
+ (set_attr "length" "12")]
+)
+
(define_insn "*cond_return"
[(set (pc)
(if_then_else (match_operator 0 "arm_comparison_operator"