[PATCH 0/7] [og10] OpenACC/OpenMP: Rework struct component handling

2021-05-11 Thread Julian Brown
Hi,

This patch series reworks how indirect struct (or class or derived-type)
component mappings are lowered for OpenMP and OpenACC.  The series is
currently based on the og10 branch, but I'm planning to rebase it to
trunk and repost soon.

Currently on og10, there are some conflicts with Chung-Lin's recent
work to support indirect struct component mapping and (particularly) C++
lambdas for OpenMP -- some of those conflicts are addressed by this
patch series, but some still need attention.  There are a couple of
regressions (see the last patch in the series) so the whole series isn't
quite ready for og10 yet.  Hopefully posting now will help us resolve
those last bits!

The first two patches in the series have been tested by themselves
however, and those ones do *not* cause regressions. If it seems helpful,
I can commit those now.

Julian

Julian Brown (7):
  [og10] Unify ARRAY_REF/INDIRECT_REF stripping code in
extract_base_bit_offset
  [og10] Refactor struct lowering for OpenMP/OpenACC in gimplify.c
  [og10] Revert gimplify.c parts of "Fix template case of non-static
member access inside member functions"
  [og10] Revert gimplify.c parts of "Arrow operator handling for C
front-end in OpenMP map clauses"
  [og10] Rewrite GOMP_MAP_ATTACH_DETACH mappings for OpenMP also
  [og10] Rework indirect struct handling for OpenACC/OpenMP in
gimplify.c
  [og10] WIP GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION changes

 gcc/fortran/trans-openmp.c|   20 +-
 gcc/gimplify.c| 1178 ++---
 gcc/omp-low.c |   16 +-
 gcc/testsuite/g++.dg/goacc/member-array-acc.C |   13 +
 gcc/testsuite/g++.dg/gomp/member-array-omp.C  |   13 +
 gcc/testsuite/g++.dg/gomp/target-3.C  |4 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |2 +-
 .../libgomp.oacc-c-c++-common/deep-copy-15.c  |   68 +
 .../libgomp.oacc-c-c++-common/deep-copy-16.c  |   95 ++
 9 files changed, 921 insertions(+), 488 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/goacc/member-array-acc.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/member-array-omp.C
 create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c
 create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-16.c

-- 
2.29.2



[PATCH 1/7] [og10] Unify ARRAY_REF/INDIRECT_REF stripping code in extract_base_bit_offset

2021-05-11 Thread Julian Brown
For historical reasons, it seems that extract_base_bit_offset
unnecessarily used two different ways to strip ARRAY_REF/INDIRECT_REF
nodes from component accesses. I verified that the two ways of performing
the operation gave the same results across the whole testsuite (and
several additional benchmarks).

The code was like this since an earlier "mechanical" refactoring by me,
first posted here:

  https://gcc.gnu.org/pipermail/gcc-patches/2018-November/510503.html

It was never clear to me if there was an important semantic
difference between the two ways of stripping the base before calling
get_inner_reference, but it appears that there is not, so one can go away.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (extract_base_bit_offset): Unify ARRAY_REF/INDIRECT_REF
stripping code in first call/subsequent call cases.
---
 gcc/gimplify.c | 32 +++-
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ba071e8ae68..b36b961bf26 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8340,31 +8340,21 @@ extract_base_bit_offset (tree base, tree *base_ref, 
poly_int64 *bitposp,
   poly_offset_int poffset;
 
   if (base_ref)
-{
-  *base_ref = NULL_TREE;
-
-  while (TREE_CODE (base) == ARRAY_REF)
-   base = TREE_OPERAND (base, 0);
+*base_ref = NULL_TREE;
 
-  if (TREE_CODE (base) == INDIRECT_REF)
-   base = TREE_OPERAND (base, 0);
-}
-  else
+  if (TREE_CODE (base) == ARRAY_REF)
 {
-  if (TREE_CODE (base) == ARRAY_REF)
-   {
- while (TREE_CODE (base) == ARRAY_REF)
-   base = TREE_OPERAND (base, 0);
- if (TREE_CODE (base) != COMPONENT_REF
- || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
-   return NULL_TREE;
-   }
-  else if (TREE_CODE (base) == INDIRECT_REF
-  && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
-  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
-  == REFERENCE_TYPE))
+  while (TREE_CODE (base) == ARRAY_REF)
base = TREE_OPERAND (base, 0);
+  if (TREE_CODE (base) != COMPONENT_REF
+ || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
+   return NULL_TREE;
 }
+  else if (TREE_CODE (base) == INDIRECT_REF
+  && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
+  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
+  == REFERENCE_TYPE))
+base = TREE_OPERAND (base, 0);
 
   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
  &unsignedp, &reversep, &volatilep);
-- 
2.29.2



[PATCH 2/7] [og10] Refactor struct lowering for OpenMP/OpenACC in gimplify.c

2021-05-11 Thread Julian Brown
This patch is a second attempt at refactoring struct component mapping
handling for OpenACC/OpenMP during gimplification, after the patch I
posted here:

  https://gcc.gnu.org/pipermail/gcc-patches/2018-November/510503.html

And improved here, post-review:

  https://gcc.gnu.org/pipermail/gcc-patches/2019-November/533394.html

This patch goes further, in that the struct-handling code is outlined
into its own function (to create the "GOMP_MAP_STRUCT" node and the
sorted list of nodes immediately following it, from a set of mappings
of components of a given struct or derived type). I've also gone through
the list-handling code and attempted to add comments documenting how it
works to the best of my understanding, and broken out a couple of helper
functions in order to (hopefully) have the code self-document better also.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (insert_struct_comp_map): Refactor function into...
(build_struct_comp_nodes): This new function.  Remove list handling
and improve self-documentation.
(insert_node_after, move_node_after, move_nodes_after,
move_concat_nodes_after): New helper functions.
(build_struct_group): New function to build up GOMP_MAP_STRUCT node
groups to map struct components. Outlined from...
(gimplify_scan_omp_clauses): Here.
---
 gcc/gimplify.c | 846 +++--
 1 file changed, 540 insertions(+), 306 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index b36b961bf26..ad192b27208 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8253,73 +8253,66 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   return 1;
 }
 
-/* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
-   GOMP_MAP_STRUCT mapping.  C is an always_pointer mapping.  STRUCT_NODE is
-   the struct node to insert the new mapping after (when the struct node is
-   initially created).  PREV_NODE is the first of two or three mappings for a
-   pointer, and is either:
- - the node before C, when a pair of mappings is used, e.g. for a C/C++
-   array section.
- - not the node before C.  This is true when we have a reference-to-pointer
-   type (with a mapping for the reference and for the pointer), or for
-   Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
-   If SCP is non-null, the new node is inserted before *SCP.
-   if SCP is null, the new node is inserted before PREV_NODE.
-   The return type is:
- - PREV_NODE, if SCP is non-null.
- - The newly-created ALLOC or RELEASE node, if SCP is null.
- - The second newly-created ALLOC or RELEASE node, if we are mapping a
-   reference to a pointer.  */
+/* For a set of mappings describing an array section pointed to by a struct
+   (or derived type, etc.) component, create an "alloc" or "release" node to
+   insert into a list following a GOMP_MAP_STRUCT node.  For some types of
+   mapping (e.g. Fortran arrays with descriptors), an additional mapping may
+   be created that is inserted into the list of mapping nodes attached to the
+   directive being processed -- not part of the sorted list of nodes after
+   GOMP_MAP_STRUCT.
+
+   CODE is the code of the directive being processed.  GRP_START and GRP_END
+   are the first and last of two or three nodes representing this array section
+   mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
+   GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER).  EXTRA_NODE is
+   filled with the additional node described above, if needed.
+
+   This function does not add the new nodes to any lists itself.  It is the
+   responsibility of the caller to do that.  */
 
 static tree
-insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
-   tree prev_node, tree *scp)
+build_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
+tree *extra_node)
 {
   enum gomp_map_kind mkind
 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
 
-  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
-  tree cl = scp ? prev_node : c2;
+  gcc_assert (grp_start != grp_end);
+
+  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
-  OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
-  OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
-  if (OMP_CLAUSE_CHAIN (prev_node) != c
-  && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
-  && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
- == GOMP_MAP_TO_PSET))
-OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
+  OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
+  OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
+  tree grp_mid = NULL_TREE;
+  if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
+grp_mid = OMP_CLAUSE_CHAIN (grp_start);
+

[PATCH 3/7] [og10] Revert gimplify.c parts of "Fix template case of non-static member access inside member functions"

2021-05-11 Thread Julian Brown
With the "rework indirect struct handling" patch later in this series,
some parts of this earlier patch (by Chung-Lin) become unnecessary.
This patch reverts those bits.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (gimplify_scan_omp_clauses): Don't strip nops in indir_p
case. Don't add map(*pointer_to_struct) mappings to struct_deref_set.
---
 gcc/gimplify.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ad192b27208..0674d882861 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -9574,7 +9574,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
{
  indir_p = true;
  decl = TREE_OPERAND (decl, 0);
- STRIP_NOPS (decl);
}
  if (TREE_CODE (decl) == INDIRECT_REF
  && DECL_P (TREE_OPERAND (decl, 0))
@@ -9747,24 +9746,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  break;
}
 
- /* If this was of the form map(*pointer_to_struct), then the
-'pointer_to_struct' DECL should be considered deref'ed.  */
- if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
-  || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
-  || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
- && INDIRECT_REF_P (orig_decl)
- && DECL_P (TREE_OPERAND (orig_decl, 0))
- && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
-   {
- tree ptr = TREE_OPERAND (orig_decl, 0);
- if (!struct_deref_set || !struct_deref_set->contains (ptr))
-   {
- if (!struct_deref_set)
-   struct_deref_set = new hash_set ();
- struct_deref_set->add (ptr);
-   }
-   }
-
  if (!remove
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
-- 
2.29.2



[PATCH 4/7] [og10] Revert gimplify.c parts of "Arrow operator handling for C front-end in OpenMP map clauses"

2021-05-11 Thread Julian Brown
With the "rework indirect struct handling" patch later in this series,
some parts of this earlier patch (by Chung-Lin) become unnecessary.
This patch reverts those bits.

An XFAIL has been added for a test that fails for the time being with
this reversion, until the later patch in the series fixes it again.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (build_struct_group): Remove COMPONENT_REF_P parameter.
Don't call gimplify_expr on decl in non-reference case.  Remove code to
add FIRSTPRIVATE_POINTER for *pointer-to-struct expressions.
(gimplify_scan_omp_clauses): Remove COMPONENT_REF_P handling.

gcc/testsuite/
* gcc.dg/gomp/target-3.c: XFAIL test.
---
 gcc/gimplify.c   | 41 
 gcc/testsuite/gcc.dg/gomp/target-3.c |  2 +-
 2 files changed, 6 insertions(+), 37 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 0674d882861..c2072c7188f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8686,8 +8686,7 @@ move_concat_nodes_after (tree first_new, tree 
*last_new_tail, tree *first_ptr,
 static tree
 build_struct_group (struct gimplify_omp_ctx *ctx,
enum omp_region_type region_type, enum tree_code code,
-   tree decl, tree *pd, bool component_ref_p,
-   unsigned int *flags, tree c,
+   tree decl, tree *pd, unsigned int *flags, tree c,
hash_map *&struct_map_to_clause,
tree *&prev_list_p, tree *&list_p, gimple_seq *pre_p,
bool *cont)
@@ -8737,13 +8736,7 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
   if (base_ref)
OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
   else
-   {
- OMP_CLAUSE_DECL (l) = unshare_expr (decl);
- if (!DECL_P (OMP_CLAUSE_DECL (l))
- && (gimplify_expr (&OMP_CLAUSE_DECL (l), pre_p, NULL,
-is_gimple_lvalue, fb_lvalue) == GS_ERROR))
-   return error_mark_node;
-   }
+   OMP_CLAUSE_DECL (l) = decl;
   OMP_CLAUSE_SIZE (l)
= (!attach ? size_int (1)
   : (DECL_P (OMP_CLAUSE_DECL (l))
@@ -8785,27 +8778,6 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
*flags |= GOVD_SEEN;
   if (has_attachments)
*flags |= GOVD_MAP_HAS_ATTACHMENTS;
-
-  /* If this is a *pointer-to-struct expression, make sure a
-firstprivate map of the base-pointer exists.  */
-  if (component_ref_p
- && ((TREE_CODE (decl) == MEM_REF
-  && integer_zerop (TREE_OPERAND (decl, 1)))
- || INDIRECT_REF_P (decl))
- && DECL_P (TREE_OPERAND (decl, 0))
- && !splay_tree_lookup (ctx->variables,
-((splay_tree_key) TREE_OPERAND (decl, 0
-   {
- decl = TREE_OPERAND (decl, 0);
- tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
- enum gomp_map_kind mkind = GOMP_MAP_FIRSTPRIVATE_POINTER;
- OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
- OMP_CLAUSE_DECL (c2) = decl;
- OMP_CLAUSE_SIZE (c2) = size_zero_node;
- OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
- OMP_CLAUSE_CHAIN (c) = c2;
-   }
-
   return decl;
 }
   else if (struct_map_to_clause)
@@ -9660,9 +9632,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
  if ((DECL_P (decl)
-  || (component_ref_p
-  && (INDIRECT_REF_P (decl)
-  || TREE_CODE (decl) == MEM_REF)))
+  || (component_ref_p && INDIRECT_REF_P (decl)))
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
@@ -9710,9 +9680,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  bool cont = false;
  tree add_decl
= build_struct_group (ctx, region_type, code, decl, pd,
- component_ref_p, &flags, c,
- struct_map_to_clause, prev_list_p,
- list_p, pre_p, &cont);
+ &flags, c, struct_map_to_clause,
+ prev_list_p, list_p, pre_p, &cont);
  if (add_decl == error_mark_node)
{
  remove = true;
diff --git a/gcc/testsuite/gcc.dg/gomp/target-3.c 
b/gcc/testsuite/gcc.dg/gomp/target-3.c
index 3e7921270c9..08e42eeb304 100644
--- a/gcc/testsuite/gcc.dg/gomp/target-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/target-3.c
@@ -13,4 +13,4 @@ void foo (struct S *s)
   #pragma omp target enter data map (alloc: s->a, s->b)

[PATCH 5/7] [og10] Rewrite GOMP_MAP_ATTACH_DETACH mappings for OpenMP also

2021-05-11 Thread Julian Brown
It never makes sense for a GOMP_MAP_ATTACH_DETACH mapping to survive
beyond gimplify.c, and with OpenMP making use of that mapping type too
now alongside OpenACC, there are cases where it was making it through
to omp-low.c.  This patch rewrites such mappings to GOMP_MAP_ATTACH or
GOMP_MAP_DETACH unconditionally for both OpenACC and OpenMP, in cases
where it hasn't otherwise been handled already in the preceding code.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (gimplify_scan_omp_clauses): Remove OpenACC-only
condition for changing GOMP_MAP_ATTACH_DETACH to GOMP_MAP_ATTACH or
GOMP_MAP_DETACH.  Use detach for OMP_TARGET_EXIT_DATA also.
---
 gcc/gimplify.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c2072c7188f..86000f8470b 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -9695,16 +9695,11 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  if (cont)
continue;
}
- else if ((code == OACC_ENTER_DATA
-   || code == OACC_EXIT_DATA
-   || code == OACC_DATA
-   || code == OACC_PARALLEL
-   || code == OACC_KERNELS
-   || code == OACC_SERIAL)
-  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
+ else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
{
- gomp_map_kind k = (code == OACC_EXIT_DATA
-? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
+ gomp_map_kind k
+   = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
+  ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
  OMP_CLAUSE_SET_MAP_KIND (c, k);
}
 
-- 
2.29.2



[PATCH 6/7] [og10] Rework indirect struct handling for OpenACC/OpenMP in gimplify.c

2021-05-11 Thread Julian Brown
This patch reworks indirect struct handling in gimplify.c (i.e. for struct
components mapped with "mystruct->a[0:n]", "mystruct->b", etc.), for
both OpenACC and OpenMP.  The key observation leading to these changes
was that component mappings of references-to-structures is already
implemented and working, and indirect struct component handling via a
pointer can work quite similarly.  That lets us remove some earlier,
special-case handling for mapping indirect struct component accesses
for OpenACC, which required the pointed-to struct to be manually mapped
before the indirect component mapping.

With this patch, you can map struct components directly (e.g. an array
slice "mystruct->a[0:n]") just like you can map a non-indirect struct
component slice ("mystruct.a[0:n]"). Both references-to-pointers (with
the former syntax) and references to structs (with the latter syntax)
work now.

For Fortran class pointers, we no longer re-use GOMP_MAP_TO_PSET for the
class metadata (the structure that points to the class data and vptr)
-- it is instead treated as any other struct.

For C++, the struct handling also works for class members ("this->foo"),
without having to explicitly map "this[:1]" first.

For OpenACC, we permit chained indirect component references
("mystruct->a->b[0:n]"), though only the last part of such mappings will
trigger an attach/detach operation.  To properly use such a construct
on the target, you must still manually map "mystruct->a[:1]" first --
but there's no need to map "mystruct[:1]" explicitly before that.

2021-05-11  Julian Brown  

gcc/fortran/
* trans-openmp.c (gfc_trans_omp_clauses): Don't create GOMP_MAP_TO_PSET
mappings for class metadata, nor GOMP_MAP_POINTER mappings for
POINTER_TYPE_P decls.

gcc/
* gimplify.c (extract_base_bit_offset): Add BASE_IND parameter.  Handle
pointer-typed indirect references alongside reference-typed ones.
(strip_components, strip_components_and_deref, aggregate_base_p): New
functions.
(build_struct_group): Remove PD parameter.  Add pointer type indirect
ref handling, including chained references.  Handle pointers and
references to structs in OpenACC regions as well as OpenMP ones.
Remove gimplification of non-pointer struct component mappings.
(gimplify_scan_omp_clauses): Remove struct_deref_set handling.  Rework
pointer-type indirect structure access handling to work more like
the reference-typed handling.
* omp-low.c (scan_sharing_clauses): Handle pointer-type indirect struct
references, and references to pointers to structs also.

gcc/testsuite/
* g++.dg/goacc/member-array-acc.C: New test.
* g++.dg/gomp/member-array-omp.C: New test.
* g++.dg/gomp/target-3.C: Adjust scan dump matching patterns.
* g++.dg/gomp/target-this-2.C: Adjust scan dump matching patterns.
* gcc.dg/gomp/target-3.c: Remove XFAIL.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c: New test.
* testsuite/libgomp.oacc-c-c++-common/deep-copy-16.c: New test.
---
 gcc/fortran/trans-openmp.c|  20 +-
 gcc/gimplify.c| 321 +++---
 gcc/omp-low.c |  16 +-
 gcc/testsuite/g++.dg/goacc/member-array-acc.C |  13 +
 gcc/testsuite/g++.dg/gomp/member-array-omp.C  |  13 +
 gcc/testsuite/g++.dg/gomp/target-3.C  |   4 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |   2 +-
 gcc/testsuite/gcc.dg/gomp/target-3.c  |   2 +-
 .../libgomp.oacc-c-c++-common/deep-copy-15.c  |  68 
 .../libgomp.oacc-c-c++-common/deep-copy-16.c  |  95 ++
 10 files changed, 405 insertions(+), 149 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/goacc/member-array-acc.C
 create mode 100644 gcc/testsuite/g++.dg/gomp/member-array-omp.C
 create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c
 create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-16.c

diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index e3df4bbf84e..9098b35c9f1 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -2693,30 +2693,16 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
  tree present = gfc_omp_check_optional_argument (decl, true);
  if (openacc && n->sym->ts.type == BT_CLASS)
{
- tree type = TREE_TYPE (decl);
  if (n->sym->attr.optional)
sorry ("optional class parameter");
- if (POINTER_TYPE_P (type))
-   {
- node4 = build_omp_clause (input_location,
-   OMP_CLAUSE_MAP);
- OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
- OMP_CLAUSE_DECL (node4) = decl;
-  

[PATCH 7/7] [og10] WIP GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION changes

2021-05-11 Thread Julian Brown
This work-in-progress patch tries to get
GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION to behave more like
GOMP_MAP_ATTACH_DETACH -- in that the mapping is made to form groups
to be processed by build_struct_group/build_struct_comp_map.  I think
that's important to integrate with how groups of mappings for array
sections are handled in other cases.

This patch isn't sufficient by itself to fix a couple of broken test cases
at present (libgomp.c++/target-lambda-1.C, libgomp.c++/target-this-4.C),
though.

2021-05-11  Julian Brown  

gcc/
* gimplify.c (build_struct_comp_nodes): Add
GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION handling.
(build_struct_group): Process GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
as part of pointer group.
(gimplify_scan_omp_clauses): Update prev_list_p such that
GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION will form part of pointer
group.
---
 gcc/gimplify.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 6d204908c82..c5cb486aa23 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -8298,7 +8298,9 @@ build_struct_comp_nodes (enum tree_code code, tree 
grp_start, tree grp_end,
   if (grp_mid
   && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
   && (OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER
- || OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ATTACH_DETACH))
+ || OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ATTACH_DETACH
+ || (OMP_CLAUSE_MAP_KIND (grp_mid)
+ == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
 {
   tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
@@ -8774,12 +8776,14 @@ build_struct_group (struct gimplify_omp_ctx *ctx,
? splay_tree_lookup (ctx->variables, (splay_tree_key) decl)
: NULL);
   bool ptr = (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER);
-  bool attach_detach = (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH);
+  bool attach_detach = (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
+   || (OMP_CLAUSE_MAP_KIND (c)
+   == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   bool attach = (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH);
   bool has_attachments = false;
   /* For OpenACC, pointers in structs should trigger an attach action.  */
-  if (attach_detach
+  if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
   && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
  || code == OMP_TARGET_ENTER_DATA
  || code == OMP_TARGET_EXIT_DATA))
@@ -9784,6 +9788,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  if (!remove
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
+ && (OMP_CLAUSE_MAP_KIND (c)
+ != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
  && OMP_CLAUSE_CHAIN (c)
  && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
@@ -9792,7 +9798,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
  == GOMP_MAP_ATTACH_DETACH)
  || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
- == GOMP_MAP_TO_PSET)))
+ == GOMP_MAP_TO_PSET)
+ || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
+ == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
prev_list_p = list_p;
 
  break;
-- 
2.29.2