[PATCH] OpenMP: Noncontiguous "target update" for Fortran
This patch implements noncontiguous "target update" for Fortran, on top of the following in-review patch series: https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609031.html (with followup: https://gcc.gnu.org/pipermail/gcc-patches/2023-January/609566.html) and: https://gcc.gnu.org/pipermail/gcc-patches/2023-March/613785.html The existing middle end/runtime bits relating to C++ support are reused, with some small adjustments, e.g.: 1. The node used to map the OMP "array descriptor" (from omp-low.cc onwards) now uses the OMP_CLAUSE_SIZE field as a bias (the difference between the "virtual origin" element with zero indices in each dimension and the first element actually stored in memory). 2. The OMP_CLAUSE_SIZE field of a GOMP_MAP_DIM_STRIDE node may now be used to store a "span", which is the distance in bytes between two adjacent elements in an array (with unit stride) when that is different from the element size, as it can be in Fortran. The implementation goes to some effort to massage Fortran array metadata (array descriptors) into a form that can ultimately be consumed by omp_target_memcpy_rect_worker. The method for doing this is described in comments in the patch body. Tested with offloading to nvptx. OK? 2023-04-27 Julian Brown gcc/fortran/ * openmp.cc (resolve_omp_clauses): Don't forbid "target update" with non-unit stride. * trans-openmp.cc (gfc_trans_omp_arrayshape_type, gfc_omp_calculate_gcd, gfc_desc_to_omp_noncontig_array, gfc_omp_contiguous_update_p): New functions. (gfc_trans_omp_clauses): Handle noncontiguous to/from clauses for OMP "target update" directives. gcc/ * gimplify.cc (gimplify_adjust_omp_clauses): Don't gimplify VIEW_CONVERT_EXPR away in GOMP_MAP_TO_GRID/GOMP_MAP_FROM_GRID clauses. * omp-low.cc (omp_noncontig_descriptor_type): Add SPAN field. (scan_sharing_clauses): Don't store descriptor size in its OMP_CLAUSE_SIZE field. (lower_omp_target): Add missing OMP_CLAUSE_MAP check. Add special-case string handling. Handle span and bias. Use low bound instead of zero as index for trailing full dimensions. libgomp/ * libgomp.h (omp_noncontig_array_desc): Add span field. * target.c (omp_target_memcpy_rect_worker): Add span parameter. Update forward declaration. Handle span != element_size. (gomp_update): Handle bias in descriptor's size slot. Update calls to omp_target_memcpy_rect_worker. * testsuite/libgomp.fortran/noncontig-updates-1.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-2.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-3.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-4.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-5.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-6.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-7.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-8.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-9.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-10.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-11.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-12.f90: New test. * testsuite/libgomp.fortran/noncontig-updates-13.f90: New test. gcc/testsuite/ * gfortran.dg/gomp/noncontig-updates-1.f90: New test. * gfortran.dg/gomp/noncontig-updates-2.f90: New test. * gfortran.dg/gomp/noncontig-updates-3.f90: New test. * gfortran.dg/gomp/noncontig-updates-4.f90: New test. --- gcc/fortran/openmp.cc | 5 +- gcc/fortran/trans-openmp.cc | 496 ++ gcc/gimplify.cc | 10 + gcc/omp-low.cc| 73 ++- .../gfortran.dg/gomp/noncontig-updates-1.f90 | 19 + .../gfortran.dg/gomp/noncontig-updates-2.f90 | 16 + .../gfortran.dg/gomp/noncontig-updates-3.f90 | 16 + .../gfortran.dg/gomp/noncontig-updates-4.f90 | 15 + libgomp/libgomp.h | 1 + libgomp/target.c | 47 +- .../libgomp.fortran/noncontig-updates-1.f90 | 54 ++ .../libgomp.fortran/noncontig-updates-10.f90 | 29 + .../libgomp.fortran/noncontig-updates-11.f90 | 51 ++ .../libgomp.fortran/noncontig-updates-12.f90 | 59 +++ .../libgomp.fortran/noncontig-updates-13.f90 | 42 ++ .../libgomp.fortran/noncontig-updates-2.f90 | 101 .../libgomp.fortran/noncontig-updates-3.f90 | 47 ++ .../libgomp.fortran/noncontig-updates-4.f90 | 78 +++ .../libgomp.fortran/noncontig-updates-5.f90 | 55 ++ .../libgomp.fortran/noncontig-updates-6.f90 | 34 ++ .../libgomp.fortran/noncontig-updates-7.f90 | 36 ++ .../libgomp.fortran/noncontig-update
[PATCH] OpenACC: Stand-alone attach/detach clause fixes for Fortran [PR109622]
This patch fixes several cases where multiple attach or detach mapping nodes were being created for stand-alone attach or detach clauses in Fortran. After the introduction of stricter checking later during compilation, these extra nodes could cause ICEs, as seen in the PR. The patch also fixes cases that "happened to work" previously where the user attaches/detaches a pointer to array using a descriptor, and (I think!) the "_data" field has offset zero, hence the same address as the descriptor as a whole. Tested with offloading to nvptx. OK? Thanks, Julian 2023-04-27 Julian Brown PR fortran/109622 gcc/fortran/ * trans-openmp.cc (gfc_trans_omp_clauses): Attach/detach clause fixes. gcc/testsuite/ * gfortran.dg/goacc/attach-descriptor.f90: Adjust expected output. libgomp/ * testsuite/libgomp.fortran/pr109622.f90: New test. * testsuite/libgomp.fortran/pr109622-2.f90: New test. * testsuite/libgomp.fortran/pr109622-3.f90: New test. --- gcc/fortran/trans-openmp.cc | 36 +-- .../gfortran.dg/goacc/attach-descriptor.f90 | 12 +++ .../testsuite/libgomp.fortran/pr109622-2.f90 | 32 + .../testsuite/libgomp.fortran/pr109622-3.f90 | 32 + .../testsuite/libgomp.fortran/pr109622.f90| 32 + 5 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 libgomp/testsuite/libgomp.fortran/pr109622-2.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr109622-3.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr109622.f90 diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 4ff9c59df5cb..dbb4a335ab57 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -3388,6 +3388,17 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, gfc_add_block_to_block (block, &se.post); if (pointer || allocatable) { + /* If it's a bare attach/detach clause, we just want +to perform a single attach/detach operation, of the +pointer itself, not of the pointed-to object. */ + if (openacc + && (n->u.map_op == OMP_MAP_ATTACH + || n->u.map_op == OMP_MAP_DETACH)) + { + OMP_CLAUSE_SIZE (node) = size_zero_node; + goto finalize_map_clause; + } + node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP); gomp_map_kind kind @@ -3458,6 +3469,19 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, { if (pointer || (openacc && allocatable)) { + /* If it's a bare attach/detach clause, we just want +to perform a single attach/detach operation, of the +pointer itself, not of the pointed-to object. */ + if (openacc + && (n->u.map_op == OMP_MAP_ATTACH + || n->u.map_op == OMP_MAP_DETACH)) + { + OMP_CLAUSE_DECL (node) + = build_fold_addr_expr (inner); + OMP_CLAUSE_SIZE (node) = size_zero_node; + goto finalize_map_clause; + } + tree data, size; if (lastref->u.c.component->ts.type == BT_CLASS) @@ -3494,12 +3518,18 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, else if (lastref->type == REF_ARRAY && lastref->u.ar.type == AR_FULL) { - /* Just pass the (auto-dereferenced) decl through for -bare attach and detach clauses. */ + /* Bare attach and detach clauses don't want any +additional nodes. */ if (n->u.map_op == OMP_MAP_ATTACH || n->u.map_op == OMP_MAP_DETACH) { - OMP_CLAUSE_DECL (node) = inner; + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (inner))) + { + tree ptr = gfc_conv_descriptor_data_get (inner); + OMP_CLAUSE_DECL (node) = ptr; + } + else + OMP_CLAUSE_DECL (node) = inner; OMP_CLAUSE_SIZE (node) = size_zero_node; goto finalize_map_clause; } diff --git a/gcc/testsuite/gfor