This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]