[gomp] Combined parallel loop tweaks

Jakub Jelinek jakub@redhat.com
Mon Nov 14 13:46:00 GMT 2005


Hi!

As shown on the attached for-18.c testcases, if schedule() clause in a combined
parallel loop has non-constant (and non-gimple reg) chunk size expression,
it wasn't using the combined loop function.  The following patch fixes
that, for combined parallel loop the schedule chunk expression is passed
to the GOMP_parallel_loop_*_start function, so can and should be gimplified
outside of the child function.
Additionally, as gimplify_expr_in_ctx temporarily switched just to a
selected gimplify context, but not to a selected gimplify omp context,
all variables mentioned in the expression were recorded in wrong parallel
clauses.

Ok for gomp?

2005-11-14  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (gimplify_expr_in_ctx): Add OMP_CTX_P argument.
	Temporarily switch to OMP_CTX_P omp context.
	(gimplify_scan_omp_clauses) <case OMP_CLAUSE_SCHEDULE>: In combined
	parallel loop, gimplify schedule chunk expression in outer context.
	(gimplify_omp_for): For combined parallel loop, gimplify INIT, COND
	and INCR expressions in parent omp context.

	* gcc.dg/gomp/for-18.c: New test.
	* gcc.dg/gomp/for-19.c: New test.

--- gcc/gimplify.c.jj	2005-11-14 09:04:18.000000000 +0100
+++ gcc/gimplify.c	2005-11-14 14:25:35.000000000 +0100
@@ -4133,15 +4133,20 @@ gimplify_to_stmt_list (tree *stmt_p)
 static enum gimplify_status
 gimplify_expr_in_ctx (tree *expr_p, tree *pre_p, tree *post_p, 
 		      bool (* gimple_test_f) (tree), fallback_t fallback,
-		      struct gimplify_ctx *ctx_p)
+		      struct gimplify_ctx *ctx_p,
+		      struct gimplify_omp_ctx *omp_ctx_p)
 {
   enum gimplify_status ret;
   struct gimplify_ctx *prev_ctxp;
+  struct gimplify_omp_ctx *prev_omp_ctxp;
   
   prev_ctxp = gimplify_ctxp;
   gimplify_ctxp = ctx_p;
+  prev_omp_ctxp = gimplify_omp_ctxp;
+  gimplify_omp_ctxp = omp_ctx_p;
   ret = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fallback);
   gimplify_ctxp = prev_ctxp;
+  gimplify_omp_ctxp = prev_omp_ctxp;
 
   return ret;
 }
@@ -4521,9 +4526,22 @@ gimplify_scan_omp_clauses (tree *list_p,
 	    omp_notice_variable (outer_ctx, decl, true);
 	  break;
 
+	case OMP_CLAUSE_SCHEDULE:
+	  if (gimplify_ctxp->combined_pre_p)
+	    {
+	      gcc_assert (gimplify_omp_ctxp == outer_ctx);
+	      gs = gimplify_expr_in_ctx (&OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c),
+					 gimplify_ctxp->combined_pre_p, NULL,
+					 is_gimple_val, fb_rvalue,
+					 gimplify_ctxp->combined_ctxp,
+					 outer_ctx->outer_context);
+	      if (gs == GS_ERROR)
+		remove = true;
+	      break;
+	    }
+	  /* FALLTHRU */
 	case OMP_CLAUSE_IF:
 	case OMP_CLAUSE_NUM_THREADS:
-	case OMP_CLAUSE_SCHEDULE:
 	  gs = gimplify_expr (&TREE_OPERAND (c, 0), pre_p, NULL,
 			      is_gimple_val, fb_rvalue);
 	  if (gs == GS_ERROR)
@@ -4710,9 +4728,13 @@ gimplify_omp_for (tree *expr_p, tree *pr
 {
   tree for_stmt, decl, t;
   enum gimplify_status ret = 0;
+  struct gimplify_omp_ctx *outer_combined_omp_ctxp = NULL;
 
   for_stmt = *expr_p;
 
+  if (gimplify_ctxp->combined_pre_p)
+    outer_combined_omp_ctxp = gimplify_omp_ctxp->outer_context;
+
   gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false);
 
   t = OMP_FOR_INIT (for_stmt);
@@ -4734,7 +4756,8 @@ gimplify_omp_for (tree *expr_p, tree *pr
     ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
 				 gimplify_ctxp->combined_pre_p, NULL,
 				 is_gimple_val, fb_rvalue,
-				 gimplify_ctxp->combined_ctxp);
+				 gimplify_ctxp->combined_ctxp,
+				 outer_combined_omp_ctxp);
   else
     ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
 			  NULL, is_gimple_val, fb_rvalue);
@@ -4749,7 +4772,8 @@ gimplify_omp_for (tree *expr_p, tree *pr
     ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
 				 gimplify_ctxp->combined_pre_p, NULL,
 				 is_gimple_val, fb_rvalue,
-				 gimplify_ctxp->combined_ctxp);
+				 gimplify_ctxp->combined_ctxp,
+				 outer_combined_omp_ctxp);
   else
     ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
 			  NULL, is_gimple_val, fb_rvalue);
@@ -4796,10 +4820,11 @@ gimplify_omp_for (tree *expr_p, tree *pr
 	ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
 				     gimplify_ctxp->combined_pre_p, NULL,
 				     is_gimple_val, fb_rvalue,
-				     gimplify_ctxp->combined_ctxp);
+				     gimplify_ctxp->combined_ctxp,
+				     outer_combined_omp_ctxp);
       else
 	ret |= gimplify_expr (&TREE_OPERAND (t, 1),
-	                      &OMP_FOR_PRE_BODY (for_stmt), NULL,
+			      &OMP_FOR_PRE_BODY (for_stmt), NULL,
 			      is_gimple_val, fb_rvalue);
       break;
 
--- gcc/testsuite/gcc.dg/gomp/for-18.c.jj	2005-11-14 13:56:08.000000000 +0100
+++ gcc/testsuite/gcc.dg/gomp/for-18.c	2005-11-14 14:01:31.000000000 +0100
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fopenmp -fdump-tree-omplower" } */
+
+void
+foo (int *a, int i)
+{
+  int j, k = 1, l = 30, m = 4;
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, i * 4)
+  for (j = 0; j <= l; j++)
+    a[j] = 1;
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, i * 4)
+  for (j = k; j <= l; j += (m - 1))
+    a[j] = 2;
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, 4)
+  for (j = 0; j <= l; j++)
+    a[j] = 3;
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, 4)
+  for (j = k; j <= l; j += (m - 1))
+    a[j] = 4;
+}
+
+void
+bar (int *a, int i)
+{
+  int j, k = 1, l = 30, m = 4;
+#pragma omp parallel for num_threads (3 * i) schedule (guided, i * 4)
+  for (j = 0; j <= l; j++)
+    a[j] = 1;
+#pragma omp parallel for num_threads (3 * i) schedule (guided, i * 4)
+  for (j = k; j <= l; j += (m - 1))
+    a[j] = 2;
+#pragma omp parallel for num_threads (3 * i) schedule (guided, 4)
+  for (j = 0; j <= l; j++)
+    a[j] = 3;
+#pragma omp parallel for num_threads (3 * i) schedule (guided, 4)
+  for (j = k; j <= l; j += (m - 1))
+    a[j] = 4;
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_dynamic_start" 4 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_guided_start" 4 "omplower" } } */
+/* { dg-final { cleanup-tree-dump "omplower" } } */
--- gcc/testsuite/gcc.dg/gomp/for-19.c.jj	2005-11-14 14:27:54.000000000 +0100
+++ gcc/testsuite/gcc.dg/gomp/for-19.c	2005-11-14 14:34:24.000000000 +0100
@@ -0,0 +1,21 @@
+/* Verify that if GOMP_parallel_loop_dynamic_start is used, variables
+   mentioned in the INIT, COND and INCR expressions aren't unnecessarily
+   copied to the omp_fn function.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fopenmp -fdump-tree-gimple" } */
+
+void foo (int *a, int i, int j, int k, int l, int m)
+{
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, i * 4)
+  for (j = 0; j <= (6 * l + 4 * k); j++)
+    a[j] = 1;
+#pragma omp parallel for num_threads (3 * i) schedule (dynamic, i * 4)
+  for (j = m; j <= l; j += (k + l - m))
+    a[j] = 1;
+}
+
+/* { dg-final { scan-tree-dump-times "shared\\(a\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "shared\\(k\\)" 0 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "shared\\(l\\)" 0 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "shared\\(m\\)" 0 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */

	Jakub



More information about the Gcc-patches mailing list