diff options
author | Michael Matz <matz@suse.de> | 2008-05-27 14:28:02 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2008-05-27 14:28:02 +0000 |
commit | bd42a56bb4d7a4a39b08eceee7eff87d3264a9c2 (patch) | |
tree | f9e2fb522e3165cb0dc981ccb4e13d343a341661 /gcc | |
parent | a46fc136fc682ea3d0429e6ac1084712fe18b612 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/tree-gimple.c | 9 | ||||
-rw-r--r-- | gcc/tree-tailcall.c | 14 |
3 files changed, 24 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0ccae4..33ef156 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-05-27 Michael Matz <matz@suse.de> + + 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. + 2008-05-27 Richard Guenther <rguenther@suse.de> PR tree-optimization/36339 diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index da84777..2334e12 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -113,13 +113,8 @@ bool is_gimple_mem_rhs (tree t) { /* If we're dealing with a renamable type, either source or dest must be - a renamed variable. Also force a temporary if the type doesn't need - to be stored in memory, since it's cheap and prevents erroneous - tailcalls (PR 17526). */ - if (is_gimple_reg_type (TREE_TYPE (t)) - || (TYPE_MODE (TREE_TYPE (t)) != BLKmode - && (TREE_CODE (t) != CALL_EXPR - || ! aggregate_value_p (t, t)))) + a renamed variable. */ + if (is_gimple_reg_type (TREE_TYPE (t))) return is_gimple_val (t); else return is_gimple_formal_tmp_rhs (t); 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); |