Message ID | 201204301619.q3UGJjkf025077@d06av02.portsmouth.uk.ibm.com |
---|---|
State | New |
Headers | show |
On Mon, Apr 30, 2012 at 6:19 PM, Ulrich Weigand <uweigand@de.ibm.com> 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 > Ulrich.Weigand@de.ibm.com >
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);