On 27/05/2016 12:41, "Richard Biener" <richard.guent...@gmail.com> wrote:

>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.

It’s probably worth making clear that this check exists in the current
GCC head - today vectorize_live_operation only supports the
simple+invariant
case and the SSE2 case.
My patch simply moved the simple+invariant code into the new function
is_simple_and_all_uses_invariant.

Looking at this again, I think what we really care about is….
*If the stmt is live but not relevant, we need to mark it to ensure it is
vectorised.
*If a stmt is simple+invariant then a live usage of it can either use the
scalar or vectorized version.

So for a live stmt:
*If it is simple+invariant and not relevant, then it is more optimal to
use the
scalar version.
*If it is simple+invariant and relevant then it is more optimal to use the
vectorized version.
*If it is not simple+invariant then we must always use the vectorized
version.

Therefore, the patch as it stands is correct but not optimal. In patch 3/3
for
the code above (vectorize_live_operation) I can change the check to if not
relevant then assert that it is not simple+invariant and return true.



>
>+  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...?

Yes, I should change this to assert that worklist is of length 1.

>
>+      /* 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.

Ok, I can change this.

>
>The rest of the changes look ok to me.

Does that include PATCH 1/3  ?

>
>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.
>>
>


Reply via email to