aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-slp.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-07-12 13:02:17 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-07-12 13:02:17 +0000
commit5249ee4d79855edda91b26bb07c9c8737cdfc96c (patch)
tree79b0f24d85f96dc00b4f8858b92f7df81b7181bf /gcc/tree-vect-slp.c
parent2c58d42c3ed599b4c2976fc173eefd8e016ea216 (diff)
downloadgcc-5249ee4d79855edda91b26bb07c9c8737cdfc96c.zip
gcc-5249ee4d79855edda91b26bb07c9c8737cdfc96c.tar.gz
gcc-5249ee4d79855edda91b26bb07c9c8737cdfc96c.tar.bz2
Implement SLP of internal functions
SLP of calls was previously restricted to built-in functions. This patch extends it to internal functions. 2018-07-12 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * internal-fn.h (vectorizable_internal_fn_p): New function. * tree-vect-slp.c (compatible_calls_p): Likewise. (vect_build_slp_tree_1): Remove nops argument. Handle calls to internal functions. (vect_build_slp_tree_2): Update call to vect_build_slp_tree_1. gcc/testsuite/ * gcc.dg/vect/vect-cond-arith-6.c: New test. * gcc.target/aarch64/sve/cond_arith_4.c: Likewise. * gcc.target/aarch64/sve/cond_arith_4_run.c: Likewise. * gcc.target/aarch64/sve/cond_arith_5.c: Likewise. * gcc.target/aarch64/sve/cond_arith_5_run.c: Likewise. * gcc.target/aarch64/sve/slp_14.c: Likewise. * gcc.target/aarch64/sve/slp_14_run.c: Likewise. From-SVN: r262590
Diffstat (limited to 'gcc/tree-vect-slp.c')
-rw-r--r--gcc/tree-vect-slp.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 528e1d5..8dc5763 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -562,6 +562,41 @@ again:
return 0;
}
+/* Return true if call statements CALL1 and CALL2 are similar enough
+ to be combined into the same SLP group. */
+
+static bool
+compatible_calls_p (gcall *call1, gcall *call2)
+{
+ unsigned int nargs = gimple_call_num_args (call1);
+ if (nargs != gimple_call_num_args (call2))
+ return false;
+
+ if (gimple_call_combined_fn (call1) != gimple_call_combined_fn (call2))
+ return false;
+
+ if (gimple_call_internal_p (call1))
+ {
+ if (!types_compatible_p (TREE_TYPE (gimple_call_lhs (call1)),
+ TREE_TYPE (gimple_call_lhs (call2))))
+ return false;
+ for (unsigned int i = 0; i < nargs; ++i)
+ if (!types_compatible_p (TREE_TYPE (gimple_call_arg (call1, i)),
+ TREE_TYPE (gimple_call_arg (call2, i))))
+ return false;
+ }
+ else
+ {
+ if (!operand_equal_p (gimple_call_fn (call1),
+ gimple_call_fn (call2), 0))
+ return false;
+
+ if (gimple_call_fntype (call1) != gimple_call_fntype (call2))
+ return false;
+ }
+ return true;
+}
+
/* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the
caller's attempt to find the vector type in STMT with the narrowest
element type. Return true if VECTYPE is nonnull and if it is valid
@@ -650,8 +685,8 @@ vect_two_operations_perm_ok_p (vec<gimple *> stmts, unsigned int group_size,
static bool
vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
vec<gimple *> stmts, unsigned int group_size,
- unsigned nops, poly_uint64 *max_nunits,
- bool *matches, bool *two_operators)
+ poly_uint64 *max_nunits, bool *matches,
+ bool *two_operators)
{
unsigned int i;
gimple *first_stmt = stmts[0], *stmt = stmts[0];
@@ -727,7 +762,9 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
{
rhs_code = CALL_EXPR;
- if (gimple_call_internal_p (call_stmt)
+ if ((gimple_call_internal_p (call_stmt)
+ && (!vectorizable_internal_fn_p
+ (gimple_call_internal_fn (call_stmt))))
|| gimple_call_tail_p (call_stmt)
|| gimple_call_noreturn_p (call_stmt)
|| !gimple_call_nothrow_p (call_stmt)
@@ -873,11 +910,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
if (rhs_code == CALL_EXPR)
{
gimple *first_stmt = stmts[0];
- if (gimple_call_num_args (stmt) != nops
- || !operand_equal_p (gimple_call_fn (first_stmt),
- gimple_call_fn (stmt), 0)
- || gimple_call_fntype (first_stmt)
- != gimple_call_fntype (stmt))
+ if (!compatible_calls_p (as_a <gcall *> (first_stmt),
+ as_a <gcall *> (stmt)))
{
if (dump_enabled_p ())
{
@@ -1193,8 +1227,7 @@ vect_build_slp_tree_2 (vec_info *vinfo,
bool two_operators = false;
unsigned char *swap = XALLOCAVEC (unsigned char, group_size);
- if (!vect_build_slp_tree_1 (vinfo, swap,
- stmts, group_size, nops,
+ if (!vect_build_slp_tree_1 (vinfo, swap, stmts, group_size,
&this_max_nunits, matches, &two_operators))
return NULL;