Handle 2 preds for fin_bb in expand_omp_for_static_chunk
2015-08-31 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/65637
* omp-low.c (expand_omp_for_static_chunk): Handle case that fin_bb has 2
predecessors.
* gcc.dg/autopar/reduc-3-chunk-size.c: New test.
---
gcc/ChangeLog | 6 +++
gcc/omp-low.c | 26 +++++++----
gcc/testsuite/gcc.dg/autopar/reduc-3-chunk-size.c | 56 +++++++++++++++++++++++
3 files changed, 79 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/autopar/reduc-3-chunk-size.c
@@ -1,6 +1,12 @@
2015-05-18 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/65637
+ * omp-low.c (expand_omp_for_static_chunk): Handle case that fin_bb has 2
+ predecessors.
+
+2015-05-18 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/65637
* omp-low.c (find_phi_with_arg_on_edge): New function.
(expand_omp_for_static_chunk): Fix inner loop phi.
@@ -7033,7 +7033,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
se->probability = REG_BR_PROB_BASE / 2000 - 1;
if (gimple_in_ssa_p (cfun))
{
- int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
+ int dest_idx = find_edge (iter_part_bb, fin_bb)->dest_idx;
for (gphi_iterator gpi = gsi_start_phis (fin_bb);
!gsi_end_p (gpi); gsi_next (&gpi))
{
@@ -7314,7 +7314,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
/* When we redirect the edge from trip_update_bb to iter_part_bb, we
remove arguments of the phi nodes in fin_bb. We need to create
appropriate phi nodes in iter_part_bb instead. */
- se = single_pred_edge (fin_bb);
+ se = find_edge (iter_part_bb, fin_bb);
re = single_succ_edge (trip_update_bb);
vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
ene = single_succ_edge (entry_bb);
@@ -7329,6 +7329,10 @@ expand_omp_for_static_chunk (struct omp_region *region,
phi = psi.phi ();
t = gimple_phi_result (phi);
gcc_assert (t == redirect_edge_var_map_result (vm));
+
+ if (!single_pred_p (fin_bb))
+ t = copy_ssa_name (t, phi);
+
nphi = create_phi_node (t, iter_part_bb);
t = PHI_ARG_DEF_FROM_EDGE (phi, se);
@@ -7353,16 +7357,20 @@ expand_omp_for_static_chunk (struct omp_region *region,
gcc_assert (inner_loop_phi != NULL);
add_phi_arg (inner_loop_phi, gimple_phi_result (nphi),
find_edge (seq_start_bb, body_bb), locus);
+
+ if (!single_pred_p (fin_bb))
+ add_phi_arg (phi, gimple_phi_result (nphi), se, locus);
}
gcc_assert (gsi_end_p (psi) && (head == NULL || i == head->length ()));
redirect_edge_var_map_clear (re);
- while (1)
- {
- psi = gsi_start_phis (fin_bb);
- if (gsi_end_p (psi))
- break;
- remove_phi_node (&psi, false);
- }
+ if (single_pred_p (fin_bb))
+ while (1)
+ {
+ psi = gsi_start_phis (fin_bb);
+ if (gsi_end_p (psi))
+ break;
+ remove_phi_node (&psi, false);
+ }
/* Make phi node for trip. */
phi = create_phi_node (trip_main, iter_part_bb);
new file mode 100644
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized --param parloops-chunk-size=100" } */
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#define N 1600
+
+unsigned int ub[N];
+unsigned int uc[N];
+
+/* Reduction of unsigned-int. */
+
+int __attribute__ ((noinline))
+main1 (int n, int res)
+{
+ int i;
+ unsigned int udiff;
+
+ udiff = 0;
+ for (i = 0; i < n; i++) {
+ udiff += (ub[i] - uc[i]);
+ }
+
+ /* check results: */
+ if (udiff != res)
+ abort ();
+
+ return 0;
+}
+
+void __attribute__((noinline))
+init_arrays ()
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ ub[i] = i * 3;
+ uc[i] = i;
+ }
+}
+
+int
+main (void)
+{
+ init_arrays ();
+ main1 (N, 2558400);
+ main1 (N-1, 2555202);
+ return 0;
+}
+
+
+/* { dg-final { scan-tree-dump-times "Detected reduction" 1 "parloops" } } */
+/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */
+
--
1.9.1