tree-ssa-forwprop.c (simplify_vce): New function.
authorRichard Biener <rguenther@suse.de>
Thu, 21 Nov 2013 11:53:20 +0000 (11:53 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 21 Nov 2013 11:53:20 +0000 (11:53 +0000)
2013-11-21  Richard Biener  <rguenther@suse.de>

* tree-ssa-forwprop.c (simplify_vce): New function.
(ssa_forward_propagate_and_combine): Call it.

From-SVN: r205211

gcc/ChangeLog
gcc/tree-ssa-forwprop.c

index cecd7578cad4260ec149d95d8ac36a75fa5568af..f9c4cc564fe952a279381f824c1732d044a6acf6 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-21  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-forwprop.c (simplify_vce): New function.
+       (ssa_forward_propagate_and_combine): Call it.
+
 2013-11-21  Richard Biener  <rguenther@suse.de>
 
        * tree-vect-loop-manip.c (vect_build_loop_niters,
index a826137aabdc482d1125621941b56998f54f0980..0c9a79f6092fcb5d2c2cf7a28c9651d63dd5daa2 100644 (file)
@@ -2994,6 +2994,69 @@ combine_conversions (gimple_stmt_iterator *gsi)
   return 0;
 }
 
+/* Combine VIEW_CONVERT_EXPRs with their defining statement.  */
+
+static bool
+simplify_vce (gimple_stmt_iterator *gsi)
+{
+  gimple stmt = gsi_stmt (*gsi);
+  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+
+  /* Drop useless VIEW_CONVERT_EXPRs.  */
+  tree op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+  if (useless_type_conversion_p (type, TREE_TYPE (op)))
+    {
+      gimple_assign_set_rhs1 (stmt, op);
+      update_stmt (stmt);
+      return true;
+    }
+
+  if (TREE_CODE (op) != SSA_NAME)
+    return false;
+
+  gimple def_stmt = SSA_NAME_DEF_STMT (op);
+  if (!is_gimple_assign (def_stmt))
+    return false;
+
+  tree def_op = gimple_assign_rhs1 (def_stmt);
+  switch (gimple_assign_rhs_code (def_stmt))
+    {
+    CASE_CONVERT:
+      /* Strip integral conversions that do not change the precision.  */
+      if ((INTEGRAL_TYPE_P (TREE_TYPE (op))
+          || POINTER_TYPE_P (TREE_TYPE (op)))
+         && (INTEGRAL_TYPE_P (TREE_TYPE (def_op))
+             || POINTER_TYPE_P (TREE_TYPE (def_op)))
+         && (TYPE_PRECISION (TREE_TYPE (op))
+             == TYPE_PRECISION (TREE_TYPE (def_op))))
+       {
+         TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) = def_op;
+         update_stmt (stmt);
+         return true;
+       }
+      break;
+
+    case VIEW_CONVERT_EXPR:
+      /* Series of VIEW_CONVERT_EXPRs on register operands can
+        be contracted.  */
+      if (TREE_CODE (TREE_OPERAND (def_op, 0)) == SSA_NAME)
+       {
+         if (useless_type_conversion_p (type,
+                                        TREE_TYPE (TREE_OPERAND (def_op, 0))))
+           gimple_assign_set_rhs1 (stmt, TREE_OPERAND (def_op, 0));
+         else
+           TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)
+               = TREE_OPERAND (def_op, 0);
+         update_stmt (stmt);
+         return true;
+       }
+
+    default:;
+    }
+
+  return false;
+}
+
 /* Combine an element access with a shuffle.  Returns true if there were
    any changes made, else it returns false.  */
  
@@ -3491,6 +3554,8 @@ ssa_forward_propagate_and_combine (void)
                      
                    changed = did_something != 0;
                  }
+               else if (code == VIEW_CONVERT_EXPR)
+                 changed = simplify_vce (&gsi);
                else if (code == VEC_PERM_EXPR)
                  {
                    int did_something = simplify_permutation (&gsi);