[PATCH 0/5] [og13] OpenMP: Implement 'declare mapper' for 'target update' directives

2023-08-10 Thread Julian Brown
This series (for the og13 branch) implements 'declare mapper' support for
'target update' directives, and improves diagnostic behaviour relating
to mapper expansion (mostly for Fortran) in several ways.

Tested with offloading to AMD GCN.  Further comments on individual
patches.  I will apply (to the og13 branch) shortly.

Julian Brown (5):
  OpenMP: Move Fortran 'declare mapper' instantiation code
  OpenMP: Reprocess expanded clauses after 'declare mapper'
instantiation
  OpenMP: Introduce C_ORT_{,OMP_}DECLARE_MAPPER c_omp_region_type types
  OpenMP: Look up 'declare mapper' definitions at resolution time not
parse time
  OpenMP: Enable 'declare mapper' mappers for 'target update' directives

 gcc/c-family/c-common.h   |4 +
 gcc/c-family/c-omp.cc |  117 +-
 gcc/c/c-parser.cc |  152 +-
 gcc/cp/parser.cc  |  160 +-
 gcc/cp/pt.cc  |4 +-
 gcc/fortran/gfortran.h|   20 +
 gcc/fortran/match.cc  |4 +-
 gcc/fortran/module.cc |6 +
 gcc/fortran/openmp.cc | 1803 +++--
 gcc/fortran/trans-openmp.cc   |  408 +---
 .../c-c++-common/gomp/declare-mapper-17.c |   38 +
 .../c-c++-common/gomp/declare-mapper-19.c |   40 +
 .../gfortran.dg/gomp/declare-mapper-24.f90|   43 +
 .../gfortran.dg/gomp/declare-mapper-26.f90|   28 +
 .../gfortran.dg/gomp/declare-mapper-27.f90|   25 +
 .../gfortran.dg/gomp/declare-mapper-29.f90|   22 +
 .../gfortran.dg/gomp/declare-mapper-31.f90|   34 +
 .../libgomp.c-c++-common/declare-mapper-18.c  |   33 +
 .../libgomp.fortran/declare-mapper-25.f90 |   44 +
 .../libgomp.fortran/declare-mapper-28.f90 |   38 +
 .../libgomp.fortran/declare-mapper-30.f90 |   24 +
 .../libgomp.fortran/declare-mapper-4.f90  |   18 +-
 22 files changed, 2031 insertions(+), 1034 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-mapper-17.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-mapper-19.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-24.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-26.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-27.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-29.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-31.f90
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/declare-mapper-18.c
 create mode 100644 libgomp/testsuite/libgomp.fortran/declare-mapper-25.f90
 create mode 100644 libgomp/testsuite/libgomp.fortran/declare-mapper-28.f90
 create mode 100644 libgomp/testsuite/libgomp.fortran/declare-mapper-30.f90

-- 
2.25.1



[PATCH 1/5] OpenMP: Move Fortran 'declare mapper' instantiation code

2023-08-10 Thread Julian Brown
This patch moves the code for explicit 'declare mapper' directive
instantiation in the Fortran front-end to openmp.cc from trans-openmp.cc.
The transformation takes place entirely in the front end's own
representation and doesn't involve middle-end trees at all. Also, having
the code in openmp.cc is more convenient for the following patch that
introduces the 'resolve_omp_mapper_clauses' function.

2023-08-10  Julian Brown  

gcc/fortran/
* gfortran.h (toc_directive): Move here.
(gfc_omp_instantiate_mappers, gfc_get_location): Add prototypes.
* openmp.cc (omp_split_map_op, omp_join_map_op, omp_map_decayed_kind,
omp_basic_map_kind_name, gfc_subst_replace, gfc_subst_prepend_ref,
gfc_subst_in_expr_1, gfc_subst_in_expr, gfc_subst_mapper_var): Move
here.
(gfc_omp_instantiate_mapper, gfc_omp_instantiate_mappers): Move here
and rename.
* trans-openmp.cc (toc_directive, omp_split_map_op, omp_join_map_op,
omp_map_decayed_kind, gfc_subst_replace, gfc_subst_prepend_ref,
gfc_subst_in_expr_1, gfc_subst_in_expr, gfc_subst_mapper_var,
gfc_trans_omp_instantiate_mapper, gfc_trans_omp_instantiate_mappers):
Remove from here.
(gfc_trans_omp_target, gfc_trans_omp_target_data,
gfc_trans_omp_target_enter_data, gfc_trans_omp_target_exit_data):
Rename calls to gfc_omp_instantiate_mappers.
---
 gcc/fortran/gfortran.h  |  16 ++
 gcc/fortran/openmp.cc   | 435 
 gcc/fortran/trans-openmp.cc | 388 +---
 3 files changed, 456 insertions(+), 383 deletions(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 0e7e80e4bf1..788b3797893 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3246,6 +3246,18 @@ 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_DECLARE_MAPPER,
+  TOC_OPENMP_EXIT_DATA,
+  TOC_OPENACC,
+  TOC_OPENACC_DECLARE
+};
 
 / Function prototypes */
 
@@ -3707,6 +3719,9 @@ void gfc_resolve_omp_do_blocks (gfc_code *, gfc_namespace 
*);
 void gfc_resolve_omp_declare_simd (gfc_namespace *);
 void gfc_resolve_omp_udrs (gfc_symtree *);
 void gfc_resolve_omp_udms (gfc_symtree *);
+void gfc_omp_instantiate_mappers (gfc_code *, gfc_omp_clauses *,
+ toc_directive = TOC_OPENMP,
+ int = OMP_LIST_MAP);
 void gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *);
 void gfc_omp_restore_state (struct gfc_omp_saved_state *);
 void gfc_free_expr_list (gfc_expr_list *);
@@ -3956,6 +3971,7 @@ bool gfc_convert_to_structure_constructor (gfc_expr *, 
gfc_symbol *,
 /* trans.cc */
 void gfc_generate_code (gfc_namespace *);
 void gfc_generate_module_code (gfc_namespace *);
+location_t gfc_get_location (locus *);
 
 /* trans-intrinsic.cc */
 bool gfc_inline_intrinsic_function_p (gfc_expr *);
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index deccb14a525..0f715a6f997 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -12584,6 +12584,441 @@ gfc_resolve_omp_udrs (gfc_symtree *st)
 gfc_resolve_omp_udr (omp_udr);
 }
 
+static enum gfc_omp_map_op
+omp_split_map_op (enum gfc_omp_map_op op, bool *force_p, bool *always_p,
+ bool *present_p)
+{
+  *force_p = *always_p = *present_p = false;
+
+  switch (op)
+{
+case OMP_MAP_FORCE_ALLOC:
+case OMP_MAP_FORCE_TO:
+case OMP_MAP_FORCE_FROM:
+case OMP_MAP_FORCE_TOFROM:
+case OMP_MAP_FORCE_PRESENT:
+  *force_p = true;
+  break;
+case OMP_MAP_ALWAYS_TO:
+case OMP_MAP_ALWAYS_FROM:
+case OMP_MAP_ALWAYS_TOFROM:
+  *always_p = true;
+  break;
+case OMP_MAP_ALWAYS_PRESENT_TO:
+case OMP_MAP_ALWAYS_PRESENT_FROM:
+case OMP_MAP_ALWAYS_PRESENT_TOFROM:
+  *always_p = true;
+  /* Fallthrough.  */
+case OMP_MAP_PRESENT_ALLOC:
+case OMP_MAP_PRESENT_TO:
+case OMP_MAP_PRESENT_FROM:
+case OMP_MAP_PRESENT_TOFROM:
+  *present_p = true;
+  break;
+default:
+  ;
+}
+
+  switch (op)
+{
+case OMP_MAP_ALLOC:
+case OMP_MAP_FORCE_ALLOC:
+case OMP_MAP_PRESENT_ALLOC:
+  return OMP_MAP_ALLOC;
+case OMP_MAP_TO:
+case OMP_MAP_FORCE_TO:
+case OMP_MAP_ALWAYS_TO:
+case OMP_MAP_PRESENT_TO:
+case OMP_MAP_ALWAYS_PRESENT_TO:
+  return OMP_MAP_TO;
+case OMP_MAP_FROM:
+case OMP_MAP_FORCE_FROM:
+case OMP_MAP_ALWAYS_FROM:
+case OMP_MAP_PRESENT_FROM:
+case OMP_MAP_ALWAYS_PRESENT_FROM:
+  return OMP_MAP_FROM;
+case OMP_MAP_TOFROM:
+case OMP_MAP_FORCE_TOFROM:
+case OMP_MAP_ALWAYS_TOFROM:
+case OMP_MAP_PRESENT_TOFROM:
+case OMP_MAP_

[PATCH 2/5] OpenMP: Reprocess expanded clauses after 'declare mapper' instantiation

2023-08-10 Thread Julian Brown
This patch reprocesses expanded clauses after 'declare mapper'
instantiation -- checking things such as duplicated clauses, illegal
use of strided accesses, and so forth.  Two functions are broken out
of the 'resolve_omp_clauses' function and reused in a new function
'resolve_omp_mapper_clauses', called after mapper instantiation.

This improves diagnostic output.

2023-08-10  Julian Brown  

gcc/fortran/
* gfortran.h (gfc_omp_clauses): Add NS field.
* openmp.cc (verify_omp_clauses_symbol_dups,
omp_verify_map_motion_clauses): New functions, broken out of...
(resolve_omp_clauses): Here.  Record namespace containing clauses.
Call above functions.
(resolve_omp_mapper_clauses): New function, using helper functions
broken out above.
(gfc_resolve_omp_directive): Add NS parameter to resolve_omp_clauses
calls.
(gfc_omp_instantiate_mappers): Call resolve_omp_mapper_clauses if we
instantiate any mappers.

gcc/testsuite/
* gfortran.dg/gomp/declare-mapper-26.f90: New test.
* gfortran.dg/gomp/declare-mapper-29.f90: New test.
---
 gcc/fortran/gfortran.h|1 +
 gcc/fortran/openmp.cc | 1250 +
 .../gfortran.dg/gomp/declare-mapper-26.f90|   28 +
 .../gfortran.dg/gomp/declare-mapper-29.f90|   22 +
 4 files changed, 718 insertions(+), 583 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-26.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-29.f90

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 788b3797893..a98424b3263 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1577,6 +1577,7 @@ typedef struct gfc_omp_clauses
   struct gfc_omp_assumptions *assume;
   struct gfc_expr_list *tile_sizes;
   const char *critical_name;
+  gfc_namespace *ns;
   enum gfc_omp_default_sharing default_sharing;
   enum gfc_omp_atomic_op atomic_op;
   enum gfc_omp_defaultmap defaultmap[OMP_DEFAULTMAP_CAT_NUM];
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 0f715a6f997..0109df4dfce 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -8123,6 +8123,611 @@ 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 and resolve_omp_mapper_clauses.  */
+
+static void
+verify_omp_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,
+ 

[PATCH 3/5] OpenMP: Introduce C_ORT_{, OMP_}DECLARE_MAPPER c_omp_region_type types

2023-08-10 Thread Julian Brown
This patch adds C_ORT_DECLARE_MAPPER and C_ORT_OMP_DECLARE_MAPPER
region types to the c_omp_region_type enum, and uses them in cp/pt.cc.
Previously the C_ORT_DECLARE_SIMD code was being abused to inhibit calling
finish_omp_clauses within mapper definitions, but this patch uses one
of the new enumeration values for that purpose instead.  This shouldn't
result in any behaviour change, but improves self-documentation.

2023-08-10  Julian Brown  

gcc/c-family/
* c-common.h (c_omp_region_type): Add C_ORT_DECLARE_MAPPER and
C_ORT_OMP_DECLARE_MAPPER codes.

gcc/cp/
* pt.cc (tsubst_omp_clauses): Use C_ORT_OMP_DECLARE_MAPPER.
(tsubst_expr): Likewise.
---
 gcc/c-family/c-common.h | 2 ++
 gcc/cp/pt.cc| 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index c805c8b2f7e..079d1eaafaa 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1271,9 +1271,11 @@ enum c_omp_region_type
   C_ORT_DECLARE_SIMD   = 1 << 2,
   C_ORT_TARGET = 1 << 3,
   C_ORT_EXIT_DATA  = 1 << 4,
+  C_ORT_DECLARE_MAPPER = 1 << 6,
   C_ORT_OMP_DECLARE_SIMD   = C_ORT_OMP | C_ORT_DECLARE_SIMD,
   C_ORT_OMP_TARGET = C_ORT_OMP | C_ORT_TARGET,
   C_ORT_OMP_EXIT_DATA  = C_ORT_OMP | C_ORT_EXIT_DATA,
+  C_ORT_OMP_DECLARE_MAPPER = C_ORT_OMP | C_ORT_DECLARE_MAPPER,
   C_ORT_ACC_TARGET = C_ORT_ACC | C_ORT_TARGET
 };
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index fb50c5ac48d..2794c0ebecb 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -18328,7 +18328,7 @@ tsubst_omp_clauses (tree clauses, enum 
c_omp_region_type ort,
 }
 
   new_clauses = nreverse (new_clauses);
-  if (ort != C_ORT_OMP_DECLARE_SIMD)
+  if (ort != C_ORT_OMP_DECLARE_SIMD && ort != C_ORT_OMP_DECLARE_MAPPER)
 {
   if (ort & C_ORT_OMP)
new_clauses = c_omp_instantiate_mappers (new_clauses, ort);
@@ -19905,7 +19905,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
decl = tsubst (decl, args, complain, in_decl);
tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
tree clauses = OMP_DECLARE_MAPPER_CLAUSES (t);
-   clauses = tsubst_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD, args,
+   clauses = tsubst_omp_clauses (clauses, C_ORT_OMP_DECLARE_MAPPER, args,
  complain, in_decl);
TREE_TYPE (t) = type;
OMP_DECLARE_MAPPER_DECL (t) = decl;
-- 
2.25.1



[PATCH 4/5] OpenMP: Look up 'declare mapper' definitions at resolution time not parse time

2023-08-10 Thread Julian Brown
This patch moves 'declare mapper' lookup for OpenMP clauses from parse
time to resolution time for Fortran, and adds diagnostics for missing
named mappers.  This changes clause lookup in a particular case -- where
several 'declare mapper's are defined in a context, mappers declared
earlier may now instantiate mappers declared later, whereas previously
they would not.  I think the new behaviour makes more sense -- at an
invocation site, all mappers are visible no matter the declaration order
in some particular block.  I've adjusted tests to account for this.

I think the new arrangement better matches the Fortran FE's usual way of
doing things -- mapper lookup is a semantic concept, not a syntactical
one, so shouldn't be handled in the syntax-handling code.

The patch also fixes a case where the user explicitly writes 'default'
as the name on the mapper modifier for a clause.

2023-08-10  Julian Brown  

gcc/fortran/
* gfortran.h (gfc_omp_namelist_udm): Add MAPPER_ID field to store the
mapper name to use for lookup during resolution.
* match.cc (gfc_free_omp_namelist): Handle OMP_LIST_TO and
OMP_LIST_FROM when freeing mapper references.
* module.cc (load_omp_udms, write_omp_udm): Handle MAPPER_ID field.
* openmp.cc (gfc_match_omp_clauses): Handle explicitly-specified
'default' name.  Don't do mapper lookup here, but record mapper name if
the user specifies one.
(resolve_omp_clauses): Do mapper lookup here instead.  Report error for
missing named mapper.

gcc/testsuite/
* gfortran.dg/gomp/declare-mapper-31.f90: New test.

libgomp/
* testsuite/libgomp.fortran/declare-mapper-30.f90: New test.
* testsuite/libgomp.fortran/declare-mapper-4.f90: Adjust test for new
lookup behaviour.
---
 gcc/fortran/gfortran.h|  3 ++
 gcc/fortran/match.cc  |  4 +-
 gcc/fortran/module.cc |  6 +++
 gcc/fortran/openmp.cc | 46 ++-
 .../gfortran.dg/gomp/declare-mapper-31.f90| 34 ++
 .../libgomp.fortran/declare-mapper-30.f90 | 24 ++
 .../libgomp.fortran/declare-mapper-4.f90  | 18 +---
 7 files changed, 116 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-31.f90
 create mode 100644 libgomp/testsuite/libgomp.fortran/declare-mapper-30.f90

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a98424b3263..3b854e14d47 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1784,6 +1784,9 @@ gfc_omp_udm;
 
 typedef struct gfc_omp_namelist_udm
 {
+  /* Used to store mapper_id before resolution.  */
+  const char *mapper_id;
+
   bool multiple_elems_p;
   struct gfc_omp_udm *udm;
 }
diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 53367ab2a0b..3db8e0f0969 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -5537,7 +5537,9 @@ void
 gfc_free_omp_namelist (gfc_omp_namelist *name, int list)
 {
   bool free_ns = (list == OMP_LIST_AFFINITY || list == OMP_LIST_DEPEND);
-  bool free_mapper = (list == OMP_LIST_MAP);
+  bool free_mapper = (list == OMP_LIST_MAP
+ || list == OMP_LIST_TO
+ || list == OMP_LIST_FROM);
   bool free_align = (list == OMP_LIST_ALLOCATE);
   gfc_omp_namelist *n;
 
diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
index 5cd52e7729b..acdbfa7924f 100644
--- a/gcc/fortran/module.cc
+++ b/gcc/fortran/module.cc
@@ -5238,6 +5238,11 @@ load_omp_udms (void)
  if (peek_atom () != ATOM_RPAREN)
{
  n->u2.udm = gfc_get_omp_namelist_udm ();
+ mio_pool_string (&n->u2.udm->mapper_id);
+
+ if (n->u2.udm->mapper_id == NULL)
+   n->u2.udm->mapper_id = gfc_get_string ("%s", "");
+
  n->u2.udm->multiple_elems_p = mio_name (0, omp_map_cardinality);
  mio_pointer_ref (&n->u2.udm->udm);
}
@@ -6314,6 +6319,7 @@ write_omp_udm (gfc_omp_udm *udm)
 
   if (n->u2.udm)
{
+ mio_pool_string (&n->u2.udm->mapper_id);
  mio_name (n->u2.udm->multiple_elems_p, omp_map_cardinality);
  mio_pointer_ref (&n->u2.udm->udm);
}
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 0109df4dfce..ba2a8221b96 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -3615,6 +3615,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const 
omp_mask mask,
  m = gfc_match (" %n ) ", mapper_id);
  if (m != MATCH_YES)
goto error;
+ if (strcmp (mapper_id, "default") == 0)
+   mapper_id[0] = '\0';
}
  else
break;
@@ -3689,19 +3691,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const 
omp_mask mask,
  for (n = *head; n; n = n->next)
   

[PATCH 5/5] OpenMP: Enable 'declare mapper' mappers for 'target update' directives

2023-08-10 Thread Julian Brown
This patch enables use of 'declare mapper' for 'target update' directives,
for each of C, C++ and Fortran.

There are some implementation choices here and some
"read-between-the-lines" consequences regarding this functionality,
as follows:

 * It is possible to invoke a mapper which contains clauses that
   don't make sense for a given 'target update' operation.  E.g. if a
   mapper definition specifies a "from:" mapping and the user does "target
   update to(...)" which triggers that mapper, the resulting map kind
   (OpenMP 5.2, "Table 5.3: Map-Type Decay of Map Type Combinations")
   is "alloc" (and for the inverse case "release").  For such cases,
   an unconditional warning is issued and the map clause in question is
   dropped from the mapper expansion.  (Other choices might be to make
   this an error, or to do the same thing but silently, or warn only
   given some special option.)

 * The array-shaping operator is *permitted* for map clauses within
   'declare mapper' definitions.  That is because such mappers may be used
   for 'target update' directives, where the array-shaping operator is
   permitted.  I think that makes sense, depending on the semantic model
   of how and when substitution is supposed to take place, but I couldn't
   find such behaviour explicitly mentioned in the spec (as of 5.2).
   If the mapper is triggered by a different directive ("omp target",
   "omp target data", etc.), an error will be raised.

Support is also added for the "mapper" modifier on to/from clauses for
all three base languages.

2023-08-10  Julian Brown  

gcc/c-family/
* c-common.h (c_omp_region_type): Add C_ORT_UPDATE and C_ORT_OMP_UPDATE
codes.
* c-omp.cc (omp_basic_map_kind_name): New function.
(omp_instantiate_mapper): Add LOC parameter.  Add 'target update'
support.
(c_omp_instantiate_mappers): Add 'target update' support.

gcc/c/
* c-parser.cc (c_parser_omp_variable_list): Support array-shaping
operator in 'declare mapper' definitions.
(c_parser_omp_clause_map): Pass C_ORT_OMP_DECLARE_MAPPER to
c_parser_omp_variable_list in mapper definitions.
(c_parser_omp_clause_from_to): Add parsing for mapper modifier.
(c_parser_omp_target_update): Instantiate mappers.

gcc/cp/
* parser.cc (cp_parser_omp_var_list_no_open): Support array-shaping
operator in 'declare mapper' definitions.
(cp_parser_omp_clause_from_to): Add parsing for mapper modifier.
(cp_parser_omp_clause_map): Pass C_ORT_OMP_DECLARE_MAPPER to
cp_parser_omp_var_list_no_open in mapper definitions.
(cp_parser_omp_target_update): Instantiate mappers.

gcc/fortran/
* openmp.cc (gfc_match_motion_var_list): Add parsing for mapper
modifier.
(gfc_match_omp_clauses): Adjust error handling for changes to
gfc_match_motion_var_list.
* trans-openmp.cc (gfc_trans_omp_clauses): Use correct ref for update
operations.
(gfc_trans_omp_target_update): Instantiate mappers.

gcc/testsuite/
* c-c++-common/gomp/declare-mapper-17.c: New test.
* c-c++-common/gomp/declare-mapper-19.c: New test.
* gfortran.dg/gomp/declare-mapper-24.f90: New test.
* gfortran.dg/gomp/declare-mapper-26.f90: Uncomment 'target update' part
of test.
* gfortran.dg/gomp/declare-mapper-27.f90: New test.

libgomp/
* testsuite/libgomp.c-c++-common/declare-mapper-18.c: New test.
* testsuite/libgomp.fortran/declare-mapper-25.f90: New test.
* testsuite/libgomp.fortran/declare-mapper-28.f90: New test.
---
 gcc/c-family/c-common.h   |   2 +
 gcc/c-family/c-omp.cc | 117 +++--
 gcc/c/c-parser.cc | 152 +++--
 gcc/cp/parser.cc  | 160 --
 gcc/fortran/openmp.cc |  86 --
 gcc/fortran/trans-openmp.cc   |  20 ++-
 .../c-c++-common/gomp/declare-mapper-17.c |  38 +
 .../c-c++-common/gomp/declare-mapper-19.c |  40 +
 .../gfortran.dg/gomp/declare-mapper-24.f90|  43 +
 .../gfortran.dg/gomp/declare-mapper-26.f90|   4 +-
 .../gfortran.dg/gomp/declare-mapper-27.f90|  25 +++
 .../libgomp.c-c++-common/declare-mapper-18.c  |  33 
 .../libgomp.fortran/declare-mapper-25.f90 |  44 +
 .../libgomp.fortran/declare-mapper-28.f90 |  38 +
 14 files changed, 746 insertions(+), 56 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-mapper-17.c
 create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-mapper-19.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-24.f90
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-mapper-27.f90
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/declare-mapper-18.c
 create mode 100644 libgomp/testsuite/libgomp.fortran/declare-mapper-25.f90
 creat