Commit 9db8f45d by Dmitry Plotnikov Committed by Richard Henderson

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
parent 9814fdd6
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.
...@@ -4824,6 +4824,60 @@ can_float_p (enum machine_mode fltmode, enum machine_mode fixmode, ...@@ -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.
......
...@@ -883,6 +883,12 @@ extern void expand_float (rtx, rtx, int); ...@@ -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);
......
...@@ -3342,7 +3342,9 @@ verify_gimple_assign_unary (gimple stmt) ...@@ -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) ...@@ -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);
......
...@@ -1824,7 +1824,6 @@ vect_gen_widened_results_half (enum tree_code code, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
......
...@@ -1120,6 +1120,13 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, ...@@ -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) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment