On Mon, 27 Nov 2023, Tamar Christina wrote:
> Ping
>
> > -----Original Message-----
> > From: Tamar Christina <[email protected]>
> > Sent: Monday, November 6, 2023 7:40 AM
> > To: [email protected]
> > Cc: nd <[email protected]>; [email protected]; [email protected]
> > Subject: [PATCH 10/21]middle-end: implement relevancy analysis support for
> > control flow
> >
> > Hi All,
> >
> > This updates relevancy analysis to support marking gcond's belonging to
> > early
> > breaks as relevant for vectorization.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> > * tree-vect-stmts.cc (vect_stmt_relevant_p,
> > vect_mark_stmts_to_be_vectorized, vect_analyze_stmt,
> > vect_is_simple_use,
> > vect_get_vector_types_for_stmt): Support early breaks.
> >
> > --- inline copy of patch --
> > diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index
> > 4809b822632279493a843d402a833c9267bb315e..31474e923cc3feb2604
> > ca2882ecfb300cd211679 100644
> > --- a/gcc/tree-vect-stmts.cc
> > +++ b/gcc/tree-vect-stmts.cc
> > @@ -359,9 +359,14 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info,
> > loop_vec_info loop_vinfo,
> > *live_p = false;
> >
> > /* cond stmt other than loop exit cond. */
> > - if (is_ctrl_stmt (stmt_info->stmt)
> > - && STMT_VINFO_TYPE (stmt_info) != loop_exit_ctrl_vec_info_type)
> > - *relevant = vect_used_in_scope;
> > + gimple *stmt = STMT_VINFO_STMT (stmt_info);
> > + if (is_ctrl_stmt (stmt) && is_a <gcond *> (stmt))
is_ctrl_stmt (stmt) is redundant
> > + {
> > + gcond *cond = as_a <gcond *> (stmt);
in total better written as
if (gcond *cond = dyn_cast <gcond *> (stmt))
{
> > + if (LOOP_VINFO_LOOP_CONDS (loop_vinfo).contains (cond)
linear search ...
> > + && LOOP_VINFO_LOOP_IV_COND (loop_vinfo) != cond)
> > + *relevant = vect_used_in_scope;
but why not simply mark all gconds as vect_used_in_scope?
> > + }
> >
> > /* changing memory. */
> > if (gimple_code (stmt_info->stmt) != GIMPLE_PHI) @@ -374,6 +379,11 @@
> > vect_stmt_relevant_p (stmt_vec_info stmt_info, loop_vec_info loop_vinfo,
> > *relevant = vect_used_in_scope;
> > }
> >
> > + auto_vec<edge> exits = get_loop_exit_edges (loop); auto_bitmap
> > + exit_bbs; for (edge exit : exits)
is it your mail client messing patches up? missing line-break
again.
> > + bitmap_set_bit (exit_bbs, exit->dest->index);
> > +
you don't seem to use the bitmap?
> > /* uses outside the loop. */
> > FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt_info->stmt, op_iter,
> > SSA_OP_DEF)
> > {
> > @@ -392,7 +402,6 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info,
> > loop_vec_info loop_vinfo,
> > /* We expect all such uses to be in the loop exit phis
> > (because of loop closed form) */
> > gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI);
> > - gcc_assert (bb == single_exit (loop)->dest);
> >
> > *live_p = true;
> > }
> > @@ -793,6 +802,20 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info
> > loop_vinfo, bool *fatal)
> > return res;
> > }
> > }
> > + }
> > + else if (gcond *cond = dyn_cast <gcond *> (stmt_vinfo->stmt))
> > + {
> > + enum tree_code rhs_code = gimple_cond_code (cond);
> > + gcc_assert (TREE_CODE_CLASS (rhs_code) == tcc_comparison);
> > + opt_result res
> > + = process_use (stmt_vinfo, gimple_cond_lhs (cond),
> > + loop_vinfo, relevant, &worklist, false);
> > + if (!res)
> > + return res;
> > + res = process_use (stmt_vinfo, gimple_cond_rhs (cond),
> > + loop_vinfo, relevant, &worklist, false);
> > + if (!res)
> > + return res;
> > }
I guess we're missing an
else
gcc_unreachable ();
to catch not handled stmt kinds (do we have gcond patterns yet?)
> > else if (gcall *call = dyn_cast <gcall *> (stmt_vinfo->stmt))
> > {
> > @@ -13043,11 +13066,15 @@ vect_analyze_stmt (vec_info *vinfo,
> > node_instance, cost_vec);
> > if (!res)
> > return res;
> > - }
> > + }
> > +
> > + if (is_ctrl_stmt (stmt_info->stmt))
> > + STMT_VINFO_DEF_TYPE (stmt_info) = vect_early_exit_def;
I think it should rather be vect_condition_def. It's also not
this functions business to set STMT_VINFO_DEF_TYPE. If we ever
get to handle not if-converted code (or BB vectorization of that)
then a gcond would define the mask stmts are under.
> > switch (STMT_VINFO_DEF_TYPE (stmt_info))
> > {
> > case vect_internal_def:
> > + case vect_early_exit_def:
> > break;
> >
> > case vect_reduction_def:
> > @@ -13080,6 +13107,7 @@ vect_analyze_stmt (vec_info *vinfo,
> > {
> > gcall *call = dyn_cast <gcall *> (stmt_info->stmt);
> > gcc_assert (STMT_VINFO_VECTYPE (stmt_info)
> > + || gimple_code (stmt_info->stmt) == GIMPLE_COND
> > || (call && gimple_call_lhs (call) == NULL_TREE));
> > *need_to_vectorize = true;
> > }
> > @@ -13835,6 +13863,14 @@ vect_is_simple_use (vec_info *vinfo,
> > stmt_vec_info stmt, slp_tree slp_node,
> > else
> > *op = gimple_op (ass, operand + 1);
> > }
> > + else if (gcond *cond = dyn_cast <gcond *> (stmt->stmt))
> > + {
> > + gimple_match_op m_op;
> > + if (!gimple_extract_op (cond, &m_op))
> > + return false;
> > + gcc_assert (m_op.code.is_tree_code ());
> > + *op = m_op.ops[operand];
> > + }
Please do not use gimple_extract_op, use
*op = gimple_op (cond, operand);
> > else if (gcall *call = dyn_cast <gcall *> (stmt->stmt))
> > *op = gimple_call_arg (call, operand);
> > else
> > @@ -14445,6 +14481,8 @@ vect_get_vector_types_for_stmt (vec_info
> > *vinfo, stmt_vec_info stmt_info,
> > *nunits_vectype_out = NULL_TREE;
> >
> > if (gimple_get_lhs (stmt) == NULL_TREE
> > + /* Allow vector conditionals through here. */
> > + && !is_ctrl_stmt (stmt)
!is_a <gcond *> (stmt)
> > /* MASK_STORE has no lhs, but is ok. */
> > && !gimple_call_internal_p (stmt, IFN_MASK_STORE))
> > {
> > @@ -14461,7 +14499,7 @@ vect_get_vector_types_for_stmt (vec_info
> > *vinfo, stmt_vec_info stmt_info,
> > }
> >
> > return opt_result::failure_at (stmt,
> > - "not vectorized: irregular stmt.%G", stmt);
> > + "not vectorized: irregular stmt: %G",
> > stmt);
> > }
> >
> > tree vectype;
> > @@ -14490,6 +14528,14 @@ vect_get_vector_types_for_stmt (vec_info
> > *vinfo, stmt_vec_info stmt_info,
> > scalar_type = TREE_TYPE (DR_REF (dr));
> > else if (gimple_call_internal_p (stmt, IFN_MASK_STORE))
> > scalar_type = TREE_TYPE (gimple_call_arg (stmt, 3));
> > + else if (is_ctrl_stmt (stmt))
else if (gcond *cond = dyn_cast <...>)
> > + {
> > + gcond *cond = dyn_cast <gcond *> (stmt);
> > + if (!cond)
> > + return opt_result::failure_at (stmt, "not vectorized: unsupported"
> > + " control flow statement.\n");
> > + scalar_type = TREE_TYPE (gimple_cond_rhs (stmt));
As said in the other patch STMT_VINFO_VECTYPE of the gcond should
be the _mask_ type the compare produces, not the vector type of
the inputs (the nunits_vectype might be that one though).
You possibly need to adjust vect_get_smallest_scalar_type for this.
Richard.
> > + }
> > else
> > scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
> >
> >
> >
> >
> >
> > --
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)