tree-cfg.c (verify_gimple_assign_unary): Allow vector conversions.

2011-10-30  Dmitry Plotnikov  <dplotnikov@ispras.ru>

        * tree-cfg.c (verify_gimple_assign_unary): Allow vector conversions.
        * optabs.c (supportable_convert_operation): New function.
        * optabs.h (supportable_convert_operation): New prototype.
        * tree-vect-stmts.c (vectorizable_conversion): Change condition and
        behavior for NONE modifier case.
        * tree.h (VECTOR_INTEGER_TYPE_P): New macro.

From-SVN: r180684
This commit is contained in:
Dmitry Plotnikov 2011-10-30 17:12:02 +00:00 committed by Richard Henderson
parent 9814fdd618
commit 9db8f45d5d
6 changed files with 104 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2011-10-30 Dmitry Plotnikov <dplotnikov@ispras.ru>
* tree-cfg.c (verify_gimple_assign_unary): Allow vector conversions.
* optabs.c (supportable_convert_operation): New function.
* optabs.h (supportable_convert_operation): New prototype.
* tree-vect-stmts.c (vectorizable_conversion): Change condition and
behavior for NONE modifier case.
* tree.h (VECTOR_INTEGER_TYPE_P): New macro.
2011-10-30 Jakub Jelinek <jakub@redhat.com> 2011-10-30 Jakub Jelinek <jakub@redhat.com>
* tree-vectorizer.h (NUM_PATTERNS): Bump to 9. * tree-vectorizer.h (NUM_PATTERNS): Bump to 9.

View File

@ -4824,6 +4824,60 @@ can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
tab = unsignedp ? ufloat_optab : sfloat_optab; tab = unsignedp ? ufloat_optab : sfloat_optab;
return convert_optab_handler (tab, fltmode, fixmode); return convert_optab_handler (tab, fltmode, fixmode);
} }
/* Function supportable_convert_operation
Check whether an operation represented by the code CODE is a
convert operation that is supported by the target platform in
vector form (i.e., when operating on arguments of type VECTYPE_IN
producing a result of type VECTYPE_OUT).
Convert operations we currently support directly are FIX_TRUNC and FLOAT.
This function checks if these operations are supported
by the target platform either directly (via vector tree-codes), or via
target builtins.
Output:
- CODE1 is code of vector operation to be used when
vectorizing the operation, if available.
- DECL is decl of target builtin functions to be used
when vectorizing the operation, if available. In this case,
CODE1 is CALL_EXPR. */
bool
supportable_convert_operation (enum tree_code code,
tree vectype_out, tree vectype_in,
tree *decl, enum tree_code *code1)
{
enum machine_mode m1,m2;
int truncp;
m1 = TYPE_MODE (vectype_out);
m2 = TYPE_MODE (vectype_in);
/* First check if we can done conversion directly. */
if ((code == FIX_TRUNC_EXPR
&& can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)
!= CODE_FOR_nothing)
|| (code == FLOAT_EXPR
&& can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in))
!= CODE_FOR_nothing))
{
*code1 = code;
return true;
}
/* Now check for builtin. */
if (targetm.vectorize.builtin_conversion
&& targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
{
*code1 = CALL_EXPR;
*decl = targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in);
return true;
}
return false;
}
/* Generate code to convert FROM to floating point /* Generate code to convert FROM to floating point
and store in TO. FROM must be fixed point and not VOIDmode. and store in TO. FROM must be fixed point and not VOIDmode.

View File

@ -883,6 +883,12 @@ extern void expand_float (rtx, rtx, int);
/* Return the insn_code for a FLOAT_EXPR. */ /* Return the insn_code for a FLOAT_EXPR. */
enum insn_code can_float_p (enum machine_mode, enum machine_mode, int); enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
/* Check whether an operation represented by the code CODE is a
convert operation that is supported by the target platform in
vector form */
bool supportable_convert_operation (enum tree_code, tree, tree, tree *,
enum tree_code *);
/* Generate code for a FIX_EXPR. */ /* Generate code for a FIX_EXPR. */
extern void expand_fix (rtx, rtx, int); extern void expand_fix (rtx, rtx, int);

View File

@ -3342,7 +3342,9 @@ verify_gimple_assign_unary (gimple stmt)
case FLOAT_EXPR: case FLOAT_EXPR:
{ {
if (!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type)) if ((!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type))
&& (!VECTOR_INTEGER_TYPE_P (rhs1_type)
|| !VECTOR_FLOAT_TYPE_P(lhs_type)))
{ {
error ("invalid types in conversion to floating point"); error ("invalid types in conversion to floating point");
debug_generic_expr (lhs_type); debug_generic_expr (lhs_type);
@ -3355,7 +3357,9 @@ verify_gimple_assign_unary (gimple stmt)
case FIX_TRUNC_EXPR: case FIX_TRUNC_EXPR:
{ {
if (!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type)) if ((!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type))
&& (!VECTOR_INTEGER_TYPE_P (lhs_type)
|| !VECTOR_FLOAT_TYPE_P(rhs1_type)))
{ {
error ("invalid types in conversion to integer"); error ("invalid types in conversion to integer");
debug_generic_expr (lhs_type); debug_generic_expr (lhs_type);

View File

@ -1824,7 +1824,6 @@ vect_gen_widened_results_half (enum tree_code code,
return new_stmt; return new_stmt;
} }
/* Check if STMT performs a conversion operation, that can be vectorized. /* Check if STMT performs a conversion operation, that can be vectorized.
If VEC_STMT is also passed, vectorize the STMT: create a vectorized If VEC_STMT is also passed, vectorize the STMT: create a vectorized
stmt to replace it, put it in VEC_STMT, and insert it at BSI. stmt to replace it, put it in VEC_STMT, and insert it at BSI.
@ -1853,7 +1852,6 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
tree vectype_out, vectype_in; tree vectype_out, vectype_in;
int ncopies, j; int ncopies, j;
tree rhs_type; tree rhs_type;
tree builtin_decl;
enum { NARROW, NONE, WIDEN } modifier; enum { NARROW, NONE, WIDEN } modifier;
int i; int i;
VEC(tree,heap) *vec_oprnds0 = NULL; VEC(tree,heap) *vec_oprnds0 = NULL;
@ -1942,7 +1940,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
/* Supportable by target? */ /* Supportable by target? */
if ((modifier == NONE if ((modifier == NONE
&& !targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in)) && !supportable_convert_operation (code, vectype_out, vectype_in, &decl1, &code1))
|| (modifier == WIDEN || (modifier == WIDEN
&& !supportable_widening_operation (code, stmt, && !supportable_widening_operation (code, stmt,
vectype_out, vectype_in, vectype_out, vectype_in,
@ -1992,19 +1990,28 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
else else
vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL); vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
builtin_decl =
targetm.vectorize.builtin_conversion (code,
vectype_out, vectype_in);
FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0) FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
{ {
/* Arguments are ready. create the new vector stmt. */ /* Arguments are ready, create the new vector stmt. */
new_stmt = gimple_build_call (builtin_decl, 1, vop0); if (code1 == CALL_EXPR)
new_temp = make_ssa_name (vec_dest, new_stmt); {
gimple_call_set_lhs (new_stmt, new_temp); new_stmt = gimple_build_call (decl1, 1, vop0);
vect_finish_stmt_generation (stmt, new_stmt, gsi); new_temp = make_ssa_name (vec_dest, new_stmt);
if (slp_node) gimple_call_set_lhs (new_stmt, new_temp);
VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt); }
} else
{
gcc_assert (TREE_CODE_LENGTH (code) == unary_op);
new_stmt = gimple_build_assign_with_ops (code, vec_dest, vop0,
NULL);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_assign_set_lhs (new_stmt, new_temp);
}
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (slp_node)
VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
}
if (j == 0) if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;

View File

@ -1120,6 +1120,13 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(TREE_CODE (TYPE) == COMPLEX_TYPE \ (TREE_CODE (TYPE) == COMPLEX_TYPE \
&& TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE) && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE)
/* Nonzero if TYPE represents a vector integer type. */
#define VECTOR_INTEGER_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == VECTOR_TYPE \
&& TREE_CODE (TREE_TYPE (TYPE)) == INTEGER_TYPE)
/* Nonzero if TYPE represents a vector floating-point type. */ /* Nonzero if TYPE represents a vector floating-point type. */
#define VECTOR_FLOAT_TYPE_P(TYPE) \ #define VECTOR_FLOAT_TYPE_P(TYPE) \