diff options
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 64 |
1 files changed, 15 insertions, 49 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 41725b57769..4d6cdd78aeb 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "rtl.h" #include "tree.h" #include "flags.h" @@ -36,10 +38,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "langhooks.h" #include "target.h" -#if !defined FUNCTION_OK_FOR_SIBCALL -#define FUNCTION_OK_FOR_SIBCALL(DECL) 1 -#endif - /* Decide whether a function's arguments should be processed from first to last or from last to first. @@ -154,35 +152,6 @@ int stack_arg_under_construction; static int calls_function PARAMS ((tree, int)); static int calls_function_1 PARAMS ((tree, int)); -/* Nonzero if this is a call to a `const' function. */ -#define ECF_CONST 1 -/* Nonzero if this is a call to a `volatile' function. */ -#define ECF_NORETURN 2 -/* Nonzero if this is a call to malloc or a related function. */ -#define ECF_MALLOC 4 -/* Nonzero if it is plausible that this is a call to alloca. */ -#define ECF_MAY_BE_ALLOCA 8 -/* Nonzero if this is a call to a function that won't throw an exception. */ -#define ECF_NOTHROW 16 -/* Nonzero if this is a call to setjmp or a related function. */ -#define ECF_RETURNS_TWICE 32 -/* Nonzero if this is a call to `longjmp'. */ -#define ECF_LONGJMP 64 -/* Nonzero if this is a syscall that makes a new process in the image of - the current one. */ -#define ECF_FORK_OR_EXEC 128 -#define ECF_SIBCALL 256 -/* Nonzero if this is a call to "pure" function (like const function, - but may read memory. */ -#define ECF_PURE 512 -/* Nonzero if this is a call to a function that returns with the stack - pointer depressed. */ -#define ECF_SP_DEPRESSED 1024 -/* Nonzero if this call is known to always return. */ -#define ECF_ALWAYS_RETURN 2048 -/* Create libcall block around the call. */ -#define ECF_LIBCALL_BLOCK 4096 - static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, rtx, rtx, int, rtx, int, @@ -219,7 +188,6 @@ static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx, enum machine_mode, int, va_list)); static int special_function_p PARAMS ((tree, int)); -static int flags_from_decl_or_type PARAMS ((tree)); static rtx try_to_integrate PARAMS ((tree, tree, rtx, int, tree, rtx)); static int check_sibcall_argument_overlap_1 PARAMS ((rtx)); @@ -818,7 +786,7 @@ alloca_call_p (exp) /* Detect flags (function attributes) from the function decl or type node. */ -static int +int flags_from_decl_or_type (exp) tree exp; { @@ -1717,10 +1685,8 @@ rtx_for_function_call (fndecl, exp) else /* Generate an rtx (probably a pseudo-register) for the address. */ { - rtx funaddr; push_temp_slots (); - funaddr = funexp - = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0); + funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0); pop_temp_slots (); /* FUNEXP can't be BLKmode. */ emit_queue (); } @@ -2281,7 +2247,10 @@ expand_call (exp, target, ignore) { struct_value_size = int_size_in_bytes (TREE_TYPE (exp)); - if (target && GET_CODE (target) == MEM) + if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (exp)) + /* The structure value address arg is already in actparms. */ + structure_value_addr_parm = 1; + else if (target && GET_CODE (target) == MEM) structure_value_addr = XEXP (target, 0); else { @@ -2467,16 +2436,13 @@ expand_call (exp, target, ignore) It does not seem worth the effort since few optimizable sibling calls will return a structure. */ || structure_value_addr != NULL_RTX - /* If the register holding the address is a callee saved - register, then we lose. We have no way to prevent that, - so we only allow calls to named functions. */ - /* ??? This could be done by having the insn constraints - use a register class that is all call-clobbered. Any - reload insns generated to fix things up would appear - before the sibcall_epilogue. */ - || fndecl == NULL_TREE + /* Check whether the target is able to optimize the call + into a sibcall. */ + || !(*targetm.function_ok_for_sibcall) (fndecl, exp) + /* Functions that do not return exactly once may not be sibcall + optimized. */ || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN)) - || !FUNCTION_OK_FOR_SIBCALL (fndecl) + || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))) /* If this function requires more stack slots than the current function, we cannot change it into a sibling call. */ || args_size.constant > current_function_args_size @@ -2608,7 +2574,7 @@ expand_call (exp, target, ignore) is subject to race conditions, just as with multithreaded programs. */ - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_fork_func"), + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gcov_flush"), LCT_ALWAYS_RETURN, VOIDmode, 0); } |