summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-30 17:12:02 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-30 17:12:02 +0000
commitb423d9f78ad53c62f3566a6c2f48fa1234d9189f (patch)
treee44c3a45aa245b7294a083e14b64e2518eec620f
parent356f20e4ff489391c56c817acf45ae695983751a (diff)
downloadgcc-b423d9f78ad53c62f3566a6c2f48fa1234d9189f.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180684 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/optabs.c54
-rw-r--r--gcc/optabs.h6
-rw-r--r--gcc/tree-cfg.c8
-rw-r--r--gcc/tree-vect-stmts.c37
-rw-r--r--gcc/tree.h7
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 <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>
* 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) \