diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2018-06-30 12:47:50 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-06-30 12:47:50 +0000 |
commit | 7b98e98a98c95029434200cdfc5ad87e204d79b4 (patch) | |
tree | 861909cc49f297a0be9d745dec74c388098a21b0 /gcc/tree-vect-patterns.c | |
parent | 0f8c840c28c11b13e630b55ad3dc6e0670b4f817 (diff) | |
download | gcc-7b98e98a98c95029434200cdfc5ad87e204d79b4.zip gcc-7b98e98a98c95029434200cdfc5ad87e204d79b4.tar.gz gcc-7b98e98a98c95029434200cdfc5ad87e204d79b4.tar.bz2 |
[10/n] PR85694: Split out check for vectorizable associative reductions
This patch adds an overload of vect_reassociating_reduction_p
that checks for a vectorizable associative reduction,
since the check was duplicated in three functions.
2018-06-30 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* tree-vect-patterns.c (vect_reassociating_reduction_p): New function.
(vect_recog_dot_prod_pattern, vect_recog_sad_pattern)
(vect_recog_widen_sum_pattern): Use it.
From-SVN: r262274
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 110 |
1 files changed, 41 insertions, 69 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 6926c84..6be23d0 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -239,6 +239,36 @@ vect_reassociating_reduction_p (stmt_vec_info stmt_vinfo) : REDUC_GROUP_FIRST_ELEMENT (stmt_vinfo) != NULL); } +/* As above, but also require it to have code CODE and to be a reduction + in the outermost loop. When returning true, store the operands in + *OP0_OUT and *OP1_OUT. */ + +static bool +vect_reassociating_reduction_p (stmt_vec_info stmt_info, tree_code code, + tree *op0_out, tree *op1_out) +{ + loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info); + if (!loop_info) + return false; + + gassign *assign = dyn_cast <gassign *> (stmt_info->stmt); + if (!assign || gimple_assign_rhs_code (assign) != code) + return false; + + /* We don't allow changing the order of the computation in the inner-loop + when doing outer-loop vectorization. */ + struct loop *loop = LOOP_VINFO_LOOP (loop_info); + if (loop && nested_in_vect_loop_p (loop, assign)) + return false; + + if (!vect_reassociating_reduction_p (stmt_info)) + return false; + + *op0_out = gimple_assign_rhs1 (assign); + *op1_out = gimple_assign_rhs2 (assign); + return true; +} + /* Function vect_recog_dot_prod_pattern Try to find the following pattern: @@ -293,26 +323,9 @@ vect_recog_dot_prod_pattern (vec<gimple *> *stmts, tree *type_out) tree type, half_type; gimple *pattern_stmt; tree prod_type; - loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - struct loop *loop; tree var; bool promotion; - if (!loop_info) - return NULL; - - loop = LOOP_VINFO_LOOP (loop_info); - - /* We don't allow changing the order of the computation in the inner-loop - when doing outer-loop vectorization. */ - if (loop && nested_in_vect_loop_p (loop, last_stmt)) - return NULL; - - if (!is_gimple_assign (last_stmt)) - return NULL; - - type = gimple_expr_type (last_stmt); - /* Look for the following pattern DX = (TYPE1) X; DY = (TYPE1) Y; @@ -337,17 +350,14 @@ vect_recog_dot_prod_pattern (vec<gimple *> *stmts, tree *type_out) /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) - return NULL; - if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) return NULL; - if (!vect_reassociating_reduction_p (stmt_vinfo)) + if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR, + &oprnd0, &oprnd1)) return NULL; - oprnd0 = gimple_assign_rhs1 (last_stmt); - oprnd1 = gimple_assign_rhs2 (last_stmt); + type = gimple_expr_type (last_stmt); stmt = last_stmt; gimple *def_stmt; @@ -471,25 +481,8 @@ vect_recog_sad_pattern (vec<gimple *> *stmts, tree *type_out) stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); vec_info *vinfo = stmt_vinfo->vinfo; tree half_type; - loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - struct loop *loop; bool promotion; - if (!loop_info) - return NULL; - - loop = LOOP_VINFO_LOOP (loop_info); - - /* We don't allow changing the order of the computation in the inner-loop - when doing outer-loop vectorization. */ - if (loop && nested_in_vect_loop_p (loop, last_stmt)) - return NULL; - - if (!is_gimple_assign (last_stmt)) - return NULL; - - tree sum_type = gimple_expr_type (last_stmt); - /* Look for the following pattern DX = (TYPE1) X; DY = (TYPE1) Y; @@ -517,19 +510,15 @@ vect_recog_sad_pattern (vec<gimple *> *stmts, tree *type_out) /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) - return NULL; - - tree plus_oprnd0, plus_oprnd1; - if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) return NULL; - if (!vect_reassociating_reduction_p (stmt_vinfo)) + tree plus_oprnd0, plus_oprnd1; + if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR, + &plus_oprnd0, &plus_oprnd1)) return NULL; - plus_oprnd0 = gimple_assign_rhs1 (last_stmt); - plus_oprnd1 = gimple_assign_rhs2 (last_stmt); + tree sum_type = gimple_expr_type (last_stmt); /* The type conversion could be promotion, demotion, or just signed -> unsigned. */ @@ -1133,26 +1122,12 @@ vect_recog_widen_sum_pattern (vec<gimple *> *stmts, tree *type_out) stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); tree type, half_type; gimple *pattern_stmt; - loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); - struct loop *loop; tree var; bool promotion; - if (!loop_info) - return NULL; - - loop = LOOP_VINFO_LOOP (loop_info); - - /* We don't allow changing the order of the computation in the inner-loop - when doing outer-loop vectorization. */ - if (loop && nested_in_vect_loop_p (loop, last_stmt)) - return NULL; - - if (!is_gimple_assign (last_stmt)) + if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) return NULL; - type = gimple_expr_type (last_stmt); - /* Look for the following pattern DX = (TYPE) X; sum_1 = DX + sum_0; @@ -1163,14 +1138,11 @@ vect_recog_widen_sum_pattern (vec<gimple *> *stmts, tree *type_out) /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) + if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR, + &oprnd0, &oprnd1)) return NULL; - if (!vect_reassociating_reduction_p (stmt_vinfo)) - return NULL; - - oprnd0 = gimple_assign_rhs1 (last_stmt); - oprnd1 = gimple_assign_rhs2 (last_stmt); + type = gimple_expr_type (last_stmt); /* So far so good. Since last_stmt was detected as a (summation) reduction, we know that oprnd1 is the reduction variable (defined by a loop-header |