aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c64
1 files changed, 15 insertions, 49 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 41725b5..4d6cdd7 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);
}