On Fri, May 27, 2016 at 11:09 AM, Alan Hayward <alan.hayw...@arm.com> wrote: > This patch is a reworking of the previous vectorize inductions that are > live > after the loop patch. > It now supports SLP and an optimisation has been moved to patch [3/3]. > > > Stmts which are live (ie: defined inside a loop and then used after the > loop) > are not currently supported by the vectorizer. In many cases > vectorization can > still occur because the SCEV cprop pass will hoist the definition of the > stmt > outside of the loop before the vectorizor pass. However, there are various > cases SCEV cprop cannot hoist, for example: > for (i = 0; i < n; ++i) > { > ret = x[i]; > x[i] = i; > } > return i; > > Currently stmts are marked live using a bool, and the relevant state using > an > enum. Both these states are propagated to the definition of all uses of the > stmt. Also, a stmt can be live but not relevant. > > This patch vectorizes a live stmt definition normally within the loop and > then > after the loop uses BIT_FIELD_REF to extract the final scalar value from > the > vector. > > This patch adds a new relevant state (vect_used_only_live) for when a stmt > is > used only outside the loop. The relevant state is still propagated to all > it's > uses, but the live bool is not (this ensures that > vectorizable_live_operation > is only called with stmts that really are live). > > Tested on x86 and aarch64.
+ /* If STMT is a simple assignment and its inputs are invariant, then it can + remain in place, unvectorized. The original last scalar value that it + computes will be used. */ + if (is_simple_and_all_uses_invariant (stmt, loop_vinfo)) { so we can't use STMT_VINFO_RELEVANT or so? I thought we somehow mark stmts we don't vectorize in the end. + lhs = (is_a <gphi *> (stmt)) ? gimple_phi_result (stmt) + : gimple_get_lhs (stmt); + lhs_type = TREE_TYPE (lhs); + + /* Find all uses of STMT outside the loop. */ + auto_vec<gimple *, 4> worklist; + FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) + { + basic_block bb = gimple_bb (use_stmt); + + if (!flow_bb_inside_loop_p (loop, bb)) + worklist.safe_push (use_stmt); } + gcc_assert (!worklist.is_empty ()); as we are in loop-closed SSA there should be exactly one such use...? + /* Get the correct slp vectorized stmt. */ + vec_oprnds.create (num_vec); + vect_get_slp_vect_defs (slp_node, &vec_oprnds); As you look at the vectorized stmt you can directly use the SLP_TREE_VEC_STMTS array (the stmts lhs, of course), no need to export this function. The rest of the changes look ok to me. Thanks, Richard. > gcc/ > * tree-vect-loop.c (vect_analyze_loop_operations): Allow live > stmts. > (vectorizable_reduction): Check for new relevant state. > (vectorizable_live_operation): vectorize live stmts using > BIT_FIELD_REF. Remove special case for gimple assigns stmts. > * tree-vect-stmts.c (is_simple_and_all_uses_invariant): New > function. > (vect_stmt_relevant_p): Check for stmts which are only used live. > (process_use): Use of a stmt does not inherit it's live value. > (vect_mark_stmts_to_be_vectorized): Simplify relevance inheritance. > (vect_analyze_stmt): Check for new relevant state. > *tree-vect-slp.c (vect_get_slp_vect_defs): Make global > *tree-vectorizer.h (vect_relevant): New entry for a stmt which is > used > outside the loop, but not inside it. > > testsuite/ > * gcc.dg/tree-ssa/pr64183.c: Ensure test does not vectorize. > * testsuite/gcc.dg/vect/no-scevccp-vect-iv-2.c: Remove xfail. > * gcc.dg/vect/vect-live-1.c: New test. > * gcc.dg/vect/vect-live-2.c: New test. > * gcc.dg/vect/vect-live-3.c: New test. > * gcc.dg/vect/vect-live-4.c: New test. > * gcc.dg/vect/vect-live-5.c: New test. > * gcc.dg/vect/vect-live-slp-1.c: New test. > * gcc.dg/vect/vect-live-slp-2.c: New test. > * gcc.dg/vect/vect-live-slp-3.c: New test. > * gcc.dg/vect/vect-live-slp-4.c: New test. > > > > Alan. >