aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-12-21 08:59:05 +0100
committerJakub Jelinek <jakub@redhat.com>2020-12-21 08:59:05 +0100
commitb6237343e78ae115d09618efc1443bdf2fd6c09b (patch)
treed6842ad9344827543f015e68d82e2ad2613404db /gcc
parent9bac66390c0c838594e42877f938bca441665937 (diff)
downloadgcc-b6237343e78ae115d09618efc1443bdf2fd6c09b.zip
gcc-b6237343e78ae115d09618efc1443bdf2fd6c09b.tar.gz
gcc-b6237343e78ae115d09618efc1443bdf2fd6c09b.tar.bz2
openmp: Fix up handling of addressable temporaries in simd lb, b and incr expressions [PR98383]
For simd, we have code to artificially add locally defined variables into private clauses if they are addressable, so that omplower turns them into "omp simd array" variables. As the testcase shows, this is undesirable if those temporaries only show in the lb, b or incr expressions and nowhere else, if it is just used there, we really want normal scalar temporaries. This patch implements that by making sure we don't set for those GOVD_LOCAL-ish temporaries turned into GOVD_PRIVATE the GOVD_SEEN flag during gimplification of the lb, b and incr expressions, which means that the private clause isn't added for those. 2020-12-21 Jakub Jelinek <jakub@redhat.com> PR c++/98383 * gimplify.c (struct gimplify_omp_ctx): Add in_for_exprs flag. (gimple_add_tmp_var): For addressable temporaries appearing in simd lb, b or incr expressions, don't add a private clause unless it is seen also outside of those expressions in the simd body. (omp_notice_variable): Likewise. (gimplify_omp_for): Set and reset in_for_exprs around gimplification of lb, b or incr expressions. * g++.dg/gomp/pr98383.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimplify.c23
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr98383.C18
2 files changed, 38 insertions, 3 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 87b6314..ea8a53e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -232,6 +232,7 @@ struct gimplify_omp_ctx
bool add_safelen1;
bool order_concurrent;
bool has_depend;
+ bool in_for_exprs;
int defaultmap[4];
};
@@ -781,7 +782,7 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- int flag = GOVD_LOCAL;
+ int flag = GOVD_LOCAL | GOVD_SEEN;
while (ctx
&& (ctx->region_type == ORT_WORKSHARE
|| ctx->region_type == ORT_TASKGROUP
@@ -794,14 +795,16 @@ gimple_add_tmp_var (tree tmp)
{
if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
ctx->add_safelen1 = true;
- else
+ else if (ctx->in_for_exprs)
flag = GOVD_PRIVATE;
+ else
+ flag = GOVD_PRIVATE | GOVD_SEEN;
break;
}
ctx = ctx->outer_context;
}
if (ctx)
- omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
+ omp_add_variable (ctx, tmp, flag);
}
}
else if (cfun)
@@ -7617,6 +7620,14 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
goto do_outer;
}
+ /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
+ lb, b or incr expressions, those shouldn't be turned into simd arrays. */
+ if (ctx->region_type == ORT_SIMD
+ && ctx->in_for_exprs
+ && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
+ == GOVD_PRIVATE))
+ flags &= ~GOVD_SEEN;
+
if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
&& (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
&& DECL_SIZE (decl))
@@ -12080,6 +12091,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
else
var = decl;
+ gimplify_omp_ctxp->in_for_exprs = true;
if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
{
tree lb = TREE_OPERAND (t, 1);
@@ -12092,6 +12104,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
else
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue, false);
+ gimplify_omp_ctxp->in_for_exprs = false;
ret = MIN (ret, tret);
if (ret == GS_ERROR)
return ret;
@@ -12101,6 +12114,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_assert (COMPARISON_CLASS_P (t));
gcc_assert (TREE_OPERAND (t, 0) == decl);
+ gimplify_omp_ctxp->in_for_exprs = true;
if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
{
tree ub = TREE_OPERAND (t, 1);
@@ -12113,6 +12127,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
else
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue, false);
+ gimplify_omp_ctxp->in_for_exprs = false;
ret = MIN (ret, tret);
/* Handle OMP_FOR_INCR. */
@@ -12178,6 +12193,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
+ gimplify_omp_ctxp->in_for_exprs = true;
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
@@ -12199,6 +12215,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
ret = MIN (ret, tret);
}
}
+ gimplify_omp_ctxp->in_for_exprs = false;
break;
default:
diff --git a/gcc/testsuite/g++.dg/gomp/pr98383.C b/gcc/testsuite/g++.dg/gomp/pr98383.C
new file mode 100644
index 0000000..8106138
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr98383.C
@@ -0,0 +1,18 @@
+// PR c++/98383
+// { dg-options "-fopenmp -O1" }
+
+int bar (const int &);
+
+void
+foo (int *a)
+{
+#pragma omp simd
+ for (int i = 0; i < bar (8); ++i)
+ a[i]++;
+#pragma omp simd
+ for (int i = bar (9); i < 16; ++i)
+ a[i]++;
+#pragma omp simd
+ for (int i = 0; i < 32; i += bar (10))
+ a[i]++;
+}