aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/calls.c
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2007-08-14 02:45:23 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2007-08-14 02:45:23 +0000
commit23baddbde1e3e9e59547d9f4e0429ef69906b216 (patch)
tree7b2fa7d3de8706d9ca72fdb284ce2a57f67d460a /contrib/gcc/calls.c
parent888346df5fa8bb2a862c2298910fe7ae332efbcb (diff)
downloadsrc-23baddbde1e3e9e59547d9f4e0429ef69906b216.tar.gz
src-23baddbde1e3e9e59547d9f4e0429ef69906b216.zip
GCC 4.2.1 release.
Notes
Notes: svn path=/vendor/gcc/dist/; revision=171825
Diffstat (limited to 'contrib/gcc/calls.c')
-rw-r--r--contrib/gcc/calls.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/contrib/gcc/calls.c b/contrib/gcc/calls.c
index 063e6847e98b..d1fcdadda33e 100644
--- a/contrib/gcc/calls.c
+++ b/contrib/gcc/calls.c
@@ -1238,13 +1238,25 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args)
/* If this is a libcall, then precompute all arguments so that we do not
get extraneous instructions emitted as part of the libcall sequence. */
- if ((flags & ECF_LIBCALL_BLOCK) == 0)
+
+ /* 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. (we have code to avoid
+ such case by saving the outgoing stack arguments, but it results in
+ worse code) */
+ if ((flags & ECF_LIBCALL_BLOCK) == 0 && !ACCUMULATE_OUTGOING_ARGS)
return;
for (i = 0; i < num_actuals; i++)
{
enum machine_mode mode;
+ if ((flags & ECF_LIBCALL_BLOCK) == 0
+ && TREE_CODE (args[i].tree_value) != CALL_EXPR)
+ continue;
+
/* If this is an addressable type, we cannot pre-evaluate it. */
gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)));