[committed] Doc update: -foffload-options= examples + OpenMP in Fortran intrinsic modules

2023-06-19 Thread Tobias Burnus

Since r14-1807-g4bcb46b3ade179, using -foffload-options='-lgfortran -lm' are
no longer required as they get automatically linked on the offload side, if
linked on the host side. (Linking with g++ implies -lm, with gfortran
'-lgfortran -lm', while an explicit 'gcc -lm -lgfortran' would also do the
autolinking.) [Note: This only affects those two libraries.]

As there the number of useful flags reduced, new ones were added, including
-foffload-options=-O3. While possible, I believe that flag is misleading as
it implies that no optimization is done unless an -O... flag has been passed
to the run-time library.

But like now for -lm and -lgfortran, also the -O... flags are automatically
passed on from the host flags. (While they can be overridden, this is usually
not required.) — As the previous line already shows an example, i.e.
  "-foffload-options='-fno-math-errno -ffinite-math-only'",
I think we can get rid of this line without needing to find another example.

* * *

Looking at Fortran's fortran/intrinsic.texi I saw references to 4.5 and 5.0;
I have now added 5.1 and 5.2 – hopefully, we can at replace them soon
(GCC 15?) the v4.5 to 5.2 by just 5.2, having implemented all of 5.x.

(The reference to v4.5 in GCC's and gfortran's invoke.texi feels also odd
as v5.* is supported and the attribute syntax shown for C/C++ is only in
v5.x. To be changed - but not now.)


Additionally, fortran/intrinsic.texi listed the content of the OMP_* modules
(except for the API routines) but missed two recently added named constants,
which I now added.

Committed as r14-1936-ge9c1679c350be0.

Like always, comments are highly welcome!

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
commit e9c1679c350be09cec5354a3d98915c3afe02c87
Author: Tobias Burnus 
Date:   Mon Jun 19 10:24:08 2023 +0200

Doc update: -foffload-options= examples + OpenMP in Fortran intrinsic modules

With LTO, the -O.. flags of the host are passed on to the lto compiler, which
also includes offloading compilers. Therefore, using --foffload-options=-O3 is
misleading as it implies that without the default optimizations are used. Hence,
this flags has now been removed from the usage examples.

The Fortran documentation lists the content (except for API routines) routines
of the intrinsic OpenMP modules OMP_LIB and OMP_LIB_KINDS; this commit adds
two missing named constants and links also to the OpenMP 5.1 and 5.2
OpenMP spec for completeness.

gcc/ChangeLog:

* doc/invoke.texi (-foffload-options): Remove '-O3' from the examples.

gcc/fortran/ChangeLog:

* intrinsic.texi (OpenMP Modules OMP_LIB and OMP_LIB_KINDS): Also
add references to the OpenMP 5.1 and 5.2 spec; add omp_initial_device
and omp_invalid_device named constants.
---
 gcc/doc/invoke.texi|  2 +-
 gcc/fortran/intrinsic.texi | 20 
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fafdee30f66..215ab0dd05c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2718,7 +2718,7 @@ Typical command lines are
 
 @smallexample
 -foffload-options='-fno-math-errno -ffinite-math-only' -foffload-options=nvptx-none=-latomic
--foffload-options=amdgcn-amdhsa=-march=gfx906 -foffload-options=-O3
+-foffload-options=amdgcn-amdhsa=-march=gfx906
 @end smallexample
 
 @opindex fopenacc
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index db227ea..6c7ad03a02c 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -15247,8 +15247,9 @@ with the following options: @code{-fno-unsafe-math-optimizations
 @table @asis
 @item @emph{Standard}:
 OpenMP Application Program Interface v4.5,
-OpenMP Application Program Interface v5.0 (partially supported) and
-OpenMP Application Program Interface v5.1 (partially supported).
+OpenMP Application Program Interface v5.0 (partially supported),
+OpenMP Application Program Interface v5.1 (partially supported) and
+OpenMP Application Program Interface v5.2 (partially supported).
 @end table
 
 The OpenMP Fortran runtime library routines are provided both in
@@ -15262,9 +15263,13 @@ below.
 
 For details refer to the actual
 @uref{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf,
-OpenMP Application Program Interface v4.5} and
+OpenMP Application Program Interface v4.5},
 @uref{https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf,
-OpenMP Application Program Interface v5.0}.
+OpenMP Application Program Interface v5.0},
+@uref{https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-1.pdf,
+OpenMP Application Program Interface v5.1} and
+@uref{https://www.openmp.org/wp-content/uplo

Re: [PATCH] Introduce hardbool attribute for C

2023-06-19 Thread Bernhard Reutner-Fischer via Fortran
On 16 June 2023 07:35:27 CEST, Alexandre Oliva via Gcc-patches 
 wrote:

index 0..634feaed4deef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hardbool-err.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef _Bool __attribute__ ((__hardbool__))
+hbbl; /* { dg-error "integral types" } */
+
+typedef double __attribute__ ((__hardbool__))
+hbdbl; /* { dg-error "integral types" } */
+
+enum x;
+typedef enum x __attribute__ ((__hardbool__))
+hbenum; /* { dg-error "integral types" } */
+
+struct s;
+typedef struct s __attribute__ ((__hardbool__))
+hbstruct; /* { dg-error "integral types" } */
+
+typedef int __attribute__ ((__hardbool__ (0, 0)))
+hb00; /* { dg-error "different values" } */
+
+typedef int __attribute__ ((__hardbool__ (4, 16))) hb4x;
+struct s {
+ hb4x m:2;
+}; /* { dg-error "is a GCC extension|different values" } */
+/* { dg-warning "changes value" "warning" { target *-*-* } .-1 } */
+
+hb4x __attribute__ ((vector_size (4 * sizeof (hb4x
+vvar; /* { dg-error "invalid vector type" } */

Arm-chair, tinfoil hat still on, didn't look closely, hence:

I don't see explicit tests with _Complex nor __complex__. Would we want to 
check these here, or are they handled thought the "underlying" tests above?

I'd welcome a fortran interop note in the docs as hinted previously to cover 
out of the box behavior. It's probably reasonably unlikely but better be safe 
than sorry?
cheers,


[PATCH 00/14] [og13] OpenMP/OpenACC: map clause and OMP gimplify rework

2023-06-19 Thread Julian Brown
This series (for the og13 branch) is a rebased and merged version of
the first few patches of the series previously sent upstream for mainline:

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

The series contains patches 1-6 and the parts of 8 ("C++
"declare mapper" support) that pertain to reorganisation of
gimplify.cc:gimplify_{scan,adjust}_omp_clauses.

The series also contains reversions and rewrites of several patches
that needed adjustment in order to fit in with the new clause-processing
arrangements.

Tested with offloading to AMD GCN. I will apply shortly.

Thanks,

Julian

Julian Brown (14):
  Revert "Assumed-size arrays with non-lexical data mappings"
  Revert "Fix references declared in lexically-enclosing OpenACC data
region"
  Revert "Fix implicit mapping for array slices on lexically-enclosing
data constructs (PR70828)"
  Revert "openmp: Handle C/C++ array reference base-pointers in array
sections"
  OpenMP/OpenACC: Reindent TO/FROM/_CACHE_ stanza in
{c_}finish_omp_clause
  OpenMP/OpenACC: Rework clause expansion and nested struct handling
  OpenMP: implicitly map base pointer for array-section pointer
components
  OpenMP: Pointers and member mappings
  OpenMP/OpenACC: Unordered/non-constant component offset runtime
diagnostic
  OpenMP/OpenACC: Reorganise OMP map clause handling in gimplify.cc
  OpenACC: Reimplement "inheritance" for lexically-nested offload
regions
  OpenACC: "declare create" fixes wrt. "allocatable" variables
  OpenACC: Allow implicit uses of assumed-size arrays in offload regions
  OpenACC: Improve implicit mapping for non-lexically nested offload
regions

 gcc/c-family/c-common.h   |   74 +-
 gcc/c-family/c-omp.cc |  837 -
 gcc/c/c-parser.cc |   17 +-
 gcc/c/c-typeck.cc |  773 ++--
 gcc/cp/parser.cc  |   17 +-
 gcc/cp/pt.cc  |4 +-
 gcc/cp/semantics.cc   | 1065 +++---
 gcc/fortran/dependency.cc |  128 +
 gcc/fortran/dependency.h  |1 +
 gcc/fortran/gfortran.h|1 +
 gcc/fortran/trans-openmp.cc   |  376 +-
 gcc/gimplify.cc   | 2239 
 gcc/omp-general.cc|  424 +++
 gcc/omp-general.h |   69 +
 gcc/omp-low.cc|   23 +-
 .../c-c++-common/goacc/acc-data-chain.c   |2 +-
 .../c-c++-common/goacc/combined-reduction.c   |2 +-
 .../c-c++-common/goacc/reduction-1.c  |4 +-
 .../c-c++-common/goacc/reduction-10.c |9 +-
 .../c-c++-common/goacc/reduction-2.c  |4 +-
 .../c-c++-common/goacc/reduction-3.c  |4 +-
 .../c-c++-common/goacc/reduction-4.c  |4 +-
 gcc/testsuite/c-c++-common/gomp/clauses-2.c   |2 +-
 gcc/testsuite/c-c++-common/gomp/target-50.c   |2 +-
 .../c-c++-common/gomp/target-enter-data-1.c   |4 +-
 .../c-c++-common/gomp/target-implicit-map-2.c |3 +-
 .../g++.dg/gomp/static-component-1.C  |   23 +
 gcc/testsuite/gcc.dg/gomp/target-3.c  |2 +-
 .../gfortran.dg/goacc/assumed-size.f90|   35 +
 .../gfortran.dg/goacc/loop-tree-1.f90 |2 +-
 gcc/testsuite/gfortran.dg/gomp/map-12.f90 |2 +-
 gcc/testsuite/gfortran.dg/gomp/map-9.f90  |2 +-
 .../gfortran.dg/gomp/map-subarray-2.f90   |   57 +
 .../gfortran.dg/gomp/map-subarray.f90 |   40 +
 gcc/tree-pretty-print.cc  |3 +
 gcc/tree.h|8 +
 include/gomp-constants.h  |9 +-
 libgomp/oacc-mem.c|6 +-
 libgomp/target.c  |   91 +-
 libgomp/testsuite/libgomp.c++/baseptrs-3.C|  275 ++
 libgomp/testsuite/libgomp.c++/baseptrs-4.C| 3154 +
 libgomp/testsuite/libgomp.c++/baseptrs-5.C|   62 +
 libgomp/testsuite/libgomp.c++/class-array-1.C |   59 +
 libgomp/testsuite/libgomp.c++/target-48.C |   32 +
 libgomp/testsuite/libgomp.c++/target-49.C |   37 +
 .../libgomp.c-c++-common/baseptrs-1.c |   50 +
 .../libgomp.c-c++-common/baseptrs-2.c |   70 +
 .../map-arrayofstruct-1.c |   38 +
 .../map-arrayofstruct-2.c |   58 +
 .../map-arrayofstruct-3.c |   68 +
 .../target-implicit-map-2.c   |2 +
 .../target-implicit-map-5.c   |   50 +
 .../libgomp.c-c++-common/target-map-zlas-1.c  |   36 +
 .../libgomp.fortran/map-subarray-2.f90|  108 +
 .../libgomp.fortran/map-subarray-3.f90|   62 +
 .../libgomp.fortran/map-subarray-4.f90|   35 +
 .../libgomp.fortran/map-subarray-5.f90|   54 +
 .../libgomp.fortran/map-subarray-6.f90|   26 +
 .../libgomp

[PATCH 01/14] Revert "Assumed-size arrays with non-lexical data mappings"

2023-06-19 Thread Julian Brown
This reverts commit 72733f6e6f6ec1bb9884fea8bfbebd3de03d9374.

2023-06-16  Julian Brown  

gcc/
Revert:
* gimplify.cc (gimplify_adjust_omp_clauses_1): Raise error for
assumed-size arrays in map clauses for Fortran/OpenMP.
* omp-low.cc (lower_omp_target): Set the size of assumed-size Fortran
arrays to one to allow use of data already mapped on the offload device.

gcc/fortran/
Revert:
* trans-openmp.cc (gfc_omp_finish_clause): Change clauses mapping
assumed-size arrays to use the GOMP_MAP_FORCE_PRESENT map type.
---
 gcc/fortran/trans-openmp.cc | 22 +-
 gcc/gimplify.cc | 14 --
 gcc/omp-low.cc  |  5 -
 3 files changed, 9 insertions(+), 32 deletions(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index e8f3b24e5f8..e55c8292d05 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1588,18 +1588,10 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   tree decl = OMP_CLAUSE_DECL (c);
 
   /* Assumed-size arrays can't be mapped implicitly, they have to be mapped
- explicitly using array sections.  For OpenACC this restriction is lifted
- if the array has already been mapped:
-
-   - Using a lexically-enclosing data region: in that case we see the
- GOMP_MAP_FORCE_PRESENT mapping kind here.
-
-   - Using a non-lexical data mapping ("acc enter data").
-
- In the latter case we change the mapping type to GOMP_MAP_FORCE_PRESENT.
- This raises an error for OpenMP in the caller
- (gimplify.c:gimplify_adjust_omp_clauses_1).  OpenACC will raise a runtime
- error if the implicitly-referenced assumed-size array is not mapped.  */
+ explicitly using array sections.  An exception is if the array is
+ mapped explicitly in an enclosing data construct for OpenACC, in which
+ case we see GOMP_MAP_FORCE_PRESENT here and do not need to raise an
+ error.  */
   if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_PRESENT
   && TREE_CODE (decl) == PARM_DECL
   && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
@@ -1607,7 +1599,11 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
 == NULL)
-OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
+{
+  error_at (OMP_CLAUSE_LOCATION (c),
+   "implicit mapping of assumed size array %qD", decl);
+  return;
+}
 
   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR)
 return;
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 09c596f026e..3729b986801 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -12828,26 +12828,12 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, 
void *data)
   *list_p = clause;
   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   gimplify_omp_ctxp = ctx->outer_context;
-  gomp_map_kind kind = (code == OMP_CLAUSE_MAP) ? OMP_CLAUSE_MAP_KIND (clause)
-   : (gomp_map_kind) GOMP_MAP_LAST;
   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
  in simd.  Those are only added for the local vars inside of simd body
  and they don't need to be e.g. default constructible.  */
   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD) 
 lang_hooks.decls.omp_finish_clause (clause, pre_p,
(ctx->region_type & ORT_ACC) != 0);
-  /* Allow OpenACC to have implicit assumed-size arrays via FORCE_PRESENT,
- which should work as long as the array has previously been mapped
- explicitly on the target (e.g. by "enter data").  Raise an error for
- OpenMP.  */
-  if (lang_GNU_Fortran ()
-  && code == OMP_CLAUSE_MAP
-  && (ctx->region_type & ORT_ACC) == 0
-  && kind == GOMP_MAP_TOFROM
-  && OMP_CLAUSE_MAP_KIND (clause) == GOMP_MAP_FORCE_PRESENT)
-error_at (OMP_CLAUSE_LOCATION (clause),
- "implicit mapping of assumed size array %qD",
- OMP_CLAUSE_DECL (clause));
   if (gimplify_omp_ctxp)
 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
   if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 3424eba2217..59143d8efe5 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -14353,11 +14353,6 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
  s = OMP_CLAUSE_SIZE (c);
if (s == NULL_TREE)
  s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
-   /* Fortran assumed-size arrays have zero size because the type is
-  incomplete.  Set the size to one to allow the runtime to remap
-  any existing data that is already present on the accelerator.  */
-   if (s == NULL_TREE && is_gimple_omp_oacc (ctx->stmt))
- s = integer_one_node;

[PATCH 03/14] Revert "Fix implicit mapping for array slices on lexically-enclosing data constructs (PR70828)"

2023-06-19 Thread Julian Brown
This reverts commit a84b89b8f070f1efe86ea347e98d57e6bc32ae2d.

Relevant tests are temporarily disabled or XFAILed.

2023-06-16  Julian Brown  

gcc/
Revert:
* gimplify.cc (oacc_array_mapping_info): New struct.
(gimplify_omp_ctx): Add decl_data_clause hash map.
(new_omp_context): Zero-initialise above.
(delete_omp_context): Delete above if allocated.
(gimplify_scan_omp_clauses): Scan for array mappings on data constructs,
and record in above map.
(gomp_oacc_needs_data_present): New function.
(gimplify_adjust_omp_clauses_1): Handle data mappings (e.g. array
slices) declared in lexically-enclosing data constructs.
* omp-low.cc (lower_omp_target): Allow decl for bias not to be present
in OpenACC context.

gcc/fortran/
Revert:
* trans-openmp.cc: Handle implicit "present".

gcc/testsuite/
* c-c++-common/goacc/acc-data-chain.c: Partly disable test.
* gfortran.dg/goacc/pr70828.f90: Likewise.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/pr70828.c: XFAIL test.
* testsuite/libgomp.oacc-c-c++-common/pr70828-2.c: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828.f90: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828-2.f90: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828-3.f90: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828-4.f90: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828-5.f90: XFAIL test.
* testsuite/libgomp.oacc-fortran/pr70828-6.f90: XFAIL test.
---
 gcc/fortran/trans-openmp.cc   |  10 +-
 gcc/gimplify.cc   | 143 +-
 gcc/omp-low.cc|  10 +-
 .../c-c++-common/goacc/acc-data-chain.c   |   4 +-
 gcc/testsuite/gfortran.dg/goacc/pr70828.f90   |   3 +-
 .../libgomp.oacc-c-c++-common/pr70828-2.c |   2 +
 .../libgomp.oacc-c-c++-common/pr70828.c   |   2 +
 .../libgomp.oacc-fortran/pr70828-2.f90|   2 +
 .../libgomp.oacc-fortran/pr70828-3.f90|   2 +
 .../libgomp.oacc-fortran/pr70828-4.f90|   2 +
 .../libgomp.oacc-fortran/pr70828-5.f90|   2 +
 .../libgomp.oacc-fortran/pr70828-6.f90|   2 +
 .../libgomp.oacc-fortran/pr70828.f90  |   2 +
 13 files changed, 28 insertions(+), 158 deletions(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 96e91a3bc50..809b96bc220 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1587,13 +1587,9 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
 
   tree decl = OMP_CLAUSE_DECL (c);
 
-  /* Assumed-size arrays can't be mapped implicitly, they have to be mapped
- explicitly using array sections.  An exception is if the array is
- mapped explicitly in an enclosing data construct for OpenACC, in which
- case we see GOMP_MAP_FORCE_PRESENT here and do not need to raise an
- error.  */
-  if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_PRESENT
-  && TREE_CODE (decl) == PARM_DECL
+  /* Assumed-size arrays can't be mapped implicitly, they have to be
+ mapped explicitly using array sections.  */
+  if (TREE_CODE (decl) == PARM_DECL
   && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
   && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
   && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 80f1f3a657f..e3384c7f65b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -218,17 +218,6 @@ enum gimplify_defaultmap_kind
   GDMK_POINTER
 };
 
-/* Used to record clauses representing array slices on data directives that
-   may affect implicit mapping semantics on enclosed OpenACC parallel/kernels
-   regions.  PSET is used for Fortran array slices with array descriptors,
-   or NULL otherwise.  */
-struct oacc_array_mapping_info
-{
-  tree mapping;
-  tree pset;
-  tree pointer;
-};
-
 struct gimplify_omp_ctx
 {
   struct gimplify_omp_ctx *outer_context;
@@ -250,7 +239,6 @@ struct gimplify_omp_ctx
   bool in_for_exprs;
   bool ompacc;
   int defaultmap[5];
-  hash_map *decl_data_clause;
 };
 
 struct privatize_reduction
@@ -485,7 +473,6 @@ new_omp_context (enum omp_region_type region_type)
   c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
   c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
   c->defaultmap[GDMK_POINTER] = GOVD_MAP;
-  c->decl_data_clause = NULL;
 
   return c;
 }
@@ -498,8 +485,6 @@ delete_omp_context (struct gimplify_omp_ctx *c)
   splay_tree_delete (c->variables);
   delete c->privatized_types;
   c->loop_iter_var.release ();
-  if (c->decl_data_clause)
-delete c->decl_data_clause;
   XDELETE (c);
 }
 
@@ -11235,41 +11220,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
case OMP_TARGET:
  break;
case OACC_DATA:
- {
-   tree base_ptr = OMP_CLAUSE_CHAIN (c);
-   tree pset = NULL;
-   

[PATCH 05/14] OpenMP/OpenACC: Reindent TO/FROM/_CACHE_ stanza in {c_}finish_omp_clause

2023-06-19 Thread Julian Brown
This patch trivially adds braces and reindents the
OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza in
c_finish_omp_clause and finish_omp_clause, in preparation for the
following patch (to clarify the diff a little).

2022-09-13  Julian Brown  

gcc/c/
* c-typeck.cc (c_finish_omp_clauses): Add braces and reindent
OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza.

gcc/cp/
* semantics.cc (finish_omp_clause): Add braces and reindent
OMP_CLAUSE_TO/OMP_CLAUSE_FROM/OMP_CLAUSE__CACHE_ stanza.
---
 gcc/c/c-typeck.cc   | 615 +-
 gcc/cp/semantics.cc | 788 ++--
 2 files changed, 707 insertions(+), 696 deletions(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 9591d67251e..2cfe2174bab 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -15520,321 +15520,326 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CACHE_:
- t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) == TREE_LIST)
-   {
- grp_start_p = pc;
- grp_sentinel = OMP_CLAUSE_CHAIN (c);
+ {
+   t = OMP_CLAUSE_DECL (c);
+   if (TREE_CODE (t) == TREE_LIST)
+ {
+   grp_start_p = pc;
+   grp_sentinel = OMP_CLAUSE_CHAIN (c);
 
- if (handle_omp_array_sections (c, ort))
-   remove = true;
- else
-   {
- t = OMP_CLAUSE_DECL (c);
- if (!omp_mappable_type (TREE_TYPE (t)))
-   {
- error_at (OMP_CLAUSE_LOCATION (c),
-   "array section does not have mappable type "
-   "in %qs clause",
-   omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
-   }
- else if (TYPE_ATOMIC (TREE_TYPE (t)))
-   {
- error_at (OMP_CLAUSE_LOCATION (c),
-   "%<_Atomic%> %qE in %qs clause", t,
-   omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
-   }
- while (TREE_CODE (t) == ARRAY_REF)
-   t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
-   {
- do
-   {
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == MEM_REF
- || TREE_CODE (t) == INDIRECT_REF)
-   {
- t = TREE_OPERAND (t, 0);
- STRIP_NOPS (t);
- if (TREE_CODE (t) == POINTER_PLUS_EXPR)
-   t = TREE_OPERAND (t, 0);
-   }
-   }
- while (TREE_CODE (t) == COMPONENT_REF
-|| TREE_CODE (t) == ARRAY_REF);
-
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
- && OMP_CLAUSE_MAP_IMPLICIT (c)
- && (bitmap_bit_p (&map_head, DECL_UID (t))
- || bitmap_bit_p (&map_field_head, DECL_UID (t))
- || bitmap_bit_p (&map_firstprivate_head,
-  DECL_UID (t
-   {
- remove = true;
- break;
-   }
- if (bitmap_bit_p (&map_field_head, DECL_UID (t)))
-   break;
- if (bitmap_bit_p (&map_head, DECL_UID (t)))
-   {
- if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
-   error_at (OMP_CLAUSE_LOCATION (c),
- "%qD appears more than once in motion "
- "clauses", t);
- else if (ort == C_ORT_ACC)
-   error_at (OMP_CLAUSE_LOCATION (c),
- "%qD appears more than once in data "
- "clauses", t);
- else
-   error_at (OMP_CLAUSE_LOCATION (c),
- "%qD appears more than once in map "
- "clauses", t);
- remove = true;
-   }
- else
-   {
- bitmap_set_bit (&map_head, DECL_UID (t));
- bitmap_set_bit (&map_field_head, DECL_UID (t));
-   }
-   }
-  

[PATCH 02/14] Revert "Fix references declared in lexically-enclosing OpenACC data region"

2023-06-19 Thread Julian Brown
This reverts commit c9cd2bac6a5127a01c6f47e5636a926ac39b5e21.

2023-06-16  Julian Brown  

gcc/fortran/
Revert:
* trans-openmp.cc (gfc_omp_finish_clause): Guard addition of clauses for
pointers with DECL_P.

gcc/
Revert:
* gimplify.cc (oacc_array_mapping_info): Add REF field.
(gimplify_scan_omp_clauses): Initialise above field for data blocks
passed by reference.
(gomp_oacc_needs_data_present): Handle references.
(gimplify_adjust_omp_clauses_1): Handle references and optional
arguments for variables declared in lexically-enclosing OpenACC data
region.
---
 gcc/fortran/trans-openmp.cc |  2 +-
 gcc/gimplify.cc | 55 +
 2 files changed, 8 insertions(+), 49 deletions(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index e55c8292d05..96e91a3bc50 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1611,7 +1611,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   tree c2 = NULL_TREE, c3 = NULL_TREE, c4 = NULL_TREE;
   tree present = gfc_omp_check_optional_argument (decl, true);
   tree orig_decl = NULL_TREE;
-  if (DECL_P (decl) && POINTER_TYPE_P (TREE_TYPE (decl)))
+  if (POINTER_TYPE_P (TREE_TYPE (decl)))
 {
   if (!gfc_omp_privatize_by_reference (decl)
  && !GFC_DECL_GET_SCALAR_POINTER (decl)
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 3729b986801..80f1f3a657f 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -227,7 +227,6 @@ struct oacc_array_mapping_info
   tree mapping;
   tree pset;
   tree pointer;
-  tree ref;
 };
 
 struct gimplify_omp_ctx
@@ -11248,9 +11247,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
  }
if (base_ptr
&& OMP_CLAUSE_CODE (base_ptr) == OMP_CLAUSE_MAP
-   && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
-&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
-|| OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
&& OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
&& ((OMP_CLAUSE_MAP_KIND (base_ptr)
 == GOMP_MAP_FIRSTPRIVATE_POINTER)
@@ -11269,19 +11265,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
ai.mapping = unshare_expr (c);
ai.pset = pset ? unshare_expr (pset) : NULL;
ai.pointer = unshare_expr (base_ptr);
-   ai.ref = NULL_TREE;
-   if (TREE_CODE (base_addr) == INDIRECT_REF
-   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base_addr, 0)))
-   == REFERENCE_TYPE))
- {
-   base_addr = TREE_OPERAND (base_addr, 0);
-   tree ref_clause = OMP_CLAUSE_CHAIN (base_ptr);
-   gcc_assert ((OMP_CLAUSE_CODE (ref_clause)
-== OMP_CLAUSE_MAP)
-   && (OMP_CLAUSE_MAP_KIND (ref_clause)
-   == GOMP_MAP_POINTER));
-   ai.ref = unshare_expr (ref_clause);
- }
ctx->decl_data_clause->put (base_addr, ai);
  }
if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
@@ -12464,15 +12447,11 @@ gomp_oacc_needs_data_present (tree decl)
   && gimplify_omp_ctxp->region_type != ORT_ACC_KERNELS)
 return NULL;
 
-  tree type = TREE_TYPE (decl);
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-type = TREE_TYPE (type);
-
-  if (TREE_CODE (type) != ARRAY_TYPE
-  && TREE_CODE (type) != POINTER_TYPE
-  && TREE_CODE (type) != RECORD_TYPE
-  && (TREE_CODE (type) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
+  if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
+  && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
+  && TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE
+  && (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) != ARRAY_TYPE))
 return NULL;
 
   decl = get_base_address (decl);
@@ -12626,12 +12605,6 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
 {
   tree mapping = array_info->mapping;
   tree pointer = array_info->pointer;
-  gomp_map_kind presence_kind = GOMP_MAP_FORCE_PRESENT;
-  bool no_alloc = (OMP_CLAUSE_CODE (mapping) == OMP_CLAUSE_MAP
-  && OMP_CLAUSE_MAP_KIND (mapping) == GOMP_MAP_IF_PRESENT);
-
-  if (no_alloc || omp_check_optional_argument (decl, false))
-presence_kind = GOMP_MAP_IF_PRESENT;
 
   if (code == OMP_CLAUSE_FIRSTPRIVATE)
/* Oops, we have the wrong type of clause.  Rebuild it.  */
@@ -12639,15 +12612,14 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, 
void *data)
 

[PATCH 04/14] Revert "openmp: Handle C/C++ array reference base-pointers in array sections"

2023-06-19 Thread Julian Brown
This reverts commit 3385743fd2fa15a2a750a29daf6d4f97f5aad0ae.

2023-06-16  Julian Brown  

Revert:
2022-02-24  Chung-Lin Tang  

gcc/c/ChangeLog:

* c-typeck.cc (handle_omp_array_sections): Add handling for
creating array-reference base-pointer attachment clause.

gcc/cp/ChangeLog:

* semantics.cc (handle_omp_array_sections): Add handling for
creating array-reference base-pointer attachment clause.

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/target-enter-data-1.c: Adjust testcase.

libgomp/ChangeLog:

* testsuite/libgomp.c-c++-common/ptr-attach-2.c: New test.
---
 gcc/c/c-typeck.cc | 27 +
 gcc/cp/semantics.cc   | 28 +
 .../c-c++-common/gomp/target-enter-data-1.c   |  3 +-
 .../libgomp.c-c++-common/ptr-attach-2.c   | 60 ---
 4 files changed, 3 insertions(+), 115 deletions(-)
 delete mode 100644 libgomp/testsuite/libgomp.c-c++-common/ptr-attach-2.c

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 450214556f9..9591d67251e 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -14113,10 +14113,6 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
   if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
maybe_zero_len = true;
 
-  struct dim { tree low_bound, length; };
-  auto_vec dims (num);
-  dims.safe_grow (num);
-
   for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
   t = TREE_CHAIN (t))
{
@@ -14238,9 +14234,6 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
  else
size = size_binop (MULT_EXPR, size, l);
}
-
- dim d = { low_bound, length };
- dims[i] = d;
}
   if (non_contiguous)
{
@@ -14288,23 +14281,6 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
  OMP_CLAUSE_DECL (c) = t;
  return false;
}
-
-  tree aref = t;
-  for (i = 0; i < dims.length (); i++)
-   {
- if (dims[i].length && integer_onep (dims[i].length))
-   {
- tree lb = dims[i].low_bound;
- aref = build_array_ref (OMP_CLAUSE_LOCATION (c), aref, lb);
-   }
- else
-   {
- if (TREE_CODE (TREE_TYPE (aref)) == POINTER_TYPE)
-   t = aref;
- break;
-   }
-   }
-
   first = c_fully_fold (first, false, NULL);
   OMP_CLAUSE_DECL (c) = first;
   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
@@ -14339,8 +14315,7 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
  break;
}
   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
-  if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
- || TREE_CODE (t) == INDIRECT_REF)
+  if (TREE_CODE (t) == COMPONENT_REF)
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH);
   else
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index e7bda6fa060..93ff7cf5e1b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5605,10 +5605,6 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
   if (processing_template_decl && maybe_zero_len)
return false;
 
-  struct dim { tree low_bound, length; };
-  auto_vec dims (num);
-  dims.safe_grow (num);
-
   for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
   t = TREE_CHAIN (t))
{
@@ -5728,9 +5724,6 @@ handle_omp_array_sections (tree c, enum c_omp_region_type 
ort)
  else
size = size_binop (MULT_EXPR, size, l);
}
-
- dim d = { low_bound, length };
- dims[i] = d;
}
   if (!processing_template_decl)
{
@@ -5782,24 +5775,6 @@ handle_omp_array_sections (tree c, enum 
c_omp_region_type ort)
  OMP_CLAUSE_DECL (c) = t;
  return false;
}
-
- tree aref = t;
- for (i = 0; i < dims.length (); i++)
-   {
- if (dims[i].length && integer_onep (dims[i].length))
-   {
- tree lb = dims[i].low_bound;
- aref = convert_from_reference (aref);
- aref = build_array_ref (OMP_CLAUSE_LOCATION (c), aref, lb);
-   }
- else
-   {
- if (TREE_CODE (TREE_TYPE (aref)) == POINTER_TYPE)
-   t = aref;
- break;
-   }
-   }
-
  OMP_CLAUSE_DECL (c) = first;
  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
return false;
@@ -5841,8 +5816,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type 
ort)
  bool reference_always_pointer = true;
  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
  OMP_CLAUSE_MAP);
- 

[PATCH 08/14] OpenMP: Pointers and member mappings

2023-06-19 Thread Julian Brown
This patch changes the mapping node arrangement used for array components
of derived types, e.g.:

  type T
  integer, pointer, dimension(:) :: arrptr
  end type T

  type(T) :: tvar
  [...]
  !$omp target map(tofrom: tvar%arrptr)

This will currently be mapped using three mapping nodes:

  GOMP_MAP_TO tvar%arrptr   (the descriptor)
  GOMP_MAP_TOFROM *tvar%arrptr%data (the actual array data)
  GOMP_MAP_ALWAYS_POINTER tvar%arrptr%data  (a pointer to the array data)

This follows OMP 5.0, 2.19.7.1 (or OpenMP 5.2, 5.8.3) "map Clause":

  "If a list item in a map clause is an associated pointer and the
   pointer is not the base pointer of another list item in a map clause
   on the same construct, then it is treated as if its pointer target
   is implicitly mapped in the same clause. For the purposes of the map
   clause, the mapped pointer target is treated as if its base pointer
   is the associated pointer."

However, we can also write this:

  map(to: tvar%arrptr) map(tofrom: tvar%arrptr(3:8))

and then instead we should follow (OpenMP 5.2, 5.8.3 "map Clause"):

  "For map clauses on map-entering constructs, if any list item has a base
   pointer for which a corresponding pointer exists in the data environment
   upon entry to the region and either a new list item or the corresponding
   pointer is created in the device data environment on entry to the region,
   then:
   1. [Fortran] The corresponding pointer variable is associated with
  a pointer target that has the same rank and bounds as the pointer
  target of the original pointer, such that the corresponding list item
  can be accessed through the pointer in a target region.
   2. The corresponding pointer variable becomes an attached pointer
  for the corresponding list item."

With this patch you can write the above mappings, and the mapping nodes
used to map pointers to array sections (with descriptors) now look
like this:

  1) map(to: tvar%arrptr)   -->
  GOMP_MAP_TO [implicit]  *tvar%arrptr%data  (the array data)
  GOMP_MAP_TO_PSETtvar%arrptr(the descriptor)
  GOMP_MAP_ATTACH_DETACH  tvar%arrptr%data

  2) map(tofrom: tvar%arrptr(3:8)   -->
  GOMP_MAP_TOFROM *tvar%arrptr%data(3)  (size 8-3+1, etc.)
  GOMP_MAP_TO_PSETtvar%arrptr
  GOMP_MAP_ATTACH_DETACH  tvar%arrptr%data  (bias 3, etc.)

In this case, we can determine in the front-end that the
whole-array/pointer mapping (1) is only needed to map the pointer --
so we drop it entirely.  (Note also that we set -- early -- the
OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P flag for whole-array-via-pointer
mappings. See below.)

In the middle end, we process mappings using the struct sibling-list
handling machinery by moving the "GOMP_MAP_TO_PSET" node from the middle
of the group of three mapping nodes to the proper sorted position after
the GOMP_MAP_STRUCT mapping:

  GOMP_MAP_STRUCT   tvar (len: 1)
  GOMP_MAP_TO_PSET  tvar%arr (size: 64, etc.)  <--. moved here
  [...]   |
  GOMP_MAP_TOFROM *tvar%arrptr%data(3) ___|
  GOMP_MAP_ATTACH_DETACH  tvar%arrptr%data

In another case, if we have an array of derived-type values "dtarr",
and mappings like:

  i = 1
  j = 1
  map(to: dtarr(i)%arrptr) map(tofrom: dtarr(j)%arrptr(3:8))

We still map the same way, but this time we cannot prove that the base
expressions "dtarr(i) and "dtarr(j)" are the same in the front-end.
So we keep both mappings, but we move the "[implicit]" mapping of the
full-array reference to the end of the clause list in gimplify.cc (by
adjusting the topological sorting algorithm):

  GOMP_MAP_STRUCT dtvar  (len: 2)
  GOMP_MAP_TO_PSETdtvar(i)%arrptr
  GOMP_MAP_TO_PSETdtvar(j)%arrptr
  [...]
  GOMP_MAP_TOFROM *dtvar(j)%arrptr%data(3)  (size: 8-3+1)
  GOMP_MAP_ATTACH_DETACH  dtvar(j)%arrptr%data
  GOMP_MAP_TO [implicit]  *dtvar(i)%arrptr%data(1)  (size: whole array)
  GOMP_MAP_ATTACH_DETACH  dtvar(i)%arrptr%data

Always moving "[implicit]" full-array mappings after array-section
mappings (without that bit set) means that we'll avoid copying the whole
array unnecessarily -- even in cases where we can't prove that the arrays
are the same.

The patch also fixes some bugs with "enter data" and "exit data"
directives with this new mapping arrangement.  Also now if you have
mappings like this:

  #pragma omp target enter data map(to: dv, dv%arr(1:20))

The whole of the derived-type variable "dv" is mapped, so the
GOMP_MAP_TO_PSET for the array-section mapping can be dropped:

  GOMP_MAP_TOdv

  GOMP_MAP_TO*dv%arr%data
  GOMP_MAP_TO_PSET   dv%arr <-- deleted (array section mapping)
  GOMP_MAP_ATTACH_DETACH dv%arr%data

To accommodate for recent changes to mapping nodes made by
Tobias, this version of the patch avoids using GOMP_MAP_TO_PSET
for "exit data" directives, in favour of using the "correct"
GOMP_MAP_RELEASE/GOMP_MAP_DELETE kinds during early expansion.

2023-06-16

[PATCH 07/14] OpenMP: implicitly map base pointer for array-section pointer components

2023-06-19 Thread Julian Brown
Following from discussion in:

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

and:

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

and also upstream OpenMP issue 342, this patch changes mapping for array
sections of pointer components on compute regions like this:

  #pragma omp target map(s.ptr[0:10])
  {
...use of 's'...
  }

so the base pointer 's.ptr' is implicitly mapped, and thus pointer
attachment happens.  This is subtly different in the "enter data"
case, e.g:

  #pragma omp target enter data map(s.ptr[0:10])

if 's.ptr' (or the whole of 's') is not present on the target before
the directive is executed, the array section is copied to the target
but pointer attachment does *not* take place, since 's' (or 's.ptr')
is not mapped implicitly for "enter data".

To get a pointer attachment with "enter data", you can do, e.g:

  #pragma omp target enter data map(s.ptr, s.ptr[0:10])

  #pragma omp target
  {
...implicit use of 's'...
  }

That is, once the attachment has happened, implicit mapping of 's'
and uses of 's.ptr[...]' work correctly in the target region.

ChangeLog

2022-12-12  Julian Brown  

gcc/
* gimplify.cc (omp_accumulate_sibling_list): Don't require
explicitly-mapped base pointer for compute regions.

gcc/testsuite/
* c-c++-comon/gomp/target-implicit-map-2.c: Update expected scan output.

libgomp/
* testsuite/libgomp.c-c++-common/target-implicit-map-2.c: Fix missing
"free".
* testsuite/libgomp.c-c++-common/target-implicit-map-3.c: New test.
* testsuite/libgomp.c-c++-common/target-map-zlas-1.c: New test.
* testsuite/libgomp.c/target-22.c: Remove explicit base pointer
mappings.
---
 gcc/gimplify.cc   |  9 ++--
 .../c-c++-common/gomp/target-implicit-map-2.c |  3 +-
 .../target-implicit-map-2.c   |  2 +
 .../target-implicit-map-5.c   | 50 +++
 .../libgomp.c-c++-common/target-map-zlas-1.c  | 36 +
 libgomp/testsuite/libgomp.c/target-22.c   |  3 +-
 6 files changed, 97 insertions(+), 6 deletions(-)
 create mode 100644 
libgomp/testsuite/libgomp.c-c++-common/target-implicit-map-5.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/target-map-zlas-1.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9be5d9c5328..6a43c792450 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -10696,6 +10696,7 @@ omp_accumulate_sibling_list (enum omp_region_type 
region_type,
   poly_int64 cbitpos;
   tree ocd = OMP_CLAUSE_DECL (grp_end);
   bool openmp = !(region_type & ORT_ACC);
+  bool target = (region_type & ORT_TARGET) != 0;
   tree *continue_at = NULL;
 
   while (TREE_CODE (ocd) == ARRAY_REF)
@@ -10800,9 +10801,9 @@ omp_accumulate_sibling_list (enum omp_region_type 
region_type,
}
 
  /* For OpenMP semantics, we don't want to implicitly allocate
-space for the pointer here.  A FRAGILE_P node is only being
-created so that omp-low.cc is able to rewrite the struct
-properly.
+space for the pointer here for non-compute regions (e.g. "enter
+data").  A FRAGILE_P node is only being created so that
+omp-low.cc is able to rewrite the struct properly.
 For references (to pointers), we want to actually allocate the
 space for the reference itself in the sorted list following the
 struct node.
@@ -10810,6 +10811,7 @@ omp_accumulate_sibling_list (enum omp_region_type 
region_type,
 mapping of the attachment point, but not otherwise.  */
  if (*fragile_p
  || (openmp
+ && !target
  && attach_detach
  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
@@ -11122,6 +11124,7 @@ omp_accumulate_sibling_list (enum omp_region_type 
region_type,
 
  if (*fragile_p
  || (openmp
+ && !target
  && attach_detach
  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
diff --git a/gcc/testsuite/c-c++-common/gomp/target-implicit-map-2.c 
b/gcc/testsuite/c-c++-common/gomp/target-implicit-map-2.c
index 5ba1d7efe08..72df5b1 100644
--- a/gcc/testsuite/c-c++-common/gomp/target-implicit-map-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/target-implicit-map-2.c
@@ -49,4 +49,5 @@ main (void)
 
 /* { dg-final { scan-tree-dump {#pragma omp target num_teams.* map\(tofrom:a 
\[len: [0-9]+\]\[implicit\]\)} "gimple" } } */
 
-/* { dg-final { scan-tree-dump {#pragma omp target num_teams.* map\(struct:a 
\[len: 1\]\) map\(alloc:a\.ptr \[len: 0\]\) map\(tofrom:\*_[0-9]+ \[len: 
[0-9]+\]\) map\(attach:a\.ptr \[bias: 0\]\)} "gimple" } } */
+/* { dg-final { scan-tree-dump {#pragma omp target num_teams.* map\(struct:a 
\[len: 1\]

[PATCH 09/14] OpenMP/OpenACC: Unordered/non-constant component offset runtime diagnostic

2023-06-19 Thread Julian Brown
This patch adds support for non-constant component offsets in "map"
clauses for OpenMP (and the equivalants for OpenACC), which are not able
to be sorted into order at compile time.  Normally struct accesses in
such clauses are gathered together and sorted into increasing address
order after a "GOMP_MAP_STRUCT" node: if we have variable indices,
that is no longer possible.

This version of the patch scales back the previously-posted version to
merely add a diagnostic for incorrect usage of component accesses with
variably-indexed arrays of structs: the only permitted variant is where
we have multiple indices that are the same, but we could not prove so
at compile time.  Rather than silently producing the wrong result for
cases where the indices are in fact different, we error out (e.g.,
"map(dtarr(i)%arrptr, dtarr(j)%arrptr(4:8))", for different i/j).

For now, multiple *constant* array indices are still supported (see
map-arrayofstruct-1.c).  That could perhaps be addressed with a follow-up
patch, if necessary.

This version of the patch renumbers the GOMP_MAP_STRUCT_UNORD kind to
avoid clashing with the OpenACC "non-contiguous" dynamic array support.

2023-06-16  Julian Brown  

gcc/fortran/
* trans-openmp.cc (gfc_omp_deep_map_kind_p): Add GOMP_MAP_STRUCT_UNORD.

gcc/
* gimplify.cc (extract_base_bit_offset): Add VARIABLE_OFFSET parameter.
(omp_get_attachment, omp_group_last, omp_group_base,
omp_directive_maps_explicitly): Add GOMP_MAP_STRUCT_UNORD support.
(omp_accumulate_sibling_list): Update calls to extract_base_bit_offset.
Support GOMP_MAP_STRUCT_UNORD.
(omp_build_struct_sibling_lists, gimplify_scan_omp_clauses,
gimplify_adjust_omp_clauses, gimplify_omp_target_update): Add
GOMP_MAP_STRUCT_UNORD support.
* omp-low.cc (lower_omp_target): Add GOMP_MAP_STRUCT_UNORD support.
* tree-pretty-print.cc (dump_omp_clause): Likewise.

include/
* gomp-constants.h (gomp_map_kind): Add GOMP_MAP_STRUCT_UNORD.

libgomp/
* oacc-mem.c (find_group_last, goacc_enter_data_internal,
goacc_exit_data_internal, GOACC_enter_exit_data): Add
GOMP_MAP_STRUCT_UNORD support.
* target.c (gomp_map_vars_internal): Add GOMP_MAP_STRUCT_UNORD support.
Detect incorrect use of variable indexing of arrays of structs.
(GOMP_target_enter_exit_data, gomp_target_task_fn): Add
GOMP_MAP_STRUCT_UNORD support.
* testsuite/libgomp.c-c++-common/map-arrayofstruct-1.c: New test.
* testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c: New test.
* testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c: New test.
* testsuite/libgomp.fortran/map-subarray-5.f90: New test.
---
 gcc/fortran/trans-openmp.cc   |   1 +
 gcc/gimplify.cc   | 110 ++
 gcc/omp-low.cc|   1 +
 gcc/tree-pretty-print.cc  |   3 +
 include/gomp-constants.h  |   6 +
 libgomp/oacc-mem.c|   6 +-
 libgomp/target.c  |  60 +-
 .../map-arrayofstruct-1.c |  38 ++
 .../map-arrayofstruct-2.c |  58 +
 .../map-arrayofstruct-3.c |  68 +++
 .../libgomp.fortran/map-subarray-5.f90|  54 +
 11 files changed, 378 insertions(+), 27 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-1.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-2.c
 create mode 100644 libgomp/testsuite/libgomp.c-c++-common/map-arrayofstruct-3.c
 create mode 100644 libgomp/testsuite/libgomp.fortran/map-subarray-5.f90

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index a108f718ffa..1a14d2bc068 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -2961,6 +2961,7 @@ gfc_omp_deep_map_kind_p (tree clause)
 case GOMP_MAP_FORCE_TOFROM:
 case GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT:
 case GOMP_MAP_STRUCT:
+case GOMP_MAP_STRUCT_UNORD:
 case GOMP_MAP_ALWAYS_POINTER:
 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
 case GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION:
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index da81582da1c..9ce1f5b983a 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -8952,7 +8952,8 @@ build_omp_struct_comp_nodes (enum tree_code code, tree 
grp_start, tree grp_end,
 
 static tree
 extract_base_bit_offset (tree base, poly_int64 *bitposp,
-poly_offset_int *poffsetp)
+poly_offset_int *poffsetp,
+bool *variable_offset)
 {
   tree offset;
   poly_int64 bitsize, bitpos;
@@ -8970,10 +8971,13 @@ extract_base_bit_offset (tree base, poly_int64 *bitposp,
   if (offset && poly_int_tree_p (offset))
 {
   poffset = wi::to_poly_offset (offset);
-  offs

[PATCH 11/14] OpenACC: Reimplement "inheritance" for lexically-nested offload regions

2023-06-19 Thread Julian Brown
This patch reimplements "lexical inheritance" for OpenACC offload regions
inside "data" regions, allowing e.g. this to work:

  int *ptr;
  [...]
  #pragma acc data copyin(ptr[10:2])
  {
#pragma acc parallel
{ ... }
  }

here, the "copyin" is mirrored on the inner "acc parallel" as
"present(ptr[10:2])" -- allowing code within the parallel to use that
section of the array even though the mapping is implicit.

In terms of implementation, this works by expanding mapping nodes for
"acc data" to include pointer mappings that might be needed by inner
offload regions. The resulting mapping group is then copied to the inner
offload region as needed, rewriting the first node to "force_present".
The pointer mapping nodes are then removed from the "acc data" later
during gimplification.

For OpenMP, pointer mapping nodes on equivalent "omp data" regions are
not needed, so remain suppressed during expansion.

2023-06-16  Julian Brown  

gcc/c-family/
* c-omp.cc (c_omp_address_inspector::expand_array_base): Don't omit
pointer nodes for OpenACC.

gcc/
* gimplify.cc (omp_tsort_mark, omp_mapping_group): Move before
gimplify_omp_ctx. Add constructor to omp_mapping_group.
(gimplify_omp_ctx): Add DECL_DATA_CLAUSE field.
(new_omp_context, delete_omp_context): Initialise and free above field.
(omp_gather_mapping_groups_1): Use constructor for omp_mapping_group.
(gimplify_scan_omp_clauses): Record mappings that might be lexically
inherited.  Don't remove
GOMP_MAP_FIRSTPRIVATE_POINTER/GOMP_MAP_FIRSTPRIVATE_REFERENCE yet.
(gomp_oacc_needs_data_present): New function.
(gimplify_adjust_omp_clauses_1): Implement lexical inheritance
behaviour for OpenACC.
(gimplify_adjust_omp_clauses): Remove
GOMP_MAP_FIRSTPRIVATE_POINTER/GOMP_MAP_FIRSTPRIVATE_REFERENCE here
instead, after lexical inheritance is done.

gcc/testsuite/
* c-c++-common/goacc/acc-data-chain.c: Re-enable scan test.
* gfortran.dg/goacc/pr70828.f90: Likewise.
* gfortran.dg/goacc/assumed-size.f90: New test.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/pr70828.c: Un-XFAIL.
* testsuite/libgomp.oacc-c-c++-common/pr70828-2.c: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828.f90: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828-2.f90: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828-3.f90: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828-4.f90: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828-5.f90: Un-XFAIL.
* testsuite/libgomp.oacc-fortran/pr70828-6.f90: Un-XFAIL.
---
 gcc/c-family/c-omp.cc |  13 +-
 gcc/gimplify.cc   | 208 +-
 .../c-c++-common/goacc/acc-data-chain.c   |   4 +-
 .../gfortran.dg/goacc/assumed-size.f90|  35 +++
 gcc/testsuite/gfortran.dg/goacc/pr70828.f90   |   3 +-
 .../libgomp.oacc-c-c++-common/pr70828-2.c |   2 -
 .../libgomp.oacc-c-c++-common/pr70828.c   |   2 -
 .../libgomp.oacc-fortran/pr70828-2.f90|   2 -
 .../libgomp.oacc-fortran/pr70828-3.f90|   2 -
 .../libgomp.oacc-fortran/pr70828-4.f90|   2 -
 .../libgomp.oacc-fortran/pr70828-5.f90|   2 -
 .../libgomp.oacc-fortran/pr70828-6.f90|   2 -
 .../libgomp.oacc-fortran/pr70828.f90  |   2 -
 13 files changed, 202 insertions(+), 77 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/assumed-size.f90

diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index e55b2aec920..291a26293ef 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4313,7 +4313,8 @@ c_omp_address_inspector::expand_array_base (tree c,
/* The code handling "firstprivatize_array_bases" in gimplify.cc is
   relevant here.  What do we need to create for arrays at this
   stage?  (This condition doesn't feel quite right.  FIXME?)  */
-   if (!target
+   if (openmp
+   && !target
&& (TREE_CODE (TREE_TYPE (addr_tokens[i + 1]->expr))
== ARRAY_TYPE))
  break;
@@ -4324,7 +4325,7 @@ c_omp_address_inspector::expand_array_base (tree c,
   virtual_origin);
tree data_addr = omp_accessed_addr (addr_tokens, i + 1, expr);
c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
-   if (decl_p && target)
+   if (decl_p && (!openmp || target))
  OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
else
  {
@@ -4375,9 +4376,11 @@ c_omp_address_inspector::expand_array_base (tree c,
tree data_addr = omp_accessed_addr (addr_tokens, last_access, expr);
c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
/* For OpenACC, use FIRSTPRIVATE_POINTER for decls even on non-compute
-  regions (e.g. "acc data" constructs).  It'll be removed anyway in
-  gimplify.cc, but doing it this way mai

[PATCH 13/14] OpenACC: Allow implicit uses of assumed-size arrays in offload regions

2023-06-19 Thread Julian Brown
This patch reimplements the functionality of the previously-reverted
patch "Assumed-size arrays with non-lexical data mappings". The purpose
is to support implicit uses of assumed-size arrays for Fortran when those
arrays have already been mapped on the target some other way (e.g. by
"acc enter data").

This relates to upstream OpenACC issue 489 (not yet resolved).

2023-06-16  Julian Brown  

gcc/fortran/
* trans-openmp.cc (gfc_omp_finish_clause): Treat implicitly-mapped
assumed-size arrays as zero-sized for OpenACC, rather than an error.

gcc/testsuite/
* gfortran.dg/goacc/assumed-size.f90: Don't expect error.

libgomp/
* testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-1.f90: New
test.
* testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-2.f90: New
test.
---
 gcc/fortran/trans-openmp.cc   | 16 ++--
 .../gfortran.dg/goacc/assumed-size.f90|  4 +-
 .../nonlexical-assumed-size-1.f90 | 28 +
 .../nonlexical-assumed-size-2.f90 | 40 +++
 4 files changed, 82 insertions(+), 6 deletions(-)
 create mode 100644 
libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-1.f90
 create mode 100644 
libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-2.f90

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 819d79cda28..230cebf250b 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1587,6 +1587,7 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
 return;
 
   tree decl = OMP_CLAUSE_DECL (c);
+  bool assumed_size = false;
 
   /* Assumed-size arrays can't be mapped implicitly, they have to be
  mapped explicitly using array sections.  */
@@ -1597,9 +1598,14 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
 == NULL)
 {
-  error_at (OMP_CLAUSE_LOCATION (c),
-   "implicit mapping of assumed size array %qD", decl);
-  return;
+  if (openacc)
+   assumed_size = true;
+  else
+   {
+ error_at (OMP_CLAUSE_LOCATION (c),
+   "implicit mapping of assumed size array %qD", decl);
+ return;
+   }
 }
 
   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR)
@@ -1654,7 +1660,9 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   else
{
  OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_SIZE (c) = NULL_TREE;
+ OMP_CLAUSE_SIZE (c) = assumed_size ? size_zero_node : NULL_TREE;
+ if (assumed_size)
+   OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
}
   if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
  && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
diff --git a/gcc/testsuite/gfortran.dg/goacc/assumed-size.f90 
b/gcc/testsuite/gfortran.dg/goacc/assumed-size.f90
index 4fced2e70c9..12f44c4743a 100644
--- a/gcc/testsuite/gfortran.dg/goacc/assumed-size.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/assumed-size.f90
@@ -4,7 +4,8 @@
 ! exit data, respectively.
 
 ! This does not appear to be supported by the OpenACC standard as of version
-! 3.0.  Check for an appropriate error message.
+! 3.0.  There is however real-world code that relies on this working, so we
+! make an attempt to support it.
 
 program test
   implicit none
@@ -26,7 +27,6 @@ subroutine dtest (a, n)
   !$acc enter data copyin(a(1:n))
 
   !$acc parallel loop
-! { dg-error {implicit mapping of assumed size array 'a'} "" { target *-*-* } 
.-1 }
   do i = 1, n
  a(i) = i
   end do
diff --git 
a/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-1.f90 
b/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-1.f90
new file mode 100644
index 000..4b61e1cee9b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-1.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+
+program p
+implicit none
+integer :: myarr(10)
+
+myarr = 0
+
+call subr(myarr)
+
+if (myarr(5).ne.5) stop 1
+
+contains
+
+subroutine subr(arr)
+implicit none
+integer :: arr(*)
+
+!$acc enter data copyin(arr(1:10))
+
+!$acc serial
+arr(5) = 5
+!$acc end serial
+
+!$acc exit data copyout(arr(1:10))
+
+end subroutine subr
+end program p
diff --git 
a/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-2.f90 
b/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-2.f90
new file mode 100644
index 000..daf7089915f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/nonlexical-assumed-size-2.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+
+program p
+implicit none
+integer :: myarr(10)
+
+myarr = 0
+
+call subr(myarr)
+
+if (myarr(5).ne.5) stop 1
+
+contains
+
+subroutine subr(arr)
+implicit none
+integer :: arr(*)
+
+! At first glance, it might not be obvious how this works.  The "enter data"
+! and "exit data" operations expand to a pair o

[PATCH 10/14] OpenMP/OpenACC: Reorganise OMP map clause handling in gimplify.cc

2023-06-19 Thread Julian Brown
This patch has been separated out from the C++ "declare mapper"
support patch.  It contains just the gimplify.cc rearrangement
work, mostly moving gimplification from gimplify_scan_omp_clauses
to gimplify_adjust_omp_clauses for map clauses.

The motivation for doing this was that we don't know if we need to
instantiate mappers implicitly until the body of an offload region has
been scanned, i.e. in gimplify_adjust_omp_clauses, but we also need the
un-gimplified form of clauses to sort by base-pointer dependencies after
mapper instantiation has taken place.

The patch also reimplements the "present" clause sorting code to avoid
another sorting pass on mapping nodes.

2023-06-16  Julian Brown  

gcc/
* gimplify.cc (omp_segregate_mapping_groups): Handle "present" groups.
(gimplify_scan_omp_clauses): Use mapping group functionality to
iterate through mapping nodes.  Remove most gimplification of
OMP_CLAUSE_MAP nodes from here, but still populate ctx->variables
splay tree.
(gimplify_adjust_omp_clauses): Move most gimplification of
OMP_CLAUSE_MAP nodes here.

gcc/testsuite/
* gfortran.dg/gomp/map-12.f90: Adjust scan output.
---
 gcc/gimplify.cc   | 670 --
 gcc/testsuite/gfortran.dg/gomp/map-12.f90 |   2 +-
 2 files changed, 378 insertions(+), 294 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 9ce1f5b983a..e21e9d99cc9 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9779,10 +9779,15 @@ omp_tsort_mapping_groups (vec 
*groups,
   return outlist;
 }
 
-/* Split INLIST into two parts, moving groups corresponding to
-   ALLOC/RELEASE/DELETE mappings to one list, and other mappings to another.
-   The former list is then appended to the latter.  Each sub-list retains the
-   order of the original list.
+/* Split INLIST into four parts:
+
+ - "present" to/from groups
+ - "present" alloc groups
+ - other to/from groups
+ - other alloc/release/delete groups
+
+   These sub-lists are then concatenated together to form the final list.
+   Each sub-list retains the order of the original list.
Note that ATTACH nodes are later moved to the end of the list in
gimplify_adjust_omp_clauses, for target regions.  */
 
@@ -9790,7 +9795,9 @@ static omp_mapping_group *
 omp_segregate_mapping_groups (omp_mapping_group *inlist)
 {
   omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
+  omp_mapping_group *pa_groups = NULL, *ptf_groups = NULL;
   omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
+  omp_mapping_group **pa_tail = &pa_groups, **ptf_tail = &ptf_groups;
 
   for (omp_mapping_group *w = inlist; w;)
 {
@@ -9809,6 +9816,20 @@ omp_segregate_mapping_groups (omp_mapping_group *inlist)
  ard_tail = &w->next;
  break;
 
+   case GOMP_MAP_PRESENT_ALLOC:
+ *pa_tail = w;
+ w->next = NULL;
+ pa_tail = &w->next;
+ break;
+
+   case GOMP_MAP_PRESENT_FROM:
+   case GOMP_MAP_PRESENT_TO:
+   case GOMP_MAP_PRESENT_TOFROM:
+ *ptf_tail = w;
+ w->next = NULL;
+ ptf_tail = &w->next;
+ break;
+
default:
  *tf_tail = w;
  w->next = NULL;
@@ -9820,8 +9841,10 @@ omp_segregate_mapping_groups (omp_mapping_group *inlist)
 
   /* Now splice the lists together...  */
   *tf_tail = ard_groups;
+  *pa_tail = tf_groups;
+  *ptf_tail = pa_groups;
 
-  return tf_groups;
+  return ptf_groups;
 }
 
 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
@@ -11673,119 +11696,30 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
break;
   }
 
-  if (code == OMP_TARGET
-  || code == OMP_TARGET_DATA
-  || code == OMP_TARGET_ENTER_DATA
-  || code == OMP_TARGET_EXIT_DATA)
-{
-  vec *groups;
-  groups = omp_gather_mapping_groups (list_p);
-  if (groups)
-   {
- hash_map *grpmap;
- grpmap = omp_index_mapping_groups (groups);
+  vec *groups = omp_gather_mapping_groups (list_p);
+  hash_map *grpmap = NULL;
+  unsigned grpnum = 0;
+  tree *grp_start_p = NULL, grp_end = NULL_TREE;
 
- omp_resolve_clause_dependencies (code, groups, grpmap);
- omp_build_struct_sibling_lists (code, region_type, groups, &grpmap,
- list_p);
-
- omp_mapping_group *outlist = NULL;
- bool enter_exit = (code == OMP_TARGET_ENTER_DATA
-|| code == OMP_TARGET_EXIT_DATA);
-
- /* Topological sorting may fail if we have duplicate nodes, which
-we should have detected and shown an error for already.  Skip
-sorting in that case.  */
- if (seen_error ())
-   goto failure;
-
- delete grpmap;
- delete groups;
-
- /* Rebuild now we have struct sibling lists.  */
- groups = omp_gather_mapping_groups (list_p);
- grpmap = omp_index_mappin

[PATCH 14/14] OpenACC: Improve implicit mapping for non-lexically nested offload regions

2023-06-19 Thread Julian Brown
This patch enables use of the OMP_CLAUSE_RUNTIME_IMPLICIT_P flag for
OpenACC.

This allows code like this to work correctly:

  int arr[100];
  [...]
  #pragma acc enter data copyin(arr[20:10])

  /* No explicit mapping of 'arr' here.  */
  #pragma acc parallel
  { /* use of arr[20:10]... */ }

  #pragma acc exit data copyout(arr[20:10])

Otherwise, the implicit "copy" ("present_or_copy") on the parallel
corresponds to the whole array, and that fails at runtime when the
subarray is mapped.

The numbering of the GOMP_MAP_IMPLICIT bit clashes with the OpenACC
"non-contiguous" dynamic array support, so the GOMP_MAP_NONCONTIG_ARRAY_P
macro has been adjusted to account for that.

This behaviour relates to upstream OpenACC issue 490 (not yet resolved).

2023-06-16  Julian Brown  

gcc/
* gimplify.cc (gimplify_adjust_omp_clauses_1): Set
OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P for OpenACC also.

gcc/testsuite/
* c-c++-common/goacc/combined-reduction.c: Adjust scan output.
* c-c++-common/goacc/reduction-1.c: Likewise.
* c-c++-common/goacc/reduction-2.c: Likewise.
* c-c++-common/goacc/reduction-3.c: Likewise.
* c-c++-common/goacc/reduction-4.c: Likewise.
* c-c++-common/goacc/reduction-10.c: Likewise.
* gfortran.dg/goacc/loop-tree-1.f90: Likewise.

include/
* gomp-constants.h (GOMP_MAP_NONCONTIG_ARRAY_P): Tweak condition.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/implicit-mapping-1.c: New test.
---
 gcc/gimplify.cc   |  5 +---
 .../c-c++-common/goacc/combined-reduction.c   |  2 +-
 .../c-c++-common/goacc/reduction-1.c  |  4 ++--
 .../c-c++-common/goacc/reduction-10.c |  9 +++
 .../c-c++-common/goacc/reduction-2.c  |  4 ++--
 .../c-c++-common/goacc/reduction-3.c  |  4 ++--
 .../c-c++-common/goacc/reduction-4.c  |  4 ++--
 .../gfortran.dg/goacc/loop-tree-1.f90 |  2 +-
 include/gomp-constants.h  |  3 ++-
 .../implicit-mapping-1.c  | 24 +++
 10 files changed, 42 insertions(+), 19 deletions(-)
 create mode 100644 
libgomp/testsuite/libgomp.oacc-c-c++-common/implicit-mapping-1.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 0706f130ebb..1e90d2ed031 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -13413,10 +13413,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
  gcc_unreachable ();
}
   OMP_CLAUSE_SET_MAP_KIND (clause, kind);
-  /* Setting of the implicit flag for the runtime is currently disabled for
-OpenACC.  */
-  if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
-   OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
+  OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
   if (DECL_SIZE (decl)
  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-reduction.c 
b/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
index ecf23f59d66..40b93acc9ea 100644
--- a/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
+++ b/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
@@ -25,5 +25,5 @@ main ()
 
 /* { dg-final { scan-tree-dump-times "omp target oacc_parallel reduction.+:v1. 
map.tofrom:v1" 1 "gimple" } } */
 /* { dg-final { scan-tree-dump-times "acc loop reduction.+:v1. private.i." 1 
"gimple" } } */
-/* { dg-final { scan-tree-dump-times "omp target oacc_kernels 
map.force_tofrom:n .len: 4.. map.force_tofrom:v1 .len: 4.." 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "omp target oacc_kernels 
map.force_tofrom:n .len: 4..implicit.. map.force_tofrom:v1 .len: 4..implicit.." 
1 "gimple" } } */
 /* { dg-final { scan-tree-dump-times "acc loop reduction.+:v1. private.i." 1 
"gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-1.c 
b/gcc/testsuite/c-c++-common/goacc/reduction-1.c
index 35bfc868708..d9e3c380b8e 100644
--- a/gcc/testsuite/c-c++-common/goacc/reduction-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-1.c
@@ -68,5 +68,5 @@ main(void)
 }
 
 /* Check that default copy maps are generated for loop reductions.  */
-/* { dg-final { scan-tree-dump-times "map\\(tofrom:result \\\[len: 
\[0-9\]+\\\]\\)" 7 "gimple" } } */
-/* { dg-final { scan-tree-dump-times "map\\(tofrom:lresult \\\[len: 
\[0-9\]+\\\]\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "map\\(tofrom:result \\\[len: 
\[0-9\]+\\\]\\\[implicit\\\]\\)" 7 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "map\\(tofrom:lresult \\\[len: 
\[0-9\]+\\\]\\\[implicit\\\]\\)" 2 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-10.c 
b/gcc/testsuite/c-c++-common/goacc/reduction-10.c
index 579aa561479..36c330e9267 100644
--- a/gcc/testsuite/c-c++-common/goacc/reduction-10.c
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-10.c
@@ -87,7 +87,8 @@ main(void)
 
 /* Check that default copy maps are generated for loop reductions.  */
 /* { dg-fina

[PATCH 12/14] OpenACC: "declare create" fixes wrt. "allocatable" variables

2023-06-19 Thread Julian Brown
This patch fixes a case revealed by the previous patch where a synthetic
"acc data" region created for a "declare create" variable could interact
strangely with lexical inheritance behaviour.  In fact, it doesn't seem
right to create the "acc data" region for allocatable variables at all
-- doing so means that a data region is likely to be created for an
unallocated variable.

The fix is not to add such variables to the synthetic "acc data" region
at all, and defer to the code that performs "enter data"/"exit data"
for them when allocated/deallocated on the host instead. Then, "declare
create" variables are implicitly turned into "present" clauses on in-scope
offload regions.

2023-06-16  Julian Brown  

gcc/fortran/
* trans-openmp.cc (gfc_omp_finish_clause): Handle "declare create" for
scalar allocatable variables.
(gfc_trans_omp_clauses): Don't include allocatable vars in synthetic
"acc data" region created for "declare create" variables.  Mark such
variables with the "oacc declare create" attribute instead.  Don't
create ALWAYS_POINTER mapping for target-to-host updates of declare
create variables.
(gfc_trans_oacc_declare): Handle empty clause list.

gcc/
* gimplify.cc (gimplify_adjust_omp_clauses_1): Handle "oacc declare
create" attribute.

libgomp/
* testsuite/libgomp.oacc-fortran/declare-create-1.f90: New test.
* testsuite/libgomp.oacc-fortran/declare-create-2.f90: New test.
* testsuite/libgomp.oacc-fortran/declare-create-3.f90: New test.
---
 gcc/fortran/trans-openmp.cc   | 45 ---
 gcc/gimplify.cc   |  8 
 .../libgomp.oacc-fortran/declare-create-1.f90 | 21 +
 .../libgomp.oacc-fortran/declare-create-2.f90 | 25 +++
 .../libgomp.oacc-fortran/declare-create-3.f90 | 25 +++
 5 files changed, 119 insertions(+), 5 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 1a14d2bc068..819d79cda28 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1619,7 +1619,16 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
   orig_decl = decl;
 
   c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
-  OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
+  if (openacc
+ && GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
+ && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_PRESENT)
+   /* This allows "declare create" to work for scalar allocatables.  The
+  resulting mapping nodes are:
+force_present(*var) firstprivate_pointer(var)
+  which is the same as an explicit "present" clause gives.  */
+   OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_FIRSTPRIVATE_POINTER);
+  else
+   OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
   OMP_CLAUSE_DECL (c4) = decl;
   OMP_CLAUSE_SIZE (c4) = size_int (0);
   decl = build_fold_indirect_ref (decl);
@@ -4588,6 +4597,29 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
  if (!n->sym->attr.referenced)
continue;
 
+ /* We do not want to include allocatable vars in a synthetic
+"acc data" region created for "!$acc declare create" vars.
+Such variables are handled by augmenting allocate/deallocate
+statements elsewhere (with
+"acc enter data declare_allocate(...)", etc.).  */
+ if (op == EXEC_OACC_DECLARE
+ && n->u.map_op == OMP_MAP_ALLOC
+ && n->sym->attr.allocatable
+ && n->sym->attr.oacc_declare_create)
+   {
+ tree tree_var = gfc_get_symbol_decl (n->sym);
+ if (!lookup_attribute ("oacc declare create",
+DECL_ATTRIBUTES (tree_var)))
+   DECL_ATTRIBUTES (tree_var)
+ = tree_cons (get_identifier ("oacc declare create"),
+  NULL_TREE, DECL_ATTRIBUTES (tree_var));
+ /* We might need to turn what would normally be a
+"firstprivate" mapping into a "present" mapping.  For the
+latter, we need the decl to be addressable.  */
+ TREE_ADDRESSABLE (tree_var) = 1;
+ continue;
+   }
+
  bool always_modifier = false;
  tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
  tree node2 = NULL_TREE;
@@ -4780,7 +4812,8 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
  tree orig_decl = decl;
 

Re: [PATCH v5 3/5] p1689r5: initial support

2023-06-19 Thread Jason Merrill via Fortran

On 5/12/23 10:24, Ben Boeckel wrote:

On Tue, Feb 14, 2023 at 16:50:27 -0500, Jason Merrill wrote:

I notice that the actual flags are all -fdep-*, though some of them are
-fdeps-* here, and the internal variables all seem to be fdeps_*.  I
lean toward harmonizing on "deps", I think.


Done.


I don't love the three separate options, but I suppose it's fine.  I'd
prefer "target" instead of "output".


Done.


It should be possible to omit both -file and -target and get reasonable
defaults, like the ones for -MD/-MQ in gcc.cc:cpp_unique_options.


`file` can be omitted (the `output_stream` will be used then). I *think*
I see that adding:

 %{fdeps_file:-fdeps-file=%{!o:%b.ddi}%{o*:%.ddi%*}}


%{!fdeps-file: but yes.


would at least do for `-fdeps-file` defaults? I don't know if there's a
reasonable default for `-fdeps-target=` though given that this command
line has no information about the object file that will be used (`-o` is
used for preprocessor output since we're leaning on `-E` here).


I would think it could default to %b.o?

I had quite a few more comments on the v5 patch that you didn't respond 
to here or address in the v6 patch; did your mail client hide them from you?


Jason



Re: [PATCH v6 1/4] libcpp: reject codepoints above 0x10FFFF

2023-06-19 Thread Jason Merrill via Fortran

On 6/6/23 16:50, Ben Boeckel wrote:

Unicode does not support such values because they are unrepresentable in
UTF-16.


Pushed.


libcpp/

* charset.cc: Reject encodings of codepoints above 0x10.
UTF-16 does not support such codepoints and therefore all
Unicode rejects such values.

Signed-off-by: Ben Boeckel 
---
  libcpp/charset.cc | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/libcpp/charset.cc b/libcpp/charset.cc
index d7f323b2cd5..3b34d804cf1 100644
--- a/libcpp/charset.cc
+++ b/libcpp/charset.cc
@@ -1886,6 +1886,13 @@ cpp_valid_utf8_p (const char *buffer, size_t num_bytes)
int err = one_utf8_to_cppchar (&iter, &bytesleft, &cp);
if (err)
return false;
+
+  /* Additionally, Unicode declares that all codepoints above 0010 are
+invalid because they cannot be represented in UTF-16.
+
+Reject such values.*/
+  if (cp >= 0x10)
+   return false;
  }
/* No problems encountered.  */
return true;




Re: [PATCH v6 0/4] P1689R5 support

2023-06-19 Thread Jason Merrill via Fortran

On 6/17/23 10:43, Ben Boeckel wrote:

On Fri, Jun 16, 2023 at 23:55:53 -0400, Jason Merrill wrote:

I see the same thing with patch 4 on x86_64-pc-linux-gnu, e.g.

FAIL: g++.dg/modules/ben-1_a.C -std=c++17 (test for excess errors)
Excess errors:
/home/jason/gt/gcc/testsuite/g++.dg/modules/ben-1_a.C:9:1: internal
compiler error: Segmentation fault
0x19e2f3c crash_signal
 /home/jason/gt/gcc/toplev.cc:314
0x340f3f8 mkdeps::vec::size() const
 /home/jason/gt/libcpp/mkdeps.cc:57
0x340dc1f apply_vpath
 /home/jason/gt/libcpp/mkdeps.cc:194
0x340e08e deps_add_dep(mkdeps*, char const*)
 /home/jason/gt/libcpp/mkdeps.cc:318
0xea7b51 module_client::open_module_client(unsigned int, char const*,
mkdeps*, void (*)(char const*), char const*)
 /home/jason/gt/gcc/cp/mapper-client.cc:291
0xef2ba8 make_mapper
 /home/jason/gt/gcc/cp/module.cc:14042
0xf0896c get_mapper(unsigned int, mkdeps*)
 /home/jason/gt/gcc/cp/module.cc:3977
0xf032ac name_pending_imports
 /home/jason/gt/gcc/cp/module.cc:19623
0xf03a7d preprocessed_module(cpp_reader*)
 /home/jason/gt/gcc/cp/module.cc:19817
0xe85104 module_token_cdtor(cpp_reader*, unsigned long)
 /home/jason/gt/gcc/cp/lex.cc:548
0xf467b2 cp_lexer_new_main
 /home/jason/gt/gcc/cp/parser.cc:756
0xfc1e3a c_parse_file()
 /home/jason/gt/gcc/cp/parser.cc:49725
0x11c5bf5 c_common_parse_file()
 /home/jason/gt/gcc/c-family/c-opts.cc:1268


Thanks. I missed a `nullptr` check before calling `deps_add_dep`. I
think I got misled by `make check` returning a zero exit code even if
there are failures.


Aha!

Patches 3 and 4 could also use testcases.

Jason