On Mon, Apr 30, 2012 at 6:19 PM, Ulrich Weigand <[email protected]> wrote:
> Hello,
>
> as a second step in refactoring this patch introduces a routine
> vect_find_single_use to determine whether a defining statement
> has one single use within the current vectorization domain.
>
> The helper is then called wherever that check is currently
> open-coded. There should be no change in behaviour.
>
> Tested on i386-linux-gnu and arm-linux-gnueabi with no regressions.
>
> OK for mainline?
You can use single_imm_use to avoid the loop and simplify the factored
routine.
Ok with that change.
Thanks,
Richard.
> Bye,
> Ulrich
>
>
> ChangeLog:
>
> * tree-vect-patterns.c (vect_find_single_use): New function.
> (vect_recog_widen_mult_pattern): Use it instead of open-coding loop.
> (vect_recog_over_widening_pattern): Likewise.
> (vect_recog_widen_shift_pattern): Likewise.
>
>
> Index: gcc-head/gcc/tree-vect-patterns.c
> ===================================================================
> --- gcc-head.orig/gcc/tree-vect-patterns.c 2012-04-26 19:46:12.000000000
> +0200
> +++ gcc-head/gcc/tree-vect-patterns.c 2012-04-26 19:46:53.000000000 +0200
> @@ -119,6 +119,33 @@ vect_same_loop_or_bb_p (gimple stmt1, gi
> return true;
> }
>
> +/* If the LHS of DEF_STMT has a single use, and that statement is
> + in the same loop or basic block, return it. */
> +
> +static gimple
> +vect_find_single_use (gimple def_stmt)
> +{
> + tree lhs = gimple_assign_lhs (def_stmt);
> + imm_use_iterator imm_iter;
> + use_operand_p use_p;
> + gimple use_stmt = NULL;
> +
> + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
> + {
> + if (is_gimple_debug (USE_STMT (use_p)))
> + continue;
> +
> + if (use_stmt)
> + return NULL;
> + use_stmt = USE_STMT (use_p);
> +
> + if (!vect_same_loop_or_bb_p (def_stmt, use_stmt))
> + return NULL;
> + }
> +
> + return use_stmt;
> +}
> +
> /* Check whether NAME, an ssa-name used in USE_STMT,
> is a result of a type promotion or demotion, such that:
> DEF_STMT: NAME = NOP (name0)
> @@ -636,31 +663,18 @@ vect_recog_widen_mult_pattern (VEC (gimp
> Use unsigned TYPE as the type for WIDEN_MULT_EXPR. */
> if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (half_type0))
> {
> - tree lhs = gimple_assign_lhs (last_stmt), use_lhs;
> - imm_use_iterator imm_iter;
> - use_operand_p use_p;
> - int nuses = 0;
> - gimple use_stmt = NULL;
> + gimple use_stmt;
> + tree use_lhs;
> tree use_type;
>
> if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (half_type1))
> return NULL;
>
> - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
> - {
> - if (is_gimple_debug (USE_STMT (use_p)))
> - continue;
> - use_stmt = USE_STMT (use_p);
> - nuses++;
> - }
> -
> - if (nuses != 1 || !is_gimple_assign (use_stmt)
> - || gimple_assign_rhs_code (use_stmt) != NOP_EXPR)
> + use_stmt = vect_find_single_use (last_stmt);
> + if (!use_stmt || !is_gimple_assign (use_stmt)
> + || gimple_assign_rhs_code (use_stmt) != NOP_EXPR)
> return NULL;
>
> - if (!vect_same_loop_or_bb_p (last_stmt, use_stmt))
> - return NULL;
> -
> use_lhs = gimple_assign_lhs (use_stmt);
> use_type = TREE_TYPE (use_lhs);
> if (!INTEGRAL_TYPE_P (use_type)
> @@ -1165,10 +1179,7 @@ vect_recog_over_widening_pattern (VEC (g
> {
> gimple stmt = VEC_pop (gimple, *stmts);
> gimple pattern_stmt = NULL, new_def_stmt, prev_stmt = NULL, use_stmt = NULL;
> - tree op0, op1, vectype = NULL_TREE, lhs, use_lhs, use_type;
> - imm_use_iterator imm_iter;
> - use_operand_p use_p;
> - int nuses = 0;
> + tree op0, op1, vectype = NULL_TREE, use_lhs, use_type;
> tree var = NULL_TREE, new_type = NULL_TREE, tmp, new_oprnd;
> bool first;
> tree type = NULL;
> @@ -1192,18 +1203,8 @@ vect_recog_over_widening_pattern (VEC (g
> }
>
> /* STMT can be performed on a smaller type. Check its uses. */
> - lhs = gimple_assign_lhs (stmt);
> - nuses = 0;
> - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
> - {
> - if (is_gimple_debug (USE_STMT (use_p)))
> - continue;
> - use_stmt = USE_STMT (use_p);
> - nuses++;
> - }
> -
> - if (nuses != 1 || !is_gimple_assign (use_stmt)
> - || !vect_same_loop_or_bb_p (stmt, use_stmt))
> + use_stmt = vect_find_single_use (stmt);
> + if (!use_stmt || !is_gimple_assign (use_stmt))
> return NULL;
>
> /* Create pattern statement for STMT. */
> @@ -1454,12 +1455,6 @@ vect_recog_widen_shift_pattern (VEC (gim
> Use unsigned TYPE as the type for WIDEN_LSHIFT_EXPR. */
> if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (half_type0))
> {
> - tree lhs = gimple_assign_lhs (last_stmt), use_lhs;
> - imm_use_iterator imm_iter;
> - use_operand_p use_p;
> - int nuses = 0;
> - tree use_type;
> -
> if (over_widen)
> {
> /* In case of over-widening pattern, S4 should be ORIG_STMT itself.
> @@ -1472,21 +1467,14 @@ vect_recog_widen_shift_pattern (VEC (gim
> }
> else
> {
> - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
> - {
> - if (is_gimple_debug (USE_STMT (use_p)))
> - continue;
> - use_stmt = USE_STMT (use_p);
> - nuses++;
> - }
> + tree use_type;
> + tree use_lhs;
>
> - if (nuses != 1 || !is_gimple_assign (use_stmt)
> + use_stmt = vect_find_single_use (last_stmt);
> + if (!use_stmt || !is_gimple_assign (use_stmt)
> || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)))
> return NULL;
>
> - if (!vect_same_loop_or_bb_p (last_stmt, use_stmt))
> - return NULL;
> -
> use_lhs = gimple_assign_lhs (use_stmt);
> use_type = TREE_TYPE (use_lhs);
>
> --
> Dr. Ulrich Weigand
> GNU Toolchain for Linux on System z and Cell BE
> [email protected]
>