aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-stmts.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2012-07-10 08:25:20 +0000
committerRichard Henderson <rth@redhat.com>2012-07-10 08:25:20 +0000
commit3967a49f3a06169e7ef351767077bdf8748fde4f (patch)
tree92ca34cfac26d6253011a1acbd60501bca8cdf7a /gcc/tree-vect-stmts.c
parent42afa16f0ea0b29a2f662896c6ed89863db6e433 (diff)
Move vector highpart emulation to the optabs layer
* expmed.c (expmed_mult_highpart): Rename from expand_mult_highpart. (expmed_mult_highpart_optab): Rename from expand_mult_highpart_optab. * optabs.c (can_mult_highpart_p): New. (expand_mult_highpart): New. * expr.c (expand_expr_real_2) [MULT_HIGHPART_EXPR): Use it. * tree-vect-generic.c (expand_vector_operations_1): Don't expand by pieces if can_mult_highpart_p. (expand_vector_divmod): Use can_mult_highpart_p and always generate MULT_HIGHPART_EXPR. * tree-vect-patterns.c (vect_recog_divmod_pattern): Likewise. * tree-vect-stmts.c (vectorizable_operation): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@189407 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-stmts.c')
-rw-r--r--gcc/tree-vect-stmts.c171
1 files changed, 19 insertions, 152 deletions
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 8e0965a5428..9caf1c6728a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3304,18 +3304,17 @@ static bool
vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
gimple *vec_stmt, slp_tree slp_node)
{
- tree vec_dest, vec_dest2 = NULL_TREE;
- tree vec_dest3 = NULL_TREE, vec_dest4 = NULL_TREE;
+ tree vec_dest;
tree scalar_dest;
tree op0, op1 = NULL_TREE, op2 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- tree vectype, wide_vectype = NULL_TREE;
+ tree vectype;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
enum tree_code code;
enum machine_mode vec_mode;
tree new_temp;
int op_type;
- optab optab, optab2 = NULL;
+ optab optab;
int icode;
tree def;
gimple def_stmt;
@@ -3332,8 +3331,6 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
tree vop0, vop1, vop2;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
int vf;
- unsigned char *sel = NULL;
- tree decl1 = NULL_TREE, decl2 = NULL_TREE, perm_mask = NULL_TREE;
if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
@@ -3455,87 +3452,26 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
|| code == RROTATE_EXPR)
return false;
- optab = optab_for_tree_code (code, vectype, optab_default);
-
/* Supportable by target? */
- if (!optab && code != MULT_HIGHPART_EXPR)
+
+ vec_mode = TYPE_MODE (vectype);
+ if (code == MULT_HIGHPART_EXPR)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab.");
- return false;
+ if (can_mult_highpart_p (vec_mode, TYPE_UNSIGNED (vectype)))
+ icode = 0;
+ else
+ icode = CODE_FOR_nothing;
}
- vec_mode = TYPE_MODE (vectype);
- icode = optab ? (int) optab_handler (optab, vec_mode) : CODE_FOR_nothing;
-
- if (icode == CODE_FOR_nothing
- && code == MULT_HIGHPART_EXPR
- && VECTOR_MODE_P (vec_mode)
- && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
- {
- /* If MULT_HIGHPART_EXPR isn't supported by the backend, see
- if we can emit VEC_WIDEN_MULT_{LO,HI}_EXPR followed by VEC_PERM_EXPR
- or builtin_mul_widen_{even,odd} followed by VEC_PERM_EXPR. */
- unsigned int prec = TYPE_PRECISION (TREE_TYPE (scalar_dest));
- unsigned int unsignedp = TYPE_UNSIGNED (TREE_TYPE (scalar_dest));
- tree wide_type
- = build_nonstandard_integer_type (prec * 2, unsignedp);
- wide_vectype
- = get_same_sized_vectype (wide_type, vectype);
-
- sel = XALLOCAVEC (unsigned char, nunits_in);
- if (VECTOR_MODE_P (TYPE_MODE (wide_vectype))
- && GET_MODE_SIZE (TYPE_MODE (wide_vectype))
- == GET_MODE_SIZE (vec_mode))
- {
- if (targetm.vectorize.builtin_mul_widen_even
- && (decl1 = targetm.vectorize.builtin_mul_widen_even (vectype))
- && targetm.vectorize.builtin_mul_widen_odd
- && (decl2 = targetm.vectorize.builtin_mul_widen_odd (vectype))
- && TYPE_MODE (TREE_TYPE (TREE_TYPE (decl1)))
- == TYPE_MODE (wide_vectype))
- {
- for (i = 0; i < nunits_in; i++)
- sel[i] = !BYTES_BIG_ENDIAN + (i & ~1)
- + ((i & 1) ? nunits_in : 0);
- if (can_vec_perm_p (vec_mode, false, sel))
- icode = 0;
- }
- if (icode == CODE_FOR_nothing)
- {
- decl1 = NULL_TREE;
- decl2 = NULL_TREE;
- optab = optab_for_tree_code (VEC_WIDEN_MULT_LO_EXPR,
- vectype, optab_default);
- optab2 = optab_for_tree_code (VEC_WIDEN_MULT_HI_EXPR,
- vectype, optab_default);
- if (optab != NULL
- && optab2 != NULL
- && optab_handler (optab, vec_mode) != CODE_FOR_nothing
- && optab_handler (optab2, vec_mode) != CODE_FOR_nothing
- && insn_data[optab_handler (optab, vec_mode)].operand[0].mode
- == TYPE_MODE (wide_vectype)
- && insn_data[optab_handler (optab2,
- vec_mode)].operand[0].mode
- == TYPE_MODE (wide_vectype))
- {
- for (i = 0; i < nunits_in; i++)
- sel[i] = !BYTES_BIG_ENDIAN + 2 * i;
- if (can_vec_perm_p (vec_mode, false, sel))
- icode = optab_handler (optab, vec_mode);
- }
- }
- }
- if (icode == CODE_FOR_nothing)
+ else
+ {
+ optab = optab_for_tree_code (code, vectype, optab_default);
+ if (!optab)
{
- if (optab_for_tree_code (code, vectype, optab_default) == NULL)
- {
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab.");
- return false;
- }
- wide_vectype = NULL_TREE;
- optab2 = NULL;
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "no optab.");
+ return false;
}
+ icode = (int) optab_handler (optab, vec_mode);
}
if (icode == CODE_FOR_nothing)
@@ -3575,16 +3511,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
fprintf (vect_dump, "transform binary/unary operation.");
/* Handle def. */
- if (wide_vectype)
- {
- vec_dest = vect_create_destination_var (scalar_dest, wide_vectype);
- vec_dest2 = vect_create_destination_var (scalar_dest, wide_vectype);
- vec_dest3 = vect_create_destination_var (scalar_dest, vectype);
- vec_dest4 = vect_create_destination_var (scalar_dest, vectype);
- perm_mask = vect_gen_perm_mask (vectype, sel);
- }
- else
- vec_dest = vect_create_destination_var (scalar_dest, vectype);
+ vec_dest = vect_create_destination_var (scalar_dest, vectype);
/* Allocate VECs for vector operands. In case of SLP, vector operands are
created in the previous stages of the recursion, so no allocation is
@@ -3693,66 +3620,6 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
? VEC_index (tree, vec_oprnds1, i) : NULL_TREE);
vop2 = ((op_type == ternary_op)
? VEC_index (tree, vec_oprnds2, i) : NULL_TREE);
- if (wide_vectype)
- {
- tree new_temp2, vce;
-
- gcc_assert (code == MULT_HIGHPART_EXPR);
- if (decl1 != NULL_TREE)
- {
- new_stmt = gimple_build_call (decl1, 2, vop0, vop1);
- new_temp = make_ssa_name (vec_dest, new_stmt);
- gimple_call_set_lhs (new_stmt, new_temp);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
-
- new_stmt = gimple_build_call (decl2, 2, vop0, vop1);
- new_temp2 = make_ssa_name (vec_dest2, new_stmt);
- gimple_call_set_lhs (new_stmt, new_temp2);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
- }
- else
- {
- new_temp = make_ssa_name (vec_dest, NULL);
- new_stmt
- = gimple_build_assign_with_ops (BYTES_BIG_ENDIAN
- ? VEC_WIDEN_MULT_HI_EXPR
- : VEC_WIDEN_MULT_LO_EXPR,
- new_temp, vop0, vop1);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
-
- new_temp2 = make_ssa_name (vec_dest2, NULL);
- new_stmt
- = gimple_build_assign_with_ops (BYTES_BIG_ENDIAN
- ? VEC_WIDEN_MULT_LO_EXPR
- : VEC_WIDEN_MULT_HI_EXPR,
- new_temp2, vop0, vop1);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
- }
-
- vce = build1 (VIEW_CONVERT_EXPR, vectype, new_temp);
- new_stmt = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR,
- vec_dest3, vce,
- NULL_TREE);
- new_temp = make_ssa_name (vec_dest3, new_stmt);
- gimple_assign_set_lhs (new_stmt, new_temp);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
-
- vce = build1 (VIEW_CONVERT_EXPR, vectype, new_temp2);
- new_stmt = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR,
- vec_dest4, vce,
- NULL_TREE);
- new_temp2 = make_ssa_name (vec_dest4, new_stmt);
- gimple_assign_set_lhs (new_stmt, new_temp2);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
-
- new_temp = permute_vec_elements (new_temp, new_temp2,
- perm_mask, stmt, gsi);
- new_stmt = SSA_NAME_DEF_STMT (new_temp);
- if (slp_node)
- VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node),
- new_stmt);
- continue;
- }
new_stmt = gimple_build_assign_with_ops3 (code, vec_dest,
vop0, vop1, vop2);
new_temp = make_ssa_name (vec_dest, new_stmt);