2012-04-27 Tom de Vries <tom@codesourcery.com>
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2012 06:12:49 +0000 (06:12 +0000)
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Apr 2012 06:12:49 +0000 (06:12 +0000)
PR tree-optimization/51879
* tree-ssa-sccvn.h (struct vn_reference_s): Add result_vdef field.
* tree-ssa-sccvn.c (mark_use_processed): New function, factored out
of ...
(defs_to_varying): ... here.  Don't set use_processed.
(visit_reference_op_call): Handle gimple_vdef.
Handle case that lhs is NULL_TREE.
(visit_use): Use mark_use_processed.  Handle calls with side-effect
using visit_reference_op_call.

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

gcc/ChangeLog
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-sccvn.h

index 493f74f..c486577 100644 (file)
@@ -1,3 +1,15 @@
+2012-04-27  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/51879
+       * tree-ssa-sccvn.h (struct vn_reference_s): Add result_vdef field.
+       * tree-ssa-sccvn.c (mark_use_processed): New function, factored out
+       of ...
+       (defs_to_varying): ... here.  Don't set use_processed.
+       (visit_reference_op_call): Handle gimple_vdef.
+       Handle case that lhs is NULL_TREE.
+       (visit_use): Use mark_use_processed.  Handle calls with side-effect
+       using visit_reference_op_call.
+
 2012-04-26  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * sched-deps.c (fixup_sched_groups): Rename to...
index ddb1ba6..e9e6bfa 100644 (file)
@@ -2525,6 +2525,30 @@ set_ssa_val_to (tree from, tree to)
   return false;
 }
 
+/* Mark as processed all the definitions in the defining stmt of USE, or
+   the USE itself.  */
+
+static void
+mark_use_processed (tree use)
+{
+  ssa_op_iter iter;
+  def_operand_p defp;
+  gimple stmt = SSA_NAME_DEF_STMT (use);
+
+  if (SSA_NAME_IS_DEFAULT_DEF (use) || gimple_code (stmt) == GIMPLE_PHI)
+    {
+      VN_INFO (use)->use_processed = true;
+      return;
+    }
+
+  FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
+    {
+      tree def = DEF_FROM_PTR (defp);
+
+      VN_INFO (def)->use_processed = true;
+    }
+}
+
 /* Set all definitions in STMT to value number to themselves.
    Return true if a value number changed. */
 
@@ -2538,8 +2562,6 @@ defs_to_varying (gimple stmt)
   FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
     {
       tree def = DEF_FROM_PTR (defp);
-
-      VN_INFO (def)->use_processed = true;
       changed |= set_ssa_val_to (def, def);
     }
   return changed;
@@ -2598,27 +2620,41 @@ visit_reference_op_call (tree lhs, gimple stmt)
 {
   bool changed = false;
   struct vn_reference_s vr1;
-  tree result;
+  vn_reference_t vnresult = NULL;
   tree vuse = gimple_vuse (stmt);
+  tree vdef = gimple_vdef (stmt);
 
   vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
   vr1.operands = valueize_shared_reference_ops_from_call (stmt);
   vr1.type = gimple_expr_type (stmt);
   vr1.set = 0;
   vr1.hashcode = vn_reference_compute_hash (&vr1);
-  result = vn_reference_lookup_1 (&vr1, NULL);
-  if (result)
+  vn_reference_lookup_1 (&vr1, &vnresult);
+
+  if (vnresult)
     {
-      changed = set_ssa_val_to (lhs, result);
-      if (TREE_CODE (result) == SSA_NAME
-         && VN_INFO (result)->has_constants)
-       VN_INFO (lhs)->has_constants = true;
+      if (vnresult->result_vdef)
+       changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
+
+      if (!vnresult->result && lhs)
+       vnresult->result = lhs;
+
+      if (vnresult->result && lhs)
+       {
+         changed |= set_ssa_val_to (lhs, vnresult->result);
+
+         if (VN_INFO (vnresult->result)->has_constants)
+           VN_INFO (lhs)->has_constants = true;
+       }
     }
   else
     {
       void **slot;
       vn_reference_t vr2;
-      changed = set_ssa_val_to (lhs, lhs);
+      if (vdef)
+       changed |= set_ssa_val_to (vdef, vdef);
+      if (lhs)
+       changed |= set_ssa_val_to (lhs, lhs);
       vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
       vr2->vuse = vr1.vuse;
       vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
@@ -2626,6 +2662,7 @@ visit_reference_op_call (tree lhs, gimple stmt)
       vr2->set = vr1.set;
       vr2->hashcode = vr1.hashcode;
       vr2->result = lhs;
+      vr2->result_vdef = vdef;
       slot = htab_find_slot_with_hash (current_info->references,
                                       vr2, vr2->hashcode, INSERT);
       if (*slot)
@@ -2795,7 +2832,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
         going to valueize the references in-place.  */
       if ((vdef = gimple_vdef (stmt)))
        {
-         VN_INFO (vdef)->use_processed = true;
          changed |= set_ssa_val_to (vdef, vdef);
        }
 
@@ -2817,7 +2853,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
       def = gimple_vdef (stmt);
       use = gimple_vuse (stmt);
 
-      VN_INFO (def)->use_processed = true;
       changed |= set_ssa_val_to (def, SSA_VAL (use));
     }
 
@@ -3167,7 +3202,7 @@ visit_use (tree use)
   bool changed = false;
   gimple stmt = SSA_NAME_DEF_STMT (use);
 
-  VN_INFO (use)->use_processed = true;
+  mark_use_processed (use);
 
   gcc_assert (!SSA_NAME_IN_FREE_LIST (use));
   if (dump_file && (dump_flags & TDF_DETAILS)
@@ -3186,8 +3221,7 @@ visit_use (tree use)
     {
       if (gimple_code (stmt) == GIMPLE_PHI)
        changed = visit_phi (stmt);
-      else if (!gimple_has_lhs (stmt)
-              || gimple_has_volatile_ops (stmt))
+      else if (gimple_has_volatile_ops (stmt))
        changed = defs_to_varying (stmt);
       else if (is_gimple_assign (stmt))
        {
@@ -3349,34 +3383,44 @@ visit_use (tree use)
 
          /* ???  We could try to simplify calls.  */
 
-         if (stmt_has_constants (stmt)
-             && TREE_CODE (lhs) == SSA_NAME)
-           VN_INFO (lhs)->has_constants = true;
-         else if (TREE_CODE (lhs) == SSA_NAME)
+         if (lhs && TREE_CODE (lhs) == SSA_NAME)
            {
-             /* We reset expr and constantness here because we may
-                have been value numbering optimistically, and
-                iterating. They may become non-constant in this case,
-                even if they were optimistically constant. */
-             VN_INFO (lhs)->has_constants = false;
-             VN_INFO (lhs)->expr = NULL_TREE;
+             if (stmt_has_constants (stmt))
+               VN_INFO (lhs)->has_constants = true;
+             else
+               {
+                 /* We reset expr and constantness here because we may
+                    have been value numbering optimistically, and
+                    iterating.  They may become non-constant in this case,
+                    even if they were optimistically constant.  */
+                 VN_INFO (lhs)->has_constants = false;
+                 VN_INFO (lhs)->expr = NULL_TREE;
+               }
+
+             if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+               {
+                 changed = defs_to_varying (stmt);
+                 goto done;
+               }
            }
 
-         if (TREE_CODE (lhs) == SSA_NAME
-             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
-           changed = defs_to_varying (stmt);
          /* ???  We should handle stores from calls.  */
-         else if (TREE_CODE (lhs) == SSA_NAME)
+         if (!gimple_call_internal_p (stmt)
+             && (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST)
+                 /* If the call has side effects, subsequent calls won't have
+                    the same incoming vuse, so it's save to assume
+                    equality.  */
+                 || gimple_has_side_effects (stmt))
+             && ((lhs && TREE_CODE (lhs) == SSA_NAME)
+                 || (!lhs && gimple_vdef (stmt))))
            {
-             if (!gimple_call_internal_p (stmt)
-                 && gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
-               changed = visit_reference_op_call (lhs, stmt);
-             else
-               changed = defs_to_varying (stmt);
+             changed = visit_reference_op_call (lhs, stmt);
            }
          else
            changed = defs_to_varying (stmt);
        }
+      else
+       changed = defs_to_varying (stmt);
     }
  done:
   return changed;
index b37b084..a4f294f 100644 (file)
@@ -110,6 +110,7 @@ typedef struct vn_reference_s
   tree type;
   VEC (vn_reference_op_s, heap) *operands;
   tree result;
+  tree result_vdef;
 } *vn_reference_t;
 typedef const struct vn_reference_s *const_vn_reference_t;