]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/calls.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / calls.c
index 41725b5776989743f6701c8e05992272d6ae6e2c..4d6cdd78aebc4d5a5f806960feac598d591f9bb4 100644 (file)
@@ -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);
     }