tree-ssa-forwprop.c (simplify_vector_constructor): New function.
authorMarc Glisse <marc.glisse@inria.fr>
Tue, 11 Sep 2012 16:51:15 +0000 (18:51 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Tue, 11 Sep 2012 16:51:15 +0000 (16:51 +0000)
2012-09-11  Marc Glisse  <marc.glisse@inria.fr>

gcc/
        * tree-ssa-forwprop.c (simplify_vector_constructor): New function.
        (ssa_forward_propagate_and_combine): Call it.

gcc/testsuite/
        * gcc.dg/tree-ssa/forwprop-22.c: New testcase.

From-SVN: r191198

gcc/ChangeLog
gcc/Makefile.in
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 0548aa5370706b907cd0edc17d34d59530a4801d..b90c1fbf57905a06452e4bb497ba7e6ccd21788f 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-11  Marc Glisse  <marc.glisse@inria.fr>
+
+        * tree-ssa-forwprop.c (simplify_vector_constructor): New function.
+        (ssa_forward_propagate_and_combine): Call it.
+
 2012-09-11  Diego Novillo  <dnovillo@google.com>
 
        * var-tracking.c (vt_add_function_parameter): Adjust for VEC
index e0998240a64035d1f5cbf9998c4ca7b60c32c737..490415e36aff9caf0dbad800ecfc329eb441f3e3 100644 (file)
@@ -2244,7 +2244,8 @@ tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
 tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
-   langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H)
+   langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \
+   $(TREE_VECTORIZER_H)
 tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
index 47def6320280526c7cade82d32d952e7673eb48d..7d50fca757be15808646f32d4b78f54172351aa4 100644 (file)
@@ -1,3 +1,7 @@
+2012-09-11  Marc Glisse  <marc.glisse@inria.fr>
+
+        * gcc.dg/tree-ssa/forwprop-22.c: New testcase.
+
 2012-09-11  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
            Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c
new file mode 100644 (file)
index 0000000..9c66c99
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vect_perm } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+typedef double vec __attribute__((vector_size (2 * sizeof (double))));
+void f (vec *px, vec *y, vec *z)
+{
+  vec x = *px;
+  vec t1 = { x[1], x[0] };
+  vec t2 = { x[0], x[1] };
+  *y = t1;
+  *z = t2;
+}
+
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 5692e21f19d575fd836054fe5b4509057a97bb15..ad407269dd7a2128cdf45132db1857e30b023147 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "expr.h"
 #include "cfgloop.h"
+#include "tree-vectorizer.h"
 
 /* This pass propagates the RHS of assignment statements into use
    sites of the LHS of the assignment.  It's basically a specialized
@@ -2794,6 +2795,84 @@ simplify_permutation (gimple_stmt_iterator *gsi)
   return 0;
 }
 
+/* Recognize a VEC_PERM_EXPR.  Returns true if there were any changes.  */
+
+static bool
+simplify_vector_constructor (gimple_stmt_iterator *gsi)
+{
+  gimple stmt = gsi_stmt (*gsi);
+  gimple def_stmt;
+  tree op, op2, orig, type, elem_type;
+  unsigned elem_size, nelts, i;
+  enum tree_code code;
+  constructor_elt *elt;
+  unsigned char *sel;
+  bool maybe_ident;
+
+  gcc_checking_assert (gimple_assign_rhs_code (stmt) == CONSTRUCTOR);
+
+  op = gimple_assign_rhs1 (stmt);
+  type = TREE_TYPE (op);
+  gcc_checking_assert (TREE_CODE (type) == VECTOR_TYPE);
+
+  nelts = TYPE_VECTOR_SUBPARTS (type);
+  elem_type = TREE_TYPE (type);
+  elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
+
+  sel = XALLOCAVEC (unsigned char, nelts);
+  orig = NULL;
+  maybe_ident = true;
+  FOR_EACH_VEC_ELT (constructor_elt, CONSTRUCTOR_ELTS (op), i, elt)
+    {
+      tree ref, op1;
+
+      if (i >= nelts)
+       return false;
+
+      if (TREE_CODE (elt->value) != SSA_NAME)
+       return false;
+      def_stmt = SSA_NAME_DEF_STMT (elt->value);
+      if (!def_stmt || !is_gimple_assign (def_stmt))
+       return false;
+      code = gimple_assign_rhs_code (def_stmt);
+      if (code != BIT_FIELD_REF)
+       return false;
+      op1 = gimple_assign_rhs1 (def_stmt);
+      ref = TREE_OPERAND (op1, 0);
+      if (orig)
+       {
+         if (ref != orig)
+           return false;
+       }
+      else
+       {
+         if (TREE_CODE (ref) != SSA_NAME)
+           return false;
+         orig = ref;
+       }
+      if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
+       return false;
+      sel[i] = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size;
+      if (sel[i] != i) maybe_ident = false;
+    }
+  if (i < nelts)
+    return false;
+
+  if (maybe_ident)
+    {
+      gimple_assign_set_rhs_from_tree (gsi, orig);
+    }
+  else
+    {
+      op2 = vect_gen_perm_mask (type, sel);
+      if (!op2)
+       return false;
+      gimple_assign_set_rhs_with_ops_1 (gsi, VEC_PERM_EXPR, orig, orig, op2);
+    }
+  update_stmt (gsi_stmt (*gsi));
+  return true;
+}
+
 /* Main entry point for the forward propagation and statement combine
    optimizer.  */
 
@@ -2965,6 +3044,9 @@ ssa_forward_propagate_and_combine (void)
                  }
                else if (code == BIT_FIELD_REF)
                  changed = simplify_bitfield_ref (&gsi);
+                else if (code == CONSTRUCTOR
+                         && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
+                  changed = simplify_vector_constructor (&gsi);
                break;
              }