aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2007-02-18 14:34:28 -0500
committerSandra Loosemore <sandra@gcc.gnu.org>2007-02-18 14:34:28 -0500
commit078a18a42304f0caa644fb42c37b55fc59673d00 (patch)
treed07869954dddb79d52f33e840dcc635ca7969c17 /gcc/calls.c
parent483edb920122339238840ddf34e6931ca92fd76a (diff)
downloadgcc-078a18a42304f0caa644fb42c37b55fc59673d00.zip
gcc-078a18a42304f0caa644fb42c37b55fc59673d00.tar.gz
gcc-078a18a42304f0caa644fb42c37b55fc59673d00.tar.bz2
calls.c (initialize_argument_information): Pass original EXP and STRUCT_VALUE_ADDR_VALUE instead of a list of arguments.
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. From-SVN: r122101
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c156
1 files changed, 72 insertions, 84 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index e65a2cc..d9ba08c 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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