[Patch] Fortran/OpenMP: Improve associate-name diagnostic [PR103039]

2022-03-18 Thread Tobias Burnus

This patch addresses a side issue found when looking at PR103039.

Namely instead of printing:

   55 |   !$omp parallel firstprivate(tt)
  |  1
Error: ASSOCIATE name ‘__tmp_INTEGER_4’ in FIRSTPRIVATE clause at (1)

With the patch, the error is:

Error: Associate name ‘tt’ in FIRSTPRIVATE clause at (1)

That is: It prints the proper name and it uses 'associate name'
matching the Fortran standard – and takes into account that an
associate name not only used with ASSOCIATE but also with
SELECT TYPE, SELECT RANK, and (untested) CHANGE TEAMS.

OK for mainline?

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
Fortran/OpenMP: Improve associate-name diagnostic [PR103039]

gcc/fortran/ChangeLog:

	PR fortran/103039
	* openmp.cc (resolve_omp_clauses): Improve associate-name diagnostic
	for select type/rank.

gcc/testsuite/ChangeLog:

	PR fortran/103039
	* gfortran.dg/gomp/associate1.f90: Update dg-error.
	* gfortran.dg/gomp/associate2.f90: New test.

 gcc/fortran/openmp.cc | 12 +++--
 gcc/testsuite/gfortran.dg/gomp/associate1.f90 | 40 +++---
 gcc/testsuite/gfortran.dg/gomp/associate2.f90 | 76 +++
 3 files changed, 104 insertions(+), 24 deletions(-)

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 16cd03a3d67..714148138c2 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -6782,8 +6782,10 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		  gfc_error ("Cray pointee %qs in SHARED clause at %L",
 			n->sym->name, &n->where);
 		if (n->sym->attr.associate_var)
-		  gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
-			 n->sym->name, &n->where);
+		  gfc_error ("Associate name %qs in SHARED clause at %L",
+			 n->sym->attr.select_type_temporary
+			 ? n->sym->assoc->target->symtree->n.sym->name
+			 : n->sym->name, &n->where);
 		if (omp_clauses->detach
 		&& n->sym == omp_clauses->detach->symtree->n.sym)
 		  gfc_error ("DETACH event handle %qs in SHARED clause at %L",
@@ -7163,8 +7165,10 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 		  gfc_error ("Cray pointee %qs in %s clause at %L",
 			n->sym->name, name, &n->where);
 		if (n->sym->attr.associate_var)
-		  gfc_error ("ASSOCIATE name %qs in %s clause at %L",
-			 n->sym->name, name, &n->where);
+		  gfc_error ("Associate name %qs in %s clause at %L",
+			 n->sym->attr.select_type_temporary
+			 ? n->sym->assoc->target->symtree->n.sym->name
+			 : n->sym->name, name, &n->where);
 		if (list != OMP_LIST_PRIVATE && is_reduction)
 		  {
 		if (n->sym->attr.proc_pointer)
diff --git a/gcc/testsuite/gfortran.dg/gomp/associate1.f90 b/gcc/testsuite/gfortran.dg/gomp/associate1.f90
index abc5ae95a0d..a44099e005f 100644
--- a/gcc/testsuite/gfortran.dg/gomp/associate1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/associate1.f90
@@ -16,65 +16,65 @@ program associate1
   j = 2
   associate(k => v, l => a(i, j), m => a(i, :))
   associate(n => b(j)%c(:, :)%i, o => a, p => b)
-!$omp parallel shared (l)	! { dg-error "ASSOCIATE name" }
+!$omp parallel shared (l)	! { dg-error "Associate name" }
 !$omp end parallel
-!$omp parallel firstprivate (m)	! { dg-error "ASSOCIATE name" }
+!$omp parallel firstprivate (m)	! { dg-error "Associate name" }
 !$omp end parallel
-!$omp parallel reduction (+: k)	! { dg-error "ASSOCIATE name" }
+!$omp parallel reduction (+: k)	! { dg-error "Associate name" }
 !$omp end parallel
-!$omp parallel do firstprivate (k)	! { dg-error "ASSOCIATE name" }
+!$omp parallel do firstprivate (k)	! { dg-error "Associate name" }
   do i = 1, 10
   end do
-!$omp parallel do lastprivate (n)	! { dg-error "ASSOCIATE name" }
+!$omp parallel do lastprivate (n)	! { dg-error "Associate name" }
   do i = 1, 10
   end do
-!$omp parallel do private (o)	! { dg-error "ASSOCIATE name" }
+!$omp parallel do private (o)	! { dg-error "Associate name" }
   do i = 1, 10
   end do
-!$omp parallel do shared (p)	! { dg-error "ASSOCIATE name" }
+!$omp parallel do shared (p)	! { dg-error "Associate name" }
   do i = 1, 10
   end do
-!$omp task private (k)		! { dg-error "ASSOCIATE name" }
+!$omp task private (k)		! { dg-error "Associate name" }
 !$omp end task
-!$omp task shared (l)		! { dg-error "ASSOCIATE name" }
+!$omp task shared (l)		! { dg-error "Associate name" }
 !$omp end task
-!$omp task firstprivate (m)	! { dg-error "ASSOCIATE name" }
+!$omp task firstprivate (m)	! { dg-error "Associate name" }
 !$omp end task
-!$omp do private (l)		! { dg-error "ASSOCIATE name" }
+!$omp do private (l)		! { dg-error "Associate name" }
   do i = 1, 10
   end do
-!$omp do reduction (*: k)	! { dg-error "ASSOCIATE name" }
+!$omp do reduction (*: k)	! { dg-error "Associate name

Re: [Patch] Fortran/OpenMP: Improve associate-name diagnostic [PR103039]

2022-03-18 Thread Jakub Jelinek via Fortran
On Fri, Mar 18, 2022 at 02:15:11PM +0100, Tobias Burnus wrote:
> This patch addresses a side issue found when looking at PR103039.
> 
> Namely instead of printing:
> 
>55 |   !$omp parallel firstprivate(tt)
>   |  1
> Error: ASSOCIATE name ‘__tmp_INTEGER_4’ in FIRSTPRIVATE clause at (1)
> 
> With the patch, the error is:
> 
> Error: Associate name ‘tt’ in FIRSTPRIVATE clause at (1)
> 
> That is: It prints the proper name and it uses 'associate name'
> matching the Fortran standard – and takes into account that an
> associate name not only used with ASSOCIATE but also with
> SELECT TYPE, SELECT RANK, and (untested) CHANGE TEAMS.
> 
> OK for mainline?

LGTM, thanks.

> Fortran/OpenMP: Improve associate-name diagnostic [PR103039]
> 
> gcc/fortran/ChangeLog:
> 
>   PR fortran/103039
>   * openmp.cc (resolve_omp_clauses): Improve associate-name diagnostic
>   for select type/rank.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR fortran/103039
>   * gfortran.dg/gomp/associate1.f90: Update dg-error.
>   * gfortran.dg/gomp/associate2.f90: New test.
> 
>  gcc/fortran/openmp.cc | 12 +++--
>  gcc/testsuite/gfortran.dg/gomp/associate1.f90 | 40 +++---
>  gcc/testsuite/gfortran.dg/gomp/associate2.f90 | 76 
> +++
>  3 files changed, 104 insertions(+), 24 deletions(-)

Jakub



[PATCH v2 00/11] OpenMP 5.0: C & C++ "declare mapper" support (plus struct rework, etc.)

2022-03-18 Thread Julian Brown
Hi Jakub,

This is a new version of the series posted here:

  https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590582.html

Again, this isn't for committing now (it's definitely stage 1 material)
but I'm posting now for comments on the general approach (to any of the
contained parts) and to avoid duplicating effort, etc..

Relative to the previously-posted version, this version of the series
makes changes to the "address inspector" code and its call sites in order
to hopefully clarify the logic used to create pointer mapping nodes and
so forth, and implements "declare mapper" support for C as well as C++.

Further commentary on individual patches.  This version of the series has
been tested (offloading to NVPTX) as a whole, for now.

Thanks,

Julian

Julian Brown (11):
  OpenMP 5.0: Clause ordering for OpenMP 5.0 (topological sorting by
base pointer)
  Remove omp_target_reorder_clauses
  OpenMP/OpenACC struct sibling list gimplification extension and rework
  OpenMP/OpenACC: Add inspector class to unify mapped address analysis
  OpenMP: Handle reference-typed struct members
  OpenMP: lvalue parsing for map clauses (C++)
  OpenMP: lvalue parsing for map clauses (C)
  Use OMP_ARRAY_SECTION instead of TREE_LIST in C++ FE
  OpenMP 5.0 "declare mapper" support for C++
  OpenMP: Use OMP_ARRAY_SECTION instead of TREE_LIST for array sections
in C FE
  OpenMP: Support OpenMP 5.0 "declare mapper" directives for C

 gcc/c-family/c-common.h   |   58 +
 gcc/c-family/c-omp.cc |  583 
 gcc/c/c-decl.cc   |  169 +
 gcc/c/c-objc-common.h |   12 +
 gcc/c/c-parser.cc |  463 ++-
 gcc/c/c-tree.h|9 +
 gcc/c/c-typeck.cc |  392 +--
 gcc/cp/cp-gimplify.cc |6 +
 gcc/cp/cp-objcp-common.h  |9 +
 gcc/cp/cp-tree.h  |   13 +
 gcc/cp/decl.cc|   18 +-
 gcc/cp/error.cc   |9 +
 gcc/cp/mangle.cc  |5 +-
 gcc/cp/name-lookup.cc |3 +-
 gcc/cp/parser.cc  |  543 ++-
 gcc/cp/parser.h   |3 +
 gcc/cp/pt.cc  |  144 +-
 gcc/cp/semantics.cc   |  728 +++--
 gcc/fortran/parse.cc  |3 +
 gcc/fortran/trans-openmp.cc   |   20 +-
 gcc/gimplify.cc   | 2905 -
 gcc/langhooks-def.h   |   13 +
 gcc/langhooks.cc  |   35 +
 gcc/langhooks.h   |   16 +
 gcc/omp-general.h |   84 +
 gcc/omp-low.cc|   23 +-
 .../c-c++-common/gomp/declare-mapper-12.c |   22 +
 .../c-c++-common/gomp/declare-mapper-3.c  |   30 +
 .../c-c++-common/gomp/declare-mapper-4.c  |   78 +
 .../c-c++-common/gomp/declare-mapper-5.c  |   26 +
 .../c-c++-common/gomp/declare-mapper-6.c  |   24 +
 .../c-c++-common/gomp/declare-mapper-7.c  |   30 +
 .../c-c++-common/gomp/declare-mapper-8.c  |   43 +
 .../c-c++-common/gomp/declare-mapper-9.c  |   34 +
 gcc/testsuite/c-c++-common/gomp/map-1.c   |3 +-
 gcc/testsuite/c-c++-common/gomp/map-6.c   |   12 +-
 gcc/testsuite/g++.dg/goacc/member-array-acc.C |   13 +
 gcc/testsuite/g++.dg/gomp/declare-mapper-1.C  |   58 +
 gcc/testsuite/g++.dg/gomp/declare-mapper-2.C  |   30 +
 gcc/testsuite/g++.dg/gomp/ind-base-3.C|   38 +
 gcc/testsuite/g++.dg/gomp/map-assignment-1.C  |   12 +
 gcc/testsuite/g++.dg/gomp/map-inc-1.C |   10 +
 gcc/testsuite/g++.dg/gomp/map-lvalue-ref-1.C  |   19 +
 gcc/testsuite/g++.dg/gomp/map-ptrmem-1.C  |   37 +
 gcc/testsuite/g++.dg/gomp/map-ptrmem-2.C  |   40 +
 .../g++.dg/gomp/map-static-cast-lvalue-1.C|   17 +
 gcc/testsuite/g++.dg/gomp/map-ternary-1.C |   20 +
 gcc/testsuite/g++.dg/gomp/member-array-2.C|   92 +
 gcc/testsuite/g++.dg/gomp/member-array-omp.C  |   13 +
 gcc/testsuite/g++.dg/gomp/pr67522.C   |2 +-
 gcc/testsuite/g++.dg/gomp/target-3.C  |4 +-
 gcc/testsuite/g++.dg/gomp/target-lambda-1.C   |6 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |2 +-
 gcc/testsuite/g++.dg/gomp/target-this-3.C |4 +-
 gcc/testsuite/g++.dg/gomp/target-this-4.C |4 +-
 .../g++.dg/gomp/unmappable-component-1.C  |   21 +
 gcc/testsuite/gcc.dg/gomp/declare-mapper-10.c |   61 +
 gcc/testsuite/gcc.dg/gomp/declare-mapper-11.c |   33 +
 gcc/tree-core.h   |4 +
 gcc/tree-pretty-print.cc  |   56 +
 gcc/tree.cc   |2 +
 gcc/tree.def  |   10 +
 gcc/tree.h 

[PATCH v2 02/11] Remove omp_target_reorder_clauses

2022-03-18 Thread Julian Brown
This patch has been split out from the previous one to avoid a
confusingly-interleaved diff.  The two patches should probably be
committed squashed together.

2021-10-01  Julian Brown  

gcc/
* gimplify.c (omp_target_reorder_clauses): Delete.
---
 gcc/gimplify.cc | 207 
 1 file changed, 207 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 968cbd263f5..b667012a118 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -8738,213 +8738,6 @@ extract_base_bit_offset (tree base, tree *base_ref, 
poly_int64 *bitposp,
   return base;
 }
 
-#if 0
-/* Returns true if EXPR is or contains (as a sub-component) BASE_PTR.  */
-
-static bool
-is_or_contains_p (tree expr, tree base_ptr)
-{
-  if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
-  || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
-return operand_equal_p (TREE_OPERAND (expr, 0),
-   TREE_OPERAND (base_ptr, 0));
-  while (!operand_equal_p (expr, base_ptr))
-{
-  if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
-   base_ptr = TREE_OPERAND (base_ptr, 1);
-  if (TREE_CODE (base_ptr) == COMPONENT_REF
- || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
- || TREE_CODE (base_ptr) == SAVE_EXPR)
-   base_ptr = TREE_OPERAND (base_ptr, 0);
-  else
-   break;
-}
-  return operand_equal_p (expr, base_ptr);
-}
-
-
-/* Implement OpenMP 5.x map ordering rules for target directives. There are
-   several rules, and with some level of ambiguity, hopefully we can at least
-   collect the complexity here in one place.  */
-
-static void
-omp_target_reorder_clauses (tree *list_p)
-{
-  /* Collect refs to alloc/release/delete maps.  */
-  auto_vec ard;
-  tree *cp = list_p;
-  while (*cp != NULL_TREE)
-if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
-   && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
-   || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
-   || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
-  {
-   /* Unlink cp and push to ard.  */
-   tree c = *cp;
-   tree nc = OMP_CLAUSE_CHAIN (c);
-   *cp = nc;
-   ard.safe_push (c);
-
-   /* Any associated pointer type maps should also move along.  */
-   while (*cp != NULL_TREE
-  && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
-  && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
-  || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
- {
-   c = *cp;
-   nc = OMP_CLAUSE_CHAIN (c);
-   *cp = nc;
-   ard.safe_push (c);
- }
-  }
-else
-  cp = &OMP_CLAUSE_CHAIN (*cp);
-
-  /* Link alloc/release/delete maps to the end of list.  */
-  for (unsigned int i = 0; i < ard.length (); i++)
-{
-  *cp = ard[i];
-  cp = &OMP_CLAUSE_CHAIN (ard[i]);
-}
-  *cp = NULL_TREE;
-
-  /* OpenMP 5.0 requires that pointer variables are mapped before
- its use as a base-pointer.  */
-  auto_vec atf;
-  for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
-if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
-  {
-   /* Collect alloc, to, from, to/from clause tree pointers.  */
-   gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
-   if (k == GOMP_MAP_ALLOC
-   || k == GOMP_MAP_TO
-   || k == GOMP_MAP_FROM
-   || k == GOMP_MAP_TOFROM
-   || k == GOMP_MAP_ALWAYS_TO
-   || k == GOMP_MAP_ALWAYS_FROM
-   || k == GOMP_MAP_ALWAYS_TOFROM)
- atf.safe_push (cp);
-  }
-
-  for (unsigned int i = 0; i < atf.length (); i++)
-if (atf[i])
-  {
-   tree *cp = atf[i];
-   tree decl = OMP_CLAUSE_DECL (*cp);
-   if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
- {
-   tree base_ptr = TREE_OPERAND (decl, 0);
-   STRIP_TYPE_NOPS (base_ptr);
-   for (unsigned int j = i + 1; j < atf.length (); j++)
- if (atf[j])
-   {
- tree *cp2 = atf[j];
- tree decl2 = OMP_CLAUSE_DECL (*cp2);
-
- decl2 = OMP_CLAUSE_DECL (*cp2);
- if (is_or_contains_p (decl2, base_ptr))
-   {
- /* Move *cp2 to before *cp.  */
- tree c = *cp2;
- *cp2 = OMP_CLAUSE_CHAIN (c);
- OMP_CLAUSE_CHAIN (c) = *cp;
- *cp = c;
-
- if (*cp2 != NULL_TREE
- && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
- && OMP_CLAUSE_MAP_KIND (*cp2) == 
GOMP_MAP_ALWAYS_POINTER)
- 

[PATCH v2 01/11] OpenMP 5.0: Clause ordering for OpenMP 5.0 (topological sorting by base pointer)

2022-03-18 Thread Julian Brown
This patch reimplements the omp_target_reorder_clauses function in
anticipation of supporting "deeper" struct mappings (that is, with
several structure dereference operators, or similar).

The idea is that in place of the (possibly quadratic) algorithm in
omp_target_reorder_clauses that greedily moves clauses containing
addresses that are subexpressions of other addresses before those other
addresses, we employ a topological sort algorithm to calculate a proper
order for map clauses. This should run in linear time, and hopefully
handles degenerate cases where multiple "levels" of indirect accesses
are present on a given directive.

The new method also takes care to keep clause groups together, addressing
the concerns raised in:

  https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570501.html

To figure out if some given clause depends on a base pointer in another
clause, we strip off the outer layers of the address expression, and check
(via a tree_operand_hash hash table we have built) if the result is a
"base pointer" as defined in OpenMP 5.0 (1.2.6 Data Terminology). There
are some subtleties involved, however:

 - We must treat MEM_REF with zero offset the same as INDIRECT_REF.
   This should probably be fixed in the front ends instead so we always
   use a canonical form (probably INDIRECT_REF). The following patch
   shows one instance of the problem, but there may be others:

   https://gcc.gnu.org/pipermail/gcc-patches/2021-May/571382.html

 - Mapping a whole struct implies mapping each of that struct's
   elements, which may be base pointers. Because those base pointers
   aren't necessarily explicitly referenced in the directive in question,
   we treat the whole-struct mapping as a dependency instead.

This version of the patch has been moved to the front of the patch queue,
thus isn't dependent on any of the following struct-rework patches.

2021-11-23  Julian Brown  

gcc/
* gimplify.c (is_or_contains_p, omp_target_reorder_clauses): Delete
functions.
(omp_tsort_mark): Add enum.
(omp_mapping_group): Add struct.
(debug_mapping_group, omp_get_base_pointer, omp_get_attachment,
omp_group_last, omp_gather_mapping_groups, omp_group_base,
omp_index_mapping_groups, omp_containing_struct,
omp_tsort_mapping_groups_1, omp_tsort_mapping_groups,
omp_segregate_mapping_groups, omp_reorder_mapping_groups): New
functions.
(gimplify_scan_omp_clauses): Call above functions instead of
omp_target_reorder_clauses, unless we've seen an error.
* omp-low.c (scan_sharing_clauses): Avoid strict test if we haven't
sorted mapping groups.

gcc/testsuite/
* g++.dg/gomp/target-lambda-1.C: Adjust expected output.
* g++.dg/gomp/target-this-3.C: Likewise.
* g++.dg/gomp/target-this-4.C: Likewise.
---
 gcc/gimplify.cc | 785 +++-
 gcc/omp-low.cc  |   7 +-
 gcc/testsuite/g++.dg/gomp/target-lambda-1.C |   7 +-
 gcc/testsuite/g++.dg/gomp/target-this-3.C   |   4 +-
 gcc/testsuite/g++.dg/gomp/target-this-4.C   |   4 +-
 5 files changed, 793 insertions(+), 14 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 875b115d02d..968cbd263f5 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -8738,6 +8738,7 @@ extract_base_bit_offset (tree base, tree *base_ref, 
poly_int64 *bitposp,
   return base;
 }
 
+#if 0
 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR.  */
 
 static bool
@@ -8761,6 +8762,7 @@ is_or_contains_p (tree expr, tree base_ptr)
   return operand_equal_p (expr, base_ptr);
 }
 
+
 /* Implement OpenMP 5.x map ordering rules for target directives. There are
several rules, and with some level of ambiguity, hopefully we can at least
collect the complexity here in one place.  */
@@ -8940,6 +8942,761 @@ omp_target_reorder_clauses (tree *list_p)
}
   }
 }
+#endif
+
+
+enum omp_tsort_mark {
+  UNVISITED,
+  TEMPORARY,
+  PERMANENT
+};
+
+struct omp_mapping_group {
+  tree *grp_start;
+  tree grp_end;
+  omp_tsort_mark mark;
+  struct omp_mapping_group *sibling;
+  struct omp_mapping_group *next;
+};
+
+__attribute__((used)) static void
+debug_mapping_group (omp_mapping_group *grp)
+{
+  tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
+  OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
+  debug_generic_expr (*grp->grp_start);
+  OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
+}
+
+/* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
+   isn't one.  This needs improvement.  */
+
+static tree
+omp_get_base_pointer (tree expr)
+{
+  while (TREE_CODE (expr) == ARRAY_REF)
+expr = TREE_OPERAND (expr, 0);
+
+  while (TREE_CODE (expr) == COMPONENT_REF
+&& (DECL_P (TREE_OPERAND (expr, 0))
+|| (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)
+|| TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF
+|| (TREE_CODE (TREE_OPERAND (expr

[PATCH v2 03/11] OpenMP/OpenACC struct sibling list gimplification extension and rework

2022-03-18 Thread Julian Brown
This patch is a combination of several previously-posted patches,
rebased and squashed together, and with a couple of additional bugfixes:

"Rewrite GOMP_MAP_ATTACH_DETACH mappings unconditionally"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585440.html

"OpenMP/OpenACC: Move array_ref/indirect_ref handling code out of
extract_base_bit_offset"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585441.html

"OpenACC/OpenMP: Refactor struct lowering in gimplify.c"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585442.html

"OpenACC: Rework indirect struct handling in gimplify.c"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585443.html

"Remove base_ind/base_ref handling from extract_base_bit_offset"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585445.html

"OpenMP/OpenACC: Hoist struct sibling list handling in gimplification"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585448.html

"OpenACC: Make deep-copy-arrayofstruct.c a libgomp/runtime test"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585452.html

Unlike the previously-posted patch, this version does *not* contain
the following changes, which have been pulled out into separate patches
again or merged with other patches in this series:

"OpenMP: Allow array ref components for C & C++"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585449.html

"OpenMP: Fix non-zero attach/detach bias for struct dereferences"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585451.html

"OpenMP: Handle reference-typed struct members"
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585453.html

This brings the patch closer to being "just a refactor" than the
previously-posted version (hopefully easing review), though several
behavioural changes still remain.

2022-03-17  Julian Brown  

gcc/fortran/
* trans-openmp.cc (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 (gimplify_omp_var_data): Remove GOVD_MAP_HAS_ATTACHMENTS.
(insert_struct_comp_map): Refactor function into...
(build_struct_comp_nodes): This new function.  Remove list handling
and improve self-documentation.
(extract_base_bit_offset): Remove BASE_REF, OFFSETP parameters.  Move
code to strip outer parts of address out of function, but strip no-op
conversions.
(omp_mapping_group): Add DELETED field for use during reindexing.
(strip_components_and_deref, strip_indirections): New functions.
(omp_group_last, omp_group_base): Add GOMP_MAP_STRUCT handling.
(omp_gather_mapping_groups): Initialise DELETED field for new groups.
(omp_index_mapping_groups): Notice DELETED groups when (re)indexing.
(insert_node_after, move_node_after, move_nodes_after,
move_concat_nodes_after): New helper functions.
(accumulate_sibling_list): New function to build up GOMP_MAP_STRUCT
node groups for sibling lists. Outlined from gimplify_scan_omp_clauses.
(omp_build_struct_sibling_lists): New function.
(gimplify_scan_omp_clauses): Remove struct_map_to_clause,
struct_seen_clause, struct_deref_set.  Call
omp_build_struct_sibling_lists as pre-pass instead of handling sibling
lists in the function's main processing loop.
(gimplify_adjust_omp_clauses_1): Remove GOVD_MAP_HAS_ATTACHMENTS
handling, unused now.
* omp-low.cc (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: Update expected output.
* g++.dg/gomp/target-lambda-1.C: Likewise.
* g++.dg/gomp/target-this-2.C: Likewise.
* c-c++-common/goacc/deep-copy-arrayofstruct.c: Move test from here.

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.
* testsuite/libgomp.oacc-c++/deep-copy-17.C: New test.
* testsuite/libgomp.oacc-c-c++-common/deep-copy-arrayofstruct.c: Move
test to here, make "run" test.
---
 gcc/fortran/trans-openmp.cc   |   20 +-
 gcc/gimplify.cc   | 1512 ++---
 gcc/omp-low.cc|   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-lambda-1.C   |3 +-
 gcc/testsuite/g++.dg/gomp/target-this-2.C |2 +-
 .../testsuite/libgomp.oacc-c++/deep-copy-17.C |  101 ++
 .../libgomp.oacc-c-c++-common/deep-copy-15.c  |   68 +
 .../libgomp.oacc-c-c++-common/deep-copy-

[PATCH v2 04/11] OpenMP/OpenACC: Add inspector class to unify mapped address analysis

2022-03-18 Thread Julian Brown
Several places in the C and C++ front-ends dig through OpenMP and OpenACC
addresses from "map" clauses (etc.) in order to determine whether they
are component accesses that need "attach" operations, check duplicate
mapping clauses, and so on.  When we're extending support for more kinds
of lvalues in map clauses for OpenMP, it seems helpful to bring these
all into one place in order to keep all the analyses in sync, and to
make it easier to reason about which kinds of expressions are supported.

This patch introduces an "address inspector" class for that purpose,
and adjusts the C and C++ front-ends to use it.

Relative to the previous posted version, this patch heavily reworks the
internals of the "address inspector" class and its call sites in the
C and C++ front-ends in order to clarify the logic used to elaborate
"map" clause nodes, which had become somewhat convoluted. It also now
implements the functionality of the "c_omp_decompose_attachable_address"
function from earlier versions of this patch series.

2022-03-17  Julian Brown  

gcc/c-family/
* c-common.h (c_omp_address_inspector): New class.
* c-omp.c (c_omp_address_inspector::get_deref_origin,
c_omp_address_inspector::component_access_p,
c_omp_address_inspector::check_clause,
c_omp_address_inspector::get_root_term,
c_omp_address_inspector::map_supported_p,
c_omp_address_inspector::mappable_type,
c_omp_address_inspector::get_origin,
c_omp_address_inspector::peel_components,
c_omp_address_inspector::maybe_peel_ref,
c_omp_address_inspector::maybe_zero_length_array_section,
c_omp_address_inspector::get_base_pointer,
c_omp_address_inspector::get_base_pointer_tgt,
c_omp_address_inspector::get_attachment_point): New methods.

gcc/c/
* c-typeck.c (handle_omp_array_sections_1,
handle_omp_array_sections, c_finish_omp_clauses): Use
c_omp_address_inspector class.

gcc/cp/
* semantics.c (cp_omp_address_inspector): New class, derived from
c_omp_address_inspector.
(handle_omp_array_sections_1, handle_omp_array_sections,
finish_omp_clauses): Use cp_omp_address_inspector class to
analyze OpenMP map clause expressions.

gcc/testsuite/
* g++.dg/gomp/unmappable-component-1.C: New test.

libgomp/
* testsuite/libgomp.c++/class-array-1.C: New test.
* testsuite/libgomp.c-c++-common/baseptrs-1.c: New test.
* testsuite/libgomp.c-c++-common/baseptrs-2.c: New test.
---
 gcc/c-family/c-common.h   |  55 +++
 gcc/c-family/c-omp.cc | 268 +++
 gcc/c/c-typeck.cc | 305 +---
 gcc/cp/semantics.cc   | 440 --
 .../g++.dg/gomp/unmappable-component-1.C  |  21 +
 libgomp/testsuite/libgomp.c++/class-array-1.C |  59 +++
 .../libgomp.c-c++-common/baseptrs-1.c |  50 ++
 .../libgomp.c-c++-common/baseptrs-2.c |  70 +++
 8 files changed, 814 insertions(+), 454 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gomp/unmappable-component-1.C
 create mode 100644 libgomp/testsuite/libgomp.c++/class-array-1.C
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/baseptrs-2.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index a8d6f82bb2c..e592e7fd368 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1253,6 +1253,61 @@ extern void c_omp_mark_declare_variant (location_t, 
tree, tree);
 extern const char *c_omp_map_clause_name (tree, bool);
 extern void c_omp_adjust_map_clauses (tree, bool);
 
+class c_omp_address_inspector
+{
+  location_t loc;
+  tree root_term;
+  bool indirections;
+  int map_supported;
+
+protected:
+  tree orig;
+
+public:
+  c_omp_address_inspector (location_t loc, tree t)
+: loc (loc), root_term (NULL_TREE), indirections (false),
+  map_supported (-1), orig (t)
+  { }
+
+  ~c_omp_address_inspector () {}
+
+  virtual bool processing_template_decl_p () { return false; }
+  virtual bool mappable_type (tree t);
+  virtual void emit_unmappable_type_notes (tree) { }
+
+  bool check_clause (tree);
+  tree get_root_term (bool);
+
+  tree get_address () { return orig; }
+  tree get_deref_origin ();
+  bool component_access_p ();
+
+  bool has_indirections_p ()
+{
+  if (!root_term)
+   get_root_term (false);
+  return indirections;
+}
+
+  bool indir_component_ref_p ()
+{
+  return component_access_p () && has_indirections_p ();
+}
+
+  bool map_supported_p ();
+
+  static tree get_origin (tree);
+  static tree peel_components (tree);
+  static tree maybe_peel_ref (tree);
+  static tree get_base_pointer (tree);
+  tree get_base_pointer () { return get_base_pointer (orig); }
+  static tree get_base_pointer_tgt (tree);
+  tree get_base_pointer_tgt () { return get_base_pointer_tgt (o

[PATCH v2 05/11] OpenMP: Handle reference-typed struct members

2022-03-18 Thread Julian Brown
This patch relates to OpenMP mapping clauses containing struct members of
reference type, e.g. "mystruct.myref.myptr[:N]".  To be able to access
the array slice through the reference in the middle, we need to perform
an attach action for that reference, since it is represented internally
as a pointer.

I don't think the spec allows for this case explicitly.  The closest
clause is (OpenMP 5.0, "2.19.7.1 map Clause"):

  "If the type of a list item is a reference to a type T then the
   reference in the device data environment is initialized to refer to
   the object in the device data environment that corresponds to the
   object referenced by the list item. If mapping occurs, it occurs as
   though the object were mapped through a pointer with an array section
   of type T and length one."

The patch as is allows the mapping to work with just
"mystruct.myref.myptr[:N]", without an explicit "mystruct.myref"
mapping also (because, would that refer to the hidden pointer used by
the reference, or the automatically-dereferenced data itself?). An
attach/detach operation is thus synthesised for the reference.

Reworking the previous "address inspector" patch, it occurred to me that
this patch might be better implemented in the frontend (or frontends).
I've added a note to that effect, but not actually made that change for
the time being.
---
 gcc/gimplify.cc|  59 -
 libgomp/testsuite/libgomp.c++/baseptrs-3.C | 275 +
 2 files changed, 327 insertions(+), 7 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c++/baseptrs-3.C

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 598c65eb430..0b8c221e4c8 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9813,7 +9813,10 @@ accumulate_sibling_list (enum omp_region_type 
region_type, enum tree_code code,
   /* FIXME: If we're not mapping the base pointer in some other clause on this
  directive, I think we want to create ALLOC/RELEASE here -- i.e. not
  early-exit.  */
-  if (openmp && attach_detach)
+  if (openmp
+  && attach_detach
+  && !(TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE
+  && TREE_CODE (TREE_TYPE (TREE_TYPE (ocd))) != POINTER_TYPE))
 return NULL;
 
   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
@@ -9862,9 +9865,37 @@ accumulate_sibling_list (enum omp_region_type 
region_type, enum tree_code code,
 
   tree noind = strip_indirections (base);
 
-  if (!openmp
+  /* TODO: the following two stanzas handling reference-typed struct
+members (for OpenMP) and nested base pointers (for OpenACC) could
+probably both be better handled in the frontends.  Doing that would
+avoid this late manipulation of the clause list.  */
+
+  if (openmp
+ && TREE_CODE (TREE_TYPE (noind)) == REFERENCE_TYPE
  && (region_type & ORT_TARGET)
  && TREE_CODE (noind) == COMPONENT_REF)
+   {
+ tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
+ OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_TO);
+ OMP_CLAUSE_DECL (c2) = unshare_expr (base);
+ OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (TREE_TYPE (noind));
+
+ tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
+ OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH_DETACH);
+ OMP_CLAUSE_DECL (c3) = unshare_expr (noind);
+ OMP_CLAUSE_SIZE (c3) = size_zero_node;
+
+ OMP_CLAUSE_CHAIN (c2) = c3;
+ OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
+
+ *inner = c2;
+ return NULL;
+   }
+  else if (!openmp
+  && (region_type & ORT_TARGET)
+  && TREE_CODE (noind) == COMPONENT_REF)
{
  /* The base for this component access is a struct component access
 itself.  Insert a node to be processed on the next iteration of
@@ -9878,13 +9909,28 @@ accumulate_sibling_list (enum omp_region_type 
region_type, enum tree_code code,
  OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FORCE_PRESENT);
  OMP_CLAUSE_DECL (c2) = unshare_expr (noind);
  OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (TREE_TYPE (noind));
+ OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
  *inner = c2;
  return NULL;
}
 
-  tree sdecl = strip_components_and_deref (base);
+  tree sdecl = base;
+  if (TREE_CODE (sdecl) == INDIRECT_REF
+ || TREE_CODE (sdecl) == MEM_REF)
+   {
+ sdecl = TREE_OPERAND (sdecl, 0);
+ if (TREE_CODE (sdecl) == INDIRECT_REF
+ && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sdecl, 0)))
+ == REFERENCE_TYPE))
+   sdecl = TREE_OPERAND (sdecl, 0);
+   }
 
-  if (POINTER_TYPE_P (TREE_TYPE (sdecl)) && (region_type & ORT_TARGET))
+  while (TREE_CODE (sdecl) == POINTER_PLUS_EXPR)
+   sdecl = TREE_OPERAND (sdecl, 0);
+
+  if (DECL_P (sdecl)
+ 

[PATCH v2 06/11] OpenMP: lvalue parsing for map clauses (C++)

2022-03-18 Thread Julian Brown
This patch changes parsing for OpenMP map clauses in C++ to use the
generic expression parser, hence adds support for parsing general
lvalues (as required by OpenMP 5.0+).  So far only a few new types of
expression are actually supported throughout compilation (including
everything in the testsuite of course, and newly-added tests), and we
attempt to reject unsupported expressions in order to avoid surprises
for the user.

This version of the patch adds code to recalculate the bias for ATTACH
operations on struct bases which are not DECL_P (edit: oops, and leaves
in a commented-out line).

2022-03-17  Julian Brown  

gcc/c-family/
* c-omp.cc (c_omp_address_inspector::map_supported_p): Support
OMP_ARRAY_SECTION.

gcc/cp/
* error.cc (dump_expr): Handle OMP_ARRAY_SECTION.
* parser.cc (cp_parser_new): Initialize parser->omp_array_section_p.
(cp_parser_postfix_open_square_expression): Support OMP_ARRAY_SECTION
parsing.
(cp_parser_omp_var_list_no_open): Remove ALLOW_DEREF parameter, add
MAP_LVALUE in its place.  Supported generalised lvalue parsing for map
clauses.
(cp_parser_omp_var_list): Remove ALLOW_DEREF parameter, add MAP_LVALUE.
Pass to cp_parser_omp_var_list_no_open.
(cp_parser_oacc_data_clause, cp_parser_omp_all_clauses): Update calls
to cp_parser_omp_var_list.
* parser.h (cp_parser): Add omp_array_section_p field.
* semantics.cc (handle_omp_array_sections_1): Handle more types of map
expression.
(handle_omp_array_section): Disallow pointer-to-member mappings.
(finish_omp_clauses): Check for supported types of expression.

gcc/
* gimplify.cc (omp_containing_struct): Handle POINTER_PLUS_EXPR.
(accumulate_sibling_list): Fix support for non-DECL_P struct bases.
Don't create firstprivate pointers for struct bases that are explicitly
mapped TO elsewhere in the clause list.  Add support for adjusting
struct ATTACH bias.
(omp_ptrmem_p): New function.
(omp_build_struct_sibling_lists): Support length-two group for
synthesized inner struct mapping.  Explicitly disallow pointers to
members.  Recalculate bias for struct ATTACH nodes.
* tree-pretty-print.c (dump_generic_node): Support OMP_ARRAY_SECTION.
* tree.def (OMP_ARRAY_SECTION): New tree code.

gcc/testsuite/
* c-c++-common/gomp/map-6.c: Update expected output.
* g++.dg/gomp/pr67522.C: Likewise.
* g++.dg/gomp/ind-base-3.C: New test.
* g++.dg/gomp/map-assignment-1.C: New test.
* g++.dg/gomp/map-inc-1.C: New test.
* g++.dg/gomp/map-lvalue-ref-1.C: New test.
* g++.dg/gomp/map-ptrmem-1.C: New test.
* g++.dg/gomp/map-ptrmem-2.C: New test.
* g++.dg/gomp/map-static-cast-lvalue-1.C: New test.
* g++.dg/gomp/map-ternary-1.C: New test.
* g++.dg/gomp/member-array-2.C: New test.

libgomp/
* testsuite/libgomp.c++/ind-base-1.C: New test.
* testsuite/libgomp.c++/ind-base-2.C: New test.
* testsuite/libgomp.c++/map-comma-1.C: New test.
* testsuite/libgomp.c++/map-rvalue-ref-1.C: New test.
* testsuite/libgomp.c++/struct-ref-1.C: New test.
* testsuite/libgomp.c-c++-common/array-field-1.c: New test.
* testsuite/libgomp.c-c++-common/array-of-struct-1.c: New test.
* testsuite/libgomp.c-c++-common/array-of-struct-2.c: New test.
---
 gcc/c-family/c-omp.cc |   1 +
 gcc/cp/error.cc   |   9 +
 gcc/cp/parser.cc  | 141 +--
 gcc/cp/parser.h   |   3 +
 gcc/cp/semantics.cc   |  59 ++-
 gcc/gimplify.cc   | 119 +++--
 gcc/testsuite/c-c++-common/gomp/map-6.c   |   4 +-
 gcc/testsuite/g++.dg/gomp/ind-base-3.C|  38 
 gcc/testsuite/g++.dg/gomp/map-assignment-1.C  |  12 ++
 gcc/testsuite/g++.dg/gomp/map-inc-1.C |  10 ++
 gcc/testsuite/g++.dg/gomp/map-lvalue-ref-1.C  |  19 ++
 gcc/testsuite/g++.dg/gomp/map-ptrmem-1.C  |  37 
 gcc/testsuite/g++.dg/gomp/map-ptrmem-2.C  |  40 +
 .../g++.dg/gomp/map-static-cast-lvalue-1.C|  17 ++
 gcc/testsuite/g++.dg/gomp/map-ternary-1.C |  20 +++
 gcc/testsuite/g++.dg/gomp/member-array-2.C|  92 ++
 gcc/testsuite/g++.dg/gomp/pr67522.C   |   2 +-
 gcc/tree-pretty-print.cc  |  14 ++
 gcc/tree.def  |   3 +
 libgomp/testsuite/libgomp.c++/ind-base-1.C| 162 ++
 libgomp/testsuite/libgomp.c++/ind-base-2.C|  49 ++
 libgomp/testsuite/libgomp.c++/map-comma-1.C   |  15 ++
 .../testsuite/libgomp.c++/map-rvalue-ref-1.C  |  22 +++
 libgomp/testsuite/libgomp.c++/struct-ref-1.C  |  97 +++
 .../libgomp.c-c++-common/array-field-1.c  |  35 
 .../libgomp.c-c++-common/array

[PATCH v2 07/11] OpenMP: lvalue parsing for map clauses (C)

2022-03-18 Thread Julian Brown
This patch adds support for parsing general lvalues for OpenMP "map"
clauses to the C front-end, similar to the previous patch for C++.

This version of the patch has been adjusted for changes to the address
inspector patch, but is otherwise the same as the last posted version.

2022-03-17  Julian Brown  

gcc/c/
* c-parser.c (c_parser_postfix_expression_after_primary): Add support
for OpenMP array section parsing.
(c_parser_omp_variable_list): Change ALLOW_DEREF parameter to
MAP_LVALUE.  Support parsing of general lvalues in "map" clauses.
(c_parser_omp_var_list_parens): Change ALLOW_DEREF parameter to
MAP_LVALUE.  Update call to c_parser_omp_variable_list.
(c_parser_oacc_data_clause, c_parser_omp_clause_to,
c_parser_omp_clause_from): Update calls to
c_parser_omp_var_list_parens.
* c-tree.h (c_omp_array_section_p): Add extern declaration.
* c-typeck.c (c_omp_array_section_p): Add flag.
(mark_exp_read): Support OMP_ARRAY_SECTION.
(handle_omp_array_sections_1): Handle more kinds of expressions.
(c_finish_omp_clauses): Check for supported expression types.  Support
non-DECL_P root term for map clauses.

gcc/testsuite/
* c-c++-common/gomp/map-1.c: Adjust expected output.
* c-c++-common/gomp/map-6.c: Likewise.

libgomp/
* testsuite/libgomp.c-c++-common/ind-base-4.c: New test.
* testsuite/libgomp.c-c++-common/unary-ptr-1.c: New test.
---
 gcc/c/c-parser.cc | 150 +++---
 gcc/c/c-tree.h|   1 +
 gcc/c/c-typeck.cc |  38 -
 gcc/testsuite/c-c++-common/gomp/map-1.c   |   3 +-
 gcc/testsuite/c-c++-common/gomp/map-6.c   |   2 +
 .../libgomp.c-c++-common/ind-base-4.c |  50 ++
 .../libgomp.c-c++-common/unary-ptr-1.c|  16 ++
 7 files changed, 236 insertions(+), 24 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/ind-base-4.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/unary-ptr-1.c

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index e9086c58524..cc590e56e75 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -10486,7 +10486,7 @@ c_parser_postfix_expression_after_primary (c_parser 
*parser,
   struct c_expr expr)
 {
   struct c_expr orig_expr;
-  tree ident, idx;
+  tree ident, idx, len;
   location_t sizeof_arg_loc[3], comp_loc;
   tree sizeof_arg[3];
   unsigned int literal_zero_mask;
@@ -10505,15 +10505,44 @@ c_parser_postfix_expression_after_primary (c_parser 
*parser,
case CPP_OPEN_SQUARE:
  /* Array reference.  */
  c_parser_consume_token (parser);
- idx = c_parser_expression (parser).value;
- c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
-"expected %<]%>");
- start = expr.get_start ();
- finish = parser->tokens_buf[0].location;
- expr.value = build_array_ref (op_loc, expr.value, idx);
- set_c_expr_source_range (&expr, start, finish);
- expr.original_code = ERROR_MARK;
- expr.original_type = NULL;
+ idx = len = NULL_TREE;
+ if (!c_omp_array_section_p
+ || c_parser_next_token_is_not (parser, CPP_COLON))
+   idx = c_parser_expression (parser).value;
+
+ if (c_omp_array_section_p
+ && c_parser_next_token_is (parser, CPP_COLON))
+   {
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
+   len = c_parser_expression (parser).value;
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+"expected %<]%>");
+
+/* NOTE: We are reusing using the type of the whole array as the
+   type of the array section here, which isn't necessarily
+   entirely correct.  Might need revisiting.  */
+ start = expr.get_start ();
+ finish = parser->tokens_buf[0].location;
+ expr.value = build3_loc (op_loc, OMP_ARRAY_SECTION,
+  TREE_TYPE (expr.value), expr.value,
+  idx, len);
+ set_c_expr_source_range (&expr, start, finish);
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
+   }
+ else
+   {
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+"expected %<]%>");
+ start = expr.get_start ();
+ finish = parser->tokens_buf[0].location;
+ expr.value = build_array_ref (op_loc, expr.value, idx);
+ set_c_expr_source_range (&expr, start, finish);
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
+   }

[PATCH v2 08/11] Use OMP_ARRAY_SECTION instead of TREE_LIST in C++ FE

2022-03-18 Thread Julian Brown
This patch changes the representation of OMP array sections in the
C++ front end to use the new OMP_ARRAY_SECTION tree code instead of a
TREE_LIST.  This is important for "declare mapper" support, because the
array section representation may stick around longer (in "declare mapper"
definitions), and special-case handling TREE_LIST becomes necessary in
more places, which starts to become unwieldy.

2022-02-18  Julian Brown  

gcc/c-family/
* c-omp.cc (c_omp_split_clauses): Support OMP_ARRAY_SECTION.

gcc/cp/
* parser.cc (cp_parser_omp_var_list_no_open): Use OMP_ARRAY_SECTION
code instead of TREE_LIST to represent OpenMP array sections.
* pt.cc (tsubst_copy, tsubst_omp_clause_decl, tsubst_copy_and_build):
Add OMP_ARRAY_SECTION support.
* semantics.cc (handle_omp_array_sections_1, handle_omp_array_sections,
cp_oacc_check_attachments, finish_omp_clauses): Use OMP_ARRAY_SECTION
instead of TREE_LIST where appropriate.
* gimplify.cc (gimplify_expr): Ensure OMP_ARRAY_SECTION has been
processed out before gimplification.
---
 gcc/c-family/c-omp.cc | 14 +++
 gcc/cp/parser.cc  | 15 
 gcc/cp/pt.cc  | 52 
 gcc/cp/semantics.cc   | 56 ++-
 gcc/gimplify.cc   |  3 +++
 5 files changed, 109 insertions(+), 31 deletions(-)

diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 421cc76..77255dd587a 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -2662,6 +2662,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
}
  else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST)
{
+ /* TODO: This can go away once we transition all uses of
+TREE_LIST for representing OMP array sections to
+OMP_ARRAY_SECTION.  */
  tree t;
  for (t = OMP_CLAUSE_DECL (c);
   TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
@@ -2670,6 +2673,17 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
bitmap_clear_bit (&allocate_head, DECL_UID (t));
  break;
}
+ else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == OMP_ARRAY_SECTION)
+   {
+ tree t;
+ for (t = OMP_CLAUSE_DECL (c);
+  TREE_CODE (t) == OMP_ARRAY_SECTION;
+  t = TREE_OPERAND (t, 0))
+   ;
+ if (DECL_P (t))
+   bitmap_clear_bit (&allocate_head, DECL_UID (t));
+ break;
+   }
  /* FALLTHRU */
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index efb65543e11..8d5ae9c44d0 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -36639,11 +36639,14 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, 
enum omp_clause_code kind,
decl = TREE_OPERAND (decl, 0);
 
  for (int i = dims.length () - 1; i >= 0; i--)
-   decl = tree_cons (dims[i].low_bound, dims[i].length, decl);
+   decl = build3_loc (input_location, OMP_ARRAY_SECTION,
+  TREE_TYPE (decl), decl, dims[i].low_bound,
+  dims[i].length);
}
  else if (TREE_CODE (decl) == INDIRECT_REF)
{
  bool ref_p = REFERENCE_REF_P (decl);
+ tree type = TREE_TYPE (decl);
 
  /* Turn *foo into the representation previously used for
 foo[0].  */
@@ -36653,7 +36656,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum 
omp_clause_code kind,
  /* ...but don't add the [0:1] representation for references
 (because they have special handling elsewhere).  */
  if (!ref_p)
-   decl = tree_cons (integer_zero_node, integer_one_node, decl);
+   decl = build3_loc (input_location, OMP_ARRAY_SECTION, type,
+  decl, integer_zero_node, integer_one_node);
}
  else if (TREE_CODE (decl) == ARRAY_REF)
{
@@ -36662,7 +3,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum 
omp_clause_code kind,
  decl = TREE_OPERAND (decl, 0);
  STRIP_NOPS (decl);
 
- decl = tree_cons (idx, integer_one_node, decl);
+ decl = build3_loc (input_location, OMP_ARRAY_SECTION,
+TREE_TYPE (decl), decl, idx, integer_one_node);
}
  else if (TREE_CODE (decl) == NON_LVALUE_EXPR
   || CONVERT_EXPR_P (decl))
@@ -36837,7 +36842,9 @@ cp_parser_omp_var_list_no_open (cp_parser 

[Patch] Fortran/OpenMP: Improve associate-name diagnostic [PR103039]

2022-03-18 Thread Tobias Burnus

SELECT TYPE, SELECT RANK and ASSOCIATE have
  associate-name => selector
and create a pointer to the selector.

GCC was fixed to handle CLASS properly in
  class(t) :: var
  !$omp ... firstprivate(var)
As a side effect, firstprivate(assoc_name) now also gets
handled that way, effectively trying to firstprivate(selector)
which should be shared...

While firstprivate(var) does not appear explicitly, it gets
added via gfc_omp_predetermined_sharing.

I went for the simple solution and handle it only
in gfortran's ctor/dtor.

An alternative would be to set OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE,
which is currently only set for C++'s __for_end / __for_range
and then later process it in ctor/dtor. I am not sure whether that's
really best and what's the best way to propagate it. One way would
be to create and use OMP_CLAUSE_DEFAULT_FIRSTPRIVATE_NO_REFERENCE.

OK as is (simple version) – or is a fuller version better. If so,
suggestion how to do this best?

Tobias
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
Fortran/OpenMP: Fix privatization of associated names

gfc_omp_predetermined_sharing cases the associate-name pointer variable
to be OMP_CLAUSE_DEFAULT_FIRSTPRIVATE, which is fine. However, the associated
selector is shared. Thus, the target of associate-name pointer should not get
copied. (It was before but because of gfc_omp_privatize_by_reference returning
false, the selector was not only wrongly copied but this was also not done
properly.)

gcc/fortran/ChangeLog:

	PR fortran/103039
	* trans-openmp.cc (gfc_omp_clause_copy_ctor, gfc_omp_clause_dtor):
	Only privatize pointer for associate names.

libgomp/ChangeLog:

	PR fortran/103039
	* testsuite/libgomp.fortran/associate4.f90: New test.

 gcc/fortran/trans-openmp.cc  | 10 +++
 libgomp/testsuite/libgomp.fortran/associate4.f90 | 92 
 2 files changed, 102 insertions(+)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index fad76a4791f..101924f5e76 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -808,6 +808,11 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
   gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
 	  || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
 
+  /* Privatize pointer, only; cf. gfc_omp_predetermined_sharing. */
+  if (DECL_P (OMP_CLAUSE_DECL (clause))
+  && GFC_DECL_ASSOCIATE_VAR_P (OMP_CLAUSE_DECL (clause)))
+return build2 (MODIFY_EXPR, TREE_TYPE (dest), dest, src);
+
   if (DECL_ARTIFICIAL (OMP_CLAUSE_DECL (clause))
   && DECL_LANG_SPECIFIC (OMP_CLAUSE_DECL (clause))
   && GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)))
@@ -1321,6 +1326,11 @@ gfc_omp_clause_dtor (tree clause, tree decl)
   tree type = TREE_TYPE (decl), tem;
   tree decl_type = TREE_TYPE (OMP_CLAUSE_DECL (clause));
 
+  /* Only pointer was privatized; cf. gfc_omp_clause_copy_ctor. */
+  if (DECL_P (OMP_CLAUSE_DECL (clause))
+  && GFC_DECL_ASSOCIATE_VAR_P (OMP_CLAUSE_DECL (clause)))
+return NULL_TREE;
+
   if (DECL_ARTIFICIAL (OMP_CLAUSE_DECL (clause))
   && DECL_LANG_SPECIFIC (OMP_CLAUSE_DECL (clause))
   && GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)))
diff --git a/libgomp/testsuite/libgomp.fortran/associate4.f90 b/libgomp/testsuite/libgomp.fortran/associate4.f90
new file mode 100644
index 000..f0949b5530d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/associate4.f90
@@ -0,0 +1,92 @@
+! PR fortran/51722
+
+module m
+implicit none
+
+contains
+
+subroutine seltype
+
+type :: a
+   integer :: p = 2
+end type a
+
+type, extends(a) :: b
+   integer :: cnt = 0
+end type b
+
+integer :: k, s
+class(a), pointer :: x
+
+allocate(a :: x)
+s = 0
+select type (y => x)
+class is (a)
+!$omp parallel do default(shared) private(k) reduction(+:s)
+   do k = 1,10
+  s = s + k*y%p
+   end do
+!$omp end parallel do
+end select
+
+if (s /= 110) error stop
+deallocate(x)
+allocate(b :: x)
+
+s = 0
+select type (y => x)
+class is (b)
+!$omp parallel do default(shared) private(k) reduction(+:s)
+   do k = 1,10
+  s = s + k*y%p
+!$omp atomic update
+  y%cnt = y%cnt + 2
+   end do
+!$omp end parallel do
+if (s /= 110) error stop
+if (y%p /= 2) error stop
+if (y%cnt /= 10*2) error stop
+end select
+
+deallocate(x)
+
+end subroutine seltype
+
+subroutine assoc
+
+type :: b
+   integer :: r = 3
+end type b
+
+type :: a
+   integer :: p = 2
+   class(b), pointer :: u => null()
+end type a
+
+integer :: k, s
+class(a), pointer :: x
+
+s = 0
+allocate(a :: x)
+allocate(b :: x%u)
+
+associate(f => x%u)
+!$omp parallel do default(shared) private(k) reduction(+:s)
+   do k = 1,10
+  s = s + k*f%r
+   end do
+!$omp end parallel do
+end associate
+
+deallocate(x%u)
+deallocate(x)
+
+if (s /

[PATCH v2 09/11] OpenMP 5.0 "declare mapper" support for C++

2022-03-18 Thread Julian Brown
This patch implements OpenMP 5.0 "declare mapper" support for C++ --
except for arrays of structs with mappers, which are TBD. I've taken cues
from the existing "declare reduction" support where appropriate, though
obviously the details of implementation differ somewhat (in particular,
"declare mappers" must survive longer, until gimplification time).

Both named and unnamed (default) mappers are supported, and both
explicitly-mapped structures and implicitly-mapped struct-typed variables
used within an offload region are supported. For the latter, we need a
way to communicate to the middle end which mapper (visible, in-scope) is
the right one to use -- for that, we scan the target body in the front
end for uses of structure (etc.) types, and create artificial "mapper
binding" clauses to associate types with visible mappers. (It doesn't
matter too much if we create these mapper bindings a bit over-eagerly,
since they will only be used if needed later during gimplification.)

Another difficulty concerns the order in which an OpenMP offload region
body's clauses are processed relative to its body: in order to add
clauses for instantiated mappers, we need to have processed the body
already in order to find which variables have been used, but at present
the region's clauses are processed strictly before the body. So, this
patch adds a second clause-processing step after gimplification of the
body in order to add clauses resulting from instantiated mappers.

This version of the patch improves detection of explicitly-mapped struct
accesses which inhibit implicitly-triggered user-defined mappers for a
target region.

2022-03-17  Julian Brown  

gcc/cp/
* cp-gimplify.cc (cxx_omp_finish_mapper_clauses): New function.
* cp-objcp-common.h (LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES): Add new
langhook.
* cp-tree.h (lang_decl_fn): Add omp_declare_mapper_p field.
(DECL_OMP_DECLARE_MAPPER_P): New function.
(omp_mapper_id, cp_check_omp_declare_mapper, omp_instantiate_mappers,
cxx_omp_finish_mapper_clauses): Add prototypes.
* decl.cc (duplicate_decls): Support DECL_OMP_DECLARE_MAPPER_P
functions.
(finish_function): Likewise.
* mangle.cc (decl_mangling_context): Likewise.
* name-lookup.cc (set_decl_context_in_fn): Likewise.
* parser.cc (cp_parser_class_specifier_1): Likewise.
(cp_parser_omp_declare_mapper, cp_parser_omp_declare_mapper_maplist):
New functions.
(cp_parser_late_parsing_for_member): Support DECL_OMP_DECLARE_MAPPER_P
functions.
(cp_parser_omp_clause_map): Add KIND parameter.  Support "mapper"
modifier.
(cp_parser_omp_all_clauses): Add KIND argument to
cp_parser_omp_clause_map call.
(cp_parser_omp_target): Call omp_instantiate_mappers before
finish_omp_clauses.
(cp_parser_omp_declare): Add "declare mapper" support.
* pt.cc (instantiate_class_template_1, tsubst_function_decl): Support
DECL_OMP_DECLARE_MAPPER_P functions.
(tsubst_omp_clauses): Call omp_instantiate_mappers before
finish_omp_clauses, for target regions.
(tsubst_expr): Support DECL_OMP_DECLARE_MAPPER_P functions.
(tsubst_omp_udm): New function.
(instantiate_body): Support DECL_OMP_DECLARE_MAPPER_P functions.
* semantics.cc (gimplify.h): Include.
(expand_or_defer_fn_1): Support DECL_OMP_DECLARE_MAPPER_P functions.
(omp_mapper_id, omp_mapper_lookup, omp_extract_mapper_directive,
cp_check_omp_declare_mapper): New functions.
(remap_mapper_decl_info): New struct.
(remap_mapper_decl_1, omp_instantiate_mapper, omp_instantiate_mappers):
New functions.
(finish_omp_clauses): Delete GOMP_MAP_PUSH_MAPPER_NAME and
GOMP_MAP_POP_MAPPER_NAME artificial clauses.
(mapper_list): New struct.
(find_nested_mappers): New function.
(omp_target_walk_data): Add MAPPERS field.
(finish_omp_target_clauses_r): Scan for uses of struct/union/class type
variables.
(finish_omp_target_clauses): Create artificial mapper binding clauses
for used structs/unions/classes in offload region.

gcc/fortran/
* parse.cc (tree.h, fold-const.h, tree-hash-traits.h): Add includes
(for additions to omp-general.h).

gcc/
* gimplify.cc (gimplify_omp_ctx): Add IMPLICIT_MAPPERS field.
(new_omp_context): Initialise IMPLICIT_MAPPERS hash map.
(delete_omp_context): Delete IMPLICIT_MAPPERS hash map.
(instantiate_mapper_info, remap_mapper_decl_info): New structs.
(remap_mapper_decl_1, omp_instantiate_mapper,
omp_find_explicitly_mapped_structs, omp_instantiate_implicit_mappers,
new_omp_context_for_scan): New functions.
(gimplify_scan_omp_clauses): Add optional USE_MAPPERS parameter.
Instantiate implicit mappers if true.  Handle artificial mapper_binding

[PATCH v2 10/11] OpenMP: Use OMP_ARRAY_SECTION instead of TREE_LIST for array sections in C FE

2022-03-18 Thread Julian Brown
This patch uses the new OMP_ARRAY_SECTION tree code to represent OpenMP
array sections, rather than TREE_LIST.  As for the C++ FE, using TREE_LIST
becomes unwieldy when the array-section representation sticks around
for longer due to adding "declare mapper" support.

We must be a little careful here because OMP_CLAUSE_DEPEND and
OMP_CLAUSE_AFFINITY also use TREE_LIST for their own purposes, and we're
not changing those ones.

No behavioural changes should be introduced by this patch.

2022-03-04  Julian Brown  

gcc/c/
* c-parser.cc (c_parser_omp_variable_list): Use OMP_ARRAY_SECTION
instead of TREE_LIST for array sections.
(c_parser_omp_clause_reduction): Likewise.
* c-typeck.cc (handle_omp_array_sections_1, handle_omp_array_sections,
c_oacc_check_attachments, c_finish_omp_clauses): Likewise.
---
 gcc/c/c-parser.cc | 21 +++--
 gcc/c/c-typeck.cc | 37 +++--
 2 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index cc590e56e75..1ca03b6a632 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -13165,16 +13165,20 @@ c_parser_omp_variable_list (c_parser *parser,
}
 
  for (int i = dims.length () - 1; i >= 0; i--)
-   decl = tree_cons (dims[i].low_bound, dims[i].length, decl);
+   decl = build3_loc (loc, OMP_ARRAY_SECTION, TREE_TYPE (decl),
+  decl, dims[i].low_bound, dims[i].length);
}
  else if (TREE_CODE (decl) == INDIRECT_REF)
{
+ tree type = TREE_TYPE (decl);
+
  /* Turn *foo into the representation previously used for
 foo[0].  */
  decl = TREE_OPERAND (decl, 0);
  STRIP_NOPS (decl);
 
- decl = tree_cons (integer_zero_node, integer_one_node, decl);
+ decl = build3_loc (loc, OMP_ARRAY_SECTION, type, decl,
+integer_zero_node, integer_one_node);
}
  else if (TREE_CODE (decl) == ARRAY_REF)
{
@@ -13183,7 +13187,8 @@ c_parser_omp_variable_list (c_parser *parser,
  decl = TREE_OPERAND (decl, 0);
  STRIP_NOPS (decl);
 
- decl = tree_cons (idx, integer_one_node, decl);
+ decl = build3_loc (loc, OMP_ARRAY_SECTION, TREE_TYPE (decl),
+decl, idx, integer_one_node);
}
  else if (TREE_CODE (decl) == NON_LVALUE_EXPR
   || CONVERT_EXPR_P (decl))
@@ -13345,7 +13350,9 @@ c_parser_omp_variable_list (c_parser *parser,
}
  else
for (unsigned i = 0; i < dims.length (); i++)
- t = tree_cons (dims[i].low_bound, dims[i].length, t);
+ t = build3_loc (clause_loc, OMP_ARRAY_SECTION,
+ TREE_TYPE (t), t, dims[i].low_bound,
+ dims[i].length);
}
 
  if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
@@ -15061,13 +15068,15 @@ c_parser_omp_clause_reduction (c_parser *parser, enum 
omp_clause_code kind,
  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
{
  tree d = OMP_CLAUSE_DECL (c), type;
- if (TREE_CODE (d) != TREE_LIST)
+ if (TREE_CODE (d) != OMP_ARRAY_SECTION)
type = TREE_TYPE (d);
  else
{
  int cnt = 0;
  tree t;
- for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
+ for (t = d;
+ TREE_CODE (t) == OMP_ARRAY_SECTION;
+ t = TREE_OPERAND (t, 0))
cnt++;
  type = TREE_TYPE (t);
  while (cnt > 0)
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 162ed0a18a2..98212c6b7f5 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -13218,7 +13218,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec 
&types,
 enum c_omp_region_type ort)
 {
   tree ret, low_bound, length, type;
-  if (TREE_CODE (t) != TREE_LIST)
+  if (TREE_CODE (t) != OMP_ARRAY_SECTION)
 {
   if (error_operand_p (t))
return error_mark_node;
@@ -13293,14 +13293,14 @@ handle_omp_array_sections_1 (tree c, tree t, 
vec &types,
   return ret;
 }
 
-  ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types,
+  ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
 maybe_zero_len, first_non_one, ort);
   if (ret == error_mark_node || ret == NULL_TREE)
 return ret;
 
   type = TREE_TYPE (ret);
-  low_bound = TREE_PURPOSE (t);
-  length = TREE_VALUE (t);
+  low_bound = TREE_OPERAND (t, 1);
+  length = TREE_OPERAND (t, 2);
 
   if (low_bound == error_mark_node || length == error_mark_node)

[PATCH v2 11/11] OpenMP: Support OpenMP 5.0 "declare mapper" directives for C

2022-03-18 Thread Julian Brown
This patch adds support for "declare mapper" directives (and the "mapper"
modifier on "map" clauses) for C.  As for C++, arrays of custom-mapped
objects are not supported yet.

I've taken hints from the existing C support for "declare reduction"
directives: this works a little differently from C++ for things such as
looking up user-defined reductions (or user-defined mappers, in our case).

Some support functions have been pulled out of the C++ FE and shared
with the C implementation: several language hooks have been added to
facilitate that, given the above differences.

(Fortran FE support is TBD.)

2022-03-17  Julian Brown  

gcc/c-family/
* c-common.h (omp_mapper_list, c_omp_find_nested_mappers,
c_omp_instantiate_mappers): Add forward declarations/prototypes.
* c-omp.cc (c_omp_find_nested_mappers): New function.
(remap_mapper_decl_info): New struct.
(remap_mapper_decl_1, omp_instantiate_mapper,
c_omp_instantiate_mappers): Add functions.
* c-decl.cc (c_omp_mapper_id, c_omp_mapper_decl, c_omp_mapper_lookup,
c_omp_extract_mapper_directive, c_omp_map_array_section,
c_omp_scan_mapper_bindings_r, c_omp_scan_mapper_bindings): New
functions.

gcc/c/
* c-objc-common.h (LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES,
LANG_HOOKS_OMP_MAPPER_LOOKUP, LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define langhooks for C.
* c-parser.cc (c_parser_omp_clause_map): Add KIND parameter.  Handle
mapper modifier.
(c_parser_omp_all_clauses): Update call to c_parser_omp_clause_map with
new kind argument.
(c_parser_omp_target): Instantiate explicit mappers and record bindings
for implicit mappers.
(c_parser_omp_declare_mapper): Parse "declare mapper" directives.
(c_parser_omp_declare): Support "declare mapper".
* c-tree.h (c_omp_finish_mapper_clauses, c_omp_mapper_lookup,
c_omp_extract_mapper_directive, c_omp_map_array_section,
c_omp_mapper_id, c_omp_mapper_decl, c_omp_scan_mapper_bindings,
c_omp_instantiate_mappers): Add prototypes.
* c-typeck.cc (c_finish_omp_clauses): Handle GOMP_MAP_PUSH_MAPPER_NAME
and GOMP_MAP_POP_MAPPER_NAME.
(c_omp_finish_mapper_clauses): New function (langhook).

gcc/cp/
* cp-objcp-common.h (LANG_HOOKS_OMP_MAPPER_LOOKUP,
LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define langhooks for C++.
* cp-tree.h (cxx_omp_mapper_lookup, cxx_omp_extract_mapper_directive,
cxx_omp_map_array_section): Add prototypes.
* parser.cc (cp_parser_omp_target): Use new name for
c_omp_instantiate_mappers.
* pt.cc (tsubst_omp_clauses): Use new name for
c_omp_instantiate_mappers.
(omp_mapper_lookup): Rename to...
(cxx_omp_mapper_lookup): This.
(omp_extract_mapper_directive): Rename to...
(cxx_omp_extract_mapper_directive): This.
(cxx_omp_map_array_section): New function.
(remap_mapper_decl_info, remap_mapper_decl_1, omp_instantiate_mapper,
omp_instantiate_mappers, mapper_list, find_nested_mappers): Remove.
(omp_target_walk_data): Rename mapper_list to omp_mapper_list.
(finish_omp_target_clauses_r): Likewise.  Use renamed
cxx_omp_mapper_lookup, cxx_omp_extract_mapper_directive and
c_omp_find_nested_mappers.
(finish_omp_target_clauses): Likewise.

gcc/
* gimplify.cc (omp_instantiate_mapper): Use omp_map_array_section
langhook to handle (singleton only, for now) array sections.  Diagnose
attempts to use length >1 array sections with custom mappers.
(gimplify_scan_omp_clauses): Use omp_extract_mapper_directive langhook.
* langhooks-def.h (lhd_omp_mapper_lookup,
lhd_omp_extract_mapper_directive, lhd_omp_map_array_section): Add
prototypes.
(LANG_HOOKS_OMP_MAPPER_LOOKUP, LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define lang hooks.
(LANG_HOOKS_DECLS): Add LANG_HOOKS_OMP_MAPPER_LOOKUP,
LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION.
* langhooks.cc (lhd_omp_mapper_lookup, lhd_omp_extract_mapper_directive,
lhd_omp_map_array_section): New default definitions of langhooks.
* langhooks.h (lang_hooks_for_decls): Add omp_mapper_lookup,
omp_extract_mapper_directive, omp_map_array_section.
* omp-general.h (omp_mapper_list): New.

gcc/testsuite/
* g++.dg/gomp/declare-mapper-3.C: Remove from here.
* c-c++-common/gomp/declare-mapper-3.c: Move test here, make
C-compatible.
* g++.dg/gomp/declare-mapper-4.C: Remove from here.
* c-c++-common/gomp/declare-mapper-4.c: Move test here, make
C-compatible.
* c-c++-common/gomp/declare-mapper-5.c: New test.
* c-c++-common

Re: [Patch] Fortran/OpenMP: Improve associate-name diagnostic [PR103039]

2022-03-18 Thread Jakub Jelinek via Fortran
On Fri, Mar 18, 2022 at 05:27:02PM +0100, Tobias Burnus wrote:
> SELECT TYPE, SELECT RANK and ASSOCIATE have
>   associate-name => selector
> and create a pointer to the selector.
> 
> GCC was fixed to handle CLASS properly in
>   class(t) :: var
>   !$omp ... firstprivate(var)
> As a side effect, firstprivate(assoc_name) now also gets
> handled that way, effectively trying to firstprivate(selector)
> which should be shared...
> 
> While firstprivate(var) does not appear explicitly, it gets
> added via gfc_omp_predetermined_sharing.
> 
> I went for the simple solution and handle it only
> in gfortran's ctor/dtor.
> 
> An alternative would be to set OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE,
> which is currently only set for C++'s __for_end / __for_range
> and then later process it in ctor/dtor. I am not sure whether that's
> really best and what's the best way to propagate it. One way would
> be to create and use OMP_CLAUSE_DEFAULT_FIRSTPRIVATE_NO_REFERENCE.
> 
> OK as is (simple version) – or is a fuller version better. If so,
> suggestion how to do this best?

LGTM.

> Fortran/OpenMP: Fix privatization of associated names
> 
> gfc_omp_predetermined_sharing cases the associate-name pointer variable
> to be OMP_CLAUSE_DEFAULT_FIRSTPRIVATE, which is fine. However, the associated
> selector is shared. Thus, the target of associate-name pointer should not get
> copied. (It was before but because of gfc_omp_privatize_by_reference returning
> false, the selector was not only wrongly copied but this was also not done
> properly.)
> 
> gcc/fortran/ChangeLog:
> 
>   PR fortran/103039
>   * trans-openmp.cc (gfc_omp_clause_copy_ctor, gfc_omp_clause_dtor):
>   Only privatize pointer for associate names.
> 
> libgomp/ChangeLog:
> 
>   PR fortran/103039
>   * testsuite/libgomp.fortran/associate4.f90: New test.
> 
>  gcc/fortran/trans-openmp.cc  | 10 +++
>  libgomp/testsuite/libgomp.fortran/associate4.f90 | 92 
> 
>  2 files changed, 102 insertions(+)
> 

Jakub