From 9e0922c4cc5a92d8a6e1580493ed1cbcde404697 Mon Sep 17 00:00:00 2001 From: rearnsha Date: Tue, 15 Aug 2000 15:14:06 +0000 Subject: [PATCH] * arm.c (arm_function_ok_for_sibcall): New function. * arm.h (FUNCTION_OK_FOR_SIBCALL): Define. * arm.md (call expanders): Don't check here for calls that can't be sibling calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35708 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/arm/arm.c | 35 +++++++++++++++++++++++++++++++++++ gcc/config/arm/arm.h | 7 +++++++ gcc/config/arm/arm.md | 17 ----------------- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8192bbe04a3..71c99bc059d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2000-08-15 Richard Earnshaw + * arm.c (arm_function_ok_for_sibcall): New function. + * arm.h (FUNCTION_OK_FOR_SIBCALL): Define. + * arm.md (call expanders): Don't check here for calls that can't + be sibling calls. + +2000-08-15 Richard Earnshaw + * arm.md (splits generating cond_exec): Disable. 2000-08-15 Richard Earnshaw diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e905daeea74..d559d0042a7 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -1830,6 +1830,41 @@ arm_is_longcall_p (sym_ref, call_cookie, call_symbol) || ENCODED_LONG_CALL_ATTR_P (XSTR (sym_ref, 0)) || TARGET_LONG_CALLS; } + +/* Return non-zero if it is ok to make a tail-call to DECL. */ +int +arm_function_ok_for_sibcall (decl) + tree decl; +{ + int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL; + + /* Never tailcall something for which we have no decl, or if we + are in Thumb mode. */ + if (decl == NULL || TARGET_THUMB) + return 0; + + /* Get the calling method. */ + if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + call_type = CALL_SHORT; + else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + call_type = CALL_LONG; + + /* Cannot tail-call to long calls, since these are out of range of + a branch instruction. However, if not compiling PIC, we know + we can reach the symbol if it is in this compilation unit. */ + if (call_type == CALL_LONG && (flag_pic || ! TREE_ASM_WRITTEN (decl))) + return 0; + + /* 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). */ + if (TARGET_INTERWORK && TREE_PUBLIC (decl) && ! TREE_ASM_WRITTEN (decl)) + return 0; + + /* Everything else is ok. */ + return 1; +} + int legitimate_pic_operand_p (x) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 04702f1134c..b94e8b4e0b2 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1450,6 +1450,13 @@ typedef struct #define FUNCTION_ARG_REGNO_P(REGNO) \ ((REGNO) >= 0 && (REGNO) <= 3) + +/* Tail calling. */ + +/* A C expression that evaluates to true if it is ok to perform a sibling + call to DECL. */ +#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL)) + /* Perform any actions needed for a function that is receiving a variable number of arguments. CUM is as above. MODE and TYPE are the mode and type of the current parameter. PRETEND_SIZE is a variable that should be set to diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 46bf515e7e8..379b308eebc 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6265,14 +6265,6 @@ { if (operands[2] == NULL_RTX) operands[2] = const0_rtx; - - /* If we need to emit a long-call, we can't do it as a sibling call, - so fail over to a normal call. */ - if (arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0)) - { - emit_call_insn (gen_call (operands[0], operands[1], operands[2])); - DONE; - } }" ) @@ -6286,15 +6278,6 @@ { if (operands[3] == NULL_RTX) operands[3] = const0_rtx; - - /* If we need to emit a long-call, we can't do it as a sibling call, - so fail over to a normal call. */ - if (arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0)) - { - emit_call_insn (gen_call_value (operands[0], operands[1], operands[2], - operands[3])); - DONE; - } }" ) -- 2.11.4.GIT