arm.c (arm_function_ok_for_sibcall): New function.

* 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.

From-SVN: r35708
This commit is contained in:
Richard Earnshaw 2000-08-15 15:14:06 +00:00 committed by Richard Earnshaw
parent 74da3101e5
commit f99fce0c53
4 changed files with 49 additions and 17 deletions

View File

@ -1,3 +1,10 @@
2000-08-15 Richard Earnshaw <rearnsha@arm.com>
* 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 <rearnsha@arm.com>
* arm.md (splits generating cond_exec): Disable.

View File

@ -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)

View File

@ -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

View File

@ -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;
}
}"
)