diff options
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); |