aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 1e43dbb..4715332 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -6010,6 +6010,45 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
n->value |= flags;
else
splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
+
+ /* For reductions clauses in OpenACC loop directives, by default create a
+ copy clause on the enclosing parallel construct for carrying back the
+ results. */
+ if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
+ {
+ struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
+ while (outer_ctx)
+ {
+ n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
+ if (n != NULL)
+ {
+ /* Ignore local variables and explicitly declared clauses. */
+ if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
+ break;
+ else if (outer_ctx->region_type == ORT_ACC_KERNELS)
+ {
+ /* According to the OpenACC spec, such a reduction variable
+ should already have a copy map on a kernels construct,
+ verify that here. */
+ gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
+ && (n->value & GOVD_MAP));
+ }
+ else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
+ {
+ /* Remove firstprivate and make it a copy map. */
+ n->value &= ~GOVD_FIRSTPRIVATE;
+ n->value |= GOVD_MAP;
+ }
+ }
+ else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
+ {
+ splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
+ GOVD_MAP | GOVD_SEEN);
+ break;
+ }
+ outer_ctx = outer_ctx->outer_context;
+ }
+ }
}
/* Notice a threadprivate variable DECL used in OMP context CTX.