[PATCH 0/8] OpenMP: lvalue parsing and "declare mapper" support

2023-09-05 Thread Julian Brown
This series implements "lvalue" parsing for C and C++ map/to/from clauses,
and "declare mapper" support for C, C++ and Fortran.  This is the latter
part of the series that was previously posted for mainline here:

  https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609031.html

and is approximately equivalent to the series posted for the og13
branch here:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623352.html

though with several follow-up patches rolled in (as mentioned on the
following patch-specific emails).

This series applies on top of the infrastructural support series posted
here:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627895.html

Tested with offloading to NVPTX and bootstrapped. OK?

Julian Brown (8):
  OpenMP: lvalue parsing for map/to/from clauses (C++)
  OpenMP: lvalue parsing for map/to/from clauses (C)
  OpenMP: C++ "declare mapper" support
  OpenMP: Support OpenMP 5.0 "declare mapper" directives for C
  OpenMP, Fortran: Pass list number to gfc_free_omp_namelist
  OpenMP, Fortran: Per-directive control for gfc_trans_omp_clauses
  OpenMP, Fortran: Split out OMP clause checking
  OpenMP: Fortran "!$omp declare mapper" support

 gcc/c-family/c-common.h   |   11 +-
 gcc/c-family/c-omp.cc |  500 ++-
 gcc/c-family/c-pretty-print.cc|   12 +
 gcc/c/c-decl.cc   |  169 +
 gcc/c/c-objc-common.h |   12 +
 gcc/c/c-parser.cc |  472 ++-
 gcc/c/c-tree.h|9 +
 gcc/c/c-typeck.cc |  124 +-
 gcc/cp/constexpr.cc   |   10 +
 gcc/cp/cp-gimplify.cc |6 +
 gcc/cp/cp-objcp-common.h  |9 +
 gcc/cp/cp-tree.h  |   19 +-
 gcc/cp/decl.cc|   27 +-
 gcc/cp/decl2.cc   |   54 +-
 gcc/cp/error.cc   |   34 +
 gcc/cp/parser.cc  |  514 ++-
 gcc/cp/parser.h   |3 +
 gcc/cp/pt.cc  |   84 +-
 gcc/cp/semantics.cc   |  260 +-
 gcc/cp/typeck.cc  |   50 +
 gcc/fortran/dump-parse-tree.cc|4 +
 gcc/fortran/f95-lang.cc   |7 +
 gcc/fortran/gfortran.h|   76 +-
 gcc/fortran/match.cc  |   14 +-
 gcc/fortran/match.h   |1 +
 gcc/fortran/module.cc |  257 +-
 gcc/fortran/openmp.cc | 2026 +++
 gcc/fortran/parse.cc  |   13 +-
 gcc/fortran/resolve.cc|2 +
 gcc/fortran/st.cc |2 +-
 gcc/fortran/symbol.cc |   16 +
 gcc/fortran/trans-decl.cc |   33 +-
 gcc/fortran/trans-openmp.cc   |  592 ++-
 gcc/fortran/trans-stmt.h  |1 +
 gcc/fortran/trans.h   |3 +
 gcc/gimplify.cc   |  560 ++-
 gcc/langhooks-def.h   |   13 +
 gcc/langhooks.cc  |   35 +
 gcc/langhooks.h   |   16 +
 gcc/omp-general.h |   86 +
 .../c-c++-common/gomp/declare-mapper-12.c |   22 +
 .../c-c++-common/gomp/declare-mapper-15.c |   59 +
 .../c-c++-common/gomp/declare-mapper-16.c |   39 +
 .../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  |   23 +
 .../c-c++-common/gomp/declare-mapper-7.c  |   29 +
 .../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-6.c   |   14 +-
 gcc/testsuite/g++.dg/gomp/array-section-1.C   |   38 +
 gcc/testsuite/g++.dg/gomp/array-section-2.C   |   63 +
 .../g++.dg/gomp/bad-array-section-1.C |   35 +
 .../g++.dg/gomp/bad-array-section-10.C|   35 +
 .../g++.dg/gomp/bad-array-section-11.C|   36 +
 .../g++.dg/gomp/bad-array-section-2.C |   33 +
 .../g++.dg/gomp/bad-array-section-3.C |   28 +
 .../g++.dg/gomp/bad-array-section-4.C |   50 +
 .../g++.dg/gomp/bad-array-section-5.C |   50 +
 .../g++.dg/gomp/bad-array-section-6.C |   24 +
 .../g++.dg/gomp/bad-array-section-7.C |   36 +
 .../g++.dg/gomp/bad-array-section-8.C |   53 +
 .../g++.dg/gomp/bad-array-section-9.C |   39 +
 gcc/testsuite/g++.dg/gomp/declare-mapper-1.C  |   58 +
 gcc/testsuite/g++.dg/gomp/declare-mapper-2.C  |   30 +
 .../gomp/has_device_addr-non-lvalue-1.C   |   36 +
 gcc/testsuite/g++.

[PATCH 2/8] OpenMP: lvalue parsing for map/to/from clauses (C)

2023-09-05 Thread Julian Brown
This patch adds support for parsing general lvalues ("locator list item
types") for OpenMP "map", "to" and "from" clauses to the C front-end,
similar to the previously-posted patch for C++.  Such syntax is permitted
for OpenMP 5.0 and above.  It was previously posted for mainline here:

  https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609038.html

and for the og13 branch here:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623355.html

2023-09-05  Julian Brown  

gcc/c/
* c-pretty-print.cc (c_pretty_printer::postfix_expression,
c_pretty_printer::expression): Add OMP_ARRAY_SECTION support.
* c-parser.cc (c_parser_braced_init, c_parser_conditional_expression):
Don't allow OpenMP array section.
(c_parser_postfix_expression): Don't allow array section in statement
expression.
(c_parser_postfix_expression_after_primary): Add support for OpenMP
array section parsing.
(c_parser_expr_list): Don't allow OpenMP array section here.
(c_parser_omp_variable_list): Change ALLOW_DEREF parameter to
MAP_LVALUE.  Support parsing of general lvalues in "map", "to" and
"from" 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): Update calls to
c_parser_omp_var_list_parens.
(c_parser_omp_clause_reduction): Use OMP_ARRAY_SECTION tree node
instead of TREE_LIST for array sections.
(c_parser_omp_target): Allow GOMP_MAP_ATTACH.
* c-tree.h (c_omp_array_section_p): Add extern declaration.
(build_omp_array_section): Add prototype.
* c-typeck.c (c_omp_array_section_p): Add flag.
(mark_exp_read): Support OMP_ARRAY_SECTION.
(build_omp_array_section): Add function.
(build_external_ref): Tweak error path for OpenMP array sections.
(handle_omp_array_sections_1): Use OMP_ARRAY_SECTION tree code instead
of TREE_LIST.  Handle more kinds of expressions.
(c_oacc_check_attachments): Use OMP_ARRAY_SECTION instead of TREE_LIST
for array sections.
(c_finish_omp_clauses): Use OMP_ARRAY_SECTION instead of TREE_LIST.
Check for supported expression types.

gcc/testsuite/
* gcc.dg/gomp/bad-array-section-c-1.c: New test.
* gcc.dg/gomp/bad-array-section-c-2.c: New test.
* gcc.dg/gomp/bad-array-section-c-3.c: New test.
* gcc.dg/gomp/bad-array-section-c-4.c: New test.
* gcc.dg/gomp/bad-array-section-c-5.c: New test.
* gcc.dg/gomp/bad-array-section-c-6.c: New test.
* gcc.dg/gomp/bad-array-section-c-7.c: New test.
* gcc.dg/gomp/bad-array-section-c-8.c: New test.

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-family/c-pretty-print.cc|  12 ++
 gcc/c/c-parser.cc | 181 +++---
 gcc/c/c-tree.h|   2 +
 gcc/c/c-typeck.cc | 109 +--
 .../gcc.dg/gomp/bad-array-section-c-1.c   |  16 ++
 .../gcc.dg/gomp/bad-array-section-c-2.c   |  13 ++
 .../gcc.dg/gomp/bad-array-section-c-3.c   |  24 +++
 .../gcc.dg/gomp/bad-array-section-c-4.c   |  26 +++
 .../gcc.dg/gomp/bad-array-section-c-5.c   |  15 ++
 .../gcc.dg/gomp/bad-array-section-c-6.c   |  16 ++
 .../gcc.dg/gomp/bad-array-section-c-7.c   |  26 +++
 .../gcc.dg/gomp/bad-array-section-c-8.c   |  21 ++
 .../libgomp.c-c++-common/ind-base-4.c |  50 +
 .../libgomp.c-c++-common/unary-ptr-1.c|  16 ++
 14 files changed, 482 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-1.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-2.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-3.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-4.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-5.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-6.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-7.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/bad-array-section-c-8.c
 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-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index 7536a7c471ff..225ac7ef2851 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -1615,6 +1615,17 @@ c_pretty_printer::postfix_expression (tree e)
   pp_c_right_bracket (this);
   break;
 
+case OMP_ARRAY_SECTION:
+  postfix_expression (TREE_OPERAND (e, 0));
+  pp_c_left_bracket (this);
+  if (TREE_OPERAND (e, 1))
+   expression (TREE_OPERAND (e, 1));
+  

[PATCH 5/8] OpenMP, Fortran: Pass list number to gfc_free_omp_namelist

2023-09-05 Thread Julian Brown
This is a cleanup to avoid passing an ever-longer list of boolean
arguments to gfc_free_omp_namelist, in support of the Fortran "declare
mapper" implementation further along this patch series.

This patch isn't intended to cause any behavioural changes.

2023-09-05  Julian Brown  

gcc/fortran/
* gfortran.h (gfc_free_omp_namelist): Update prototype.
* match.cc (gfc_free_omp_namelist): Remove FREE_NS,
FREE_ALIGN_ALLOCATOR, FREE_MEM_TRAITS_SPACE parameters and replace
with LIST.
* openmp.cc (gfc_free_omp_clauses, gfc_match_omp_clause_reduction,
gfc_match_omp_clause_uses_allocators, gfc_match_omp_clauses,
gfc_match_omp_allocate, gfc_match_omp_flush, resolve_omp_clauses):
Update calls to gfc_free_omp_namelist.
* st.cc (gfc_free_statement): Update call to gfc_free_omp_namelist.
---
 gcc/fortran/gfortran.h |  2 +-
 gcc/fortran/match.cc   |  7 ---
 gcc/fortran/openmp.cc  | 31 ++-
 gcc/fortran/st.cc  |  2 +-
 4 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3c8270a0f83a..34ee800668ca 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3605,7 +3605,7 @@ void gfc_free_iterator (gfc_iterator *, int);
 void gfc_free_forall_iterator (gfc_forall_iterator *);
 void gfc_free_alloc_list (gfc_alloc *);
 void gfc_free_namelist (gfc_namelist *);
-void gfc_free_omp_namelist (gfc_omp_namelist *, bool, bool, bool);
+void gfc_free_omp_namelist (gfc_omp_namelist *, int = OMP_LIST_NUM);
 void gfc_free_equiv (gfc_equiv *);
 void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index ba23bcd96923..dd72a03027a1 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -5536,10 +5536,11 @@ gfc_free_namelist (gfc_namelist *name)
 /* Free an OpenMP namelist structure.  */
 
 void
-gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns,
-  bool free_align_allocator,
-  bool free_mem_traits_space)
+gfc_free_omp_namelist (gfc_omp_namelist *name, int list)
 {
+  bool free_ns = (list == OMP_LIST_AFFINITY || list == OMP_LIST_DEPEND);
+  bool free_align_allocator = (list == OMP_LIST_ALLOCATE);
+  bool free_mem_traits_space = (list == OMP_LIST_USES_ALLOCATORS);
   gfc_omp_namelist *n;
 
   for (; name; name = n)
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 234d896b2ce2..576b6784b441 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -186,10 +186,7 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
   gfc_free_expr (c->num_workers_expr);
   gfc_free_expr (c->vector_length_expr);
   for (i = 0; i < OMP_LIST_NUM; i++)
-gfc_free_omp_namelist (c->lists[i],
-  i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND,
-  i == OMP_LIST_ALLOCATE,
-  i == OMP_LIST_USES_ALLOCATORS);
+gfc_free_omp_namelist (c->lists[i], i);
   gfc_free_expr_list (c->wait_list);
   gfc_free_expr_list (c->tile_list);
   free (CONST_CAST (char *, c->critical_name));
@@ -554,7 +551,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false, false, false);
+  gfc_free_omp_namelist (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -644,7 +641,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false, false, false);
+  gfc_free_omp_namelist (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -753,7 +750,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false, false, false);
+  gfc_free_omp_namelist (head);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -1504,7 +1501,7 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses 
*c, bool openacc,
   *head = NULL;
   gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
 buffer, &old_loc);
-  gfc_free_omp_namelist (n, false, false, false);
+  gfc_free_omp_namelist (n, list_idx);
 }
   else
 for (n = *head; n; n = n->next)
@@ -1795,7 +1792,7 @@ gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
   return MATCH_YES;
 
 error:
-  gfc_free_omp_namelist (head, false, false, true);
+  gfc_free_omp_namelist (head, OMP_LIST_USES_ALLOCATORS);
   return MATCH_ERROR;
 }
 
@@ -1922,7 +1919,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const 
omp_mask mask,
 
  if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
{
- gfc_free_omp_namelist (*head, false, false, false);
+ gfc_free_omp_namelist (*head);
  gfc_current_locus = old_loc;
  *head = NULL;
  break;
@@ -2865,7 +2862,7 @@ gfc_matc

[PATCH 3/8] OpenMP: C++ "declare mapper" support

2023-09-05 Thread Julian Brown
This patch adds support for OpenMP 5.0 "declare mapper" functionality
for C++.  This is based on the version of the patch posted for the og13
branch here:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623353.html

The following follow up patches/fixes have also been incorporated into
this version:

"OpenMP: Expand "declare mapper" mappers for target {enter,exit,}
data directives":

  https://gcc.gnu.org/pipermail/gcc-patches/2023-July/623780.html

"OpenMP: Introduce C_ORT_{,OMP_}DECLARE_MAPPER c_omp_region_type types":

  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627005.html

2023-09-05  Julian Brown  

gcc/c-family/
* c-common.h (c_omp_region_type): Add C_ORT_EXIT_DATA,
C_ORT_DECLARE_MAPPER, C_ORT_OMP_EXIT_DATA, C_ORT_OMP_DECLARE_MAPPER
values.
(omp_mapper_list): Add forward declaration.
(c_omp_find_nested_mappers, c_omp_instantiate_mappers): Add prototypes.
* c-omp.cc (c_omp_find_nested_mappers): New function.
(remap_mapper_decl_info): New struct.
(remap_mapper_decl_1, omp_split_map_kind, omp_join_map_kind,
omp_map_decayed_kind, omp_instantiate_mapper,
c_omp_instantiate_mappers): New functions.

gcc/cp/
* constexpr.cc (reduced_constant_expression_p): Add OMP_DECLARE_MAPPER
case.
(cxx_eval_constant_expression, potential_constant_expression_1):
Likewise.
* cp-gimplify.cc (cxx_omp_finish_mapper_clauses): New function.
* cp-objcp-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.
* cp-tree.h (lang_decl_base): Add omp_declare_mapper_p field.  Recount
spare bits comment.
(DECL_OMP_DECLARE_MAPPER_P): New macro.
(omp_mapper_id, cp_check_omp_declare_mapper, omp_instantiate_mappers,
cxx_omp_finish_mapper_clauses, cxx_omp_mapper_lookup,
cxx_omp_extract_mapper_directive, cxx_omp_map_array_section): Add
prototypes.
* decl.cc (check_initializer): Add OpenMP declare mapper support.
(cp_finish_decl): Set DECL_INITIAL for OpenMP declare mapper var decls
as appropriate.
* decl2.cc (mark_used): Instantiate OpenMP "declare mapper" magic var
decls.
* error.cc (dump_omp_declare_mapper): New function.
(dump_simple_decl): Use above.
* parser.cc (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_mapper): New function.
(cp_parser_omp_declare): Add "declare mapper" support.
* pt.cc (tsubst_decl): Adjust name of "declare mapper" magic var decls
once we know their type.
(tsubst_omp_clauses): Call omp_instantiate_mappers before
finish_omp_clauses, for target regions.
(tsubst_expr): Support OMP_DECLARE_MAPPER nodes.
(instantiate_decl): Instantiate initialiser (i.e definition) for OpenMP
declare mappers.
* semantics.cc (gimplify.h): Include.
(omp_mapper_id, cxx_omp_mapper_lookup, cxx_omp_extract_mapper_directive,
cxx_omp_map_array_section, cp_check_omp_declare_mapper): New functions.
(finish_omp_clauses): Delete GOMP_MAP_PUSH_MAPPER_NAME and
GOMP_MAP_POP_MAPPER_NAME artificial clauses.
(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): New structs.
(remap_mapper_decl_1, omp_mapper_copy_decl, omp_instantiate_mapper,
omp_instantiate_implicit_mappers): New functions.
(gimplify_scan_omp_clauses): Handle MAPPER_BINDING clauses.
(gimplify_adjust_omp_clauses): Instantiate implicit declared mappers.
(gimplify_omp_declare_mapper): New function.
(gimplify_expr): Call above function.
* langhooks-def.h (lhd_omp_finish_mapper_clauses,
lhd_omp_mapper_lookup, lhd_omp_extract_mapper_directive,
lhd_omp_map_array_section): Add prototypes.
(LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES,
LANG_HOOKS_OMP_MAPPER_LOOKUP, LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define macros.
(LANG_H

[PATCH 7/8] OpenMP, Fortran: Split out OMP clause checking

2023-09-05 Thread Julian Brown
This patch breaks out two helper functions from
openmp.cc:resolve_omp_clauses, so those parts can be reused in order
to improve diagnostics (duplicate clause checking, etc.) after "declare
mapper" instantiation in the patch later in this series.  This is pretty
mechanical -- most previous lines are still executed in the same order,
though there is a little harmless reshuffling in a couple of places to
make things fit.

There shouldn't be any behavioural changes introduced by this patch.

2023-09-05  Julian Brown  

gcc/fortran/
* openmp.cc (omp_verify_clauses_symbol_dups,
omp_verify_map_motion_clauses): New helper functions, broken out of...
(resolve_omp_clauses): Here.  Call above.
---
 gcc/fortran/openmp.cc | 1229 +
 1 file changed, 629 insertions(+), 600 deletions(-)

diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 576b6784b441..1e0da61e9693 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -7314,6 +7314,631 @@ gfc_resolve_omp_assumptions (gfc_omp_assumptions 
*assume)
 &el->expr->where);
 }
 
+/* Check OMP_CLAUSES for duplicate symbols and various other constraints.
+   Helper function for resolve_omp_clauses.  */
+
+static void
+omp_verify_clauses_symbol_dups (gfc_code *code, gfc_omp_clauses *omp_clauses,
+   gfc_namespace *ns, bool openacc)
+{
+  gfc_omp_namelist *n;
+  int list;
+
+  /* Check that no symbol appears on multiple clauses, except that a symbol
+ can appear on both firstprivate and lastprivate.  */
+  for (list = 0; list < OMP_LIST_NUM; list++)
+for (n = omp_clauses->lists[list]; n; n = n->next)
+  {
+   if (!n->sym)  /* omp_all_memory.  */
+ continue;
+   n->sym->mark = 0;
+   n->sym->comp_mark = 0;
+   n->sym->data_mark = 0;
+   n->sym->dev_mark = 0;
+   n->sym->gen_mark = 0;
+   n->sym->reduc_mark = 0;
+   if (n->sym->attr.flavor == FL_VARIABLE
+   || n->sym->attr.proc_pointer
+   || (!code
+   && !ns->omp_udm_ns
+   && (!n->sym->attr.dummy || n->sym->ns != ns)))
+ {
+   if (!code
+   && !ns->omp_udm_ns
+   && (!n->sym->attr.dummy || n->sym->ns != ns))
+ gfc_error ("Variable %qs is not a dummy argument at %L",
+n->sym->name, &n->where);
+   continue;
+ }
+   if (n->sym->attr.flavor == FL_PROCEDURE
+   && n->sym->result == n->sym
+   && n->sym->attr.function)
+ {
+   if (gfc_current_ns->proc_name == n->sym
+   || (gfc_current_ns->parent
+   && gfc_current_ns->parent->proc_name == n->sym))
+ continue;
+   if (gfc_current_ns->proc_name->attr.entry_master)
+ {
+   gfc_entry_list *el = gfc_current_ns->entries;
+   for (; el; el = el->next)
+ if (el->sym == n->sym)
+   break;
+   if (el)
+ continue;
+ }
+   if (gfc_current_ns->parent
+   && gfc_current_ns->parent->proc_name->attr.entry_master)
+ {
+   gfc_entry_list *el = gfc_current_ns->parent->entries;
+   for (; el; el = el->next)
+ if (el->sym == n->sym)
+   break;
+   if (el)
+ continue;
+ }
+ }
+   if (list == OMP_LIST_MAP
+   && n->sym->attr.flavor == FL_PARAMETER)
+ {
+   if (openacc)
+ gfc_error ("Object %qs is not a variable at %L; parameters"
+" cannot be and need not be copied", n->sym->name,
+&n->where);
+   else
+ gfc_error ("Object %qs is not a variable at %L; parameters"
+" cannot be and need not be mapped", n->sym->name,
+&n->where);
+ }
+   else if (list != OMP_LIST_USES_ALLOCATORS)
+ gfc_error ("Object %qs is not a variable at %L", n->sym->name,
+&n->where);
+  }
+  if (omp_clauses->lists[OMP_LIST_REDUCTION_INSCAN]
+  && code->op != EXEC_OMP_DO
+  && code->op != EXEC_OMP_SIMD
+  && code->op != EXEC_OMP_DO_SIMD
+  && code->op != EXEC_OMP_PARALLEL_DO
+  && code->op != EXEC_OMP_PARALLEL_DO_SIMD)
+gfc_error ("% REDUCTION clause on construct other than DO, SIMD, "
+  "DO SIMD, PARALLEL DO, PARALLEL DO SIMD at %L",
+  &omp_clauses->lists[OMP_LIST_REDUCTION_INSCAN]->where);
+
+  for (list = 0; list < OMP_LIST_NUM; list++)
+if (list != OMP_LIST_FIRSTPRIVATE
+   && list != OMP_LIST_LASTPRIVATE
+   && list != OMP_LIST_ALIGNED
+   && list != OMP_LIST_DEPEND
+   && list != OMP_LIST_FROM
+   && list != OMP_LIST_TO
+   && (list != OMP_LIST_REDUCTION || !openacc)
+   && list != OMP_LIST_ALLOCATE)
+  for (n = omp_claus

[PATCH 6/8] OpenMP, Fortran: Per-directive control for gfc_trans_omp_clauses

2023-09-05 Thread Julian Brown
Some of the processing done by gfc_trans_omp_clauses depends on the
directive that that clause is attached to.  This patch refactors two
booleans and one gfc_exec_op parameter for gfc_trans_omp_clauses into
a single parameter of (new) enumerated type 'toc_directive'.  The same
parameter is also passed to gfc_trans_omp_array_section instead of a
gfc_exec_op type parameter and an 'openmp' boolean.

This is mostly done in aid of the patch later in the series implementing
"declare mapper" support for Fortran.

There shouldn't be any behavioural changes introduced by this patch.

2023-09-05  Julian Brown  

gcc/fortran/
* gfortran.h (toc_directive): New enum.
* trans-openmp.cc (gfc_trans_omp_array_section): Take toc_directive
parameter instead of gfc_exec_op and 'openmp' boolean.
(gfc_trans_omp_clauses): Take toc_directive parameter instead of
'declare_simd', 'openacc' and gfc_exec_op 'op' parameters.
(gfc_trans_oacc_construct, gfc_trans_oacc_executable_directive,
gfc_trans_oacc_combined_directive, gfc_trans_omp_target_exit_data,
gfc_trans_oacc_declare, gfc_trans_omp_declare_simd,
gfc_trans_omp_declare_variant): Update calls to gfc_trans_omp_clauses.
---
 gcc/fortran/gfortran.h  | 11 ++
 gcc/fortran/trans-openmp.cc | 77 +++--
 2 files changed, 50 insertions(+), 38 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 34ee800668ca..3070b4675e8e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3180,6 +3180,17 @@ typedef struct gfc_finalizer
 gfc_finalizer;
 #define gfc_get_finalizer() XCNEW (gfc_finalizer)
 
+/* Control clause translation per-directive for gfc_trans_omp_clauses.  Also
+   used for gfc_omp_instantiate_mappers.  */
+
+enum toc_directive
+{
+  TOC_OPENMP,
+  TOC_OPENMP_DECLARE_SIMD,
+  TOC_OPENMP_EXIT_DATA,
+  TOC_OPENACC,
+  TOC_OPENACC_DECLARE
+};
 
 / Function prototypes */
 
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index a9dc1a617be5..829b28b24c79 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -2404,11 +2404,13 @@ static vec *doacross_steps;
 /* Translate an array section or array element.  */
 
 static void
-gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
+gfc_trans_omp_array_section (stmtblock_t *block, toc_directive cd,
 gfc_omp_namelist *n, tree decl, bool element,
-bool openmp, gomp_map_kind ptr_kind, tree &node,
+gomp_map_kind ptr_kind, tree &node,
 tree &node2, tree &node3, tree &node4)
 {
+  bool openmp = (cd < TOC_OPENACC);
+  bool omp_exit_data = (cd == TOC_OPENMP_EXIT_DATA);
   gfc_se se;
   tree ptr, ptr2;
   tree elemsz = NULL_TREE;
@@ -2460,7 +2462,7 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
   if (POINTER_TYPE_P (TREE_TYPE (decl))
   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
   && ptr_kind == GOMP_MAP_POINTER
-  && op != EXEC_OMP_TARGET_EXIT_DATA
+  && !omp_exit_data
   && OMP_CLAUSE_MAP_KIND (node) != GOMP_MAP_RELEASE
   && OMP_CLAUSE_MAP_KIND (node) != GOMP_MAP_DELETE)
 
@@ -2479,8 +2481,7 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
   gomp_map_kind map_kind;
   if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DELETE)
map_kind = OMP_CLAUSE_MAP_KIND (node);
-  else if (op == EXEC_OMP_TARGET_EXIT_DATA
-  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE)
+  else if (omp_exit_data || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE)
map_kind = GOMP_MAP_RELEASE;
   else
map_kind = GOMP_MAP_TO;
@@ -2499,11 +2500,10 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
   OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
   if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DELETE
  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE
- || op == EXEC_OMP_TARGET_EXIT_DATA)
+ || omp_exit_data)
{
- gomp_map_kind map_kind
-   = (op == EXEC_OMP_TARGET_EXIT_DATA) ? GOMP_MAP_RELEASE
-   : OMP_CLAUSE_MAP_KIND (node);
+ gomp_map_kind map_kind = omp_exit_data ? GOMP_MAP_RELEASE
+: OMP_CLAUSE_MAP_KIND (node);
  OMP_CLAUSE_SET_MAP_KIND (node2, map_kind);
  OMP_CLAUSE_RELEASE_DESCRIPTOR (node2) = 1;
}
@@ -2681,9 +2681,11 @@ get_symbol_rooted_namelist (hash_map= TOC_OPENACC);
+  bool omp_exit_data = (cd == TOC_OPENMP_EXIT_DATA);
   tree omp_clauses = NULL_TREE, prev_clauses, chunk_size, c;
   tree iterator = NULL_TREE;
   tree tree_block = NULL_TREE;
@@ -3250,7 +3252,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
  && n->sym->ts.deferred
 

[PATCH 4/8] OpenMP: Support OpenMP 5.0 "declare mapper" directives for C

2023-09-05 Thread Julian Brown
This patch adds support for "declare mapper" directives (and the "mapper"
modifier on "map" clauses) for C.  It was previously posted for mainline
here:

  https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609041.html

and for the og13 branch here:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623356.html

This version supports mappers on "target data", "target enter data" and
"target exit data" directives as well as on "target" directives.

2023-09-05  Julian Brown  

gcc/c/
* 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.
* 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_data, c_parser_omp_target_enter_data,
c_parser_omp_target_exit_data): Instantiate explicit mappers.
(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): 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/testsuite/
* c-c++-common/gomp/declare-mapper-3.c: Enable for C.
* c-c++-common/gomp/declare-mapper-4.c: Likewise.
* c-c++-common/gomp/declare-mapper-5.c: Likewise.
* c-c++-common/gomp/declare-mapper-6.c: Likewise.
* c-c++-common/gomp/declare-mapper-7.c: Likewise.
* c-c++-common/gomp/declare-mapper-8.c: Likewise.
* c-c++-common/gomp/declare-mapper-9.c: Likewise.
* c-c++-common/gomp/declare-mapper-12.c: Likewise.
* c-c++-common/gomp/declare-mapper-15.c: Likewise.
* c-c++-common/gomp/declare-mapper-16.c: Likewise.
* gcc.dg/gomp/declare-mapper-10.c: New test.
* gcc.dg/gomp/declare-mapper-11.c: New test.

libgomp/
* testsuite/libgomp.c-c++-common/declare-mapper-9.c: Enable for C.
* testsuite/libgomp.c-c++-common/declare-mapper-10.c: Likewise.
* testsuite/libgomp.c-c++-common/declare-mapper-11.c: Likewise.
* testsuite/libgomp.c-c++-common/declare-mapper-12.c: Likewise.
* testsuite/libgomp.c-c++-common/declare-mapper-13.c: Likewise.
* testsuite/libgomp.c-c++-common/declare-mapper-14.c: Likewise.
---
 gcc/c/c-decl.cc   | 169 ++
 gcc/c/c-objc-common.h |  12 +
 gcc/c/c-parser.cc | 291 --
 gcc/c/c-tree.h|   7 +
 gcc/c/c-typeck.cc |  15 +
 .../c-c++-common/gomp/declare-mapper-12.c |   2 +-
 .../c-c++-common/gomp/declare-mapper-15.c |   2 +-
 .../c-c++-common/gomp/declare-mapper-16.c |   2 +-
 .../c-c++-common/gomp/declare-mapper-3.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-4.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-5.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-6.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-7.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-8.c  |   2 +-
 .../c-c++-common/gomp/declare-mapper-9.c  |   2 +-
 gcc/testsuite/gcc.dg/gomp/declare-mapper-10.c |  61 
 gcc/testsuite/gcc.dg/gomp/declare-mapper-11.c |  33 ++
 .../libgomp.c-c++-common/declare-mapper-10.c  |   2 +-
 .../libgomp.c-c++-common/declare-mapper-11.c  |   2 +-
 .../libgomp.c-c++-common/declare-mapper-12.c  |   2 +-
 .../libgomp.c-c++-common/declare-mapper-13.c  |   2 +-
 .../libgomp.c-c++-common/declare-mapper-14.c  |   2 +-
 .../libgomp.c-c++-common/declare-mapper-9.c   |   2 +-
 23 files changed, 584 insertions(+), 36 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/declare-mapper-10.c
 create mode 100644 gcc/testsuite/gcc.dg/gomp/declare-mapper-11.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 1f9eb44dbaa2..ac71092fcad6 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -13144,6 +13144,175 @@ c_check_omp_declare_reduction_r (tree *tp, int *, 
void *data)
   return NULL_TREE;
 }
 
+/* Return identifier to look up for omp declare reduction.  */
+
+tree
+c_omp_mapper_id (tree mapper_id)
+{
+  const char *p = NULL;
+
+  const char prefix

[PATCH 8/8] OpenMP: Fortran "!$omp declare mapper" support

2023-09-05 Thread Julian Brown
This patch implements "omp declare mapper" functionality for Fortran,
following the equivalent support for C and C++.  This version of the
patch is based on the version posted for the og13 branch:

  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623357.html

and contains some significant changes from the version last posted for
mainline, here:

  https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609042.html

In particular, mappers are resolved during resolution in the Fortran
FE, rather than directly at parse time, and there are improvements to
diagnostics.  Each of 'target', 'target data', 'target enter data', and
'target exit data' directives are supported for mappers.  The following
patches from the og13 branch have also been incorporated into this one:

"OpenMP: Reprocess expanded clauses after 'declare mapper' instantiation":

  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627006.html

"OpenMP: Look up 'declare mapper' definitions at resolution time not
parse time":

  https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627007.html

2023-09-05  Julian Brown  

gcc/fortran/
* dump-parse-tree.cc (show_attr): Show omp_udm_artificial_var flag.
(show_omp_namelist): Support OMP_MAP_POINTER_ONLY and OMP_MAP_UNSET.
* f95-lang.cc (LANG_HOOKS_OMP_FINISH_MAPPER_CLAUSES,
LANG_HOOKS_OMP_EXTRACT_MAPPER_DIRECTIVE,
LANG_HOOKS_OMP_MAP_ARRAY_SECTION): Define language hooks.
* gfortran.h (gfc_statement): Add ST_OMP_DECLARE_MAPPER.
(symbol_attribute): Add omp_udm_artificial_var attribute.
(gfc_omp_map_op): Add OMP_MAP_POINTER_ONLY and OMP_MAP_UNSET.
(gfc_omp_namelist): Add udm pointer to u2 union.
(gfc_omp_clauses): Add gfc_namespace pointer field 'ns'.
(gfc_omp_udm): New struct.
(gfc_omp_namelist_udm): New struct.
(gfc_symtree): Add omp_udm pointer.
(gfc_namespace): Add omp_udm_root symtree. Add omp_udm_ns flag.
(toc_directive): Add TOC_OPENMP_DECLARE_MAPPER value.
(gfc_free_omp_udm, gfc_omp_udm_find, gfc_find_omp_udm,
gfc_resolve_omp_udms, gfc_omp_instantiate_mappers): Add prototypes.
* match.cc (gfc_free_omp_namelist): Add support for freeing
user-defined 'declare mapper' definitions safely.
* match.h (gfc_match_omp_declare_mapper): Add prototype.
* module.cc (ab_attribute): Add AB_OMP_DECLARE_MAPPER_VAR.
(attr_bits): Add OMP_DECLARE_MAPPER_VAR.
(mio_symbol_attribute): Read/write AB_OMP_DECLARE_MAPPER_VAR attribute.
Set referenced attr on read.
(omp_map_clause_ops, omp_map_cardinality): New arrays.
(load_omp_udms, check_omp_declare_mappers): New functions.
(read_module): Load and check OMP declare mappers.
(write_omp_udm, write_omp_udms): New functions.
(write_module): Write OMP declare mappers.
* openmp.cc (gfc_match_omp_clauses): Add DEFAULT_MAP_OP parameter.  Add
declare mapper support.
(gfc_free_omp_udm, gfc_find_omp_udm, gfc_omp_udm_find,
gfc_match_omp_declare_mapper): New functions.
(omp_verify_clauses_symbol_dups, omp_verify_map_motion_clauses): Update
function comments.
(resolve_omp_clauses): Record namespace for 'declare mapper'
definitions.  Resolve mappers.
(resolve_omp_mapper_clauses): New function.
(resolve_omp_directive): Pass namespace to resolve_omp_clauses.
(omp_split_map_op, omp_join_map_op, omp_map_decayed_kind,
omp_basic_map_kind_name): New functions.
(gfc_subst_replace, gfc_subst_prepend_ref): New static globals.
(gfc_subst_in_expr_1, gfc_subst_in_expr, gfc_subst_mapper_var,
gfc_omp_instantiate_mapper, gfc_omp_instantiate_mappers,
gfc_resolve_omp_udm, gfc_resolve_omp_udms): New functions.
* parse.cc (decode_omp_directive): Add declare mapper support.
(case_omp_decl): Add ST_OMP_DECLARE_MAPPER case.
(gfc_ascii_statement): Add ST_OMP_DECLARE_MAPPER case.
* resolve.cc (resolve_types): Call gfc_resolve_omp_udms.
* symbol.cc (free_omp_udm_tree): New function.
(gfc_free_namespace): Call above.
* trans-decl.cc (omp_declare_mapper_ns): New global.
(gfc_finish_var_decl, gfc_generate_function_code): Support declare
mappers.
(gfc_trans_deferred_vars): Ignore artificial declare-mapper vars.
* trans-openmp.cc (tree-iterator.h): Include.
(gfc_omp_finish_mapper_clauses, gfc_omp_extract_mapper_directive,
gfc_omp_map_array_section): New functions.
(gfc_trans_omp_clauses): Add declare mapper support and
OMP_MAP_POINTER_ONLY support.
(gfc_record_mapper_bindings_code_fn, gfc_record_mapper_bindings_expr_fn,
gfc_find_nested_mappers, gfc_record_mapper_bindings): New functions.
(gfc_typespec * hash traits): New template.
(omp_declare_mapper_ns): Extern declaration.
(gfc_trans_omp_target):