re PR middle-end/36326 (gimplification of aggregate copies introduces extra aggregate...
authorMichael Matz <matz@suse.de>
Tue, 27 May 2008 14:28:02 +0000 (14:28 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Tue, 27 May 2008 14:28:02 +0000 (14:28 +0000)
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

gcc/ChangeLog
gcc/tree-gimple.c
gcc/tree-tailcall.c

index b0ccae4f652e0331b301d1369e31942713b38a84..33ef156a46affe01255313ca4a42766a9dacdff6 100644 (file)
@@ -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
index da84777725ad301984a547d6e9415ce1e1773334..2334e12634340ecb234825634dbb18afd6354466 100644 (file)
@@ -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);
index 7481de593252ee3d4e0e984ccdb0f37d5a464f0a..09a2eafe11939ac59b2fcb4d6d71db00b24bc811 100644 (file)
@@ -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);