mirror of git://gcc.gnu.org/git/gcc.git
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. From-SVN: r182663
This commit is contained in:
parent
7dab511cf3
commit
3fcc1b5520
|
@ -1,3 +1,40 @@
|
||||||
|
2011-12-23 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2011-12-23 Richard Henderson <rth@redhat.com>
|
2011-12-23 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* config/mips/loongson.md (UNSPEC_LOONGSON_PINSR_0,
|
* config/mips/loongson.md (UNSPEC_LOONGSON_PINSR_0,
|
||||||
|
@ -329,7 +366,7 @@
|
||||||
|
|
||||||
PR target/49865
|
PR target/49865
|
||||||
* ira-costs.c (find_costs_and_classes): Prefer registers even
|
* ira-costs.c (find_costs_and_classes): Prefer registers even
|
||||||
if the memory cost is the same.
|
if the memory cost is the same.
|
||||||
|
|
||||||
2011-12-20 Joseph Myers <joseph@codesourcery.com>
|
2011-12-20 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
|
|
@ -3451,8 +3451,6 @@ expand_debug_expr (tree exp)
|
||||||
case VEC_COND_EXPR:
|
case VEC_COND_EXPR:
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
case VEC_LSHIFT_EXPR:
|
case VEC_LSHIFT_EXPR:
|
||||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||||
case VEC_PACK_SAT_EXPR:
|
case VEC_PACK_SAT_EXPR:
|
||||||
|
|
|
@ -36021,6 +36021,8 @@ expand_vec_perm_palignr (struct expand_vec_perm_d *d)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool expand_vec_perm_interleave3 (struct expand_vec_perm_d *d);
|
||||||
|
|
||||||
/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
|
/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
|
||||||
a two vector permutation into a single vector permutation by using
|
a two vector permutation into a single vector permutation by using
|
||||||
an interleave operation to merge the vectors. */
|
an interleave operation to merge the vectors. */
|
||||||
|
@ -36047,6 +36049,17 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
|
||||||
/* For 32-byte modes allow even d->op0 == d->op1.
|
/* For 32-byte modes allow even d->op0 == d->op1.
|
||||||
The lack of cross-lane shuffling in some instructions
|
The lack of cross-lane shuffling in some instructions
|
||||||
might prevent a single insn shuffle. */
|
might prevent a single insn shuffle. */
|
||||||
|
dfinal = *d;
|
||||||
|
dfinal.testing_p = true;
|
||||||
|
/* If expand_vec_perm_interleave3 can expand this into
|
||||||
|
a 3 insn sequence, give up and let it be expanded as
|
||||||
|
3 insn sequence. While that is one insn longer,
|
||||||
|
it doesn't need a memory operand and in the common
|
||||||
|
case that both interleave low and high permutations
|
||||||
|
with the same operands are adjacent needs 4 insns
|
||||||
|
for both after CSE. */
|
||||||
|
if (expand_vec_perm_interleave3 (&dfinal))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -36886,18 +36899,23 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
|
||||||
stopping once we have promoted to V4SImode and then use pshufd. */
|
stopping once we have promoted to V4SImode and then use pshufd. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
optab otab = vec_interleave_low_optab;
|
rtx dest;
|
||||||
|
rtx (*gen) (rtx, rtx, rtx)
|
||||||
|
= vmode == V16QImode ? gen_vec_interleave_lowv16qi
|
||||||
|
: gen_vec_interleave_lowv8hi;
|
||||||
|
|
||||||
if (elt >= nelt2)
|
if (elt >= nelt2)
|
||||||
{
|
{
|
||||||
otab = vec_interleave_high_optab;
|
gen = vmode == V16QImode ? gen_vec_interleave_highv16qi
|
||||||
|
: gen_vec_interleave_highv8hi;
|
||||||
elt -= nelt2;
|
elt -= nelt2;
|
||||||
}
|
}
|
||||||
nelt2 /= 2;
|
nelt2 /= 2;
|
||||||
|
|
||||||
op0 = expand_binop (vmode, otab, op0, op0, NULL, 0, OPTAB_DIRECT);
|
dest = gen_reg_rtx (vmode);
|
||||||
|
emit_insn (gen (dest, op0, op0));
|
||||||
vmode = get_mode_wider_vector (vmode);
|
vmode = get_mode_wider_vector (vmode);
|
||||||
op0 = gen_lowpart (vmode, op0);
|
op0 = gen_lowpart (vmode, dest);
|
||||||
}
|
}
|
||||||
while (vmode != V4SImode);
|
while (vmode != V4SImode);
|
||||||
|
|
||||||
|
|
|
@ -1697,8 +1697,6 @@ its sole argument yields the representation for @code{ap}.
|
||||||
@tindex VEC_PACK_FIX_TRUNC_EXPR
|
@tindex VEC_PACK_FIX_TRUNC_EXPR
|
||||||
@tindex VEC_EXTRACT_EVEN_EXPR
|
@tindex VEC_EXTRACT_EVEN_EXPR
|
||||||
@tindex VEC_EXTRACT_ODD_EXPR
|
@tindex VEC_EXTRACT_ODD_EXPR
|
||||||
@tindex VEC_INTERLEAVE_HIGH_EXPR
|
|
||||||
@tindex VEC_INTERLEAVE_LOW_EXPR
|
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item VEC_LSHIFT_EXPR
|
@item VEC_LSHIFT_EXPR
|
||||||
|
@ -1774,17 +1772,6 @@ These nodes represent extracting of the even/odd elements of the two input
|
||||||
vectors, respectively. Their operands and result are vectors that contain the
|
vectors, respectively. Their operands and result are vectors that contain the
|
||||||
same number of elements of the same type.
|
same number of elements of the same type.
|
||||||
|
|
||||||
@item VEC_INTERLEAVE_HIGH_EXPR
|
|
||||||
@itemx VEC_INTERLEAVE_LOW_EXPR
|
|
||||||
These nodes represent merging and interleaving of the high/low elements of the
|
|
||||||
two input vectors, respectively. The operands and the result are vectors that
|
|
||||||
contain the same number of elements (@code{N}) of the same type.
|
|
||||||
In the case of @code{VEC_INTERLEAVE_HIGH_EXPR}, the high @code{N/2} elements of
|
|
||||||
the first input vector are interleaved with the high @code{N/2} elements of the
|
|
||||||
second input vector. In the case of @code{VEC_INTERLEAVE_LOW_EXPR}, the low
|
|
||||||
@code{N/2} elements of the first input vector are interleaved with the low
|
|
||||||
@code{N/2} elements of the second input vector.
|
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4159,20 +4159,6 @@ 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.
|
1 in their original order. The result is stored in operand 0.
|
||||||
The output and input vectors should have the same modes.
|
The output and input vectors should have the same modes.
|
||||||
|
|
||||||
@cindex @code{vec_interleave_high@var{m}} instruction pattern
|
|
||||||
@item @samp{vec_interleave_high@var{m}}
|
|
||||||
Merge high elements of the two input vectors into the output vector. The output
|
|
||||||
and input vectors should have the same modes (@code{N} elements). The high
|
|
||||||
@code{N/2} elements of the first input vector are interleaved with the high
|
|
||||||
@code{N/2} elements of the second input vector.
|
|
||||||
|
|
||||||
@cindex @code{vec_interleave_low@var{m}} instruction pattern
|
|
||||||
@item @samp{vec_interleave_low@var{m}}
|
|
||||||
Merge low elements of the two input vectors into the output vector. The output
|
|
||||||
and input vectors should have the same modes (@code{N} elements). The low
|
|
||||||
@code{N/2} elements of the first input vector are interleaved with the low
|
|
||||||
@code{N/2} elements of the second input vector.
|
|
||||||
|
|
||||||
@cindex @code{vec_init@var{m}} instruction pattern
|
@cindex @code{vec_init@var{m}} instruction pattern
|
||||||
@item @samp{vec_init@var{m}}
|
@item @samp{vec_init@var{m}}
|
||||||
Initialize the vector to given values. Operand 0 is the vector to initialize
|
Initialize the vector to given values. Operand 0 is the vector to initialize
|
||||||
|
|
|
@ -8649,8 +8649,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
||||||
|
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
goto binop;
|
goto binop;
|
||||||
|
|
||||||
case VEC_LSHIFT_EXPR:
|
case VEC_LSHIFT_EXPR:
|
||||||
|
|
|
@ -13503,8 +13503,6 @@ fold_binary_loc (location_t loc,
|
||||||
|
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
if ((TREE_CODE (arg0) == VECTOR_CST
|
if ((TREE_CODE (arg0) == VECTOR_CST
|
||||||
|| TREE_CODE (arg0) == CONSTRUCTOR)
|
|| TREE_CODE (arg0) == CONSTRUCTOR)
|
||||||
&& (TREE_CODE (arg1) == VECTOR_CST
|
&& (TREE_CODE (arg1) == VECTOR_CST
|
||||||
|
@ -13522,14 +13520,6 @@ fold_binary_loc (location_t loc,
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
sel[i] = i * 2 + 1;
|
sel[i] = i * 2 + 1;
|
||||||
break;
|
break;
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
sel[i] = (i + (BYTES_BIG_ENDIAN ? 0 : nelts)) / 2
|
|
||||||
+ ((i & 1) ? nelts : 0);
|
|
||||||
break;
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
sel[i] = (i + (BYTES_BIG_ENDIAN ? nelts : 0)) / 2
|
|
||||||
+ ((i & 1) ? nelts : 0);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Generate code to initialize optabs from machine description.
|
/* Generate code to initialize optabs from machine description.
|
||||||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
|
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
@ -269,8 +269,6 @@ static const char * const optabs[] =
|
||||||
"set_optab_handler (vec_extract_optab, $A, CODE_FOR_$(vec_extract$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_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_extract_odd_optab, $A, CODE_FOR_$(vec_extract_odd$a$))",
|
||||||
"set_optab_handler (vec_interleave_high_optab, $A, CODE_FOR_$(vec_interleave_high$a$))",
|
|
||||||
"set_optab_handler (vec_interleave_low_optab, $A, CODE_FOR_$(vec_interleave_low$a$))",
|
|
||||||
"set_optab_handler (vec_init_optab, $A, CODE_FOR_$(vec_init$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_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))",
|
||||||
"set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
|
"set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
|
||||||
|
|
|
@ -347,8 +347,6 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
|
||||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
||||||
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
||||||
for (p = tree_code_name [(int) code]; *p; p++)
|
for (p = tree_code_name [(int) code]; *p; p++)
|
||||||
|
|
28
gcc/optabs.c
28
gcc/optabs.c
|
@ -553,12 +553,6 @@ optab_for_tree_code (enum tree_code code, const_tree type,
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
return vec_extract_odd_optab;
|
return vec_extract_odd_optab;
|
||||||
|
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
return vec_interleave_high_optab;
|
|
||||||
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
return vec_interleave_low_optab;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1612,11 +1606,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
|
||||||
enum tree_code tcode = ERROR_MARK;
|
enum tree_code tcode = ERROR_MARK;
|
||||||
rtx sel;
|
rtx sel;
|
||||||
|
|
||||||
if (binoptab == vec_interleave_high_optab)
|
if (binoptab == vec_extract_even_optab)
|
||||||
tcode = VEC_INTERLEAVE_HIGH_EXPR;
|
|
||||||
else if (binoptab == vec_interleave_low_optab)
|
|
||||||
tcode = VEC_INTERLEAVE_LOW_EXPR;
|
|
||||||
else if (binoptab == vec_extract_even_optab)
|
|
||||||
tcode = VEC_EXTRACT_EVEN_EXPR;
|
tcode = VEC_EXTRACT_EVEN_EXPR;
|
||||||
else if (binoptab == vec_extract_odd_optab)
|
else if (binoptab == vec_extract_odd_optab)
|
||||||
tcode = VEC_EXTRACT_ODD_EXPR;
|
tcode = VEC_EXTRACT_ODD_EXPR;
|
||||||
|
@ -6271,8 +6261,6 @@ init_optabs (void)
|
||||||
init_optab (vec_extract_optab, UNKNOWN);
|
init_optab (vec_extract_optab, UNKNOWN);
|
||||||
init_optab (vec_extract_even_optab, UNKNOWN);
|
init_optab (vec_extract_even_optab, UNKNOWN);
|
||||||
init_optab (vec_extract_odd_optab, UNKNOWN);
|
init_optab (vec_extract_odd_optab, UNKNOWN);
|
||||||
init_optab (vec_interleave_high_optab, UNKNOWN);
|
|
||||||
init_optab (vec_interleave_low_optab, UNKNOWN);
|
|
||||||
init_optab (vec_set_optab, UNKNOWN);
|
init_optab (vec_set_optab, UNKNOWN);
|
||||||
init_optab (vec_init_optab, UNKNOWN);
|
init_optab (vec_init_optab, UNKNOWN);
|
||||||
init_optab (vec_shl_optab, UNKNOWN);
|
init_optab (vec_shl_optab, UNKNOWN);
|
||||||
|
@ -6880,8 +6868,7 @@ can_vec_perm_p (enum machine_mode mode, bool variable,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if we can implement VEC_INTERLEAVE_{HIGH,LOW}_EXPR or
|
/* Return true if we can implement with VEC_PERM_EXPR for this target.
|
||||||
VEC_EXTRACT_{EVEN,ODD}_EXPR with VEC_PERM_EXPR for this target.
|
|
||||||
If PSEL is non-null, return the selector for the permutation. */
|
If PSEL is non-null, return the selector for the permutation. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -6931,17 +6918,6 @@ can_vec_perm_for_code_p (enum tree_code code, enum machine_mode mode,
|
||||||
data[i] = i * 2 + alt;
|
data[i] = i * 2 + alt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
if ((BYTES_BIG_ENDIAN != 0) ^ (code == VEC_INTERLEAVE_HIGH_EXPR))
|
|
||||||
alt = nelt / 2;
|
|
||||||
for (i = 0; i < nelt / 2; ++i)
|
|
||||||
{
|
|
||||||
data[i * 2] = i + alt;
|
|
||||||
data[i * 2 + 1] = i + nelt + alt;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,9 +335,6 @@ enum optab_index
|
||||||
/* Extract even/odd fields of vector operands. */
|
/* Extract even/odd fields of vector operands. */
|
||||||
OTI_vec_extract_even,
|
OTI_vec_extract_even,
|
||||||
OTI_vec_extract_odd,
|
OTI_vec_extract_odd,
|
||||||
/* Interleave fields of vector operands. */
|
|
||||||
OTI_vec_interleave_high,
|
|
||||||
OTI_vec_interleave_low,
|
|
||||||
/* Initialize vector operand. */
|
/* Initialize vector operand. */
|
||||||
OTI_vec_init,
|
OTI_vec_init,
|
||||||
/* Whole vector shift. The shift amount is in bits. */
|
/* Whole vector shift. The shift amount is in bits. */
|
||||||
|
@ -564,8 +561,6 @@ enum optab_index
|
||||||
#define vec_extract_optab (&optab_table[OTI_vec_extract])
|
#define vec_extract_optab (&optab_table[OTI_vec_extract])
|
||||||
#define vec_extract_even_optab (&optab_table[OTI_vec_extract_even])
|
#define vec_extract_even_optab (&optab_table[OTI_vec_extract_even])
|
||||||
#define vec_extract_odd_optab (&optab_table[OTI_vec_extract_odd])
|
#define vec_extract_odd_optab (&optab_table[OTI_vec_extract_odd])
|
||||||
#define vec_interleave_high_optab (&optab_table[OTI_vec_interleave_high])
|
|
||||||
#define vec_interleave_low_optab (&optab_table[OTI_vec_interleave_low])
|
|
||||||
#define vec_init_optab (&optab_table[OTI_vec_init])
|
#define vec_init_optab (&optab_table[OTI_vec_init])
|
||||||
#define vec_shl_optab (&optab_table[OTI_vec_shl])
|
#define vec_shl_optab (&optab_table[OTI_vec_shl])
|
||||||
#define vec_shr_optab (&optab_table[OTI_vec_shr])
|
#define vec_shr_optab (&optab_table[OTI_vec_shr])
|
||||||
|
|
|
@ -3713,8 +3713,6 @@ do_pointer_plus_expr_check:
|
||||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
/* FIXME. */
|
/* FIXME. */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -3401,8 +3401,6 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
|
||||||
case VEC_PACK_FIX_TRUNC_EXPR:
|
case VEC_PACK_FIX_TRUNC_EXPR:
|
||||||
case VEC_EXTRACT_EVEN_EXPR:
|
case VEC_EXTRACT_EVEN_EXPR:
|
||||||
case VEC_EXTRACT_ODD_EXPR:
|
case VEC_EXTRACT_ODD_EXPR:
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
case VEC_INTERLEAVE_LOW_EXPR:
|
|
||||||
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
||||||
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
||||||
|
|
||||||
|
|
|
@ -2404,22 +2404,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
||||||
pp_string (buffer, " > ");
|
pp_string (buffer, " > ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VEC_INTERLEAVE_HIGH_EXPR:
|
|
||||||
pp_string (buffer, " VEC_INTERLEAVE_HIGH_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_INTERLEAVE_LOW_EXPR:
|
|
||||||
pp_string (buffer, " VEC_INTERLEAVE_LOW_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:
|
default:
|
||||||
NIY;
|
NIY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3800,7 +3800,6 @@ vect_create_destination_var (tree scalar_dest, tree vectype)
|
||||||
bool
|
bool
|
||||||
vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
vect_strided_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
|
||||||
{
|
{
|
||||||
optab ih_optab, il_optab;
|
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
|
|
||||||
mode = TYPE_MODE (vectype);
|
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. */
|
/* Check that the operation is supported. */
|
||||||
ih_optab = optab_for_tree_code (VEC_INTERLEAVE_HIGH_EXPR,
|
if (VECTOR_MODE_P (mode))
|
||||||
vectype, optab_default);
|
{
|
||||||
il_optab = optab_for_tree_code (VEC_INTERLEAVE_LOW_EXPR,
|
unsigned int i, nelt = GET_MODE_NUNITS (mode);
|
||||||
vectype, optab_default);
|
unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
|
||||||
if (il_optab && ih_optab
|
for (i = 0; i < nelt / 2; i++)
|
||||||
&& optab_handler (ih_optab, mode) != CODE_FOR_nothing
|
{
|
||||||
&& optab_handler (il_optab, mode) != CODE_FOR_nothing)
|
sel[i * 2] = i;
|
||||||
return true;
|
sel[i * 2 + 1] = i + nelt;
|
||||||
|
}
|
||||||
if (can_vec_perm_for_code_p (VEC_INTERLEAVE_HIGH_EXPR, mode, NULL)
|
if (can_vec_perm_p (mode, false, sel))
|
||||||
&& can_vec_perm_for_code_p (VEC_INTERLEAVE_LOW_EXPR, mode, NULL))
|
{
|
||||||
return true;
|
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))
|
if (vect_print_dump_info (REPORT_DETAILS))
|
||||||
fprintf (vect_dump, "interleave op not supported by target.");
|
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;
|
tree perm_dest, vect1, vect2, high, low;
|
||||||
gimple perm_stmt;
|
gimple perm_stmt;
|
||||||
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
|
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
|
||||||
int i;
|
tree perm_mask_low, perm_mask_high;
|
||||||
unsigned int j;
|
unsigned int i, n;
|
||||||
enum tree_code high_code, low_code;
|
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));
|
gcc_assert (vect_strided_store_supported (vectype, length));
|
||||||
|
|
||||||
*result_chain = VEC_copy (tree, heap, dr_chain);
|
*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++)
|
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);
|
vect2 = VEC_index (tree, dr_chain, j+length/2);
|
||||||
|
|
||||||
/* Create interleaving stmt:
|
/* Create interleaving stmt:
|
||||||
in the case of big endian:
|
high = VEC_PERM_EXPR <vect1, vect2, {0, nelt, 1, nelt+1, ...}> */
|
||||||
high = interleave_high (vect1, vect2)
|
|
||||||
and in the case of little endian:
|
|
||||||
high = interleave_low (vect1, vect2). */
|
|
||||||
perm_dest = create_tmp_var (vectype, "vect_inter_high");
|
perm_dest = create_tmp_var (vectype, "vect_inter_high");
|
||||||
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
||||||
add_referenced_var (perm_dest);
|
add_referenced_var (perm_dest);
|
||||||
if (BYTES_BIG_ENDIAN)
|
high = make_ssa_name (perm_dest, NULL);
|
||||||
{
|
perm_stmt
|
||||||
high_code = VEC_INTERLEAVE_HIGH_EXPR;
|
= gimple_build_assign_with_ops3 (VEC_PERM_EXPR, high,
|
||||||
low_code = VEC_INTERLEAVE_LOW_EXPR;
|
vect1, vect2, perm_mask_high);
|
||||||
}
|
|
||||||
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);
|
|
||||||
vect_finish_stmt_generation (stmt, perm_stmt, gsi);
|
vect_finish_stmt_generation (stmt, perm_stmt, gsi);
|
||||||
VEC_replace (tree, *result_chain, 2*j, high);
|
VEC_replace (tree, *result_chain, 2*j, high);
|
||||||
|
|
||||||
/* Create interleaving stmt:
|
/* Create interleaving stmt:
|
||||||
in the case of big endian:
|
low = VEC_PERM_EXPR <vect1, vect2, {nelt/2, nelt*3/2, nelt/2+1,
|
||||||
low = interleave_low (vect1, vect2)
|
nelt*3/2+1, ...}> */
|
||||||
and in the case of little endian:
|
|
||||||
low = interleave_high (vect1, vect2). */
|
|
||||||
perm_dest = create_tmp_var (vectype, "vect_inter_low");
|
perm_dest = create_tmp_var (vectype, "vect_inter_low");
|
||||||
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
DECL_GIMPLE_REG_P (perm_dest) = 1;
|
||||||
add_referenced_var (perm_dest);
|
add_referenced_var (perm_dest);
|
||||||
perm_stmt = gimple_build_assign_with_ops (low_code, perm_dest,
|
low = make_ssa_name (perm_dest, NULL);
|
||||||
vect1, vect2);
|
perm_stmt
|
||||||
low = make_ssa_name (perm_dest, perm_stmt);
|
= gimple_build_assign_with_ops3 (VEC_PERM_EXPR, low,
|
||||||
gimple_assign_set_lhs (perm_stmt, low);
|
vect1, vect2, perm_mask_low);
|
||||||
vect_finish_stmt_generation (stmt, perm_stmt, gsi);
|
vect_finish_stmt_generation (stmt, perm_stmt, gsi);
|
||||||
VEC_replace (tree, *result_chain, 2*j+1, low);
|
VEC_replace (tree, *result_chain, 2*j+1, low);
|
||||||
}
|
}
|
||||||
|
|
|
@ -776,9 +776,7 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
|
||||||
/* These are only created by the vectorizer, after having queried
|
/* These are only created by the vectorizer, after having queried
|
||||||
the target support. It's more than just looking at the optab,
|
the target support. It's more than just looking at the optab,
|
||||||
and there's no need to do it again. */
|
and there's no need to do it again. */
|
||||||
if (code == VEC_INTERLEAVE_HIGH_EXPR
|
if (code == VEC_EXTRACT_EVEN_EXPR
|
||||||
|| code == VEC_INTERLEAVE_LOW_EXPR
|
|
||||||
|| code == VEC_EXTRACT_EVEN_EXPR
|
|
||||||
|| code == VEC_EXTRACT_ODD_EXPR)
|
|| code == VEC_EXTRACT_ODD_EXPR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -3828,8 +3828,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||||
|
|
||||||
Then permutation statements are generated:
|
Then permutation statements are generated:
|
||||||
|
|
||||||
VS5: vx5 = VEC_INTERLEAVE_HIGH_EXPR < vx0, vx3 >
|
VS5: vx5 = VEC_PERM_EXPR < vx0, vx3, {0, 8, 1, 9, 2, 10, 3, 11} >
|
||||||
VS6: vx6 = VEC_INTERLEAVE_LOW_EXPR < vx0, vx3 >
|
VS6: vx6 = VEC_PERM_EXPR < vx0, vx3, {4, 12, 5, 13, 6, 14, 7, 15} >
|
||||||
...
|
...
|
||||||
|
|
||||||
And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
|
And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
|
||||||
|
@ -4026,8 +4026,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||||
the VECTOR_CST mask that implements the permutation of the
|
the VECTOR_CST mask that implements the permutation of the
|
||||||
vector elements. If that is impossible to do, returns NULL. */
|
vector elements. If that is impossible to do, returns NULL. */
|
||||||
|
|
||||||
static tree
|
tree
|
||||||
gen_perm_mask (tree vectype, unsigned char *sel)
|
vect_gen_perm_mask (tree vectype, unsigned char *sel)
|
||||||
{
|
{
|
||||||
tree mask_elt_type, mask_type, mask_vec;
|
tree mask_elt_type, mask_type, mask_vec;
|
||||||
int i, nunits;
|
int i, nunits;
|
||||||
|
@ -4067,7 +4067,7 @@ perm_mask_for_reverse (tree vectype)
|
||||||
for (i = 0; i < nunits; ++i)
|
for (i = 0; i < nunits; ++i)
|
||||||
sel[i] = nunits - 1 - i;
|
sel[i] = nunits - 1 - i;
|
||||||
|
|
||||||
return gen_perm_mask (vectype, sel);
|
return vect_gen_perm_mask (vectype, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a vector variable X and Y, that was generated for the scalar
|
/* Given a vector variable X and Y, that was generated for the scalar
|
||||||
|
@ -4314,7 +4314,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||||
for (i = 0; i < gather_off_nunits; ++i)
|
for (i = 0; i < gather_off_nunits; ++i)
|
||||||
sel[i] = i | nunits;
|
sel[i] = i | nunits;
|
||||||
|
|
||||||
perm_mask = gen_perm_mask (gather_off_vectype, sel);
|
perm_mask = vect_gen_perm_mask (gather_off_vectype, sel);
|
||||||
gcc_assert (perm_mask != NULL_TREE);
|
gcc_assert (perm_mask != NULL_TREE);
|
||||||
}
|
}
|
||||||
else if (nunits == gather_off_nunits * 2)
|
else if (nunits == gather_off_nunits * 2)
|
||||||
|
@ -4326,7 +4326,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||||
sel[i] = i < gather_off_nunits
|
sel[i] = i < gather_off_nunits
|
||||||
? i : i + nunits - gather_off_nunits;
|
? i : i + nunits - gather_off_nunits;
|
||||||
|
|
||||||
perm_mask = gen_perm_mask (vectype, sel);
|
perm_mask = vect_gen_perm_mask (vectype, sel);
|
||||||
gcc_assert (perm_mask != NULL_TREE);
|
gcc_assert (perm_mask != NULL_TREE);
|
||||||
ncopies *= 2;
|
ncopies *= 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -848,6 +848,7 @@ extern void vect_get_store_cost (struct data_reference *, int, unsigned int *);
|
||||||
extern bool vect_supportable_shift (enum tree_code, tree);
|
extern bool vect_supportable_shift (enum tree_code, tree);
|
||||||
extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **,
|
extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **,
|
||||||
VEC (tree, heap) **, slp_tree, int);
|
VEC (tree, heap) **, slp_tree, int);
|
||||||
|
extern tree vect_gen_perm_mask (tree, unsigned char *);
|
||||||
|
|
||||||
/* In tree-vect-data-refs.c. */
|
/* In tree-vect-data-refs.c. */
|
||||||
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
|
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
|
||||||
|
|
|
@ -1192,10 +1192,6 @@ DEFTREECODE (VEC_PACK_FIX_TRUNC_EXPR, "vec_pack_fix_trunc_expr", tcc_binary, 2)
|
||||||
DEFTREECODE (VEC_EXTRACT_EVEN_EXPR, "vec_extract_even_expr", tcc_binary, 2)
|
DEFTREECODE (VEC_EXTRACT_EVEN_EXPR, "vec_extract_even_expr", tcc_binary, 2)
|
||||||
DEFTREECODE (VEC_EXTRACT_ODD_EXPR, "vec_extract_odd_expr", tcc_binary, 2)
|
DEFTREECODE (VEC_EXTRACT_ODD_EXPR, "vec_extract_odd_expr", tcc_binary, 2)
|
||||||
|
|
||||||
/* Merge input vectors interleaving their fields. */
|
|
||||||
DEFTREECODE (VEC_INTERLEAVE_HIGH_EXPR, "vec_interleave_high_expr", tcc_binary, 2)
|
|
||||||
DEFTREECODE (VEC_INTERLEAVE_LOW_EXPR, "vec_interleave_low_expr", tcc_binary, 2)
|
|
||||||
|
|
||||||
/* Widening vector shift left in bits.
|
/* Widening vector shift left in bits.
|
||||||
Operand 0 is a vector to be shifted with N elements of size S.
|
Operand 0 is a vector to be shifted with N elements of size S.
|
||||||
Operand 1 is an integer shift amount in bits.
|
Operand 1 is an integer shift amount in bits.
|
||||||
|
|
Loading…
Reference in New Issue