[9/19] AArch64 middle-end: refactor vectorizable_comparison to make the main body re-usable.
Checks
Commit Message
Hi All,
Vectorization of a gcond starts off essentially the same as vectorizing a
comparison witht he only difference being how the operands are extracted.
This refactors vectorable_comparison such that we now have a generic function
that can be used from vectorizable_early_break. The refactoring splits the
gassign checks and actual validation/codegen off to a helper function.
No change in functionality expected.
Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
Ok for master?
Thanks,
Tamar
gcc/ChangeLog:
* tree-vect-stmts.cc (vectorizable_comparison): Refactor, splitting body
to ...
(vectorizable_comparison_1): ...This.
--- inline copy of patch --
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ae24f3e66e63d9bd9763284a47fb2c911335c4c1..f3e33cd4ed125b9564ca81acd197693fc3457c31 100644
--
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ae24f3e66e63d9bd9763284a47fb2c911335c4c1..f3e33cd4ed125b9564ca81acd197693fc3457c31 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -11332,21 +11332,22 @@ vectorizable_condition (vec_info *vinfo,
/* vectorizable_comparison.
- Check if STMT_INFO is comparison expression that can be vectorized.
+/* Helper of vectorizable_comparison.
+
+ Check if STMT_INFO is comparison expression CODE that can be vectorized.
If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
comparison, put it in VEC_STMT, and insert it at GSI.
Return true if STMT_INFO is vectorizable in this way. */
static bool
-vectorizable_comparison (vec_info *vinfo,
- stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
- gimple **vec_stmt,
- slp_tree slp_node, stmt_vector_for_cost *cost_vec)
+vectorizable_comparison_1 (vec_info *vinfo, tree vectype,
+ stmt_vec_info stmt_info, tree_code code,
+ gimple_stmt_iterator *gsi, gimple **vec_stmt,
+ slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{
tree lhs, rhs1, rhs2;
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
- tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree vec_rhs1 = NULL_TREE, vec_rhs2 = NULL_TREE;
tree new_temp;
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
@@ -11354,7 +11355,7 @@ vectorizable_comparison (vec_info *vinfo,
int ndts = 2;
poly_uint64 nunits;
int ncopies;
- enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
+ enum tree_code bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
int i;
bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
vec<tree> vec_oprnds0 = vNULL;
@@ -11377,14 +11378,6 @@ vectorizable_comparison (vec_info *vinfo,
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
- if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
- return false;
-
- gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
- if (!stmt)
- return false;
-
- code = gimple_assign_rhs_code (stmt);
if (TREE_CODE_CLASS (code) != tcc_comparison)
return false;
@@ -11499,7 +11492,6 @@ vectorizable_comparison (vec_info *vinfo,
return false;
}
- STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
vect_model_simple_cost (vinfo, stmt_info,
ncopies * (1 + (bitop2 != NOP_EXPR)),
dts, ndts, slp_node, cost_vec);
@@ -11565,6 +11557,44 @@ vectorizable_comparison (vec_info *vinfo,
return true;
}
+/* vectorizable_comparison.
+
+ Check if STMT_INFO is comparison expression that can be vectorized.
+ If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
+ comparison, put it in VEC_STMT, and insert it at GSI.
+
+ Return true if STMT_INFO is vectorizable in this way. */
+
+static bool
+vectorizable_comparison (vec_info *vinfo,
+ stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
+ gimple **vec_stmt,
+ slp_tree slp_node, stmt_vector_for_cost *cost_vec)
+{
+ bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
+
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
+ return false;
+
+ if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
+ return false;
+
+ gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
+ if (!stmt)
+ return false;
+
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ if (!vectorizable_comparison_1 (vinfo, vectype, stmt_info, code, gsi,
+ vec_stmt, slp_node, cost_vec))
+ return false;
+
+ if (!vec_stmt)
+ STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
+
+ return true;
+}
+
/* If SLP_NODE is nonnull, return true if vectorizable_live_operation
can handle all live statements in the node. Otherwise return true
if STMT_INFO is not live or if vectorizable_live_operation can handle it.
Comments
Adding proper maintainers.
> -----Original Message-----
> From: Tamar Christina <tamar.christina@arm.com>
> Sent: Wednesday, June 28, 2023 2:46 PM
> To: gcc-patches@gcc.gnu.org
> Cc: nd <nd@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>;
> Marcus Shawcroft <Marcus.Shawcroft@arm.com>; Kyrylo Tkachov
> <Kyrylo.Tkachov@arm.com>; Richard Sandiford
> <Richard.Sandiford@arm.com>
> Subject: [PATCH 9/19]AArch64 middle-end: refactor vectorizable_comparison
> to make the main body re-usable.
>
> Hi All,
>
> Vectorization of a gcond starts off essentially the same as vectorizing a
> comparison witht he only difference being how the operands are extracted.
>
> This refactors vectorable_comparison such that we now have a generic
> function that can be used from vectorizable_early_break. The refactoring
> splits the gassign checks and actual validation/codegen off to a helper
> function.
>
> No change in functionality expected.
>
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
>
> Ok for master?
>
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
> * tree-vect-stmts.cc (vectorizable_comparison): Refactor, splitting
> body
> to ...
> (vectorizable_comparison_1): ...This.
>
> --- inline copy of patch --
> diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index
> ae24f3e66e63d9bd9763284a47fb2c911335c4c1..f3e33cd4ed125b9564ca8
> 1acd197693fc3457c31 100644
> --- a/gcc/tree-vect-stmts.cc
> +++ b/gcc/tree-vect-stmts.cc
> @@ -11332,21 +11332,22 @@ vectorizable_condition (vec_info *vinfo,
>
> /* vectorizable_comparison.
>
> - Check if STMT_INFO is comparison expression that can be vectorized.
> +/* Helper of vectorizable_comparison.
> +
> + Check if STMT_INFO is comparison expression CODE that can be vectorized.
> If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
> comparison, put it in VEC_STMT, and insert it at GSI.
>
> Return true if STMT_INFO is vectorizable in this way. */
>
> static bool
> -vectorizable_comparison (vec_info *vinfo,
> - stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
> - gimple **vec_stmt,
> - slp_tree slp_node, stmt_vector_for_cost *cost_vec)
> +vectorizable_comparison_1 (vec_info *vinfo, tree vectype,
> + stmt_vec_info stmt_info, tree_code code,
> + gimple_stmt_iterator *gsi, gimple **vec_stmt,
> + slp_tree slp_node, stmt_vector_for_cost *cost_vec)
> {
> tree lhs, rhs1, rhs2;
> tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
> - tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> tree vec_rhs1 = NULL_TREE, vec_rhs2 = NULL_TREE;
> tree new_temp;
> loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); @@ -11354,7
> +11355,7 @@ vectorizable_comparison (vec_info *vinfo,
> int ndts = 2;
> poly_uint64 nunits;
> int ncopies;
> - enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
> + enum tree_code bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
> int i;
> bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
> vec<tree> vec_oprnds0 = vNULL;
> @@ -11377,14 +11378,6 @@ vectorizable_comparison (vec_info *vinfo,
> ncopies = vect_get_num_copies (loop_vinfo, vectype);
>
> gcc_assert (ncopies >= 1);
> - if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
> - return false;
> -
> - gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
> - if (!stmt)
> - return false;
> -
> - code = gimple_assign_rhs_code (stmt);
>
> if (TREE_CODE_CLASS (code) != tcc_comparison)
> return false;
> @@ -11499,7 +11492,6 @@ vectorizable_comparison (vec_info *vinfo,
> return false;
> }
>
> - STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
> vect_model_simple_cost (vinfo, stmt_info,
> ncopies * (1 + (bitop2 != NOP_EXPR)),
> dts, ndts, slp_node, cost_vec); @@ -11565,6
> +11557,44 @@ vectorizable_comparison (vec_info *vinfo,
> return true;
> }
>
> +/* vectorizable_comparison.
> +
> + Check if STMT_INFO is comparison expression that can be vectorized.
> + If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
> + comparison, put it in VEC_STMT, and insert it at GSI.
> +
> + Return true if STMT_INFO is vectorizable in this way. */
> +
> +static bool
> +vectorizable_comparison (vec_info *vinfo,
> + stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
> + gimple **vec_stmt,
> + slp_tree slp_node, stmt_vector_for_cost *cost_vec) {
> + bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
> +
> + if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
> + return false;
> +
> + if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
> + return false;
> +
> + gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt); if (!stmt)
> + return false;
> +
> + enum tree_code code = gimple_assign_rhs_code (stmt);
> + tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> + if (!vectorizable_comparison_1 (vinfo, vectype, stmt_info, code, gsi,
> + vec_stmt, slp_node, cost_vec))
> + return false;
> +
> + if (!vec_stmt)
> + STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
> +
> + return true;
> +}
> +
> /* If SLP_NODE is nonnull, return true if vectorizable_live_operation
> can handle all live statements in the node. Otherwise return true
> if STMT_INFO is not live or if vectorizable_live_operation can handle it.
>
>
>
>
> --
On Wed, 28 Jun 2023, Tamar Christina wrote:
> Adding proper maintainers.
>
> > -----Original Message-----
> > From: Tamar Christina <tamar.christina@arm.com>
> > Sent: Wednesday, June 28, 2023 2:46 PM
> > To: gcc-patches@gcc.gnu.org
> > Cc: nd <nd@arm.com>; Richard Earnshaw <Richard.Earnshaw@arm.com>;
> > Marcus Shawcroft <Marcus.Shawcroft@arm.com>; Kyrylo Tkachov
> > <Kyrylo.Tkachov@arm.com>; Richard Sandiford
> > <Richard.Sandiford@arm.com>
> > Subject: [PATCH 9/19]AArch64 middle-end: refactor vectorizable_comparison
> > to make the main body re-usable.
> >
> > Hi All,
> >
> > Vectorization of a gcond starts off essentially the same as vectorizing a
> > comparison witht he only difference being how the operands are extracted.
> >
> > This refactors vectorable_comparison such that we now have a generic
> > function that can be used from vectorizable_early_break. The refactoring
> > splits the gassign checks and actual validation/codegen off to a helper
> > function.
> >
> > No change in functionality expected.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> > * tree-vect-stmts.cc (vectorizable_comparison): Refactor, splitting
> > body
> > to ...
> > (vectorizable_comparison_1): ...This.
> >
> > --- inline copy of patch --
> > diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index
> > ae24f3e66e63d9bd9763284a47fb2c911335c4c1..f3e33cd4ed125b9564ca8
> > 1acd197693fc3457c31 100644
> > --- a/gcc/tree-vect-stmts.cc
> > +++ b/gcc/tree-vect-stmts.cc
> > @@ -11332,21 +11332,22 @@ vectorizable_condition (vec_info *vinfo,
> >
> > /* vectorizable_comparison.
> >
> > - Check if STMT_INFO is comparison expression that can be vectorized.
> > +/* Helper of vectorizable_comparison.
> > +
> > + Check if STMT_INFO is comparison expression CODE that can be vectorized.
> > If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
> > comparison, put it in VEC_STMT, and insert it at GSI.
> >
> > Return true if STMT_INFO is vectorizable in this way. */
> >
> > static bool
> > -vectorizable_comparison (vec_info *vinfo,
> > - stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
> > - gimple **vec_stmt,
> > - slp_tree slp_node, stmt_vector_for_cost *cost_vec)
> > +vectorizable_comparison_1 (vec_info *vinfo, tree vectype,
> > + stmt_vec_info stmt_info, tree_code code,
> > + gimple_stmt_iterator *gsi, gimple **vec_stmt,
> > + slp_tree slp_node, stmt_vector_for_cost *cost_vec)
> > {
> > tree lhs, rhs1, rhs2;
> > tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
> > - tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> > tree vec_rhs1 = NULL_TREE, vec_rhs2 = NULL_TREE;
> > tree new_temp;
> > loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); @@ -11354,7
> > +11355,7 @@ vectorizable_comparison (vec_info *vinfo,
> > int ndts = 2;
> > poly_uint64 nunits;
> > int ncopies;
> > - enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
> > + enum tree_code bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
> > int i;
> > bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
> > vec<tree> vec_oprnds0 = vNULL;
> > @@ -11377,14 +11378,6 @@ vectorizable_comparison (vec_info *vinfo,
> > ncopies = vect_get_num_copies (loop_vinfo, vectype);
> >
> > gcc_assert (ncopies >= 1);
> > - if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
> > - return false;
> > -
> > - gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
> > - if (!stmt)
> > - return false;
> > -
> > - code = gimple_assign_rhs_code (stmt);
> >
> > if (TREE_CODE_CLASS (code) != tcc_comparison)
> > return false;
> > @@ -11499,7 +11492,6 @@ vectorizable_comparison (vec_info *vinfo,
> > return false;
> > }
> >
> > - STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
> > vect_model_simple_cost (vinfo, stmt_info,
> > ncopies * (1 + (bitop2 != NOP_EXPR)),
> > dts, ndts, slp_node, cost_vec); @@ -11565,6
> > +11557,44 @@ vectorizable_comparison (vec_info *vinfo,
> > return true;
> > }
> >
> > +/* vectorizable_comparison.
> > +
> > + Check if STMT_INFO is comparison expression that can be vectorized.
> > + If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
> > + comparison, put it in VEC_STMT, and insert it at GSI.
> > +
> > + Return true if STMT_INFO is vectorizable in this way. */
> > +
> > +static bool
> > +vectorizable_comparison (vec_info *vinfo,
> > + stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
> > + gimple **vec_stmt,
> > + slp_tree slp_node, stmt_vector_for_cost *cost_vec) {
{ to the next line
> > + bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
> > +
> > + if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
> > + return false;
> > +
> > + if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
> > + return false;
> > +
> > + gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt); if (!stmt)
> > + return false;
new line before 'if'
otherwise OK.
Thanks,
Richard.
> > + enum tree_code code = gimple_assign_rhs_code (stmt);
> > + tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> > + if (!vectorizable_comparison_1 (vinfo, vectype, stmt_info, code, gsi,
> > + vec_stmt, slp_node, cost_vec))
> > + return false;
> > +
> > + if (!vec_stmt)
> > + STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
> > +
> > + return true;
> > +}
> > +
> > /* If SLP_NODE is nonnull, return true if vectorizable_live_operation
> > can handle all live statements in the node. Otherwise return true
> > if STMT_INFO is not live or if vectorizable_live_operation can handle it.
> >
> >
> >
> >
> > --
>
@@ -11332,21 +11332,22 @@ vectorizable_condition (vec_info *vinfo,
/* vectorizable_comparison.
- Check if STMT_INFO is comparison expression that can be vectorized.
+/* Helper of vectorizable_comparison.
+
+ Check if STMT_INFO is comparison expression CODE that can be vectorized.
If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
comparison, put it in VEC_STMT, and insert it at GSI.
Return true if STMT_INFO is vectorizable in this way. */
static bool
-vectorizable_comparison (vec_info *vinfo,
- stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
- gimple **vec_stmt,
- slp_tree slp_node, stmt_vector_for_cost *cost_vec)
+vectorizable_comparison_1 (vec_info *vinfo, tree vectype,
+ stmt_vec_info stmt_info, tree_code code,
+ gimple_stmt_iterator *gsi, gimple **vec_stmt,
+ slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{
tree lhs, rhs1, rhs2;
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
- tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree vec_rhs1 = NULL_TREE, vec_rhs2 = NULL_TREE;
tree new_temp;
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
@@ -11354,7 +11355,7 @@ vectorizable_comparison (vec_info *vinfo,
int ndts = 2;
poly_uint64 nunits;
int ncopies;
- enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
+ enum tree_code bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
int i;
bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
vec<tree> vec_oprnds0 = vNULL;
@@ -11377,14 +11378,6 @@ vectorizable_comparison (vec_info *vinfo,
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
- if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
- return false;
-
- gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
- if (!stmt)
- return false;
-
- code = gimple_assign_rhs_code (stmt);
if (TREE_CODE_CLASS (code) != tcc_comparison)
return false;
@@ -11499,7 +11492,6 @@ vectorizable_comparison (vec_info *vinfo,
return false;
}
- STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
vect_model_simple_cost (vinfo, stmt_info,
ncopies * (1 + (bitop2 != NOP_EXPR)),
dts, ndts, slp_node, cost_vec);
@@ -11565,6 +11557,44 @@ vectorizable_comparison (vec_info *vinfo,
return true;
}
+/* vectorizable_comparison.
+
+ Check if STMT_INFO is comparison expression that can be vectorized.
+ If VEC_STMT is also passed, vectorize STMT_INFO: create a vectorized
+ comparison, put it in VEC_STMT, and insert it at GSI.
+
+ Return true if STMT_INFO is vectorizable in this way. */
+
+static bool
+vectorizable_comparison (vec_info *vinfo,
+ stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
+ gimple **vec_stmt,
+ slp_tree slp_node, stmt_vector_for_cost *cost_vec)
+{
+ bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
+
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
+ return false;
+
+ if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
+ return false;
+
+ gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt);
+ if (!stmt)
+ return false;
+
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ if (!vectorizable_comparison_1 (vinfo, vectype, stmt_info, code, gsi,
+ vec_stmt, slp_node, cost_vec))
+ return false;
+
+ if (!vec_stmt)
+ STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
+
+ return true;
+}
+
/* If SLP_NODE is nonnull, return true if vectorizable_live_operation
can handle all live statements in the node. Otherwise return true
if STMT_INFO is not live or if vectorizable_live_operation can handle it.