2007-02-18 Sandra Loosemore <sandra@codesourcery.com>
authorsandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Feb 2007 19:34:28 +0000 (19:34 +0000)
committersandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Feb 2007 19:34:28 +0000 (19:34 +0000)
* calls.c (initialize_argument_information): Pass original EXP
and STRUCT_VALUE_ADDR_VALUE instead of a list of arguments.  Move
code to split complex arguments here, as part of initializing the
ARGS array.
(expand_call): Remove code that builds a list of arguments and
inserts implicit arguments into it.  Instead, just count how many
implicit arguments there will be so we can determine the size of
the ARGS array, and let initialize_argument_information do the work.
(split_complex_values): Delete unused function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122101 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c

index b01cccf..751d6c1 100644 (file)
@@ -1,3 +1,15 @@
+2007-02-18  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * calls.c (initialize_argument_information): Pass original EXP
+       and STRUCT_VALUE_ADDR_VALUE instead of a list of arguments.  Move
+       code to split complex arguments here, as part of initializing the
+       ARGS array.
+       (expand_call): Remove code that builds a list of arguments and
+       inserts implicit arguments into it.  Instead, just count how many
+       implicit arguments there will be so we can determine the size of
+       the ARGS array, and let initialize_argument_information do the work.
+       (split_complex_values): Delete unused function.
+
 2007-02-18  Eric Botcazou  <ebotcazou@adacore.com>
 
        * tree-eh.c (tree_could_trap_p): Handle VIEW_CONVERT_EXPR.
index e65a2cc..d9ba08c 100644 (file)
@@ -132,7 +132,8 @@ static int finalize_must_preallocate (int, int, struct arg_data *,
 static void precompute_arguments (int, int, struct arg_data *);
 static int compute_argument_block_size (int, struct args_size *, int);
 static void initialize_argument_information (int, struct arg_data *,
-                                            struct args_size *, int, tree,
+                                            struct args_size *, int,
+                                            tree, tree,
                                             tree, CUMULATIVE_ARGS *, int,
                                             rtx *, int *, int *, int *,
                                             bool *, bool);
@@ -148,7 +149,6 @@ static int check_sibcall_argument_overlap (rtx, struct arg_data *, int);
 
 static int combine_pending_stack_adjustment_and_call (int, struct args_size *,
                                                      unsigned int);
-static tree split_complex_values (tree);
 static tree split_complex_types (tree);
 
 #ifdef REG_PARM_STACK_SPACE
@@ -889,12 +889,15 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
 }
 
 /* Fill in ARGS_SIZE and ARGS array based on the parameters found in
-   ACTPARMS.
+   CALL_EXPR EXP.  
 
    NUM_ACTUALS is the total number of parameters.
 
    N_NAMED_ARGS is the total number of named arguments.
 
+   STRUCT_VALUE_ADDR_VALUE is the implicit argument for a struct return
+   value, or null.
+
    FNDECL is the tree code for the target of this call (if known)
 
    ARGS_SO_FAR holds state needed by the target to know where to place
@@ -920,7 +923,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
                                 struct arg_data *args,
                                 struct args_size *args_size,
                                 int n_named_args ATTRIBUTE_UNUSED,
-                                tree actparms, tree fndecl,
+                                tree exp, tree struct_value_addr_value,
+                                tree fndecl,
                                 CUMULATIVE_ARGS *args_so_far,
                                 int reg_parm_stack_space,
                                 rtx *old_stack_level, int *old_pending_adj,
@@ -934,7 +938,6 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
   int argpos;
 
   int i;
-  tree p;
 
   args_size->constant = 0;
   args_size->var = 0;
@@ -954,15 +957,45 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
       i = 0, inc = 1;
     }
 
+  /* First fill in the actual arguments in the ARGS array, splitting
+     complex arguments if necessary.  */
+  {
+    int j = i;
+    call_expr_arg_iterator iter;
+    tree arg;
+
+    if (struct_value_addr_value)
+      {
+       args[j].tree_value = struct_value_addr_value;
+       j += inc;
+      }
+    FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+      {
+       tree argtype = TREE_TYPE (arg);
+       if (targetm.calls.split_complex_arg
+           && argtype
+           && TREE_CODE (argtype) == COMPLEX_TYPE
+           && targetm.calls.split_complex_arg (argtype))
+         {
+           tree subtype = TREE_TYPE (argtype);
+           arg = save_expr (arg);
+           args[j].tree_value = build1 (REALPART_EXPR, subtype, arg);
+           j += inc;
+           args[j].tree_value = build1 (IMAGPART_EXPR, subtype, arg);
+         }
+       else
+         args[j].tree_value = arg;
+       j += inc;
+      }
+  }
+
   /* I counts args in order (to be) pushed; ARGPOS counts in order written.  */
-  for (p = actparms, argpos = 0; p; p = TREE_CHAIN (p), i += inc, argpos++)
+  for (argpos = 0; argpos < num_actuals; i += inc, argpos++)
     {
-      tree type = TREE_TYPE (TREE_VALUE (p));
+      tree type = TREE_TYPE (args[i].tree_value);
       int unsignedp;
       enum machine_mode mode;
 
-      args[i].tree_value = TREE_VALUE (p);
-
       /* Replace erroneous argument with constant zero.  */
       if (type == error_mark_node || !COMPLETE_TYPE_P (type))
        args[i].tree_value = integer_zero_node, type = integer_type_node;
@@ -1030,7 +1063,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
                {
                  /* This is a variable-sized object.  Make space on the stack
                     for it.  */
-                 rtx size_rtx = expr_size (TREE_VALUE (p));
+                 rtx size_rtx = expr_size (args[i].tree_value);
 
                  if (*old_stack_level == 0)
                    {
@@ -1825,9 +1858,6 @@ expand_call (tree exp, rtx target, int ignore)
   /* Nonzero if we are currently expanding a call.  */
   static int currently_expanding_call = 0;
 
-  /* List of actual parameters.  */
-  /* FIXME: rewrite this so that it doesn't cons up a TREE_LIST.  */
-  tree actparms = CALL_EXPR_ARGS (exp);
   /* RTX for the function to be called.  */
   rtx funexp;
   /* Sequence of insns to perform a normal "call".  */
@@ -1855,6 +1885,8 @@ expand_call (tree exp, rtx target, int ignore)
      an extra, implicit first parameter.  Otherwise,
      it is passed by being copied directly into struct_value_rtx.  */
   int structure_value_addr_parm = 0;
+  /* Holds the value of implicit argument for the struct value.  */
+  tree structure_value_addr_value = NULL_TREE;
   /* Size of aggregate value wanted, or zero if none wanted
      or if we are using the non-reentrant PCC calling convention
      or expecting the value in registers.  */
@@ -1869,6 +1901,8 @@ expand_call (tree exp, rtx target, int ignore)
   /* Number of named args.  Args after this are anonymous ones
      and they must all go on the stack.  */
   int n_named_args;
+  /* Number of complex actual arguments that need to be split.  */
+  int num_complex_actuals = 0;
 
   /* Vector of information about each argument.
      Arguments are numbered in the order they will be pushed,
@@ -1971,9 +2005,10 @@ expand_call (tree exp, rtx target, int ignore)
     {
       bool volatilep = false;
       tree arg;
+      call_expr_arg_iterator iter;
 
-      for (arg = actparms; arg; arg = TREE_CHAIN (arg))
-       if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
+      FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+       if (TREE_THIS_VOLATILE (arg))
          {
            volatilep = true;
            break;
@@ -1981,9 +2016,8 @@ expand_call (tree exp, rtx target, int ignore)
 
       if (! volatilep)
        {
-         for (arg = actparms; arg; arg = TREE_CHAIN (arg))
-           expand_expr (TREE_VALUE (arg), const0_rtx,
-                        VOIDmode, EXPAND_NORMAL);
+         FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+           expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
          return const0_rtx;
        }
     }
@@ -2044,12 +2078,21 @@ expand_call (tree exp, rtx target, int ignore)
   gcc_assert (POINTER_TYPE_P (funtype));
   funtype = TREE_TYPE (funtype);
 
-  /* Munge the tree to split complex arguments into their imaginary
-     and real parts.  */
+  /* Count whether there are actual complex arguments that need to be split
+     into their real and imaginary parts.  Munge the type_arg_types
+     appropriately here as well.  */
   if (targetm.calls.split_complex_arg)
     {
+      call_expr_arg_iterator iter;
+      tree arg;
+      FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+       {
+         tree type = TREE_TYPE (arg);
+         if (type && TREE_CODE (type) == COMPLEX_TYPE
+             && targetm.calls.split_complex_arg (type))
+           num_complex_actuals++;
+       }
       type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype));
-      actparms = split_complex_values (actparms);
     }
   else
     type_arg_types = TYPE_ARG_TYPES (funtype);
@@ -2058,7 +2101,8 @@ expand_call (tree exp, rtx target, int ignore)
     current_function_calls_alloca = 1;
 
   /* If struct_value_rtx is 0, it means pass the address
-     as if it were an extra parameter.  */
+     as if it were an extra parameter.  Put the argument expression
+     in structure_value_addr_value.  */
   if (structure_value_addr && struct_value == 0)
     {
       /* If structure_value_addr is a REG other than
@@ -2074,17 +2118,14 @@ expand_call (tree exp, rtx target, int ignore)
                                      (Pmode, structure_value_addr))
                  : structure_value_addr);
 
-      actparms
-       = tree_cons (error_mark_node,
-                    make_tree (build_pointer_type (TREE_TYPE (funtype)),
-                               temp),
-                    actparms);
+      structure_value_addr_value =
+       make_tree (build_pointer_type (TREE_TYPE (funtype)), temp);
       structure_value_addr_parm = 1;
     }
 
   /* Count the arguments and set NUM_ACTUALS.  */
-  for (p = actparms, num_actuals = 0; p; p = TREE_CHAIN (p))
-    num_actuals++;
+  num_actuals =
+    call_expr_nargs (exp) + num_complex_actuals + structure_value_addr_parm;
 
   /* Compute number of named args.
      First, do a raw count of the args for INIT_CUMULATIVE_ARGS.  */
@@ -2142,7 +2183,8 @@ expand_call (tree exp, rtx target, int ignore)
   /* Build up entries in the ARGS array, compute the size of the
      arguments into ARGS_SIZE, etc.  */
   initialize_argument_information (num_actuals, args, &args_size,
-                                  n_named_args, actparms, fndecl,
+                                  n_named_args, exp,
+                                  structure_value_addr_value, fndecl,
                                   &args_so_far, reg_parm_stack_space,
                                   &old_stack_level, &old_pending_adj,
                                   &must_preallocate, &flags,
@@ -3151,60 +3193,6 @@ fixup_tail_calls (void)
     }
 }
 
-/* Traverse an argument list in VALUES and expand all complex
-   arguments into their components.  */
-static tree
-split_complex_values (tree values)
-{
-  tree p;
-
-  /* Before allocating memory, check for the common case of no complex.  */
-  for (p = values; p; p = TREE_CHAIN (p))
-    {
-      tree type = TREE_TYPE (TREE_VALUE (p));
-      if (type && TREE_CODE (type) == COMPLEX_TYPE
-         && targetm.calls.split_complex_arg (type))
-       goto found;
-    }
-  return values;
-
- found:
-  values = copy_list (values);
-
-  for (p = values; p; p = TREE_CHAIN (p))
-    {
-      tree complex_value = TREE_VALUE (p);
-      tree complex_type;
-
-      complex_type = TREE_TYPE (complex_value);
-      if (!complex_type)
-       continue;
-
-      if (TREE_CODE (complex_type) == COMPLEX_TYPE
-         && targetm.calls.split_complex_arg (complex_type))
-       {
-         tree subtype;
-         tree real, imag, next;
-
-         subtype = TREE_TYPE (complex_type);
-         complex_value = save_expr (complex_value);
-         real = build1 (REALPART_EXPR, subtype, complex_value);
-         imag = build1 (IMAGPART_EXPR, subtype, complex_value);
-
-         TREE_VALUE (p) = real;
-         next = TREE_CHAIN (p);
-         imag = build_tree_list (NULL_TREE, imag);
-         TREE_CHAIN (p) = imag;
-         TREE_CHAIN (imag) = next;
-
-         /* Skip the newly created node.  */
-         p = TREE_CHAIN (p);
-       }
-    }
-
-  return values;
-}
-
 /* Traverse a list of TYPES and expand all complex types into their
    components.  */
 static tree