diff mbox

[committed] Fix taskloop handling inside of parallel construct body (PR c/79940)

Message ID 20170308172541.GB22703@tucnak
State New
Headers show

Commit Message

Jakub Jelinek March 8, 2017, 5:25 p.m. UTC
Hi!

We split OMP_TASKLOOP into 3 constructs, two GIMPLE_OMP_FOR
with GIMPLE_OMP_PARALLEL sandwiched in between them, so that
it is possible to compute number of iterations etc. before calling
GOMP_taskloop*.  Using the original iterator in the outer gfor
doesn't play very well if the taskloop region is nested in other
OpenMP regions like parallel.  This patch just creates a temporary
for that.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed
to trunk so far, queued for 6.x.

2017-03-08  Jakub Jelinek  <jakub@redhat.com>

	PR c/79940
	* gimplify.c (gimplify_omp_for): Replace index var in outer
	taskloop statement with an artificial variable and add
	OMP_CLAUSE_PRIVATE clause for it.

	* testsuite/libgomp.c/pr79940.c: New test.


	Jakub
diff mbox

Patch

--- gcc/gimplify.c.jj	2017-02-21 09:03:57.000000000 +0100
+++ gcc/gimplify.c	2017-03-08 10:06:11.926501447 +0100
@@ -10232,8 +10232,9 @@  gimplify_omp_for (tree *expr_p, gimple_s
       gimple_omp_for_set_combined_into_p (gfor, true);
       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
 	{
-	  t = unshare_expr (gimple_omp_for_index (gfor, i));
-	  gimple_omp_for_set_index (gforo, i, t);
+	  tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
+	  tree v = create_tmp_var (type);
+	  gimple_omp_for_set_index (gforo, i, v);
 	  t = unshare_expr (gimple_omp_for_initial (gfor, i));
 	  gimple_omp_for_set_initial (gforo, i, t);
 	  gimple_omp_for_set_cond (gforo, i,
@@ -10241,7 +10242,13 @@  gimplify_omp_for (tree *expr_p, gimple_s
 	  t = unshare_expr (gimple_omp_for_final (gfor, i));
 	  gimple_omp_for_set_final (gforo, i, t);
 	  t = unshare_expr (gimple_omp_for_incr (gfor, i));
+	  gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
+	  TREE_OPERAND (t, 0) = v;
 	  gimple_omp_for_set_incr (gforo, i, t);
+	  t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+	  OMP_CLAUSE_DECL (t) = v;
+	  OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
+	  gimple_omp_for_set_clauses (gforo, t);
 	}
       gimplify_seq_add_stmt (pre_p, gforo);
     }
--- libgomp/testsuite/libgomp.c/pr79940.c.jj	2017-03-08 10:47:26.179154442 +0100
+++ libgomp/testsuite/libgomp.c/pr79940.c	2017-03-08 10:46:46.000000000 +0100
@@ -0,0 +1,47 @@ 
+/* PR c/79940 */
+
+int
+main ()
+{
+  int i, j, l, m;
+  int a[10000], b[10000], c[10000];
+  for (i = 0; i < 10000; i++)
+    {
+      a[i] = i;
+      b[i] = i & 31;
+    }
+#pragma omp parallel shared(a, b, c)
+#pragma omp single
+#pragma omp taskloop shared(a, b, c)
+  for (i = 0; i < 10000; i++)
+    c[i] = a[i] + b[i];
+#pragma omp parallel
+#pragma omp single
+  {
+    #pragma omp taskloop shared(a, b, c) lastprivate (i)
+    for (i = 0; i < 10000; i++)
+      c[i] += a[i] + b[i];
+    l = i;
+  }
+#pragma omp parallel
+#pragma omp single
+#pragma omp taskloop shared(a, b, c) collapse(2)
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 100; j++)
+      c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j];
+#pragma omp parallel
+#pragma omp single
+  {
+    #pragma omp taskloop shared(a, b, c) lastprivate (i, j)
+    for (i = 0; i < 100; i++)
+      for (j = 0; j < 100; j++)
+	c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j];
+    m = i * 100 + j;
+  }
+  for (i = 0; i < 10000; i++)
+    if (a[i] != i || b[i] != (i & 31) || c[i] != 4 * i + 4 * (i & 31))
+      __builtin_abort ();
+  if (l != 10000 || m != 10100)
+    __builtin_abort ();
+  return 0;
+}