From b423d9f78ad53c62f3566a6c2f48fa1234d9189f Mon Sep 17 00:00:00 2001 From: rth Date: Sun, 30 Oct 2011 17:12:02 +0000 Subject: [PATCH] 2011-10-30 Dmitry Plotnikov * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180684 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/optabs.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/optabs.h | 6 ++++++ gcc/tree-cfg.c | 8 ++++++-- gcc/tree-vect-stmts.c | 37 +++++++++++++++++++++-------------- gcc/tree.h | 7 +++++++ 6 files changed, 104 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c089100b689..155625c9da2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-10-30 Dmitry Plotnikov + + * 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 * tree-vectorizer.h (NUM_PATTERNS): Bump to 9. diff --git a/gcc/optabs.c b/gcc/optabs.c index 736d8264cf1..f07381cf836 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4824,6 +4824,60 @@ can_float_p (enum machine_mode fltmode, enum machine_mode fixmode, tab = unsignedp ? ufloat_optab : sfloat_optab; 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 and store in TO. FROM must be fixed point and not VOIDmode. diff --git a/gcc/optabs.h b/gcc/optabs.h index 057f6533ad1..8357a298618 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -883,6 +883,12 @@ extern void expand_float (rtx, rtx, int); /* Return the insn_code for a FLOAT_EXPR. */ 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. */ extern void expand_fix (rtx, rtx, int); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index a8409db5982..2819e7b2fc6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3342,7 +3342,9 @@ verify_gimple_assign_unary (gimple stmt) 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"); debug_generic_expr (lhs_type); @@ -3355,7 +3357,9 @@ verify_gimple_assign_unary (gimple stmt) 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"); debug_generic_expr (lhs_type); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index dc81acb77e6..08abd23c0a1 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1824,7 +1824,6 @@ vect_gen_widened_results_half (enum tree_code code, return new_stmt; } - /* Check if STMT performs a conversion operation, that can be 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. @@ -1853,7 +1852,6 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, tree vectype_out, vectype_in; int ncopies, j; tree rhs_type; - tree builtin_decl; enum { NARROW, NONE, WIDEN } modifier; int i; VEC(tree,heap) *vec_oprnds0 = NULL; @@ -1942,7 +1940,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, /* Supportable by target? */ if ((modifier == NONE - && !targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in)) + && !supportable_convert_operation (code, vectype_out, vectype_in, &decl1, &code1)) || (modifier == WIDEN && !supportable_widening_operation (code, stmt, vectype_out, vectype_in, @@ -1992,19 +1990,28 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, else 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) - { - /* Arguments are ready. create the new vector stmt. */ - new_stmt = gimple_build_call (builtin_decl, 1, vop0); - 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); - if (slp_node) - VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt); - } + { + /* Arguments are ready, create the new vector stmt. */ + if (code1 == CALL_EXPR) + { + new_stmt = gimple_build_call (decl1, 1, vop0); + new_temp = make_ssa_name (vec_dest, new_stmt); + gimple_call_set_lhs (new_stmt, new_temp); + } + 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) STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; diff --git a/gcc/tree.h b/gcc/tree.h index 64ccdb03417..4f9970b3c8c 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1120,6 +1120,13 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, (TREE_CODE (TYPE) == COMPLEX_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. */ #define VECTOR_FLOAT_TYPE_P(TYPE) \ -- 2.11.0