diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-13 19:58:49 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-13 19:58:49 +0000 |
commit | 1965a2418178355ae64b5dab96a0eb822e300105 (patch) | |
tree | 4b91de0e187a185ef4ce79585ee921262874444a /gcc/tree-vect-data-refs.c | |
parent | 8da0577c87baa75ad56a412fe624f397ec90bd9b (diff) | |
download | gcc-1965a2418178355ae64b5dab96a0eb822e300105.tar.gz |
Delete VEC_INTERLEAVE_*_EXPR.
* tree.def (VEC_INTERLEAVE_HIGH_EXPR, VEC_INTERLEAVE_LOW_EXPR): Remove.
* gimple-pretty-print.c (dump_binary_rhs): Don't handle
VEC_INTERLEAVE_HIGH_EXPR and VEC_INTERLEAVE_LOW_EXPR.
* expr.c (expand_expr_real_2): Likewise.
* tree-cfg.c (verify_gimple_assign_binary): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* tree-inline.c (estimate_operator_cost): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-vect-generic.c (expand_vector_operations_1): Likewise.
* fold-const.c (fold_binary_loc): Likewise.
* doc/generic.texi (VEC_INTERLEAVE_HIGH_EXPR,
VEC_INTERLEAVE_LOW_EXPR): Remove documentation.
* optabs.c (optab_for_tree_code): Don't handle
VEC_INTERLEAVE_HIGH_EXPR and VEC_INTERLEAVE_LOW_EXPR.
(expand_binop, init_optabs): Remove vec_interleave_high_optab
and vec_interleave_low_optab.
* genopinit.c (optabs): Likewise.
* optabs.h (OTI_vec_interleave_high, OTI_vec_interleave_low): Remove.
(vec_interleave_high_optab, vec_interleave_low_optab): Remove.
* doc/md.texi (vec_interleave_high, vec_interleave_low): Remove
documentation.
* tree-vect-stmts.c (gen_perm_mask): Renamed to...
(vect_gen_perm_mask): ... this. No longer static.
(perm_mask_for_reverse, vectorizable_load): Adjust callers.
* tree-vectorizer.h (vect_gen_perm_mask): New prototype.
* tree-vect-data-refs.c (vect_strided_store_supported): Don't try
VEC_INTERLEAVE_*_EXPR, use can_vec_perm_p instead of
can_vec_perm_for_code_p.
(vect_permute_store_chain): Generate VEC_PERM_EXPR with interleaving
masks instead of VEC_INTERLEAVE_HIGH_EXPR and VEC_INTERLEAVE_LOW_EXPR.
* config/i386/i386.c (expand_vec_perm_interleave2): If
expand_vec_perm_interleave3 would handle it, return false.
(expand_vec_perm_broadcast_1): Don't use vec_interleave_*_optab.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182298 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 86 |
1 files changed, 43 insertions, 43 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 6a85b7bf4aa..e6f03813a40 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3800,7 +3800,6 @@ vect_create_destination_var (tree scalar_dest, tree vectype) bool vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count) { - optab ih_optab, il_optab; enum machine_mode mode; mode = TYPE_MODE (vectype); @@ -3815,18 +3814,23 @@ vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count) } /* Check that the operation is supported. */ - ih_optab = optab_for_tree_code (VEC_INTERLEAVE_HIGH_EXPR, - vectype, optab_default); - il_optab = optab_for_tree_code (VEC_INTERLEAVE_LOW_EXPR, - vectype, optab_default); - if (il_optab && ih_optab - && optab_handler (ih_optab, mode) != CODE_FOR_nothing - && optab_handler (il_optab, mode) != CODE_FOR_nothing) - return true; - - if (can_vec_perm_for_code_p (VEC_INTERLEAVE_HIGH_EXPR, mode, NULL) - && can_vec_perm_for_code_p (VEC_INTERLEAVE_LOW_EXPR, mode, NULL)) - return true; + if (VECTOR_MODE_P (mode)) + { + unsigned int i, nelt = GET_MODE_NUNITS (mode); + unsigned char *sel = XALLOCAVEC (unsigned char, nelt); + for (i = 0; i < nelt / 2; i++) + { + sel[i * 2] = i; + sel[i * 2 + 1] = i + nelt; + } + if (can_vec_perm_p (mode, false, sel)) + { + for (i = 0; i < nelt; i++) + sel[i] += nelt / 2; + if (can_vec_perm_p (mode, false, sel)) + return true; + } + } if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "interleave op not supported by target."); @@ -3917,15 +3921,26 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain, tree perm_dest, vect1, vect2, high, low; gimple perm_stmt; tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt)); - int i; - unsigned int j; - enum tree_code high_code, low_code; + tree perm_mask_low, perm_mask_high; + unsigned int i, n; + unsigned int j, nelt = GET_MODE_NUNITS (TYPE_MODE (vectype)); + unsigned char *sel = XALLOCAVEC (unsigned char, nelt); gcc_assert (vect_strided_store_supported (vectype, length)); *result_chain = VEC_copy (tree, heap, dr_chain); - for (i = 0; i < exact_log2 (length); i++) + for (i = 0, n = nelt / 2; i < n; i++) + { + sel[i * 2] = i; + sel[i * 2 + 1] = i + nelt; + } + perm_mask_high = vect_gen_perm_mask (vectype, sel); + for (i = 0; i < nelt; i++) + sel[i] += nelt / 2; + perm_mask_low = vect_gen_perm_mask (vectype, sel); + + for (i = 0, n = exact_log2 (length); i < n; i++) { for (j = 0; j < length/2; j++) { @@ -3933,42 +3948,27 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain, vect2 = VEC_index (tree, dr_chain, j+length/2); /* Create interleaving stmt: - in the case of big endian: - high = interleave_high (vect1, vect2) - and in the case of little endian: - high = interleave_low (vect1, vect2). */ + high = VEC_PERM_EXPR <vect1, vect2, {0, nelt, 1, nelt+1, ...}> */ perm_dest = create_tmp_var (vectype, "vect_inter_high"); DECL_GIMPLE_REG_P (perm_dest) = 1; add_referenced_var (perm_dest); - if (BYTES_BIG_ENDIAN) - { - high_code = VEC_INTERLEAVE_HIGH_EXPR; - low_code = VEC_INTERLEAVE_LOW_EXPR; - } - else - { - low_code = VEC_INTERLEAVE_HIGH_EXPR; - high_code = VEC_INTERLEAVE_LOW_EXPR; - } - perm_stmt = gimple_build_assign_with_ops (high_code, perm_dest, - vect1, vect2); - high = make_ssa_name (perm_dest, perm_stmt); - gimple_assign_set_lhs (perm_stmt, high); + high = make_ssa_name (perm_dest, NULL); + perm_stmt + = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, high, + vect1, vect2, perm_mask_high); vect_finish_stmt_generation (stmt, perm_stmt, gsi); VEC_replace (tree, *result_chain, 2*j, high); /* Create interleaving stmt: - in the case of big endian: - low = interleave_low (vect1, vect2) - and in the case of little endian: - low = interleave_high (vect1, vect2). */ + low = VEC_PERM_EXPR <vect1, vect2, {nelt/2, nelt*3/2, nelt/2+1, + nelt*3/2+1, ...}> */ perm_dest = create_tmp_var (vectype, "vect_inter_low"); DECL_GIMPLE_REG_P (perm_dest) = 1; add_referenced_var (perm_dest); - perm_stmt = gimple_build_assign_with_ops (low_code, perm_dest, - vect1, vect2); - low = make_ssa_name (perm_dest, perm_stmt); - gimple_assign_set_lhs (perm_stmt, low); + low = make_ssa_name (perm_dest, NULL); + perm_stmt + = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, low, + vect1, vect2, perm_mask_low); vect_finish_stmt_generation (stmt, perm_stmt, gsi); VEC_replace (tree, *result_chain, 2*j+1, low); } |