summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-25 21:29:56 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-25 21:29:56 +0000
commit6620d7d7c5f2fe5df0df2b85e143746f76fdd4cf (patch)
tree45f2e4d1399a268bc62cbc1f51000ceee9bcc2b1 /gcc/tree-vect-data-refs.c
parente21c468f20819a1d6545741af280a77e4f89c8e0 (diff)
downloadgcc-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.c80
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