On Fri, May 27, 2016 at 11:09 AM, Alan Hayward <[email protected]> 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.
>