[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