From fef96d8e2a370e826acdf914d51c88aa2657340a Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 31 Jul 2018 14:22:01 +0000 Subject: [PATCH] [11/46] Pass back a stmt_vec_info from vect_is_simple_use This patch makes vect_is_simple_use pass back a stmt_vec_info to those callers that want it. Most users only need the stmt_vec_info but some need the gimple stmt too. It's probably high time we added a class to represent "simple operands" instead, but I have a separate series that tries to clean up how operands are handled (with a view to allowing mixed vector sizes). 2018-07-31 Richard Sandiford gcc/ * tree-vectorizer.h (vect_is_simple_use): Add an optional stmt_vec_info * parameter before the optional gimple **. * tree-vect-stmts.c (vect_is_simple_use): Likewise. (process_use, vect_get_vec_def_for_operand_1): Update callers. (vect_get_vec_def_for_operand, vectorizable_shift): Likewise. * tree-vect-loop.c (vectorizable_reduction): Likewise. (vectorizable_live_operation): Likewise. * tree-vect-patterns.c (type_conversion_p): Likewise. (vect_look_through_possible_promotion): Likewise. (vect_recog_rotate_pattern): Likewise. * tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise. From-SVN: r263126 --- gcc/ChangeLog | 14 ++++++++ gcc/tree-vect-loop.c | 26 +++++++-------- gcc/tree-vect-patterns.c | 30 +++++++++-------- gcc/tree-vect-slp.c | 21 ++++++------ gcc/tree-vect-stmts.c | 69 ++++++++++++++++++++-------------------- gcc/tree-vectorizer.h | 5 +-- 6 files changed, 90 insertions(+), 75 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5695829357..873b298d314 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-07-31 Richard Sandiford + + * tree-vectorizer.h (vect_is_simple_use): Add an optional + stmt_vec_info * parameter before the optional gimple **. + * tree-vect-stmts.c (vect_is_simple_use): Likewise. + (process_use, vect_get_vec_def_for_operand_1): Update callers. + (vect_get_vec_def_for_operand, vectorizable_shift): Likewise. + * tree-vect-loop.c (vectorizable_reduction): Likewise. + (vectorizable_live_operation): Likewise. + * tree-vect-patterns.c (type_conversion_p): Likewise. + (vect_look_through_possible_promotion): Likewise. + (vect_recog_rotate_pattern): Likewise. + * tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise. + 2018-07-31 Richard Sandiford * tree-vectorizer.h (stmt_vec_info): Temporarily change from diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index e451cbcff8d..1f8847f529f 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6090,7 +6090,6 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, int op_type; optab optab; tree new_temp = NULL_TREE; - gimple *def_stmt; enum vect_def_type dt, cond_reduc_dt = vect_unknown_def_type; gimple *cond_reduc_def_stmt = NULL; enum tree_code cond_reduc_op_code = ERROR_MARK; @@ -6324,13 +6323,14 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, if (i == 0 && code == COND_EXPR) continue; - is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, - &dts[i], &tem, &def_stmt); + stmt_vec_info def_stmt_info; + is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &dts[i], &tem, + &def_stmt_info); dt = dts[i]; gcc_assert (is_simple_use); if (dt == vect_reduction_def) { - reduc_def_stmt = def_stmt; + reduc_def_stmt = def_stmt_info; reduc_index = i; continue; } @@ -6352,11 +6352,11 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, return false; if (dt == vect_nested_cycle) - { - found_nested_cycle_def = true; - reduc_def_stmt = def_stmt; - reduc_index = i; - } + { + found_nested_cycle_def = true; + reduc_def_stmt = def_stmt_info; + reduc_index = i; + } if (i == 1 && code == COND_EXPR) { @@ -6367,11 +6367,11 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, cond_reduc_val = ops[i]; } if (dt == vect_induction_def - && def_stmt != NULL - && is_nonwrapping_integer_induction (def_stmt, loop)) + && def_stmt_info + && is_nonwrapping_integer_induction (def_stmt_info, loop)) { cond_reduc_dt = dt; - cond_reduc_def_stmt = def_stmt; + cond_reduc_def_stmt = def_stmt_info; } } } @@ -7958,7 +7958,7 @@ vectorizable_live_operation (gimple *stmt, else { enum vect_def_type dt = STMT_VINFO_DEF_TYPE (stmt_info); - vec_lhs = vect_get_vec_def_for_operand_1 (stmt, dt); + vec_lhs = vect_get_vec_def_for_operand_1 (stmt_info, dt); gcc_checking_assert (ncopies == 1 || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)); diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index f4174e46bbc..4ac8f9b4b39 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -250,7 +250,9 @@ type_conversion_p (tree name, gimple *use_stmt, bool check_sign, enum vect_def_type dt; stmt_vinfo = vinfo_for_stmt (use_stmt); - if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, def_stmt)) + stmt_vec_info def_stmt_info; + if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, &def_stmt_info, + def_stmt)) return false; if (dt != vect_internal_def @@ -371,9 +373,10 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op, while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type)) { /* See whether OP is simple enough to vectorize. */ + stmt_vec_info def_stmt_info; gimple *def_stmt; vect_def_type dt; - if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt)) + if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, &def_stmt)) break; /* If OP is the input of a demotion, skip over it to see whether @@ -407,17 +410,15 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op, the cast is potentially vectorizable. */ if (!def_stmt) break; - if (dt == vect_internal_def) - { - caster = vinfo_for_stmt (def_stmt); - /* Ignore pattern statements, since we don't link uses for them. */ - if (single_use_p - && !STMT_VINFO_RELATED_STMT (caster) - && !has_single_use (res)) - *single_use_p = false; - } - else - caster = NULL; + caster = def_stmt_info; + + /* Ignore pattern statements, since we don't link uses for them. */ + if (caster + && single_use_p + && !STMT_VINFO_RELATED_STMT (caster) + && !has_single_use (res)) + *single_use_p = false; + gassign *assign = dyn_cast (def_stmt); if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))) break; @@ -1988,7 +1989,8 @@ vect_recog_rotate_pattern (stmt_vec_info stmt_vinfo, tree *type_out) || !TYPE_UNSIGNED (type)) return NULL; - if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt)) + stmt_vec_info def_stmt_info; + if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt_info, &def_stmt)) return NULL; if (dt != vect_internal_def diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 883de92b26c..fbb419f3ee8 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -303,7 +303,6 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char *swap, gimple *stmt = stmts[stmt_num]; tree oprnd; unsigned int i, number_of_oprnds; - gimple *def_stmt; enum vect_def_type dt = vect_uninitialized_def; bool pattern = false; slp_oprnd_info oprnd_info; @@ -357,7 +356,8 @@ again: oprnd_info = (*oprnds_info)[i]; - if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt)) + stmt_vec_info def_stmt_info; + if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info)) { if (dump_enabled_p ()) { @@ -370,13 +370,10 @@ again: return -1; } - /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt - from the pattern. Check that all the stmts of the node are in the - pattern. */ - if (def_stmt && gimple_bb (def_stmt) - && vect_stmt_in_region_p (vinfo, def_stmt) - && vinfo_for_stmt (def_stmt) - && is_pattern_stmt_p (vinfo_for_stmt (def_stmt))) + /* Check if DEF_STMT_INFO is a part of a pattern in LOOP and get + the def stmt from the pattern. Check that all the stmts of the + node are in the pattern. */ + if (def_stmt_info && is_pattern_stmt_p (def_stmt_info)) { pattern = true; if (!first && !oprnd_info->first_pattern @@ -405,7 +402,7 @@ again: return 1; } - dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); + dt = STMT_VINFO_DEF_TYPE (def_stmt_info); if (dt == vect_unknown_def_type) { @@ -415,7 +412,7 @@ again: return -1; } - switch (gimple_code (def_stmt)) + switch (gimple_code (def_stmt_info->stmt)) { case GIMPLE_PHI: case GIMPLE_ASSIGN: @@ -499,7 +496,7 @@ again: case vect_reduction_def: case vect_induction_def: case vect_internal_def: - oprnd_info->def_stmts.quick_push (def_stmt); + oprnd_info->def_stmts.quick_push (def_stmt_info); break; default: diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 629e2055498..c5524dd82f3 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -459,11 +459,9 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, enum vect_relevant relevant, vec *worklist, bool force) { - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); stmt_vec_info dstmt_vinfo; basic_block bb, def_bb; - gimple *def_stmt; enum vect_def_type dt; /* case 1: we are only interested in uses that need to be vectorized. Uses @@ -471,7 +469,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, if (!force && !exist_non_indexing_operands_for_use_p (use, stmt)) return true; - if (!vect_is_simple_use (use, loop_vinfo, &dt, &def_stmt)) + if (!vect_is_simple_use (use, loop_vinfo, &dt, &dstmt_vinfo)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -479,27 +477,20 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, return false; } - if (!def_stmt || gimple_nop_p (def_stmt)) + if (!dstmt_vinfo) return true; - def_bb = gimple_bb (def_stmt); - if (!flow_bb_inside_loop_p (loop, def_bb)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n"); - return true; - } + def_bb = gimple_bb (dstmt_vinfo->stmt); - /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT). - DEF_STMT must have already been processed, because this should be the + /* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO). + DSTMT_VINFO must have already been processed, because this should be the only way that STMT, which is a reduction-phi, was put in the worklist, - as there should be no other uses for DEF_STMT in the loop. So we just + as there should be no other uses for DSTMT_VINFO in the loop. So we just check that everything is as expected, and we are done. */ - dstmt_vinfo = vinfo_for_stmt (def_stmt); bb = gimple_bb (stmt); if (gimple_code (stmt) == GIMPLE_PHI && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def - && gimple_code (def_stmt) != GIMPLE_PHI + && gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def && bb->loop_father == def_bb->loop_father) { @@ -514,7 +505,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, /* case 3a: outer-loop stmt defining an inner-loop stmt: outer-loop-header-bb: - d = def_stmt + d = dstmt_vinfo inner-loop: stmt # use (d) outer-loop-tail-bb: @@ -554,7 +545,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, outer-loop-header-bb: ... inner-loop: - d = def_stmt + d = dstmt_vinfo outer-loop-tail-bb (or outer-loop-exit-bb in double reduction): stmt # use (d) */ else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father)) @@ -601,7 +592,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, } - vect_mark_relevant (worklist, def_stmt, relevant, false); + vect_mark_relevant (worklist, dstmt_vinfo, relevant, false); return true; } @@ -1563,7 +1554,9 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype) dump_printf (MSG_NOTE, "\n"); } - is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, &def_stmt); + stmt_vec_info def_stmt_info; + is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, + &def_stmt_info, &def_stmt); gcc_assert (is_simple_use); if (def_stmt && dump_enabled_p ()) { @@ -1588,7 +1581,7 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree vectype) return vect_init_vector (stmt, op, vector_type, NULL); } else - return vect_get_vec_def_for_operand_1 (def_stmt, dt); + return vect_get_vec_def_for_operand_1 (def_stmt_info, dt); } @@ -5479,7 +5472,9 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, return false; op1 = gimple_assign_rhs2 (stmt); - if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype)) + stmt_vec_info op1_def_stmt_info; + if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype, + &op1_def_stmt_info)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -5524,12 +5519,8 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, /* If the shift amount is computed by a pattern stmt we cannot use the scalar amount directly thus give up and use a vector shift. */ - if (dt[1] == vect_internal_def) - { - gimple *def = SSA_NAME_DEF_STMT (op1); - if (is_pattern_stmt_p (vinfo_for_stmt (def))) - scalar_shift_arg = false; - } + if (op1_def_stmt_info && is_pattern_stmt_p (op1_def_stmt_info)) + scalar_shift_arg = false; } else { @@ -10051,7 +10042,10 @@ get_same_sized_vectype (tree scalar_type, tree vector_type) VINFO - the vect info of the loop or basic block that is being vectorized. OPERAND - operand in the loop or bb. Output: - DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME. + DEF_STMT_INFO_OUT (optional) - information about the defining stmt in + case OPERAND is an SSA_NAME that is defined in the vectorizable region + DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME; + the definition could be anywhere in the function DT - the type of definition Returns whether a stmt with OPERAND can be vectorized. @@ -10064,8 +10058,10 @@ get_same_sized_vectype (tree scalar_type, tree vector_type) bool vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, - gimple **def_stmt_out) + stmt_vec_info *def_stmt_info_out, gimple **def_stmt_out) { + if (def_stmt_info_out) + *def_stmt_info_out = NULL; if (def_stmt_out) *def_stmt_out = NULL; *dt = vect_unknown_def_type; @@ -10113,6 +10109,8 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, *dt = vect_unknown_def_type; break; } + if (def_stmt_info_out) + *def_stmt_info_out = stmt_vinfo; } if (def_stmt_out) *def_stmt_out = def_stmt; @@ -10175,14 +10173,18 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, bool vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, - tree *vectype, gimple **def_stmt_out) + tree *vectype, stmt_vec_info *def_stmt_info_out, + gimple **def_stmt_out) { + stmt_vec_info def_stmt_info; gimple *def_stmt; - if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt)) + if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt_info, &def_stmt)) return false; if (def_stmt_out) *def_stmt_out = def_stmt; + if (def_stmt_info_out) + *def_stmt_info_out = def_stmt_info; /* Now get a vector type if the def is internal, otherwise supply NULL_TREE and leave it up to the caller to figure out a proper @@ -10193,8 +10195,7 @@ vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt, || *dt == vect_double_reduction_def || *dt == vect_nested_cycle) { - stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt); - *vectype = STMT_VINFO_VECTYPE (stmt_info); + *vectype = STMT_VINFO_VECTYPE (def_stmt_info); gcc_assert (*vectype != NULL_TREE); if (dump_enabled_p ()) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 31d2db4d8c5..e302d3524a2 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1532,9 +1532,10 @@ extern tree get_mask_type_for_scalar_type (tree); extern tree get_same_sized_vectype (tree, tree); extern bool vect_get_loop_mask_type (loop_vec_info); extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, - gimple ** = NULL); + stmt_vec_info * = NULL, gimple ** = NULL); extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, - tree *, gimple ** = NULL); + tree *, stmt_vec_info * = NULL, + gimple ** = NULL); extern bool supportable_widening_operation (enum tree_code, gimple *, tree, tree, enum tree_code *, enum tree_code *, int *, -- 2.30.2