summaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-24 16:29:36 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-24 16:29:36 +0000
commit04707f1cc10529d5832fb60ddcf816fc3e269a08 (patch)
treef87ae99a30be3d490d78e0fe431e2bbdffdf283d /gcc/calls.c
parent47d8eb1d8cc0e782b93a44dd97151cda5e61645d (diff)
downloadgcc-04707f1cc10529d5832fb60ddcf816fc3e269a08.tar.gz
* calls.c (precompute_arguments): New function, extracted from
expand_call. (expand_call): Use precompute_arguments. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25409 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c123
1 files changed, 78 insertions, 45 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index f7e5eb24ebc..bfc71e7f775 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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. */