Commit 1ce0cb53 by Jim Wilson

(calls_alloca): Change name to calls_function.

(calls_alloca): Change name to calls_function.  Add new
parameter WHICH to control old or new behaviour.
(expand_call): When stack space is preallocated and parameters
must be passed on the stack, precompute parameters that involve
function calls.

From-SVN: r3330
parent 867b0d7a
...@@ -105,11 +105,18 @@ int stack_arg_under_construction; ...@@ -105,11 +105,18 @@ int stack_arg_under_construction;
static void store_one_arg (); static void store_one_arg ();
extern enum machine_mode mode_for_size (); extern enum machine_mode mode_for_size ();
/* Return 1 if EXP contains a call to the built-in function `alloca'. */ /* If WHICH is 1, return 1 if EXP contains a call to the built-in function
`alloca'.
If WHICH is 0, return 1 if EXP contains a call to any function.
Actually, we only need return 1 if evaluating EXP would require pushing
arguments on the stack, but that is too difficult to compute, so we just
assume any function call might require the stack. */
static int static int
calls_alloca (exp) calls_function (exp, which)
tree exp; tree exp;
int which;
{ {
register int i; register int i;
int type = TREE_CODE_CLASS (TREE_CODE (exp)); int type = TREE_CODE_CLASS (TREE_CODE (exp));
...@@ -124,12 +131,14 @@ calls_alloca (exp) ...@@ -124,12 +131,14 @@ calls_alloca (exp)
switch (TREE_CODE (exp)) switch (TREE_CODE (exp))
{ {
case CALL_EXPR: case CALL_EXPR:
if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR if (which == 0)
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) return 1;
== FUNCTION_DECL) else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
&& DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
&& (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == FUNCTION_DECL)
== BUILT_IN_ALLOCA)) && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
&& (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
== BUILT_IN_ALLOCA))
return 1; return 1;
/* Third operand is RTL. */ /* Third operand is RTL. */
...@@ -146,7 +155,8 @@ calls_alloca (exp) ...@@ -146,7 +155,8 @@ calls_alloca (exp)
register tree local; register tree local;
for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local)) for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local))
if (DECL_INITIAL (local) != 0 && calls_alloca (DECL_INITIAL (local))) if (DECL_INITIAL (local) != 0
&& calls_function (DECL_INITIAL (local), which))
return 1; return 1;
} }
{ {
...@@ -155,7 +165,7 @@ calls_alloca (exp) ...@@ -155,7 +165,7 @@ calls_alloca (exp)
for (subblock = BLOCK_SUBBLOCKS (exp); for (subblock = BLOCK_SUBBLOCKS (exp);
subblock; subblock;
subblock = TREE_CHAIN (subblock)) subblock = TREE_CHAIN (subblock))
if (calls_alloca (subblock)) if (calls_function (subblock, which))
return 1; return 1;
} }
return 0; return 0;
...@@ -174,7 +184,7 @@ calls_alloca (exp) ...@@ -174,7 +184,7 @@ calls_alloca (exp)
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
if (TREE_OPERAND (exp, i) != 0 if (TREE_OPERAND (exp, i) != 0
&& calls_alloca (TREE_OPERAND (exp, i))) && calls_function (TREE_OPERAND (exp, i), which))
return 1; return 1;
return 0; return 0;
...@@ -1151,10 +1161,18 @@ expand_call (exp, target, ignore) ...@@ -1151,10 +1161,18 @@ expand_call (exp, target, ignore)
If a parameter contains a call to alloca and this function uses the If a parameter contains a call to alloca and this function uses the
stack, precompute the parameter. */ 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++) for (i = 0; i < num_actuals; i++)
if (is_const if (is_const
|| ((args_size.var != 0 || args_size.constant != 0) || ((args_size.var != 0 || args_size.constant != 0)
&& calls_alloca (args[i].tree_value))) && calls_function (args[i].tree_value, 1))
|| (must_preallocate && (args_size.var != 0 || args_size.constant != 0)
&& calls_function (args[i].tree_value, 0)))
{ {
args[i].initial_value = args[i].value args[i].initial_value = args[i].value
= expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment