diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-25 21:29:56 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-25 21:29:56 +0000 |
commit | 6620d7d7c5f2fe5df0df2b85e143746f76fdd4cf (patch) | |
tree | 45f2e4d1399a268bc62cbc1f51000ceee9bcc2b1 /gcc/tree-vect-data-refs.c | |
parent | e21c468f20819a1d6545741af280a77e4f89c8e0 (diff) | |
download | gcc-6620d7d7c5f2fe5df0df2b85e143746f76fdd4cf.tar.gz |
Implement interleave via permutation.
* expr.c (expand_expr_real_2) [VEC_EXTRACT_EVEN_EXPR]: Use binop.
[VEC_EXTRACT_ODD_EXPR, VEC_INTERLEAVE_HIGH_EXPR]: Likewise.
[VEC_INTERLEAVE_LOW_EXPR]: Likewise.
* optabs.c (expand_binop): Implement vec_interleave_high_optab,
vec_interleave_low_optab, vec_extract_even_optab,
vec_extract_odd_optab with expand_vec_perm.
(can_vec_perm_for_code_p): New.
* optabs.h: Update.
* tree-vect-data-refs.c (vect_strided_store_supported): Allow for
fallback via can_vec_perm_for_code_p.
(vect_strided_load_supported): Likewise.
* tree-vect-generic.c (expand_vector_operations_1): Never lower
VEC_INTERLEAVE_HIGH_EXPR, VEC_INTERLEAVE_LOW_EXPR,
VEC_EXTRACT_EVEN_EXPR, VEC_EXTRACT_ODD_EXPR.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180450 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 80 |
1 files changed, 30 insertions, 50 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 4b6164a095a..a239216cf2d 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3467,7 +3467,7 @@ vect_create_destination_var (tree scalar_dest, tree vectype) bool vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count) { - optab interleave_high_optab, interleave_low_optab; + optab ih_optab, il_optab; enum machine_mode mode; mode = TYPE_MODE (vectype); @@ -3482,26 +3482,22 @@ vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count) } /* Check that the operation is supported. */ - interleave_high_optab = optab_for_tree_code (VEC_INTERLEAVE_HIGH_EXPR, - vectype, optab_default); - interleave_low_optab = optab_for_tree_code (VEC_INTERLEAVE_LOW_EXPR, - vectype, optab_default); - if (!interleave_high_optab || !interleave_low_optab) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "no optab for interleave."); - return false; - } + 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 (optab_handler (interleave_high_optab, mode) == CODE_FOR_nothing - || optab_handler (interleave_low_optab, mode) == CODE_FOR_nothing) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "interleave op not supported by target."); - return false; - } + 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; - return true; + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "interleave op not supported by target."); + return false; } @@ -3923,7 +3919,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi, bool vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count) { - optab perm_even_optab, perm_odd_optab; + optab ee_optab, eo_optab; enum machine_mode mode; mode = TYPE_MODE (vectype); @@ -3937,38 +3933,22 @@ vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count) return false; } - perm_even_optab = optab_for_tree_code (VEC_EXTRACT_EVEN_EXPR, vectype, - optab_default); - if (!perm_even_optab) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "no optab for perm_even."); - return false; - } - - if (optab_handler (perm_even_optab, mode) == CODE_FOR_nothing) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "perm_even op not supported by target."); - return false; - } + ee_optab = optab_for_tree_code (VEC_EXTRACT_EVEN_EXPR, + vectype, optab_default); + eo_optab = optab_for_tree_code (VEC_EXTRACT_ODD_EXPR, + vectype, optab_default); + if (ee_optab && eo_optab + && optab_handler (ee_optab, mode) != CODE_FOR_nothing + && optab_handler (eo_optab, mode) != CODE_FOR_nothing) + return true; - perm_odd_optab = optab_for_tree_code (VEC_EXTRACT_ODD_EXPR, vectype, - optab_default); - if (!perm_odd_optab) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "no optab for perm_odd."); - return false; - } + if (can_vec_perm_for_code_p (VEC_EXTRACT_EVEN_EXPR, mode, NULL) + && can_vec_perm_for_code_p (VEC_EXTRACT_ODD_EXPR, mode, NULL)) + return true; - if (optab_handler (perm_odd_optab, mode) == CODE_FOR_nothing) - { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "perm_odd op not supported by target."); - return false; - } - return true; + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "extract even/odd not supported by target"); + return false; } /* Return TRUE if vec_load_lanes is available for COUNT vectors of |