diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2020-09-15 09:24:47 +0200 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2020-09-15 09:24:47 +0200 |
commit | 972da557463ec946a31577294764a186b9821012 (patch) | |
tree | d0ab3a41af83955eccee4b164c805262939e022d /gcc/fortran | |
parent | f9d2def016410a2095df6b399097b482f82064a5 (diff) | |
download | gcc-972da557463ec946a31577294764a186b9821012.zip gcc-972da557463ec946a31577294764a186b9821012.tar.gz gcc-972da557463ec946a31577294764a186b9821012.tar.bz2 |
OpenMP/Fortran: Fix (re)mapping of allocatable/pointer arrays [PR96668]
gcc/cp/ChangeLog:
PR fortran/96668
* cp-gimplify.c (cxx_omp_finish_clause): Add bool openacc arg.
* cp-tree.h (cxx_omp_finish_clause): Likewise
* semantics.c (handle_omp_for_class_iterator): Update call.
gcc/fortran/ChangeLog:
PR fortran/96668
* trans.h (gfc_omp_finish_clause): Add bool openacc arg.
* trans-openmp.c (gfc_omp_finish_clause): Ditto. Use
GOMP_MAP_ALWAYS_POINTER with PSET for pointers.
(gfc_trans_omp_clauses): Like the latter and also if the always
modifier is used.
gcc/ChangeLog:
PR fortran/96668
* gimplify.c (gimplify_omp_for): Add 'bool openacc' argument;
update omp_finish_clause calls.
(gimplify_adjust_omp_clauses_1, gimplify_adjust_omp_clauses,
gimplify_expr, gimplify_omp_loop): Update omp_finish_clause
and/or gimplify_for calls.
* langhooks-def.h (lhd_omp_finish_clause): Add bool openacc arg.
* langhooks.c (lhd_omp_finish_clause): Likewise.
* langhooks.h (lhd_omp_finish_clause): Likewise.
* omp-low.c (scan_sharing_clauses): Keep GOMP_MAP_TO_PSET cause for
'declare target' vars.
include/ChangeLog:
PR fortran/96668
* gomp-constants.h (GOMP_MAP_ALWAYS_POINTER_P): Define.
libgomp/ChangeLog:
PR fortran/96668
* libgomp.h (struct target_var_desc): Add has_null_ptr_assoc member.
* target.c (gomp_map_vars_existing): Add always_to_flag flag.
(gomp_map_vars_existing): Update call to it.
(gomp_map_fields_existing): Likewise
(gomp_map_vars_internal): Update PSET handling such that if a nullptr is
now allocated or if GOMP_MAP_POINTER is used PSET is updated and pointer
remapped.
(GOMP_target_enter_exit_data): Hanlde GOMP_MAP_ALWAYS_POINTER like
GOMP_MAP_POINTER.
* testsuite/libgomp.fortran/map-alloc-ptr-1.f90: New test.
* testsuite/libgomp.fortran/map-alloc-ptr-2.f90: New test.
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/trans-openmp.c | 31 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 2 |
2 files changed, 29 insertions, 4 deletions
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 0e1da04..9ec0df2 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1276,7 +1276,7 @@ gfc_build_cond_assign_expr (stmtblock_t *block, tree cond_val, } void -gfc_omp_finish_clause (tree c, gimple_seq *pre_p) +gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) return; @@ -1357,6 +1357,16 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) tree type = TREE_TYPE (decl); tree ptr = gfc_conv_descriptor_data_get (decl); + /* OpenMP: automatically map pointer targets with the pointer; + hence, always update the descriptor/pointer itself. + NOTE: This also remaps the pointer for allocatable arrays with + 'target' attribute which also don't have the 'restrict' qualifier. */ + bool always_modifier = false; + + if (!openacc + && !(TYPE_QUALS (TREE_TYPE (ptr)) & TYPE_QUAL_RESTRICT)) + always_modifier = true; + if (present) ptr = gfc_build_cond_assign_expr (&block, present, ptr, null_pointer_node); @@ -1376,7 +1386,8 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p) OMP_CLAUSE_DECL (c2) = decl; OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (type); c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER); + OMP_CLAUSE_SET_MAP_KIND (c3, always_modifier ? GOMP_MAP_ALWAYS_POINTER + : GOMP_MAP_POINTER); if (present) { ptr = gfc_conv_descriptor_data_get (decl); @@ -2549,11 +2560,19 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, if (!n->sym->attr.referenced) continue; + bool always_modifier = false; tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP); tree node2 = NULL_TREE; tree node3 = NULL_TREE; tree node4 = NULL_TREE; + /* OpenMP: automatically map pointer targets with the pointer; + hence, always update the descriptor/pointer itself. */ + if (!openacc + && ((n->expr == NULL && n->sym->attr.pointer) + || (n->expr && gfc_expr_attr (n->expr).pointer))) + always_modifier = true; + switch (n->u.map_op) { case OMP_MAP_ALLOC: @@ -2575,12 +2594,15 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TOFROM); break; case OMP_MAP_ALWAYS_TO: + always_modifier = true; OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TO); break; case OMP_MAP_ALWAYS_FROM: + always_modifier = true; OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_FROM); break; case OMP_MAP_ALWAYS_TOFROM: + always_modifier = true; OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TOFROM); break; case OMP_MAP_RELEASE: @@ -2760,7 +2782,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, goto finalize_map_clause; } else - OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER); + OMP_CLAUSE_SET_MAP_KIND (node3, + always_modifier + ? GOMP_MAP_ALWAYS_POINTER + : GOMP_MAP_POINTER); /* We have to check for n->sym->attr.dimension because of scalar coarrays. */ diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index e126fe9..d257963 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -810,7 +810,7 @@ tree gfc_omp_clause_copy_ctor (tree, tree, tree); tree gfc_omp_clause_assign_op (tree, tree, tree); tree gfc_omp_clause_linear_ctor (tree, tree, tree, tree); tree gfc_omp_clause_dtor (tree, tree); -void gfc_omp_finish_clause (tree, gimple_seq *); +void gfc_omp_finish_clause (tree, gimple_seq *, bool); bool gfc_omp_scalar_p (tree); bool gfc_omp_disregard_value_expr (tree, bool); bool gfc_omp_private_debug_clause (tree, bool); |