diff mbox series

[1/3] OpenMP: Fix "exit data" for array sections for ref-to-ptr components

Message ID f39626f1c48c842b523aa46e3c23b2aabe356e27.1678491986.git.julian@codesourcery.com
State New
Headers show
Series OpenMP 5.0: Strided updates and array shape-operator support (C++) | expand

Commit Message

Julian Brown March 10, 2023, 11:53 p.m. UTC
This patch fixes "exit data" for (C++) reference-to-pointer struct
components with array sections, such as:

  struct S { int *&ptr; [...] };
  ...
  #pragma omp target exit data map(from: str->ptr, str->ptr[0:n])

Such exits need two "detach" operations. We need to unmap
both the pointer and the slice. That idiom is recognized by
omp_resolve_clause_dependencies, but before omp_build_struct_sibling_lists
finishes the resulting mapping nodes are represented like this:

  GOMP_MAP_FROM GOMP_MAP_DETACH GOMP_MAP_ATTACH_DETACH

And at the moment, that won't be recognized as a single mapping group
as it should be. This patch fixes that.

(This is covered by a test case added in later patches in this series,
e.g. libgomp/testsuite/libgomp.c++/array-shaping-8.C.)

2023-03-10  Julian Brown  <julian@codesourcery.com>

gcc/
	* gimplify.cc (omp_get_attachment): Handle GOMP_MAP_DETACH here.
	(omp_group_last): Handle *, GOMP_MAP_DETACH, GOMP_MAP_ATTACH_DETACH
	groups for "exit data" of reference-to-pointer component array
	sections.
	(omp_group_base): Handle GOMP_MAP_DETACH.
---
 gcc/gimplify.cc | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index f3c97932608a..ae2fbc65c690 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9067,6 +9067,7 @@  omp_get_attachment (omp_mapping_group *grp)
 
 	  case GOMP_MAP_ATTACH_DETACH:
 	  case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
+	  case GOMP_MAP_DETACH:
 	    return OMP_CLAUSE_DECL (node);
 
 	  default:
@@ -9143,23 +9144,43 @@  omp_group_last (tree *start_p)
 		     == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
 		 || (OMP_CLAUSE_MAP_KIND (nc)
 		     == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
+		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_TO_PSET))
 	{
-	  grp_last_p = &OMP_CLAUSE_CHAIN (c);
-	  c = nc;
 	  tree nc2 = OMP_CLAUSE_CHAIN (nc);
+	  if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
+	    {
+	      /* In the specific case we're doing "exit data" on an array
+		 slice of a reference-to-pointer struct component, we will see
+		 DETACH followed by ATTACH_DETACH here.  We want to treat that
+		 as a single group. In other cases DETACH might represent a
+		 stand-alone "detach" clause, so we don't want to consider
+		 that part of the group.  */
+	      if (nc2
+		  && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
+		  && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
+		goto consume_two_nodes;
+	      else
+		break;
+	    }
 	  if (nc2
 	      && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
 	      && (OMP_CLAUSE_MAP_KIND (nc)
 		  == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
 	      && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
 	    {
+	    consume_two_nodes:
 	      grp_last_p = &OMP_CLAUSE_CHAIN (nc);
 	      c = nc2;
-	      nc2 = OMP_CLAUSE_CHAIN (nc2);
+	      nc = OMP_CLAUSE_CHAIN (nc2);
+	    }
+	  else
+	    {
+	      grp_last_p = &OMP_CLAUSE_CHAIN (c);
+	      c = nc;
+	      nc = nc2;
 	    }
-	   nc = nc2;
 	}
       break;
 
@@ -9305,6 +9326,7 @@  omp_group_base (omp_mapping_group *grp, unsigned int *chained,
 	  case GOMP_MAP_ALWAYS_POINTER:
 	  case GOMP_MAP_ATTACH_DETACH:
 	  case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
+	  case GOMP_MAP_DETACH:
 	    return *grp->grp_start;
 
 	  default: