aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2008-05-27 14:28:02 +0000
committerMichael Matz <matz@gcc.gnu.org>2008-05-27 14:28:02 +0000
commitbd42a56bb4d7a4a39b08eceee7eff87d3264a9c2 (patch)
treef9e2fb522e3165cb0dc981ccb4e13d343a341661 /gcc/tree-tailcall.c
parenta46fc136fc682ea3d0429e6ac1084712fe18b612 (diff)
downloadgcc-bd42a56bb4d7a4a39b08eceee7eff87d3264a9c2.zip
gcc-bd42a56bb4d7a4a39b08eceee7eff87d3264a9c2.tar.gz
gcc-bd42a56bb4d7a4a39b08eceee7eff87d3264a9c2.tar.bz2
re PR middle-end/36326 (gimplification of aggregate copies introduces extra aggregate copy)
PR middle-end/36326 * tree-gimple.c (is_gimple_mem_rhs): Remove work-around for non-BLKmode types. * tree-tailcall.c (find_tail_calls): Don't mark calls storing into memory as tail calls. From-SVN: r136033
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 7481de5..09a2eaf 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -429,6 +429,20 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
return;
}
+ /* If the LHS of our call is not just a simple register, we can't
+ transform this into a tail or sibling call. This situation happens,
+ in (e.g.) "*p = foo()" where foo returns a struct. In this case
+ we won't have a temporary here, but we need to carry out the side
+ effect anyway, so tailcall is impossible.
+
+ ??? In some situations (when the struct is returned in memory via
+ invisible argument) we could deal with this, e.g. by passing 'p'
+ itself as that argument to foo, but it's too early to do this here,
+ and expand_call() will not handle it anyway. If it ever can, then
+ we need to revisit this here, to allow that situation. */
+ if (ass_var && !is_gimple_reg (ass_var))
+ return;
+
/* We found the call, check whether it is suitable. */
tail_recursion = false;
func = get_callee_fndecl (call);