aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-parloops.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-parloops.c')
-rw-r--r--gcc/tree-parloops.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 2e55b7961d8..bd43af6dff7 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -2511,8 +2511,8 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
{
gphi_iterator gsi;
loop_vec_info simple_loop_info;
- loop_vec_info simple_inner_loop_info = NULL;
- bool allow_double_reduc = true;
+ auto_vec<gphi *, 4> double_reduc_phis;
+ auto_vec<gimple *, 4> double_reduc_stmts;
if (!stmt_vec_info_vec.exists ())
init_stmt_vec_info_vec ();
@@ -2542,43 +2542,55 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
if (double_reduc)
{
- if (!allow_double_reduc
- || loop->inner->inner != NULL)
+ if (loop->inner->inner != NULL)
continue;
- if (!simple_inner_loop_info)
- {
- simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
- if (!simple_inner_loop_info)
- {
- allow_double_reduc = false;
- continue;
- }
- }
-
- use_operand_p use_p;
- gimple *inner_stmt;
- bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
- gcc_assert (single_use_p);
- if (gimple_code (inner_stmt) != GIMPLE_PHI)
- continue;
- gphi *inner_phi = as_a <gphi *> (inner_stmt);
- if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
- &iv, true))
- continue;
-
- gimple *inner_reduc_stmt
- = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
- true, &double_reduc, true);
- gcc_assert (!double_reduc);
- if (inner_reduc_stmt == NULL)
- continue;
+ double_reduc_phis.safe_push (phi);
+ double_reduc_stmts.safe_push (reduc_stmt);
+ continue;
}
build_new_reduction (reduction_list, reduc_stmt, phi);
}
destroy_loop_vec_info (simple_loop_info, true);
- destroy_loop_vec_info (simple_inner_loop_info, true);
+
+ if (!double_reduc_phis.is_empty ())
+ {
+ simple_loop_info = vect_analyze_loop_form (loop->inner);
+ if (simple_loop_info)
+ {
+ gphi *phi;
+ unsigned int i;
+
+ FOR_EACH_VEC_ELT (double_reduc_phis, i, phi)
+ {
+ affine_iv iv;
+ tree res = PHI_RESULT (phi);
+ bool double_reduc;
+
+ use_operand_p use_p;
+ gimple *inner_stmt;
+ bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
+ gcc_assert (single_use_p);
+ if (gimple_code (inner_stmt) != GIMPLE_PHI)
+ continue;
+ gphi *inner_phi = as_a <gphi *> (inner_stmt);
+ if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
+ &iv, true))
+ continue;
+
+ gimple *inner_reduc_stmt
+ = vect_force_simple_reduction (simple_loop_info, inner_phi,
+ true, &double_reduc, true);
+ gcc_assert (!double_reduc);
+ if (inner_reduc_stmt == NULL)
+ continue;
+
+ build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
+ }
+ destroy_loop_vec_info (simple_loop_info, true);
+ }
+ }
gather_done:
/* Release the claim on gimple_uid. */