From 1ce0cb532454a5048493b09fa4e4646d8b7d1eba Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Mon, 25 Jan 1993 11:52:15 -0800 Subject: [PATCH] (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 --- gcc/calls.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/gcc/calls.c b/gcc/calls.c index 959805bd1d8..6597eece7e0 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -105,11 +105,18 @@ int stack_arg_under_construction; static void store_one_arg (); 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 -calls_alloca (exp) +calls_function (exp, which) tree exp; + int which; { register int i; int type = TREE_CODE_CLASS (TREE_CODE (exp)); @@ -124,12 +131,14 @@ calls_alloca (exp) switch (TREE_CODE (exp)) { case CALL_EXPR: - if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - == FUNCTION_DECL) - && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - && (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - == BUILT_IN_ALLOCA)) + if (which == 0) + return 1; + else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR + && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) + == FUNCTION_DECL) + && 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; /* Third operand is RTL. */ @@ -146,7 +155,8 @@ calls_alloca (exp) register tree 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; } { @@ -155,7 +165,7 @@ calls_alloca (exp) for (subblock = BLOCK_SUBBLOCKS (exp); subblock; subblock = TREE_CHAIN (subblock)) - if (calls_alloca (subblock)) + if (calls_function (subblock, which)) return 1; } return 0; @@ -174,7 +184,7 @@ calls_alloca (exp) for (i = 0; i < length; i++) if (TREE_OPERAND (exp, i) != 0 - && calls_alloca (TREE_OPERAND (exp, i))) + && calls_function (TREE_OPERAND (exp, i), which)) return 1; return 0; @@ -1151,10 +1161,18 @@ expand_call (exp, target, ignore) 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_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 = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); -- 2.30.2