diff options
| -rw-r--r-- | gcc/ChangeLog | 12 | ||||
| -rw-r--r-- | gcc/calls.c | 156 |
2 files changed, 84 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b01cccf..751d6c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. 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 |
