re PR tree-optimization/52009 (Another missed tail merging opportunity)
authorTom de Vries <tom@codesourcery.com>
Fri, 6 Jul 2012 11:07:32 +0000 (11:07 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Fri, 6 Jul 2012 11:07:32 +0000 (11:07 +0000)
2012-07-06  Tom de Vries  <tom@codesourcery.com>

PR tree-optimization/52009
* tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare
value numbers of gimple_vdef.
* tree-ssa-sccvn.h (vn_reference_insert): Add vdef parameter to
prototype.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MODIFY_EXPR.
(vn_reference_insert): Add and handle vdef parameter.
(visit_reference_op_load): Add argument to vn_reference_insert call.
(visit_reference_op_store): Find value number of vdef of store.  Insert
value number of vdef of store.

From-SVN: r189321

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

index 15053da446bfb1352c524d336a80b22d4120cf13..12339ad08739f65e321416b5716888674efbdafb 100644 (file)
@@ -1,3 +1,16 @@
+2012-07-06  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/52009
+       * tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare
+       value numbers of gimple_vdef.
+       * tree-ssa-sccvn.h (vn_reference_insert): Add vdef parameter to
+       prototype.
+       * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MODIFY_EXPR.
+       (vn_reference_insert): Add and handle vdef parameter.
+       (visit_reference_op_load): Add argument to vn_reference_insert call.
+       (visit_reference_op_store): Find value number of vdef of store.  Insert
+       value number of vdef of store.
+
 2012-07-06  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (simple lea to add peephole): Also transform
index ae912d732a8a50c55220cd933e130c4addd6611d..cd1acde49dfc231db331a5a3ab06fa1095c40e23 100644 (file)
@@ -628,6 +628,9 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
 
       switch (temp.opcode)
        {
+       case MODIFY_EXPR:
+         temp.op0 = TREE_OPERAND (ref, 1);
+         break;
        case WITH_SIZE_EXPR:
          temp.op0 = TREE_OPERAND (ref, 1);
          temp.off = 0;
@@ -748,6 +751,7 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
       VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
 
       if (REFERENCE_CLASS_P (ref)
+         || TREE_CODE (ref) == MODIFY_EXPR
          || TREE_CODE (ref) == WITH_SIZE_EXPR
          || (TREE_CODE (ref) == ADDR_EXPR
              && !is_gimple_min_invariant (ref)))
@@ -1941,7 +1945,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
    RESULT, and return the resulting reference structure we created.  */
 
 vn_reference_t
-vn_reference_insert (tree op, tree result, tree vuse)
+vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
 {
   void **slot;
   vn_reference_t vr1;
@@ -1957,6 +1961,7 @@ vn_reference_insert (tree op, tree result, tree vuse)
   vr1->set = get_alias_set (op);
   vr1->hashcode = vn_reference_compute_hash (vr1);
   vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
+  vr1->result_vdef = vdef;
 
   slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
                                   INSERT);
@@ -2775,7 +2780,7 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt)
   else
     {
       changed = set_ssa_val_to (lhs, lhs);
-      vn_reference_insert (op, lhs, last_vuse);
+      vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
     }
 
   return changed;
@@ -2789,8 +2794,11 @@ static bool
 visit_reference_op_store (tree lhs, tree op, gimple stmt)
 {
   bool changed = false;
-  tree result;
+  vn_reference_t vnresult = NULL;
+  tree result, assign;
   bool resultsame = false;
+  tree vuse = gimple_vuse (stmt);
+  tree vdef = gimple_vdef (stmt);
 
   /* First we want to lookup using the *vuses* from the store and see
      if there the last store to this location with the same address
@@ -2808,7 +2816,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
      Otherwise, the vdefs for the store are used when inserting into
      the table, since the store generates a new memory state.  */
 
-  result = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_NOWALK, NULL);
+  result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL);
 
   if (result)
     {
@@ -2821,8 +2829,17 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
 
   if (!result || !resultsame)
     {
-      tree vdef;
+      assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
+      vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult);
+      if (vnresult)
+       {
+         VN_INFO (vdef)->use_processed = true;
+         return set_ssa_val_to (vdef, vnresult->result_vdef);
+       }
+    }
 
+  if (!result || !resultsame)
+    {
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "No store match\n");
@@ -2834,7 +2851,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
        }
       /* Have to set value numbers before insert, since insert is
         going to valueize the references in-place.  */
-      if ((vdef = gimple_vdef (stmt)))
+      if (vdef)
        {
          changed |= set_ssa_val_to (vdef, vdef);
        }
@@ -2842,22 +2859,21 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
       /* Do not insert structure copies into the tables.  */
       if (is_gimple_min_invariant (op)
          || is_gimple_reg (op))
-        vn_reference_insert (lhs, op, vdef);
+        vn_reference_insert (lhs, op, vdef, NULL);
+
+      assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
+      vn_reference_insert (assign, lhs, vuse, vdef);
     }
   else
     {
       /* We had a match, so value number the vdef to have the value
         number of the vuse it came from.  */
-      tree def, use;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Store matched earlier value,"
                 "value numbering store vdefs to matching vuses.\n");
 
-      def = gimple_vdef (stmt);
-      use = gimple_vuse (stmt);
-
-      changed |= set_ssa_val_to (def, SSA_VAL (use));
+      changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
     }
 
   return changed;
index a4f294f0788cd44f11473a423949268d0b069d9c..6109463ffa9d062d189e7c219cdf6b63f87b9c3a 100644 (file)
@@ -200,7 +200,7 @@ tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
                                 VEC (vn_reference_op_s, heap) *,
                                 vn_reference_t *, vn_lookup_kind);
 tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *);
-vn_reference_t vn_reference_insert (tree, tree, tree);
+vn_reference_t vn_reference_insert (tree, tree, tree, tree);
 vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
                                           VEC (vn_reference_op_s, heap) *,
                                           tree, unsigned int);
index da5878ad797acf0249af7b634cb683c3fbce2d15..9ec3b8a5091b1a6a67deef5157ee84be4d0bc4a5 100644 (file)
@@ -1119,6 +1119,14 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
     case GIMPLE_ASSIGN:
       lhs1 = gimple_get_lhs (s1);
       lhs2 = gimple_get_lhs (s2);
+      if (gimple_vdef (s1))
+       {
+         if (vn_valueize (gimple_vdef (s1)) != vn_valueize (gimple_vdef (s2)))
+           return false;
+         if (TREE_CODE (lhs1) != SSA_NAME
+             && TREE_CODE (lhs2) != SSA_NAME)
+           return true;
+       }
       return (TREE_CODE (lhs1) == SSA_NAME
              && TREE_CODE (lhs2) == SSA_NAME
              && vn_valueize (lhs1) == vn_valueize (lhs2));