OSDN Git Service

* parse.y (check_static_final_variable_assignment_flag): Fix spelling.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 2163e51..9513c30 100644 (file)
@@ -473,10 +473,9 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
 #if defined (HAVE_sibcall_pop) && defined (HAVE_sibcall_value_pop)
   if ((ecf_flags & ECF_SIBCALL)
       && HAVE_sibcall_pop && HAVE_sibcall_value_pop
-      && (RETURN_POPS_ARGS (fndecl, funtype, stack_size) > 0
-         || stack_size == 0))
+      && (n_popped > 0 || stack_size == 0))
     {
-      rtx n_pop = GEN_INT (RETURN_POPS_ARGS (fndecl, funtype, stack_size));
+      rtx n_pop = GEN_INT (n_popped));
       rtx pat;
 
       /* If this subroutine pops its own args, record that in the call insn
@@ -1929,7 +1928,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
      after the arguments are pushed.  */
   if (preferred_unit_stack_boundary > 1)
     {
-      if (unadjusted_alignment >= 0)
+      if (unadjusted_alignment > 0)
        adjustment -= preferred_unit_stack_boundary - unadjusted_alignment;
       else
        adjustment += unadjusted_alignment;
@@ -2377,7 +2376,7 @@ expand_call (exp, target, ignore)
 
   /* Make a vector to hold all the information about each arg.  */
   args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
-  bzero ((char *) args, num_actuals * sizeof (struct arg_data));
+  memset ((char *) args, 0, num_actuals * sizeof (struct arg_data));
 
   /* Build up entries inthe ARGS array, compute the size of the arguments
      into ARGS_SIZE, etc.  */
@@ -2417,9 +2416,8 @@ expand_call (exp, target, ignore)
 
   /* Tail calls can make things harder to debug, and we're traditionally
      pushed these optimizations into -O2.  Don't try if we're already
-     expanding a call, as that means we're an argument.  Similarly, if
-     there's pending loops or cleanups we know there's code to follow
-     the call.
+     expanding a call, as that means we're an argument.  Don't try if
+     there's cleanups, as we know there's code to follow the call.
 
      If rtx_equal_function_value_matters is false, that means we've
      finished with regular parsing.  Which means that some of the
@@ -2430,7 +2428,6 @@ expand_call (exp, target, ignore)
   if (currently_expanding_call++ != 0
       || !flag_optimize_sibling_calls
       || !rtx_equal_function_value_matters
-      || !stmt_loop_nest_empty ()
       || any_pending_cleanups (1)
       || args_size.var)
     try_tail_call = try_tail_recursion = 0;
@@ -2463,6 +2460,7 @@ expand_call (exp, target, ignore)
         before the sibcall_epilogue.  */
       || fndecl == NULL_TREE
       || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP))
+      || TREE_THIS_VOLATILE (fndecl)
       || !FUNCTION_OK_FOR_SIBCALL (fndecl)
       /* If this function requires more stack slots than the current
         function, we cannot change it into a sibling call.  */
@@ -2554,6 +2552,10 @@ expand_call (exp, target, ignore)
       int save_pending_stack_adjust = pending_stack_adjust;
       int save_stack_pointer_delta = stack_pointer_delta;
 
+      /* Emit any queued insns now; otherwise they would end up in
+        only one of the alternates.  */
+      emit_queue ();
+
       /* Use a new sequence to hold any RTL we generate.  We do not even
         know if we will use this RTL yet.  The final decision can not be
         made until after RTL generation for the entire function is
@@ -2659,11 +2661,6 @@ expand_call (exp, target, ignore)
          expand_start_target_temps ();
        }
 
-      /* When calling a const function, we must pop the stack args right away,
-        so that the pop is deleted or moved with the call.  */
-      if (flags & (ECF_CONST | ECF_PURE))
-       NO_DEFER_POP;
-
       /* Don't let pending stack adjusts add up to too much.
         Also, do all pending adjustments now if there is any chance
         this might be a call to alloca or if we are expanding a sibling
@@ -2673,6 +2670,11 @@ expand_call (exp, target, ignore)
          || pass == 0)
        do_pending_stack_adjust ();
 
+      /* When calling a const function, we must pop the stack args right away,
+        so that the pop is deleted or moved with the call.  */
+      if (flags & (ECF_CONST | ECF_PURE))
+       NO_DEFER_POP;
+
       /* Push the temporary stack slot level so that we can free any
         temporaries we make.  */
       push_temp_slots ();
@@ -2782,11 +2784,11 @@ expand_call (exp, target, ignore)
                    = (char *) alloca (highest_outgoing_arg_in_use);
 
                  if (initial_highest_arg_in_use)
-                   bcopy (initial_stack_usage_map, stack_usage_map,
-                          initial_highest_arg_in_use);
+                   memcpy (stack_usage_map, initial_stack_usage_map,
+                           initial_highest_arg_in_use);
 
                  if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
-                   bzero (&stack_usage_map[initial_highest_arg_in_use],
+                   memset (&stack_usage_map[initial_highest_arg_in_use], 0,
                           (highest_outgoing_arg_in_use
                            - initial_highest_arg_in_use));
                  needed = 0;
@@ -2875,7 +2877,7 @@ expand_call (exp, target, ignore)
                          /* Make a new map for the new argument list.  */
                          stack_usage_map = (char *)
                            alloca (highest_outgoing_arg_in_use);
-                         bzero (stack_usage_map, highest_outgoing_arg_in_use);
+                         memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
                          highest_outgoing_arg_in_use = 0;
                        }
                      allocate_dynamic_stack_space (push_size, NULL_RTX,
@@ -3258,7 +3260,12 @@ expand_call (exp, target, ignore)
          emit_move_insn (target, valreg);
        }
       else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
-       target = copy_blkmode_from_reg (target, valreg, TREE_TYPE (exp));
+       {
+         target = copy_blkmode_from_reg (target, valreg, TREE_TYPE (exp));
+
+         /* We can not support sibling calls for this case.  */
+         sibcall_failure = 1;
+       }
       else
        target = copy_to_reg (valreg);
 
@@ -3357,10 +3364,6 @@ expand_call (exp, target, ignore)
        {
          tail_call_insns = insns;
 
-         /* If something prevents making this a sibling call,
-            zero out the sequence.  */
-         if (sibcall_failure)
-           tail_call_insns = NULL_RTX;
          /* Restore the pending stack adjustment now that we have
             finished generating the sibling call sequence.  */
 
@@ -3379,6 +3382,11 @@ expand_call (exp, target, ignore)
        }
       else
        normal_call_insns = insns;
+
+      /* If something prevents making this a sibling call,
+        zero out the sequence.  */
+      if (sibcall_failure)
+       tail_call_insns = NULL_RTX;
     }
 
   /* The function optimize_sibling_and_tail_recursive_calls doesn't
@@ -3571,7 +3579,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
      library functions shouldn't have many args.  */
 
   argvec = (struct arg *) alloca ((nargs + 1) * sizeof (struct arg));
-  bzero ((char *) argvec, (nargs + 1) * sizeof (struct arg));
+  memset ((char *) argvec, 0, (nargs + 1) * sizeof (struct arg));
 
   INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0);
 
@@ -3760,11 +3768,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
       stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
 
       if (initial_highest_arg_in_use)
-       bcopy (initial_stack_usage_map, stack_usage_map,
-              initial_highest_arg_in_use);
+       memcpy (stack_usage_map, initial_stack_usage_map,
+               initial_highest_arg_in_use);
 
       if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
-       bzero (&stack_usage_map[initial_highest_arg_in_use],
+       memset (&stack_usage_map[initial_highest_arg_in_use], 0,
               highest_outgoing_arg_in_use - initial_highest_arg_in_use);
       needed = 0;