OSDN Git Service

2007-05-02 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 May 2007 09:12:49 +0000 (09:12 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 May 2007 09:12:49 +0000 (09:12 +0000)
PR tree-optimization/31146
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): New
argument, single_use_p.  If we have a single use that is
a conversion to the definition rhs type, propagate that rhs.
(forward_propagate_addr_expr): Pass single_use_p argument
to forward_propagate_addr_expr_1.

* g++.dg/tree-ssa/pr31146-2.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124349 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 3882b8b..d45664e 100644 (file)
@@ -1,3 +1,12 @@
+2007-05-02  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/31146
+       * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): New
+       argument, single_use_p.  If we have a single use that is
+       a conversion to the definition rhs type, propagate that rhs.
+       (forward_propagate_addr_expr): Pass single_use_p argument
+       to forward_propagate_addr_expr_1.
+
 2007-05-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.c (ix86_expand_sse_comi): Remove unused
index ed9816f..287a097 100644 (file)
@@ -1,3 +1,8 @@
+2007-05-02  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/31146
+       * g++.dg/tree-ssa/pr31146-2.C: New testcase.
+
 2007-05-01  Geoffrey Keating  <geoffk@apple.com>
 
        * gcc.c-torture/compile/limits-blockid.c: New.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
new file mode 100644 (file)
index 0000000..0fd6027
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+#include <new>
+
+template <class T>
+struct Vec
+{
+  Vec()
+  {
+    for (int i=0; i<3; ++i)
+      new (&a[i]) T(0);
+  }
+  T a[3];
+};
+
+double foo (void)
+{
+  Vec<double> v;
+  return v.a[2];
+}
+
+/* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
index 860a4c4..d91aa89 100644 (file)
@@ -559,7 +559,8 @@ forward_propagate_addr_into_variable_array_index (tree offset, tree lhs,
    be not totally successful, yet things may have been changed).  */
 
 static bool
-forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt)
+forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
+                              bool single_use_p)
 {
   tree lhs, rhs, array_ref;
 
@@ -584,10 +585,20 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt)
       /* Continue propagating into the RHS.  */
     }
 
-  /* Trivial case.  The use statement could be a trivial copy or a
+  /* Trivial cases.  The use statement could be a trivial copy or a
      useless conversion.  Recurse to the uses of the lhs as copyprop does
      not copy through differen variant pointers and FRE does not catch
-     all useless conversions.  */
+     all useless conversions.  Treat the case of a single-use name and
+     a conversion to def_rhs type separate, though.  */
+  else if (TREE_CODE (lhs) == SSA_NAME
+          && (TREE_CODE (rhs) == NOP_EXPR
+              || TREE_CODE (rhs) == CONVERT_EXPR)
+          && TREE_TYPE (rhs) == TREE_TYPE (def_rhs)
+          && single_use_p)
+    {
+      GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
+      return true;
+    }
   else if ((TREE_CODE (lhs) == SSA_NAME
            && rhs == name)
           || ((TREE_CODE (rhs) == NOP_EXPR
@@ -702,6 +713,7 @@ forward_propagate_addr_expr (tree name, tree rhs)
   imm_use_iterator iter;
   tree use_stmt;
   bool all = true;
+  bool single_use_p = has_single_use (name);
 
   FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
     {
@@ -726,7 +738,8 @@ forward_propagate_addr_expr (tree name, tree rhs)
       
       push_stmt_changes (&use_stmt);
 
-      result = forward_propagate_addr_expr_1 (name, rhs, use_stmt);
+      result = forward_propagate_addr_expr_1 (name, rhs, use_stmt,
+                                             single_use_p);
       all &= result;
 
       pop_stmt_changes (&use_stmt);