This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] PATCH: get rid of temporary arglist in calls.c
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 11 Aug 2006 13:30:41 -0400
- Subject: [lto] PATCH: get rid of temporary arglist in calls.c
This patch reorganizes bits of expand_call and initialize_argument_information
to avoid constructing a temporary list to hold the arguments. Instead, the
argument values are inserted directly into the ARGS array.
Already committed as "obvious".
-Sandra
2006-08-11 Sandra Loosemore <sandra@codesourcery.com>
* gcc/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. Simply
count how many implicit arguments need to be inserted to compute
the size of the ARGS array.
(split_complex_values): Delete unused function.
Index: gcc/calls.c
===================================================================
*** gcc/calls.c (revision 116083)
--- gcc/calls.c (working copy)
*************** static int finalize_must_preallocate (in
*** 132,138 ****
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,
tree, CUMULATIVE_ARGS *, int,
rtx *, int *, int *, int *,
bool *, bool);
--- 132,139 ----
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, tree,
tree, CUMULATIVE_ARGS *, int,
rtx *, int *, int *, int *,
bool *, bool);
*************** static int check_sibcall_argument_overla
*** 148,154 ****
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
--- 149,154 ----
*************** store_unaligned_arguments_into_pseudos (
*** 889,900 ****
}
/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
! ACTPARMS.
NUM_ACTUALS is the total number of parameters.
N_NAMED_ARGS is the total number of named arguments.
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
--- 889,903 ----
}
/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
! 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
*************** initialize_argument_information (int num
*** 920,926 ****
struct arg_data *args,
struct args_size *args_size,
int n_named_args ATTRIBUTE_UNUSED,
! tree actparms, tree fndecl,
CUMULATIVE_ARGS *args_so_far,
int reg_parm_stack_space,
rtx *old_stack_level, int *old_pending_adj,
--- 923,930 ----
struct arg_data *args,
struct args_size *args_size,
int n_named_args ATTRIBUTE_UNUSED,
! 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,
*************** initialize_argument_information (int num
*** 934,940 ****
int argpos;
int i;
- tree p;
args_size->constant = 0;
args_size->var = 0;
--- 938,943 ----
*************** initialize_argument_information (int num
*** 954,968 ****
i = 0, inc = 1;
}
/* 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++)
{
! tree type = TREE_TYPE (TREE_VALUE (p));
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;
--- 957,1001 ----
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 (argpos = 0; argpos < num_actuals; i += inc, argpos++)
{
! tree type = TREE_TYPE (args[i].tree_value);
int unsignedp;
enum machine_mode mode;
/* 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;
*************** initialize_argument_information (int num
*** 1030,1036 ****
{
/* This is a variable-sized object. Make space on the stack
for it. */
! rtx size_rtx = expr_size (TREE_VALUE (p));
if (*old_stack_level == 0)
{
--- 1063,1069 ----
{
/* This is a variable-sized object. Make space on the stack
for it. */
! rtx size_rtx = expr_size (args[i].tree_value);
if (*old_stack_level == 0)
{
*************** expand_call (tree exp, rtx target, int i
*** 1790,1798 ****
/* 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". */
--- 1823,1828 ----
*************** expand_call (tree exp, rtx target, int i
*** 1820,1825 ****
--- 1850,1857 ----
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. */
*************** expand_call (tree exp, rtx target, int i
*** 1834,1839 ****
--- 1866,1873 ----
/* 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,
*************** expand_call (tree exp, rtx target, int i
*** 1936,1944 ****
{
bool volatilep = false;
tree arg;
! for (arg = actparms; arg; arg = TREE_CHAIN (arg))
! if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
{
volatilep = true;
break;
--- 1970,1979 ----
{
bool volatilep = false;
tree arg;
+ call_expr_arg_iterator iter;
! FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
! if (TREE_THIS_VOLATILE (arg))
{
volatilep = true;
break;
*************** expand_call (tree exp, rtx target, int i
*** 1946,1954 ****
if (! volatilep)
{
! for (arg = actparms; arg; arg = TREE_CHAIN (arg))
! expand_expr (TREE_VALUE (arg), const0_rtx,
! VOIDmode, EXPAND_NORMAL);
return const0_rtx;
}
}
--- 1981,1988 ----
if (! volatilep)
{
! FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
! expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
return const0_rtx;
}
}
*************** expand_call (tree exp, rtx target, int i
*** 2009,2020 ****
gcc_assert (POINTER_TYPE_P (funtype));
funtype = TREE_TYPE (funtype);
! /* Munge the tree to split complex arguments into their imaginary
! and real parts. */
if (targetm.calls.split_complex_arg)
{
type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype));
- actparms = split_complex_values (actparms);
}
else
type_arg_types = TYPE_ARG_TYPES (funtype);
--- 2043,2063 ----
gcc_assert (POINTER_TYPE_P (funtype));
funtype = TREE_TYPE (funtype);
! /* 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));
}
else
type_arg_types = TYPE_ARG_TYPES (funtype);
*************** expand_call (tree exp, rtx target, int i
*** 2023,2029 ****
current_function_calls_alloca = 1;
/* If struct_value_rtx is 0, it means pass the address
! as if it were an extra parameter. */
if (structure_value_addr && struct_value == 0)
{
/* If structure_value_addr is a REG other than
--- 2066,2073 ----
current_function_calls_alloca = 1;
/* If struct_value_rtx is 0, it means pass the address
! 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
*************** expand_call (tree exp, rtx target, int i
*** 2039,2055 ****
(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_parm = 1;
}
/* Count the arguments and set NUM_ACTUALS. */
! for (p = actparms, num_actuals = 0; p; p = TREE_CHAIN (p))
! num_actuals++;
/* Compute number of named args.
First, do a raw count of the args for INIT_CUMULATIVE_ARGS. */
--- 2083,2096 ----
(Pmode, structure_value_addr))
: structure_value_addr);
! 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. */
! 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. */
*************** expand_call (tree exp, rtx target, int i
*** 2107,2113 ****
/* 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,
&args_so_far, reg_parm_stack_space,
&old_stack_level, &old_pending_adj,
&must_preallocate, &flags,
--- 2148,2155 ----
/* 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, exp,
! structure_value_addr_value, fndecl,
&args_so_far, reg_parm_stack_space,
&old_stack_level, &old_pending_adj,
&must_preallocate, &flags,
*************** fixup_tail_calls (void)
*** 3109,3168 ****
}
}
- /* 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
--- 3151,3156 ----