aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2015-11-11 14:24:09 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2015-11-11 14:24:09 +0000
commit182190f2b3a236eb30bd717981e1f2c9b51cea06 (patch)
tree295e38d6632d00a37b02d200a9f7a761f46af3f8 /gcc/gimplify.c
parent7700cd858ff97a257d6f48b0d079780f445821da (diff)
downloadgcc-182190f2b3a236eb30bd717981e1f2c9b51cea06.zip
gcc-182190f2b3a236eb30bd717981e1f2c9b51cea06.tar.gz
gcc-182190f2b3a236eb30bd717981e1f2c9b51cea06.tar.bz2
gimplify.c (enum omp_region_type): Add ORT_ACC, ORT_ACC_DATA, ORT_ACC_PARALLEL, ORT_ACC_KERNELS.
gcc/ * gcc/gimplify.c (enum omp_region_type): Add ORT_ACC, ORT_ACC_DATA, ORT_ACC_PARALLEL, ORT_ACC_KERNELS. Adjust ORT_NONE. (gimple_add_tmp_var): Add ORT_ACC checks. (gimplify_var_or_parm_decl): Likewise. (omp_firstprivatize_variable): Likewise. Use ORT_TARGET_DATA as a mask. (omp_add_variable): Look in outer contexts for openacc and allow reductions with other sharing. Add ORT_ACC and ORT_TARGET_DATA checks. (omp_notice_variable, omp_is_private, omp_check_private): Add ORT_ACC checks. (gimplify_scan_omp_clauses: Treat ORT_ACC as ORT_WORKSHARE. Permit private openacc reductions. (gimplify_oacc_cache): Specify ORT_ACC. (gimplify_omp_workshare): Adjust OpenACC region types. (gimplify_omp_target_update): Likewise. * gcc/omp-low.c (scan_sharing_clauses): Remove Openacc firstprivate sorry. (lower-rec_input_clauses): Don't handle openacc firstprivate references here. (lower_omp_target): Emit initializers for openacc firstprivate vars. gcc/testsuite/ * gfortran.dg/goacc/private-3.f95: Remove xfail. * gfortran.dg/goacc/combined_loop.f90: Remove xfail. libgomp/ * testsuite/libgomp.oacc-c-c++-common/loop-red-v-2.c: Remove xfail. * testsuite/libgomp.oacc-c-c++-common/loop-red-w-2.c: Remove xfail. * testsuite/libgomp.oacc-c-c++-common/firstprivate-1.c: New. * testsuite/libgomp.oacc-c-c++-common/firstprivate-2.c: New. Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com> From-SVN: r230169
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c141
1 files changed, 99 insertions, 42 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 287e51e..66e5168 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -95,22 +95,34 @@ enum gimplify_omp_var_data
enum omp_region_type
{
- ORT_WORKSHARE = 0,
- ORT_SIMD = 1,
- ORT_PARALLEL = 2,
- ORT_COMBINED_PARALLEL = 3,
- ORT_TASK = 4,
- ORT_UNTIED_TASK = 5,
- ORT_TEAMS = 8,
- ORT_COMBINED_TEAMS = 9,
+ ORT_WORKSHARE = 0x00,
+ ORT_SIMD = 0x01,
+
+ ORT_PARALLEL = 0x02,
+ ORT_COMBINED_PARALLEL = 0x03,
+
+ ORT_TASK = 0x04,
+ ORT_UNTIED_TASK = 0x05,
+
+ ORT_TEAMS = 0x08,
+ ORT_COMBINED_TEAMS = 0x09,
+
/* Data region. */
- ORT_TARGET_DATA = 16,
+ ORT_TARGET_DATA = 0x10,
+
/* Data region with offloading. */
- ORT_TARGET = 32,
- ORT_COMBINED_TARGET = 33,
+ ORT_TARGET = 0x20,
+ ORT_COMBINED_TARGET = 0x21,
+
+ /* OpenACC variants. */
+ ORT_ACC = 0x40, /* A generic OpenACC region. */
+ ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
+ ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
+ ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 0x80, /* Kernels construct. */
+
/* Dummy OpenMP region, used to disable expansion of
DECL_VALUE_EXPRs in taskloop pre body. */
- ORT_NONE = 64
+ ORT_NONE = 0x100
};
/* Gimplify hashtable helper. */
@@ -689,7 +701,8 @@ gimple_add_tmp_var (tree tmp)
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
while (ctx
&& (ctx->region_type == ORT_WORKSHARE
- || ctx->region_type == ORT_SIMD))
+ || ctx->region_type == ORT_SIMD
+ || ctx->region_type == ORT_ACC))
ctx = ctx->outer_context;
if (ctx)
omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
@@ -1804,7 +1817,8 @@ gimplify_var_or_parm_decl (tree *expr_p)
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
while (ctx
&& (ctx->region_type == ORT_WORKSHARE
- || ctx->region_type == ORT_SIMD))
+ || ctx->region_type == ORT_SIMD
+ || ctx->region_type == ORT_ACC))
ctx = ctx->outer_context;
if (!ctx && !nonlocal_vlas->add (decl))
{
@@ -5579,7 +5593,8 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
}
else if (ctx->region_type != ORT_WORKSHARE
&& ctx->region_type != ORT_SIMD
- && ctx->region_type != ORT_TARGET_DATA)
+ && ctx->region_type != ORT_ACC
+ && !(ctx->region_type & ORT_TARGET_DATA))
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@@ -5667,11 +5682,13 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
/* We shouldn't be re-adding the decl with the same data
sharing class. */
gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
- /* The only combination of data sharing classes we should see is
- FIRSTPRIVATE and LASTPRIVATE. */
nflags = n->value | flags;
- gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
- == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)
+ /* The only combination of data sharing classes we should see is
+ FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
+ reduction variables to be used in data sharing clauses. */
+ gcc_assert ((ctx->region_type & ORT_ACC) != 0
+ || ((nflags & GOVD_DATA_SHARE_CLASS)
+ == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
|| (flags & GOVD_DATA_SHARE_CLASS) == 0);
n->value = nflags;
return;
@@ -5968,20 +5985,47 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
else if (is_scalar)
nflags |= GOVD_FIRSTPRIVATE;
}
- tree type = TREE_TYPE (decl);
- if (nflags == flags
- && gimplify_omp_ctxp->target_firstprivatize_array_bases
- && lang_hooks.decls.omp_privatize_by_reference (decl))
- type = TREE_TYPE (type);
- if (nflags == flags
- && !lang_hooks.types.omp_mappable_type (type))
+
+ struct gimplify_omp_ctx *octx = ctx->outer_context;
+ if ((ctx->region_type & ORT_ACC) && octx)
{
- error ("%qD referenced in target region does not have "
- "a mappable type", decl);
- nflags |= GOVD_MAP | GOVD_EXPLICIT;
+ /* Look in outer OpenACC contexts, to see if there's a
+ data attribute for this variable. */
+ omp_notice_variable (octx, decl, in_code);
+
+ for (; octx; octx = octx->outer_context)
+ {
+ if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
+ break;
+ splay_tree_node n2
+ = splay_tree_lookup (octx->variables,
+ (splay_tree_key) decl);
+ if (n2)
+ {
+ nflags |= GOVD_MAP;
+ goto found_outer;
+ }
+ }
}
- else if (nflags == flags)
- nflags |= GOVD_MAP;
+
+ {
+ tree type = TREE_TYPE (decl);
+
+ if (nflags == flags
+ && gimplify_omp_ctxp->target_firstprivatize_array_bases
+ && lang_hooks.decls.omp_privatize_by_reference (decl))
+ type = TREE_TYPE (type);
+ if (nflags == flags
+ && !lang_hooks.types.omp_mappable_type (type))
+ {
+ error ("%qD referenced in target region does not have "
+ "a mappable type", decl);
+ nflags |= GOVD_MAP | GOVD_EXPLICIT;
+ }
+ else if (nflags == flags)
+ nflags |= GOVD_MAP;
+ }
+ found_outer:
omp_add_variable (ctx, decl, nflags);
}
else
@@ -5998,7 +6042,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
{
if (ctx->region_type == ORT_WORKSHARE
|| ctx->region_type == ORT_SIMD
- || ctx->region_type == ORT_TARGET_DATA)
+ || ctx->region_type == ORT_ACC
+ || (ctx->region_type & ORT_TARGET_DATA) != 0)
goto do_outer;
flags = omp_default_clause (ctx, decl, in_code, flags);
@@ -6112,7 +6157,8 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
}
if (ctx->region_type != ORT_WORKSHARE
- && ctx->region_type != ORT_SIMD)
+ && ctx->region_type != ORT_SIMD
+ && ctx->region_type != ORT_ACC)
return false;
else if (ctx->outer_context)
return omp_is_private (ctx->outer_context, decl, simd);
@@ -6168,7 +6214,8 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
}
}
while (ctx->region_type == ORT_WORKSHARE
- || ctx->region_type == ORT_SIMD);
+ || ctx->region_type == ORT_SIMD
+ || ctx->region_type == ORT_ACC);
return false;
}
@@ -6311,7 +6358,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
omp_notice_variable (outer_ctx->outer_context, decl, true);
}
else if (outer_ctx
- && outer_ctx->region_type == ORT_WORKSHARE
+ && (outer_ctx->region_type == ORT_WORKSHARE
+ || outer_ctx->region_type == ORT_ACC)
&& outer_ctx->combined_loop
&& splay_tree_lookup (outer_ctx->variables,
(splay_tree_key) decl) == NULL
@@ -6335,7 +6383,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
goto do_add;
case OMP_CLAUSE_REDUCTION:
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
- check_non_private = "reduction";
+ /* OpenACC permits reductions on private variables. */
+ if (!(region_type & ORT_ACC))
+ check_non_private = "reduction";
decl = OMP_CLAUSE_DECL (c);
if (TREE_CODE (decl) == MEM_REF)
{
@@ -7704,7 +7754,7 @@ gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
- gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_WORKSHARE,
+ gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
OACC_CACHE);
gimplify_adjust_omp_clauses (pre_p, &OACC_CACHE_CLAUSES (expr), OACC_CACHE);
@@ -7833,7 +7883,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case OMP_FOR:
case CILK_FOR:
case OMP_DISTRIBUTE:
+ break;
case OACC_LOOP:
+ ort = ORT_ACC;
break;
case OMP_TASKLOOP:
if (find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
@@ -8895,10 +8947,14 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
break;
case OACC_KERNELS:
+ ort = ORT_ACC_KERNELS;
+ break;
case OACC_PARALLEL:
- ort = ORT_TARGET;
+ ort = ORT_ACC_PARALLEL;
break;
case OACC_DATA:
+ ort = ORT_ACC_DATA;
+ break;
case OMP_TARGET_DATA:
ort = ORT_TARGET_DATA;
break;
@@ -8920,7 +8976,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
pop_gimplify_context (g);
else
pop_gimplify_context (NULL);
- if (ort == ORT_TARGET_DATA)
+ if ((ort & ORT_TARGET_DATA) != 0)
{
enum built_in_function end_ix;
switch (TREE_CODE (expr))
@@ -8995,17 +9051,18 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
tree expr = *expr_p;
int kind;
gomp_target *stmt;
+ enum omp_region_type ort = ORT_WORKSHARE;
switch (TREE_CODE (expr))
{
case OACC_ENTER_DATA:
- kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
- break;
case OACC_EXIT_DATA:
kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
+ ort = ORT_ACC;
break;
case OACC_UPDATE:
kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
+ ort = ORT_ACC;
break;
case OMP_TARGET_UPDATE:
kind = GF_OMP_TARGET_KIND_UPDATE;
@@ -9020,7 +9077,7 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
- ORT_WORKSHARE, TREE_CODE (expr));
+ ort, TREE_CODE (expr));
gimplify_adjust_omp_clauses (pre_p, &OMP_STANDALONE_CLAUSES (expr),
TREE_CODE (expr));
stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));