https://gcc.gnu.org/g:4e14dd9c20db032fb77cc59fa3e5dc9a18ca533f
commit 4e14dd9c20db032fb77cc59fa3e5dc9a18ca533f Author: Julian Brown <jul...@codesourcery.com> Date: Sat Jun 10 07:53:57 2023 +0000 OpenACC: "declare create" fixes wrt. "allocatable" variables This patch fixes a case revealed by the previous patch where a synthetic "acc data" region created for a "declare create" variable could interact strangely with lexical inheritance behaviour. In fact, it doesn't seem right to create the "acc data" region for allocatable variables at all -- doing so means that a data region is likely to be created for an unallocated variable. The fix is not to add such variables to the synthetic "acc data" region at all, and defer to the code that performs "enter data"/"exit data" for them when allocated/deallocated on the host instead. Then, "declare create" variables are implicitly turned into "present" clauses on in-scope offload regions. 2023-06-16 Julian Brown <jul...@codesourcery.com> gcc/fortran/ * trans-openmp.cc (gfc_omp_finish_clause): Handle "declare create" for scalar allocatable variables. (gfc_trans_omp_clauses): Don't include allocatable vars in synthetic "acc data" region created for "declare create" variables. Mark such variables with the "oacc declare create" attribute instead. Don't create ALWAYS_POINTER mapping for target-to-host updates of declare create variables. (gfc_trans_oacc_declare): Handle empty clause list. gcc/ * gimplify.cc (gimplify_adjust_omp_clauses_1): Handle "oacc declare create" attribute. libgomp/ * testsuite/libgomp.oacc-fortran/declare-create-1.f90: New test. * testsuite/libgomp.oacc-fortran/declare-create-2.f90: New test. * testsuite/libgomp.oacc-fortran/declare-create-3.f90: New test. Diff: --- gcc/ChangeLog.omp | 5 +++ gcc/fortran/ChangeLog.omp | 11 ++++++ gcc/fortran/trans-openmp.cc | 45 +++++++++++++++++++--- gcc/gimplify.cc | 8 ++++ libgomp/ChangeLog.omp | 6 +++ .../libgomp.oacc-fortran/declare-create-1.f90 | 21 ++++++++++ .../libgomp.oacc-fortran/declare-create-2.f90 | 25 ++++++++++++ .../libgomp.oacc-fortran/declare-create-3.f90 | 25 ++++++++++++ 8 files changed, 141 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index ac55142fa48..05120c5266d 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,8 @@ +2023-06-19 Julian Brown <jul...@codesourcery.com> + + * gimplify.cc (gimplify_adjust_omp_clauses_1): Handle "oacc declare + create" attribute. + 2023-06-19 Julian Brown <jul...@codesourcery.com> * gimplify.cc (omp_tsort_mark, omp_mapping_group): Move before diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp index 04c900a3ee3..e28e1133d69 100644 --- a/gcc/fortran/ChangeLog.omp +++ b/gcc/fortran/ChangeLog.omp @@ -1,3 +1,14 @@ +2023-06-19 Julian Brown <jul...@codesourcery.com> + + * trans-openmp.cc (gfc_omp_finish_clause): Handle "declare create" for + scalar allocatable variables. + (gfc_trans_omp_clauses): Don't include allocatable vars in synthetic + "acc data" region created for "declare create" variables. Mark such + variables with the "oacc declare create" attribute instead. Don't + create ALWAYS_POINTER mapping for target-to-host updates of declare + create variables. + (gfc_trans_oacc_declare): Handle empty clause list. + 2024-06-05 Jakub Jelinek <ja...@redhat.com> Frederik Harwath <frede...@codesourcery.com> Sandra Loosemore <san...@codesourcery.com> diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 71a8fff7496..33436bd9c5f 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -1628,7 +1628,16 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc) orig_decl = decl; c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); - OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER); + if (openacc + && GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) + && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_PRESENT) + /* This allows "declare create" to work for scalar allocatables. The + resulting mapping nodes are: + force_present(*var) firstprivate_pointer(var) + which is the same as an explicit "present" clause gives. */ + OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_FIRSTPRIVATE_POINTER); + else + OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER); OMP_CLAUSE_DECL (c4) = decl; OMP_CLAUSE_SIZE (c4) = size_int (0); decl = build_fold_indirect_ref (decl); @@ -4579,6 +4588,29 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, if (!n->sym->attr.referenced) continue; + /* We do not want to include allocatable vars in a synthetic + "acc data" region created for "!$acc declare create" vars. + Such variables are handled by augmenting allocate/deallocate + statements elsewhere (with + "acc enter data declare_allocate(...)", etc.). */ + if (op == EXEC_OACC_DECLARE + && n->u.map.op == OMP_MAP_ALLOC + && n->sym->attr.allocatable + && n->sym->attr.oacc_declare_create) + { + tree tree_var = gfc_get_symbol_decl (n->sym); + if (!lookup_attribute ("oacc declare create", + DECL_ATTRIBUTES (tree_var))) + DECL_ATTRIBUTES (tree_var) + = tree_cons (get_identifier ("oacc declare create"), + NULL_TREE, DECL_ATTRIBUTES (tree_var)); + /* We might need to turn what would normally be a + "firstprivate" mapping into a "present" mapping. For the + latter, we need the decl to be addressable. */ + TREE_ADDRESSABLE (tree_var) = 1; + continue; + } + bool always_modifier = false; tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP); tree node2 = NULL_TREE; @@ -4807,7 +4839,8 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, else if (op == EXEC_OMP_TARGET_EXIT_DATA) gmk = GOMP_MAP_RELEASE; else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) - && n->sym->attr.oacc_declare_create) + && n->sym->attr.oacc_declare_create + && n->u.map.op != OMP_MAP_FORCE_FROM) { if (clauses->update_allocatable) gmk = GOMP_MAP_ALWAYS_POINTER; @@ -9781,10 +9814,12 @@ gfc_trans_oacc_declare (gfc_code *code) gfc_start_block (&block); oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->clauses, - code->loc, false, true); + code->loc, false, true, + EXEC_OACC_DECLARE); stmt = gfc_trans_omp_code (code->block->next, true); - stmt = build2_loc (input_location, construct_code, void_type_node, stmt, - oacc_clauses); + if (oacc_clauses) + stmt = build2_loc (input_location, construct_code, void_type_node, stmt, + oacc_clauses); gfc_add_expr_to_block (&block, stmt); return gfc_finish_block (&block); diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index cf9cf613784..efa28440a80 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -13692,6 +13692,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) g->have_offload = true; } } + if (lookup_attribute ("oacc declare create", DECL_ATTRIBUTES (decl))) + flags |= GOVD_MAP_FORCE_PRESENT; } else if (flags & GOVD_SHARED) { @@ -13731,6 +13733,12 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) "%<target%> construct", decl); return 0; } + if (lookup_attribute ("oacc declare create", DECL_ATTRIBUTES (decl))) + { + code = OMP_CLAUSE_MAP; + flags &= ~GOVD_FIRSTPRIVATE; + flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT; + } } else if (flags & GOVD_LASTPRIVATE) code = OMP_CLAUSE_LASTPRIVATE; diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp index 518f51b091f..ff49b4769de 100644 --- a/libgomp/ChangeLog.omp +++ b/libgomp/ChangeLog.omp @@ -1,3 +1,9 @@ +2023-06-19 Julian Brown <jul...@codesourcery.com> + + * testsuite/libgomp.oacc-fortran/declare-create-1.f90: New test. + * testsuite/libgomp.oacc-fortran/declare-create-2.f90: New test. + * testsuite/libgomp.oacc-fortran/declare-create-3.f90: New test. + 2023-06-19 Julian Brown <jul...@codesourcery.com> * testsuite/libgomp.oacc-c-c++-common/pr70828.c: New test. diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90 new file mode 100644 index 00000000000..9e7e60f1440 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90 @@ -0,0 +1,21 @@ +! { dg-do run } + +module m +integer :: mint +!$acc declare create (mint) +end module m + +program p +use m + +mint = 0 + +!$acc serial +mint = 5 +!$acc end serial + +!$acc update host(mint) + +if (mint.ne.5) stop 1 + +end program p diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90 new file mode 100644 index 00000000000..675f6902775 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90 @@ -0,0 +1,25 @@ +! { dg-do run } + +module m +integer, allocatable :: mint +!$acc declare create (mint) +end module m + +program p +use m + +allocate(mint) + +mint = 0 + +!$acc serial +mint = 5 +!$acc end serial + +!$acc update host(mint) + +if (mint.ne.5) stop 1 + +deallocate(mint) + +end program p diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90 new file mode 100644 index 00000000000..16651cb1f5e --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90 @@ -0,0 +1,25 @@ +! { dg-do run } + +module m +integer, allocatable :: mint(:) +!$acc declare create (mint) +end module m + +program p +use m + +allocate(mint(1:20)) + +mint = 0 + +!$acc serial +mint = 5 +!$acc end serial + +!$acc update host(mint) + +if (any(mint.ne.5)) stop 1 + +deallocate(mint) + +end program p