rs6000.c (rs6000_gimple_fold_builtin): Add support for early gimple folding of vec_sp...
authorWill Schmidt <will_schmidt@vnet.ibm.com>
Thu, 6 Sep 2018 15:34:58 +0000 (15:34 +0000)
committerWill Schmidt <willschm@gcc.gnu.org>
Thu, 6 Sep 2018 15:34:58 +0000 (15:34 +0000)
[gcc]

2018-09-06  Will Schmidt  <will_schmidt@vnet.ibm.com>

* config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add support for
early gimple folding of vec_splat().
* tree-vect-generic.c: Remove static from tree_vec_extract() definition.
* gimple-fold.h: Add an extern define for tree_vec_extract().

From-SVN: r264146

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/gimple-fold.h
gcc/tree-vect-generic.c

index 7ac78ddf2ce05fff31cdd06c30a78521d01b4e57..19800f5930b5ff3e7caaa51a48c6aafc66b8a8ad 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-06  Will Schmidt  <will_schmidt@vnet.ibm.com>
+
+       * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add support for
+       early gimple folding of vec_splat().
+       * tree-vect-generic.c: Remove static from tree_vec_extract() definition.
+       * gimple-fold.h: Add an extern define for tree_vec_extract().
+
 2018-09-06  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * config/rs6000/rs6000.c (fold_mergehl_helper): Add types_compatible_p
index cc69b5db9fd0ffecc50373ae664cad0d7517d5e3..6f6c945ab7b8fe9c64fe21a668fc51be0364de05 100644 (file)
@@ -15772,6 +15772,48 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
         gimple_set_location (g, gimple_location (stmt));
         gsi_replace (gsi, g, true);
         return true;
+       }
+
+    /* Flavors of vec_splat.  */
+    /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...};  */
+    case ALTIVEC_BUILTIN_VSPLTB:
+    case ALTIVEC_BUILTIN_VSPLTH:
+    case ALTIVEC_BUILTIN_VSPLTW:
+    case VSX_BUILTIN_XXSPLTD_V2DI:
+    case VSX_BUILTIN_XXSPLTD_V2DF:
+      {
+       arg0 = gimple_call_arg (stmt, 0); /* input vector.  */
+       arg1 = gimple_call_arg (stmt, 1); /* index into arg0.  */
+       /* Only fold the vec_splat_*() if arg1 is both a constant value and
+          is a valid index into the arg0 vector.  */
+       unsigned int n_elts = VECTOR_CST_NELTS (arg0);
+       if (TREE_CODE (arg1) != INTEGER_CST
+           || TREE_INT_CST_LOW (arg1) > (n_elts -1))
+         return false;
+       lhs = gimple_call_lhs (stmt);
+       tree lhs_type = TREE_TYPE (lhs);
+       tree arg0_type = TREE_TYPE (arg0);
+       tree splat;
+       if (TREE_CODE (arg0) == VECTOR_CST)
+         splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
+       else
+         {
+           /* Determine (in bits) the length and start location of the
+              splat value for a call to the tree_vec_extract helper.  */
+           int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
+                                 * BITS_PER_UNIT / n_elts;
+           int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
+           tree len = build_int_cst (bitsizetype, splat_elem_size);
+           tree start = build_int_cst (bitsizetype, splat_start_bit);
+           splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
+                                     len, start);
+         }
+       /* And finally, build the new vector.  */
+       tree splat_tree = build_vector_from_val (lhs_type, splat);
+       g = gimple_build_assign (lhs, splat_tree);
+       gimple_set_location (g, gimple_location (stmt));
+       gsi_replace (gsi, g, true);
+       return true;
       }
 
     /* vec_mergel (integrals).  */
index e3fad83bbfb687188c8289c95aaf9e1456857456..fcb0d31bef39a580a35900ee70dc347d594e4193 100644 (file)
@@ -61,6 +61,7 @@ extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *);
 extern bool arith_code_with_undefined_signed_overflow (tree_code);
 extern gimple_seq rewrite_to_defined_overflow (gimple *);
 extern void replace_call_with_value (gimple_stmt_iterator *, tree);
+extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
 
 /* gimple_build, functionally matching fold_buildN, outputs stmts
    int the provided sequence, matching and simplifying them on-the-fly.
index 909f7903b93ad66a5d615935a384a727d630fb6e..1c9701ddffa5c449c4cc3101772c65c75127b154 100644 (file)
@@ -120,7 +120,7 @@ typedef tree (*elem_op_func) (gimple_stmt_iterator *,
                              tree, tree, tree, tree, tree, enum tree_code,
                              tree);
 
-static inline tree
+tree
 tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
                  tree t, tree bitsize, tree bitpos)
 {