Delete VEC_EXTRACT_EVEN/ODD_EXPR.
* tree.def (VEC_EXTRACT_EVEN_EXPR, VEC_EXTRACT_ODD_EXPR): Remove. * cfgexpand.c (expand_debug_expr): Don't handle them. * expr.c (expand_expr_real_2): Likewise. * fold-const.c (fold_binary_loc): Likewise. * gimple-pretty-print.c (dump_binary_rhs): Likewise. * tree-cfg.c (verify_gimple_assign_binary): 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. * optabs.c (optab_for_tree_code): Likewise. (can_vec_perm_for_code_p): Remove. (expand_binop): Don't try it. (init_optabs): Don't init vec_extract_even/odd_optab. * genopinit.c (optabs): Likewise. * optabs.h (OTI_vec_extract_even, OTI_vec_extract_odd): Remove. (vec_extract_even_optab, vec_extract_odd_optab): Remove. * tree-vect-data-refs.c (vect_strided_store_supported): Tidy code. (vect_permute_store_chain): Use TYPE_VECTOR_SUBPARTS instead of GET_MODE_NUNITS; check vect_gen_perm_mask return value instead of asserting vect_strided_store_supported. (vect_strided_load_supported): Use can_vec_perm_p. (vect_permute_load_chain): Use VEC_PERM_EXPR. * doc/generic.texi (VEC_EXTRACT_EVEN_EXPR): Remove. (VEC_EXTRACT_ODD_EXPR): Remove. * doc/md.texi (vec_extract_even, vec_extract_odd): Remove. From-SVN: r182669
This commit is contained in:
parent
ef2361a9e5
commit
e2c8363087
17 changed files with 80 additions and 246 deletions
|
@ -1,3 +1,32 @@
|
|||
2011-12-23 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* tree.def (VEC_EXTRACT_EVEN_EXPR, VEC_EXTRACT_ODD_EXPR): Remove.
|
||||
* cfgexpand.c (expand_debug_expr): Don't handle them.
|
||||
* expr.c (expand_expr_real_2): Likewise.
|
||||
* fold-const.c (fold_binary_loc): Likewise.
|
||||
* gimple-pretty-print.c (dump_binary_rhs): Likewise.
|
||||
* tree-cfg.c (verify_gimple_assign_binary): 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.
|
||||
* optabs.c (optab_for_tree_code): Likewise.
|
||||
(can_vec_perm_for_code_p): Remove.
|
||||
(expand_binop): Don't try it.
|
||||
(init_optabs): Don't init vec_extract_even/odd_optab.
|
||||
* genopinit.c (optabs): Likewise.
|
||||
* optabs.h (OTI_vec_extract_even, OTI_vec_extract_odd): Remove.
|
||||
(vec_extract_even_optab, vec_extract_odd_optab): Remove.
|
||||
* tree-vect-data-refs.c (vect_strided_store_supported): Tidy code.
|
||||
(vect_permute_store_chain): Use TYPE_VECTOR_SUBPARTS instead of
|
||||
GET_MODE_NUNITS; check vect_gen_perm_mask return value instead of
|
||||
asserting vect_strided_store_supported.
|
||||
(vect_strided_load_supported): Use can_vec_perm_p.
|
||||
(vect_permute_load_chain): Use VEC_PERM_EXPR.
|
||||
|
||||
* doc/generic.texi (VEC_EXTRACT_EVEN_EXPR): Remove.
|
||||
(VEC_EXTRACT_ODD_EXPR): Remove.
|
||||
* doc/md.texi (vec_extract_even, vec_extract_odd): Remove.
|
||||
|
||||
2011-12-23 Anatoly Sokolov <aesok@post.ru>
|
||||
|
||||
* config/score/score.h (REGISTER_MOVE_COST, MEMORY_MOVE_COST): Remove.
|
||||
|
|
|
@ -3449,8 +3449,6 @@ expand_debug_expr (tree exp)
|
|||
case REDUC_MIN_EXPR:
|
||||
case REDUC_PLUS_EXPR:
|
||||
case VEC_COND_EXPR:
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
case VEC_LSHIFT_EXPR:
|
||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
case VEC_PACK_SAT_EXPR:
|
||||
|
|
|
@ -1695,8 +1695,6 @@ its sole argument yields the representation for @code{ap}.
|
|||
@tindex VEC_PACK_TRUNC_EXPR
|
||||
@tindex VEC_PACK_SAT_EXPR
|
||||
@tindex VEC_PACK_FIX_TRUNC_EXPR
|
||||
@tindex VEC_EXTRACT_EVEN_EXPR
|
||||
@tindex VEC_EXTRACT_ODD_EXPR
|
||||
|
||||
@table @code
|
||||
@item VEC_LSHIFT_EXPR
|
||||
|
@ -1765,13 +1763,6 @@ of elements of a floating point type. The result is a vector that contains
|
|||
twice as many elements of an integral type whose size is half as wide. The
|
||||
elements of the two vectors are merged (concatenated) to form the output
|
||||
vector.
|
||||
|
||||
@item VEC_EXTRACT_EVEN_EXPR
|
||||
@itemx VEC_EXTRACT_ODD_EXPR
|
||||
These nodes represent extracting of the even/odd elements of the two input
|
||||
vectors, respectively. Their operands and result are vectors that contain the
|
||||
same number of elements of the same type.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
|
|
|
@ -4145,20 +4145,6 @@ operand 1 is new value of field and operand 2 specify the field index.
|
|||
Extract given field from the vector value. Operand 1 is the vector, operand 2
|
||||
specify field index and operand 0 place to store value into.
|
||||
|
||||
@cindex @code{vec_extract_even@var{m}} instruction pattern
|
||||
@item @samp{vec_extract_even@var{m}}
|
||||
Extract even elements from the input vectors (operand 1 and operand 2).
|
||||
The even elements of operand 2 are concatenated to the even elements of operand
|
||||
1 in their original order. The result is stored in operand 0.
|
||||
The output and input vectors should have the same modes.
|
||||
|
||||
@cindex @code{vec_extract_odd@var{m}} instruction pattern
|
||||
@item @samp{vec_extract_odd@var{m}}
|
||||
Extract odd elements from the input vectors (operand 1 and operand 2).
|
||||
The odd elements of operand 2 are concatenated to the odd elements of operand
|
||||
1 in their original order. The result is stored in operand 0.
|
||||
The output and input vectors should have the same modes.
|
||||
|
||||
@cindex @code{vec_init@var{m}} instruction pattern
|
||||
@item @samp{vec_init@var{m}}
|
||||
Initialize the vector to given values. Operand 0 is the vector to initialize
|
||||
|
|
|
@ -8647,10 +8647,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
|||
return temp;
|
||||
}
|
||||
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
goto binop;
|
||||
|
||||
case VEC_LSHIFT_EXPR:
|
||||
case VEC_RSHIFT_EXPR:
|
||||
{
|
||||
|
|
|
@ -13501,33 +13501,6 @@ fold_binary_loc (location_t loc,
|
|||
/* An ASSERT_EXPR should never be passed to fold_binary. */
|
||||
gcc_unreachable ();
|
||||
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
if ((TREE_CODE (arg0) == VECTOR_CST
|
||||
|| TREE_CODE (arg0) == CONSTRUCTOR)
|
||||
&& (TREE_CODE (arg1) == VECTOR_CST
|
||||
|| TREE_CODE (arg1) == CONSTRUCTOR))
|
||||
{
|
||||
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
|
||||
unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
|
||||
|
||||
for (i = 0; i < nelts; i++)
|
||||
switch (code)
|
||||
{
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
sel[i] = i * 2;
|
||||
break;
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
sel[i] = i * 2 + 1;
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return fold_vec_perm (type, arg0, arg1, sel);
|
||||
}
|
||||
return NULL_TREE;
|
||||
|
||||
case VEC_PACK_TRUNC_EXPR:
|
||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
{
|
||||
|
|
|
@ -267,8 +267,6 @@ static const char * const optabs[] =
|
|||
"set_direct_optab_handler (atomic_or_optab, $A, CODE_FOR_$(atomic_or$I$a$))",
|
||||
"set_optab_handler (vec_set_optab, $A, CODE_FOR_$(vec_set$a$))",
|
||||
"set_optab_handler (vec_extract_optab, $A, CODE_FOR_$(vec_extract$a$))",
|
||||
"set_optab_handler (vec_extract_even_optab, $A, CODE_FOR_$(vec_extract_even$a$))",
|
||||
"set_optab_handler (vec_extract_odd_optab, $A, CODE_FOR_$(vec_extract_odd$a$))",
|
||||
"set_optab_handler (vec_init_optab, $A, CODE_FOR_$(vec_init$a$))",
|
||||
"set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))",
|
||||
"set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
|
||||
|
|
|
@ -345,8 +345,6 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
|
|||
case VEC_PACK_TRUNC_EXPR:
|
||||
case VEC_PACK_SAT_EXPR:
|
||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
||||
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
||||
for (p = tree_code_name [(int) code]; *p; p++)
|
||||
|
|
108
gcc/optabs.c
108
gcc/optabs.c
|
@ -547,12 +547,6 @@ optab_for_tree_code (enum tree_code code, const_tree type,
|
|||
case ABS_EXPR:
|
||||
return trapv ? absv_optab : abs_optab;
|
||||
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
return vec_extract_even_optab;
|
||||
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
return vec_extract_odd_optab;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1600,26 +1594,6 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
|
|||
}
|
||||
}
|
||||
|
||||
/* Certain vector operations can be implemented with vector permutation. */
|
||||
if (VECTOR_MODE_P (mode))
|
||||
{
|
||||
enum tree_code tcode = ERROR_MARK;
|
||||
rtx sel;
|
||||
|
||||
if (binoptab == vec_extract_even_optab)
|
||||
tcode = VEC_EXTRACT_EVEN_EXPR;
|
||||
else if (binoptab == vec_extract_odd_optab)
|
||||
tcode = VEC_EXTRACT_ODD_EXPR;
|
||||
|
||||
if (tcode != ERROR_MARK
|
||||
&& can_vec_perm_for_code_p (tcode, mode, &sel))
|
||||
{
|
||||
temp = expand_vec_perm (mode, op0, op1, sel, target);
|
||||
gcc_assert (temp != NULL);
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for a wider mode of the same class for which we think we
|
||||
can open-code the operation. Check for a widening multiply at the
|
||||
wider mode as well. */
|
||||
|
@ -6259,8 +6233,6 @@ init_optabs (void)
|
|||
init_optab (udot_prod_optab, UNKNOWN);
|
||||
|
||||
init_optab (vec_extract_optab, UNKNOWN);
|
||||
init_optab (vec_extract_even_optab, UNKNOWN);
|
||||
init_optab (vec_extract_odd_optab, UNKNOWN);
|
||||
init_optab (vec_set_optab, UNKNOWN);
|
||||
init_optab (vec_init_optab, UNKNOWN);
|
||||
init_optab (vec_shl_optab, UNKNOWN);
|
||||
|
@ -6868,86 +6840,6 @@ can_vec_perm_p (enum machine_mode mode, bool variable,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Return true if we can implement with VEC_PERM_EXPR for this target.
|
||||
If PSEL is non-null, return the selector for the permutation. */
|
||||
|
||||
bool
|
||||
can_vec_perm_for_code_p (enum tree_code code, enum machine_mode mode,
|
||||
rtx *psel)
|
||||
{
|
||||
bool need_sel_test = false;
|
||||
enum insn_code icode;
|
||||
|
||||
/* If the target doesn't implement a vector mode for the vector type,
|
||||
then no operations are supported. */
|
||||
if (!VECTOR_MODE_P (mode))
|
||||
return false;
|
||||
|
||||
/* Do as many tests as possible without reqiring the selector. */
|
||||
icode = direct_optab_handler (vec_perm_optab, mode);
|
||||
if (icode == CODE_FOR_nothing && GET_MODE_INNER (mode) != QImode)
|
||||
{
|
||||
enum machine_mode qimode
|
||||
= mode_for_vector (QImode, GET_MODE_SIZE (mode));
|
||||
if (VECTOR_MODE_P (qimode))
|
||||
icode = direct_optab_handler (vec_perm_optab, qimode);
|
||||
}
|
||||
if (icode == CODE_FOR_nothing)
|
||||
{
|
||||
icode = direct_optab_handler (vec_perm_const_optab, mode);
|
||||
if (icode != CODE_FOR_nothing
|
||||
&& targetm.vectorize.vec_perm_const_ok != NULL)
|
||||
need_sel_test = true;
|
||||
}
|
||||
if (icode == CODE_FOR_nothing)
|
||||
return false;
|
||||
|
||||
/* If the selector is required, or if we need to test it, build it. */
|
||||
if (psel || need_sel_test)
|
||||
{
|
||||
int i, nelt = GET_MODE_NUNITS (mode), alt = 0;
|
||||
unsigned char *data = XALLOCAVEC (unsigned char, nelt);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
alt = 1;
|
||||
/* FALLTHRU */
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
for (i = 0; i < nelt; ++i)
|
||||
data[i] = i * 2 + alt;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (need_sel_test
|
||||
&& !targetm.vectorize.vec_perm_const_ok (mode, data))
|
||||
return false;
|
||||
|
||||
if (psel)
|
||||
{
|
||||
rtvec vec = rtvec_alloc (nelt);
|
||||
enum machine_mode imode = mode;
|
||||
|
||||
for (i = 0; i < nelt; ++i)
|
||||
RTVEC_ELT (vec, i) = GEN_INT (data[i]);
|
||||
|
||||
if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
|
||||
{
|
||||
imode = int_mode_for_mode (GET_MODE_INNER (mode));
|
||||
imode = mode_for_vector (imode, nelt);
|
||||
gcc_assert (GET_MODE_CLASS (imode) == MODE_VECTOR_INT);
|
||||
}
|
||||
|
||||
*psel = gen_rtx_CONST_VECTOR (imode, vec);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
|
||||
|
||||
static rtx
|
||||
|
|
|
@ -332,9 +332,6 @@ enum optab_index
|
|||
OTI_vec_set,
|
||||
/* Extract specified field of vector operand. */
|
||||
OTI_vec_extract,
|
||||
/* Extract even/odd fields of vector operands. */
|
||||
OTI_vec_extract_even,
|
||||
OTI_vec_extract_odd,
|
||||
/* Initialize vector operand. */
|
||||
OTI_vec_init,
|
||||
/* Whole vector shift. The shift amount is in bits. */
|
||||
|
@ -559,8 +556,6 @@ enum optab_index
|
|||
|
||||
#define vec_set_optab (&optab_table[OTI_vec_set])
|
||||
#define vec_extract_optab (&optab_table[OTI_vec_extract])
|
||||
#define vec_extract_even_optab (&optab_table[OTI_vec_extract_even])
|
||||
#define vec_extract_odd_optab (&optab_table[OTI_vec_extract_odd])
|
||||
#define vec_init_optab (&optab_table[OTI_vec_init])
|
||||
#define vec_shl_optab (&optab_table[OTI_vec_shl])
|
||||
#define vec_shr_optab (&optab_table[OTI_vec_shr])
|
||||
|
@ -1003,9 +998,6 @@ extern rtx expand_vec_shift_expr (sepops, rtx);
|
|||
/* Return tree if target supports vector operations for VEC_PERM_EXPR. */
|
||||
extern bool can_vec_perm_p (enum machine_mode, bool, const unsigned char *);
|
||||
|
||||
/* Return true if target supports vector operations using VEC_PERM_EXPR. */
|
||||
extern bool can_vec_perm_for_code_p (enum tree_code, enum machine_mode, rtx *);
|
||||
|
||||
/* Generate code for VEC_PERM_EXPR. */
|
||||
extern rtx expand_vec_perm (enum machine_mode, rtx, rtx, rtx, rtx);
|
||||
|
||||
|
|
|
@ -3711,8 +3711,6 @@ do_pointer_plus_expr_check:
|
|||
case VEC_PACK_TRUNC_EXPR:
|
||||
case VEC_PACK_SAT_EXPR:
|
||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
/* FIXME. */
|
||||
return false;
|
||||
|
||||
|
|
|
@ -3399,8 +3399,6 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
|
|||
case VEC_PACK_TRUNC_EXPR:
|
||||
case VEC_PACK_SAT_EXPR:
|
||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
||||
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
||||
|
||||
|
|
|
@ -2388,22 +2388,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
dump_block_node (buffer, node, spc, flags);
|
||||
break;
|
||||
|
||||
case VEC_EXTRACT_EVEN_EXPR:
|
||||
pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
|
||||
pp_string (buffer, ", ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
|
||||
pp_string (buffer, " > ");
|
||||
break;
|
||||
|
||||
case VEC_EXTRACT_ODD_EXPR:
|
||||
pp_string (buffer, " VEC_EXTRACT_ODD_EXPR < ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
|
||||
pp_string (buffer, ", ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
|
||||
pp_string (buffer, " > ");
|
||||
break;
|
||||
|
||||
default:
|
||||
NIY;
|
||||
}
|
||||
|
|
|
@ -3794,15 +3794,13 @@ vect_create_destination_var (tree scalar_dest, tree vectype)
|
|||
|
||||
/* Function vect_strided_store_supported.
|
||||
|
||||
Returns TRUE is INTERLEAVE_HIGH and INTERLEAVE_LOW operations are supported,
|
||||
and FALSE otherwise. */
|
||||
Returns TRUE if interleave high and interleave low permutations
|
||||
are supported, and FALSE otherwise. */
|
||||
|
||||
bool
|
||||
vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
|
||||
mode = TYPE_MODE (vectype);
|
||||
enum machine_mode mode = TYPE_MODE (vectype);
|
||||
|
||||
/* vect_permute_store_chain requires the group size to be a power of two. */
|
||||
if (exact_log2 (count) == -1)
|
||||
|
@ -3813,7 +3811,7 @@ vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Check that the operation is supported. */
|
||||
/* Check that the permutation is supported. */
|
||||
if (VECTOR_MODE_P (mode))
|
||||
{
|
||||
unsigned int i, nelt = GET_MODE_NUNITS (mode);
|
||||
|
@ -3923,11 +3921,9 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
|
|||
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
|
||||
tree perm_mask_low, perm_mask_high;
|
||||
unsigned int i, n;
|
||||
unsigned int j, nelt = GET_MODE_NUNITS (TYPE_MODE (vectype));
|
||||
unsigned int j, nelt = TYPE_VECTOR_SUBPARTS (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, n = nelt / 2; i < n; i++)
|
||||
|
@ -3936,9 +3932,12 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
|
|||
sel[i * 2 + 1] = i + nelt;
|
||||
}
|
||||
perm_mask_high = vect_gen_perm_mask (vectype, sel);
|
||||
gcc_assert (perm_mask_high != NULL);
|
||||
|
||||
for (i = 0; i < nelt; i++)
|
||||
sel[i] += nelt / 2;
|
||||
perm_mask_low = vect_gen_perm_mask (vectype, sel);
|
||||
gcc_assert (perm_mask_low != NULL);
|
||||
|
||||
for (i = 0, n = exact_log2 (length); i < n; i++)
|
||||
{
|
||||
|
@ -4246,16 +4245,13 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
|
|||
|
||||
/* Function vect_strided_load_supported.
|
||||
|
||||
Returns TRUE is EXTRACT_EVEN and EXTRACT_ODD operations are supported,
|
||||
Returns TRUE if even and odd permutations are supported,
|
||||
and FALSE otherwise. */
|
||||
|
||||
bool
|
||||
vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
||||
{
|
||||
optab ee_optab, eo_optab;
|
||||
enum machine_mode mode;
|
||||
|
||||
mode = TYPE_MODE (vectype);
|
||||
enum machine_mode mode = TYPE_MODE (vectype);
|
||||
|
||||
/* vect_permute_load_chain requires the group size to be a power of two. */
|
||||
if (exact_log2 (count) == -1)
|
||||
|
@ -4266,18 +4262,22 @@ vect_strided_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
|||
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;
|
||||
/* Check that the permutation is supported. */
|
||||
if (VECTOR_MODE_P (mode))
|
||||
{
|
||||
unsigned int i, nelt = GET_MODE_NUNITS (mode);
|
||||
unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
|
||||
|
||||
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;
|
||||
for (i = 0; i < nelt; i++)
|
||||
sel[i] = i * 2;
|
||||
if (can_vec_perm_p (mode, false, sel))
|
||||
{
|
||||
for (i = 0; i < nelt; i++)
|
||||
sel[i] = i * 2 + 1;
|
||||
if (can_vec_perm_p (mode, false, sel))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (vect_print_dump_info (REPORT_DETAILS))
|
||||
fprintf (vect_dump, "extract even/odd not supported by target");
|
||||
|
@ -4379,17 +4379,28 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
|
|||
VEC(tree,heap) **result_chain)
|
||||
{
|
||||
tree perm_dest, data_ref, first_vect, second_vect;
|
||||
tree perm_mask_even, perm_mask_odd;
|
||||
gimple perm_stmt;
|
||||
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
|
||||
int i;
|
||||
unsigned int j;
|
||||
|
||||
gcc_assert (vect_strided_load_supported (vectype, length));
|
||||
unsigned int i, j, log_length = exact_log2 (length);
|
||||
unsigned nelt = TYPE_VECTOR_SUBPARTS (vectype);
|
||||
unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
|
||||
|
||||
*result_chain = VEC_copy (tree, heap, dr_chain);
|
||||
for (i = 0; i < exact_log2 (length); i++)
|
||||
|
||||
for (i = 0; i < nelt; ++i)
|
||||
sel[i] = i * 2;
|
||||
perm_mask_even = vect_gen_perm_mask (vectype, sel);
|
||||
gcc_assert (perm_mask_even != NULL);
|
||||
|
||||
for (i = 0; i < nelt; ++i)
|
||||
sel[i] = i * 2 + 1;
|
||||
perm_mask_odd = vect_gen_perm_mask (vectype, sel);
|
||||
gcc_assert (perm_mask_odd != NULL);
|
||||
|
||||
for (i = 0; i < log_length; i++)
|
||||
{
|
||||
for (j = 0; j < length; j +=2)
|
||||
for (j = 0; j < length; j += 2)
|
||||
{
|
||||
first_vect = VEC_index (tree, dr_chain, j);
|
||||
second_vect = VEC_index (tree, dr_chain, j+1);
|
||||
|
@ -4399,9 +4410,9 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
|
|||
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
||||
add_referenced_var (perm_dest);
|
||||
|
||||
perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_EVEN_EXPR,
|
||||
perm_dest, first_vect,
|
||||
second_vect);
|
||||
perm_stmt = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, perm_dest,
|
||||
first_vect, second_vect,
|
||||
perm_mask_even);
|
||||
|
||||
data_ref = make_ssa_name (perm_dest, perm_stmt);
|
||||
gimple_assign_set_lhs (perm_stmt, data_ref);
|
||||
|
@ -4415,9 +4426,10 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
|
|||
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
||||
add_referenced_var (perm_dest);
|
||||
|
||||
perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_ODD_EXPR,
|
||||
perm_dest, first_vect,
|
||||
second_vect);
|
||||
perm_stmt = gimple_build_assign_with_ops3 (VEC_PERM_EXPR, perm_dest,
|
||||
first_vect, second_vect,
|
||||
perm_mask_odd);
|
||||
|
||||
data_ref = make_ssa_name (perm_dest, perm_stmt);
|
||||
gimple_assign_set_lhs (perm_stmt, data_ref);
|
||||
vect_finish_stmt_generation (stmt, perm_stmt, gsi);
|
||||
|
|
|
@ -773,13 +773,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
|
|||
|| code == VIEW_CONVERT_EXPR)
|
||||
return;
|
||||
|
||||
/* These are only created by the vectorizer, after having queried
|
||||
the target support. It's more than just looking at the optab,
|
||||
and there's no need to do it again. */
|
||||
if (code == VEC_EXTRACT_EVEN_EXPR
|
||||
|| code == VEC_EXTRACT_ODD_EXPR)
|
||||
return;
|
||||
|
||||
gcc_assert (code != CONVERT_EXPR);
|
||||
|
||||
/* The signedness is determined from input argument. */
|
||||
|
|
|
@ -4542,8 +4542,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
|||
|
||||
Then permutation statements are generated:
|
||||
|
||||
VS5: vx5 = VEC_EXTRACT_EVEN_EXPR < vx0, vx1 >
|
||||
VS6: vx6 = VEC_EXTRACT_ODD_EXPR < vx0, vx1 >
|
||||
VS5: vx5 = VEC_PERM_EXPR < vx0, vx1, { 0, 2, ..., i*2 } >
|
||||
VS6: vx6 = VEC_PERM_EXPR < vx0, vx1, { 1, 3, ..., i*2+1 } >
|
||||
...
|
||||
|
||||
And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
|
||||
|
|
|
@ -1188,10 +1188,6 @@ DEFTREECODE (VEC_PACK_SAT_EXPR, "vec_pack_sat_expr", tcc_binary, 2)
|
|||
the output vector. */
|
||||
DEFTREECODE (VEC_PACK_FIX_TRUNC_EXPR, "vec_pack_fix_trunc_expr", tcc_binary, 2)
|
||||
|
||||
/* Extract even/odd fields from vectors. */
|
||||
DEFTREECODE (VEC_EXTRACT_EVEN_EXPR, "vec_extract_even_expr", tcc_binary, 2)
|
||||
DEFTREECODE (VEC_EXTRACT_ODD_EXPR, "vec_extract_odd_expr", tcc_binary, 2)
|
||||
|
||||
/* Widening vector shift left in bits.
|
||||
Operand 0 is a vector to be shifted with N elements of size S.
|
||||
Operand 1 is an integer shift amount in bits.
|
||||
|
|
Loading…
Add table
Reference in a new issue