diff options
author | Cesar Philippidis <cesar@codesourcery.com> | 2019-10-25 07:28:40 -0700 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2019-10-25 16:28:40 +0200 |
commit | ec0846134e08ed5f645db858385b385227ae5026 (patch) | |
tree | cf234892de7408cd52df5184bcccdcae675e7bb4 /gcc/gimplify.c | |
parent | 643c11a1f7407d694031b12d86fd6fc0fd5e9d10 (diff) | |
download | gcc-ec0846134e08ed5f645db858385b385227ae5026.zip gcc-ec0846134e08ed5f645db858385b385227ae5026.tar.gz gcc-ec0846134e08ed5f645db858385b385227ae5026.tar.bz2 |
[Fortran] OpenACC – permit common blocks in some clauses
2019-10-25 Cesar Philippidis <cesar@codesourcery.com>
Tobias Burnus <tobias@codesourcery.com>
gcc/fortran/
* openmp.c (gfc_match_omp_map_clause): Add and pass allow_commons
argument.
(gfc_match_omp_clauses): Update calls to permit common blocks for
OpenACC's copy/copyin/copyout, create/delete, host,
pcopy/pcopy_in/pcopy_out, present_or_copy, present_or_copy_in,
present_or_copy_out, present_or_create and self.
gcc/
* gimplify.c (oacc_default_clause): Privatize fortran common blocks.
(omp_notice_variable): Defer the expansion of DECL_VALUE_EXPR for
common block decls.
gcc/testsuite/
* gfortran.dg/goacc/common-block-1.f90: New test.
* gfortran.dg/goacc/common-block-2.f90: New test.
* gfortran.dg/goacc/common-block-3.f90: New test.
libgomp/
* testsuite/libgomp.oacc-fortran/common-block-1.f90: New test.
* testsuite/libgomp.oacc-fortran/common-block-2.f90: New test.
* testsuite/libgomp.oacc-fortran/common-block-3.f90: New test.
Reviewed-by: Thomas Schwinge <thomas@codesourcery.com>
Co-Authored-By: Tobias Burnus <tobias@codesourcery.com>
From-SVN: r277451
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 05ae2f1..fdf6b69 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -7227,15 +7227,28 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) { const char *rkind; bool on_device = false; + bool is_private = false; bool declared = is_oacc_declared (decl); tree type = TREE_TYPE (decl); if (lang_hooks.decls.omp_privatize_by_reference (decl)) type = TREE_TYPE (type); + /* For Fortran COMMON blocks, only used variables in those blocks are + transfered and remapped. The block itself will have a private clause to + avoid transfering the data twice. + The hook evaluates to false by default. For a variable in Fortran's COMMON + or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only + the variables in such a COMMON/EQUIVALENCE block shall be privatized not + the whole block. For C++ and Fortran, it can also be true under certain + other conditions, if DECL_HAS_VALUE_EXPR. */ + if (RECORD_OR_UNION_TYPE_P (type)) + is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false); + if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0 && is_global_var (decl) - && device_resident_p (decl)) + && device_resident_p (decl) + && !is_private) { on_device = true; flags |= GOVD_MAP_TO_ONLY; @@ -7246,7 +7259,9 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) case ORT_ACC_KERNELS: rkind = "kernels"; - if (AGGREGATE_TYPE_P (type)) + if (is_private) + flags |= GOVD_FIRSTPRIVATE; + else if (AGGREGATE_TYPE_P (type)) { /* Aggregates default to 'present_or_copy', or 'present'. */ if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT) @@ -7263,7 +7278,9 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) case ORT_ACC_PARALLEL: rkind = "parallel"; - if (on_device || declared) + if (is_private) + flags |= GOVD_FIRSTPRIVATE; + else if (on_device || declared) flags |= GOVD_MAP; else if (AGGREGATE_TYPE_P (type)) { @@ -7327,10 +7344,18 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) if (DECL_HAS_VALUE_EXPR_P (decl)) { - tree value = get_base_address (DECL_VALUE_EXPR (decl)); + if (ctx->region_type & ORT_ACC) + /* For OpenACC, defer expansion of value to avoid transfering + privatized common block data instead of im-/explicitly transfered + variables which are in common blocks. */ + ; + else + { + tree value = get_base_address (DECL_VALUE_EXPR (decl)); - if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) - return omp_notice_threadprivate_variable (ctx, decl, value); + if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value)) + return omp_notice_threadprivate_variable (ctx, decl, value); + } } if (gimplify_omp_ctxp->outer_context == NULL @@ -7361,7 +7386,13 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); if ((ctx->region_type & ORT_TARGET) != 0) { - ret = lang_hooks.decls.omp_disregard_value_expr (decl, true); + if (ctx->region_type & ORT_ACC) + /* For OpenACC, as remarked above, defer expansion. */ + shared = false; + else + shared = true; + + ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); if (n == NULL) { unsigned nflags = flags; @@ -7528,7 +7559,11 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) } } - shared = ((flags | n->value) & GOVD_SHARED) != 0; + if (ctx->region_type & ORT_ACC) + /* For OpenACC, as remarked above, defer expansion. */ + shared = false; + else + shared = ((flags | n->value) & GOVD_SHARED) != 0; ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared); /* If nothing changed, there's nothing left to do. */ |