[PATCH] Pattern recognize shifts with different rhs1/rhs2 types
Ira Rosen
ira.rosen@linaro.org
Sun Oct 30 10:18:00 GMT 2011
On 28 October 2011 20:44, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
Hi,
>
> This patch implements what I've talked about, with this we can now
> with -mavx2 as well as -mxop vectorize long long/unsigned long long
> shifts by int or long long/unsigned long long shifts by long long
> (where the FE casts it to int first). Already covered by the *vshift-*
> testcases I've committed recently (eyeballed for -mxop plus link tested,
> for -mavx2 tested on sde).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Thanks,
Ira
>
> 2011-10-28 Jakub Jelinek <jakub@redhat.com>
>
> * tree-vectorizer.h (NUM_PATTERNS): Bump to 9.
> * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern): New
> function.
> (vect_vect_recog_func_ptrs): Add it.
>
> --- gcc/tree-vectorizer.h.jj 2011-10-27 08:42:51.000000000 +0200
> +++ gcc/tree-vectorizer.h 2011-10-28 16:26:30.000000000 +0200
> @@ -902,7 +902,7 @@ extern void vect_slp_transform_bb (basic
> Additional pattern recognition functions can (and will) be added
> in the future. */
> typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *);
> -#define NUM_PATTERNS 8
> +#define NUM_PATTERNS 9
> void vect_pattern_recog (loop_vec_info);
>
> /* In tree-vectorizer.c. */
> --- gcc/tree-vect-patterns.c.jj 2011-10-26 14:19:11.000000000 +0200
> +++ gcc/tree-vect-patterns.c 2011-10-28 17:41:26.000000000 +0200
> @@ -51,6 +51,8 @@ static gimple vect_recog_over_widening_p
> tree *);
> static gimple vect_recog_widen_shift_pattern (VEC (gimple, heap) **,
> tree *, tree *);
> +static gimple vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **,
> + tree *, tree *);
> static gimple vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **,
> tree *, tree *);
> static gimple vect_recog_bool_pattern (VEC (gimple, heap) **, tree *, tree *);
> @@ -61,6 +63,7 @@ static vect_recog_func_ptr vect_vect_rec
> vect_recog_pow_pattern,
> vect_recog_over_widening_pattern,
> vect_recog_widen_shift_pattern,
> + vect_recog_vector_vector_shift_pattern,
> vect_recog_mixed_size_cond_pattern,
> vect_recog_bool_pattern};
>
> @@ -1439,6 +1442,133 @@ vect_recog_widen_shift_pattern (VEC (gim
> return pattern_stmt;
> }
>
> +/* Detect a vector by vector shift pattern that wouldn't be otherwise
> + vectorized:
> +
> + type a_t;
> + TYPE b_T, res_T;
> +
> + S1 a_t = ;
> + S2 b_T = ;
> + S3 res_T = b_T op a_t;
> +
> + where type 'TYPE' is a type with different size than 'type',
> + and op is <<, >> or rotate.
> +
> + Also detect cases:
> +
> + type a_t;
> + TYPE b_T, c_T, res_T;
> +
> + S0 c_T = ;
> + S1 a_t = (type) c_T;
> + S2 b_T = ;
> + S3 res_T = b_T op a_t;
> +
> + Input/Output:
> +
> + * STMTS: Contains a stmt from which the pattern search begins,
> + i.e. the shift/rotate stmt. The original stmt (S3) is replaced
> + with a shift/rotate which has same type on both operands, in the
> + second case just b_T op c_T, in the first case with added cast
> + from a_t to c_T in STMT_VINFO_PATTERN_DEF_STMT.
> +
> + Output:
> +
> + * TYPE_IN: The type of the input arguments to the pattern.
> +
> + * TYPE_OUT: The type of the output of this pattern.
> +
> + * Return value: A new stmt that will be used to replace the shift/rotate
> + S3 stmt. */
> +
> +static gimple
> +vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts,
> + tree *type_in, tree *type_out)
> +{
> + gimple last_stmt = VEC_pop (gimple, *stmts);
> + tree oprnd0, oprnd1, lhs, var;
> + gimple pattern_stmt, def_stmt;
> + enum tree_code rhs_code;
> + stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
> + loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
> + enum vect_def_type dt;
> + tree def;
> +
> + if (!is_gimple_assign (last_stmt))
> + return NULL;
> +
> + rhs_code = gimple_assign_rhs_code (last_stmt);
> + switch (rhs_code)
> + {
> + case LSHIFT_EXPR:
> + case RSHIFT_EXPR:
> + case LROTATE_EXPR:
> + case RROTATE_EXPR:
> + break;
> + default:
> + return NULL;
> + }
> +
> + if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
> + return NULL;
> +
> + lhs = gimple_assign_lhs (last_stmt);
> + oprnd0 = gimple_assign_rhs1 (last_stmt);
> + oprnd1 = gimple_assign_rhs2 (last_stmt);
> + if (TREE_CODE (oprnd0) != SSA_NAME
> + || TREE_CODE (oprnd1) != SSA_NAME
> + || TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1))
> + || TYPE_PRECISION (TREE_TYPE (oprnd1))
> + != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (oprnd1)))
> + || TYPE_PRECISION (TREE_TYPE (lhs))
> + != TYPE_PRECISION (TREE_TYPE (oprnd0)))
> + return NULL;
> +
> + if (!vect_is_simple_use (oprnd1, loop_vinfo, NULL, &def_stmt, &def, &dt))
> + return NULL;
> +
> + if (dt != vect_internal_def)
> + return NULL;
> +
> + *type_in = get_vectype_for_scalar_type (TREE_TYPE (oprnd0));
> + *type_out = *type_in;
> + if (*type_in == NULL_TREE)
> + return NULL;
> +
> + def = NULL_TREE;
> + if (gimple_assign_cast_p (def_stmt))
> + {
> + tree rhs1 = gimple_assign_rhs1 (def_stmt);
> + if (TYPE_MODE (TREE_TYPE (rhs1)) == TYPE_MODE (TREE_TYPE (oprnd0))
> + && TYPE_PRECISION (TREE_TYPE (rhs1))
> + == TYPE_PRECISION (TREE_TYPE (oprnd0)))
> + def = rhs1;
> + }
> +
> + if (def == NULL_TREE)
> + {
> + def = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
> + def_stmt = gimple_build_assign_with_ops (NOP_EXPR, def, oprnd1,
> + NULL_TREE);
> + STMT_VINFO_PATTERN_DEF_STMT (stmt_vinfo) = def_stmt;
> + }
> +
> + /* Pattern detected. */
> + if (vect_print_dump_info (REPORT_DETAILS))
> + fprintf (vect_dump, "vect_recog_vector_vector_shift_pattern: detected: ");
> +
> + /* Pattern supported. Create a stmt to be used to replace the pattern. */
> + var = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
> + pattern_stmt = gimple_build_assign_with_ops (rhs_code, var, oprnd0, def);
> +
> + if (vect_print_dump_info (REPORT_DETAILS))
> + print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
> +
> + VEC_safe_push (gimple, heap, *stmts, last_stmt);
> + return pattern_stmt;
> +}
> +
> /* Function vect_recog_mixed_size_cond_pattern
>
> Try to find the following pattern:
>
> Jakub
>
More information about the Gcc-patches
mailing list