calls.c (precompute_arguments): New function, extracted from expand_call.
authorJeffrey A Law <law@cygnus.com>
Wed, 24 Feb 1999 16:29:36 +0000 (16:29 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 24 Feb 1999 16:29:36 +0000 (09:29 -0700)
        * calls.c (precompute_arguments): New function, extracted from
        expand_call.
        (expand_call): Use precompute_arguments.

From-SVN: r25409

gcc/ChangeLog
gcc/calls.c

index d380435a3f86cd0a65b9a0f56a8401a9972c88a8..3f6f0857b871f274a2a2ac4c2172e191ed07a153 100644 (file)
@@ -1,5 +1,9 @@
 Wed Feb 24 14:03:54 1999  Jeffrey A Law  (law@cygnus.com)
 
+       * calls.c (precompute_arguments): New function, extracted from
+       expand_call.
+       (expand_call): Use precompute_arguments.
+
        * calls.c (finalize_must_preallocate): New function, extracted from
        expand_call.
        (expand_call): Use finalize_must_preallocate.
index f7e5eb24ebceb21ac0fd8a227a170d5fb487b7e7..bfc71e7f775936ca73812a9227bcff4b876d6dd9 100644 (file)
@@ -140,6 +140,9 @@ static void store_unaligned_arguments_into_pseudos PROTO ((struct arg_data *,
 static int finalize_must_preallocate           PROTO ((int, int,
                                                        struct arg_data *,
                                                        struct args_size *));
+static void precompute_arguments               PROTO ((int, int, int,
+                                                       struct arg_data *,
+                                                       struct args_size *));
 
 
 #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
@@ -826,6 +829,78 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
       }
 }
 
+/* Precompute parameters has needed for a function call.
+
+   IS_CONST indicates the target function is a pure function.
+
+   MUST_PREALLOCATE indicates that we must preallocate stack space for
+   any stack arguments.
+
+   NUM_ACTUALS is the number of arguments.
+
+   ARGS is an array containing information for each argument; this routine
+   fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.
+
+   ARGS_SIZE contains information about the size of the arg list.  */
+
+static void
+precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
+     int is_const;
+     int must_preallocate;
+     int num_actuals;
+     struct arg_data *args;
+     struct args_size *args_size;
+{
+  int i;
+
+  /* If this function call is cse'able, precompute all the parameters.
+     Note that if the parameter is constructed into a temporary, this will
+     cause an additional copy because the parameter will be constructed
+     into a temporary location and then copied into the outgoing arguments.
+     If a parameter contains a call to alloca and this function uses the
+     stack, precompute the parameter.  */
+
+  /* If we preallocated the stack space, and some arguments must be passed
+     on the stack, then we must precompute any parameter which contains a
+     function call which will store arguments on the stack.
+     Otherwise, evaluating the parameter may clobber previous parameters
+     which have already been stored into the stack.  */
+
+  for (i = 0; i < num_actuals; i++)
+    if (is_const
+       || ((args_size->var != 0 || args_size->constant != 0)
+           && calls_function (args[i].tree_value, 1))
+       || (must_preallocate
+           && (args_size->var != 0 || args_size->constant != 0)
+           && calls_function (args[i].tree_value, 0)))
+      {
+       /* If this is an addressable type, we cannot pre-evaluate it.  */
+       if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
+         abort ();
+
+       push_temp_slots ();
+
+       args[i].initial_value = args[i].value
+         = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
+
+       preserve_temp_slots (args[i].value);
+       pop_temp_slots ();
+
+       /* ANSI doesn't require a sequence point here,
+          but PCC has one, so this will avoid some problems.  */
+       emit_queue ();
+
+       args[i].initial_value = args[i].value
+         = protect_from_queue (args[i].initial_value, 0);
+
+       if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode)
+         args[i].value
+           = convert_modes (args[i].mode, 
+                            TYPE_MODE (TREE_TYPE (args[i].tree_value)),
+                            args[i].value, args[i].unsignedp);
+      }
+}
+
 /* Given the current state of MUST_PREALLOCATE and information about
    arguments to a function call in NUM_ACTUALS, ARGS and ARGS_SIZE,
    compute and return the final value for MUST_PREALLOCATE.  */
@@ -1649,51 +1724,9 @@ expand_call (exp, target, ignore)
          ))
     structure_value_addr = copy_to_reg (structure_value_addr);
 
-  /* If this function call is cse'able, precompute all the parameters.
-     Note that if the parameter is constructed into a temporary, this will
-     cause an additional copy because the parameter will be constructed
-     into a temporary location and then copied into the outgoing arguments.
-     If a parameter contains a call to alloca and this function uses the
-     stack, precompute the parameter.  */
-
-  /* If we preallocated the stack space, and some arguments must be passed
-     on the stack, then we must precompute any parameter which contains a
-     function call which will store arguments on the stack.
-     Otherwise, evaluating the parameter may clobber previous parameters
-     which have already been stored into the stack.  */
-
-  for (i = 0; i < num_actuals; i++)
-    if (is_const
-       || ((args_size.var != 0 || args_size.constant != 0)
-           && calls_function (args[i].tree_value, 1))
-       || (must_preallocate && (args_size.var != 0 || args_size.constant != 0)
-           && calls_function (args[i].tree_value, 0)))
-      {
-       /* If this is an addressable type, we cannot pre-evaluate it.  */
-       if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
-         abort ();
-
-       push_temp_slots ();
-
-       args[i].initial_value = args[i].value
-         = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
-
-       preserve_temp_slots (args[i].value);
-       pop_temp_slots ();
-
-       /* ANSI doesn't require a sequence point here,
-          but PCC has one, so this will avoid some problems.  */
-       emit_queue ();
-
-       args[i].initial_value = args[i].value
-         = protect_from_queue (args[i].initial_value, 0);
-
-       if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode)
-         args[i].value
-           = convert_modes (args[i].mode, 
-                            TYPE_MODE (TREE_TYPE (args[i].tree_value)),
-                            args[i].value, args[i].unsignedp);
-      }
+  /* Precompute any arguments as needed.  */
+  precompute_arguments (is_const, must_preallocate, num_actuals,
+                        args, &args_size);
 
   /* Now we are about to start emitting insns that can be deleted
      if a libcall is deleted.  */