[PATCH 0/2] C++ "declare mapper" support and map clause expansion fixes

2022-11-30 Thread Julian Brown
These two patches (posting as a "partial series" to avoid too much
duplication) comprise bug fixes for map clause expansion and a new version
of the patch to support OpenMP 5.0+ "declare mapper" directives for
C++. Hopefully previous review comments for the latter have been
adequately addressed.

These patches depend on various other patches that are not yet committed,
as described in the following emails.  (I may post the whole series
again after revising bits that already have review comments, if that'd
be helpful.)

Tested (with dependent patches) with offloading to NVPTX, and bootstrapped.

Julian Brown (~2):
  OpenMP/OpenACC: Refine condition for when map clause expansion happens
  [...]
  OpenMP: C++ "declare mapper" support

-- 
2.29.2



[PATCH 1/7] OpenMP/OpenACC: Refine condition for when map clause expansion happens

2022-11-30 Thread Julian Brown
This patch fixes some cases for OpenACC and OpenMP where map clauses were
being expanded (adding firstprivate_pointer, attach/detach nodes, and so
forth) unnecessarily, after the "OpenMP/OpenACC: Rework clause expansion
and nested struct handling" patch (approved but not yet committed):

  https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603792.html

This is done by introducing a C_ORT_ACC_TARGET region type for OpenACC
compute regions to help distinguish them from non-compute regions that
need different handling, and by passing the region type through to the
clause expansion functions.

The patch also fixes clause expansion for OpenMP TO/FROM clauses, which
need to dereference references but not have any additional mapping nodes.

(These cases showed up due to the gimplification changes in the C++
"declare mapper" patch, but logically belong next to the earlier patch
named above.)

2022-11-30  Julian Brown  

gcc/
* c-family/c-common.h (c_omp_region_type): Add C_ORT_ACC_TARGET.
(c_omp_address_inspector): Pass c_omp_region_type instead of "target"
bool.
* c-family/c-omp.cc (c_omp_address_inspector::expand_array_base):
Adjust clause expansion for OpenACC and non-map (OpenMP to/from)
clauses.
(c_omp_address_inspector::expand_component_selector): Use
c_omp_region_type parameter.  Don't expand OpenMP to/from clauses.
(c_omp_address_inspector::expand_map_clause): Take ORT parameter, pass
to expand_array_base, etc.

gcc/c/
* c-parser.cc (c_parser_oacc_all_clauses): Add TARGET parameter. Use
to select region type for c_finish_omp_clauses call.
(c_parser_oacc_loop): Update calls to c_parser_oacc_all_clauses.
(c_parser_oacc_compute): Likewise.
* c-typeck.cc (handle_omp_array_sctions_1): Update for C_ORT_ACC_TARGET
addition and ai.expand_map_clause signature change.
(c_finish_omp_clauses): Likewise.

gcc/cp/
* parser.cc (cp_parser_oacc_all_clauses): Add TARGET parameter. Use
to select region type for finish_omp_clauses call.
(cp_parser_oacc_declare): Update call to cp_parser_oacc_all_clauses.
(cp_parser_oacc_loop): Update calls to cp_parser_oacc_all_clauses.
(cp_parser_oacc_compute): Likewise.
* pt.cc (tsubst_expr): Use C_ORT_ACC_TARGET for call to
tsubst_omp_clauses for compute regions.
* semantics.cc (handle_omp_array_sections_1): Update for
C_ORT_ACC_TARGET addition and ai.expand_map_clause signature change.
(finish_omp_clauses): Likewise.
---
 gcc/c-family/c-common.h | 10 +++--
 gcc/c-family/c-omp.cc   | 90 -
 gcc/c/c-parser.cc   | 15 ---
 gcc/c/c-typeck.cc   | 39 --
 gcc/cp/parser.cc| 15 ---
 gcc/cp/pt.cc|  4 +-
 gcc/cp/semantics.cc | 47 ++---
 7 files changed, 144 insertions(+), 76 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 14523fdefbc2..87e999becd5d 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1221,7 +1221,8 @@ enum c_omp_region_type
   C_ORT_DECLARE_SIMD   = 1 << 2,
   C_ORT_TARGET = 1 << 3,
   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_TARGET = C_ORT_OMP | C_ORT_TARGET,
+  C_ORT_ACC_TARGET = C_ORT_ACC | C_ORT_TARGET
 };
 
 extern tree c_finish_omp_master (location_t, tree);
@@ -1321,10 +1322,11 @@ public:
   bool maybe_zero_length_array_section (tree);
 
   tree expand_array_base (tree, vec &, tree, unsigned *,
- bool, bool);
+ c_omp_region_type, bool);
   tree expand_component_selector (tree, vec &, tree,
- unsigned *, bool);
-  tree expand_map_clause (tree, tree, vec &, bool);
+ unsigned *, c_omp_region_type);
+  tree expand_map_clause (tree, tree, vec &,
+ c_omp_region_type);
 };
 
 enum c_omp_directive_kind {
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 7498c883be80..aab4ad9bed32 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -3369,7 +3369,8 @@ tree
 c_omp_address_inspector::expand_array_base (tree c,
vec &addr_tokens,
tree expr, unsigned *idx,
-   bool target, bool decl_p)
+   c_omp_region_type ort,
+   bool decl_p)
 {
   using namespace omp_addr_tokenizer;
   location_t loc = OMP_CLAUSE_LOCATION (c);
@@ -3379,14 +3380,26 @@ c_omp_address_inspector::expand_array_base (tree c,
   && is_global_var (decl)
   && lookup_attribute ("omp declare target",
  

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

2022-11-30 Thread Julian Brown
This is a new version of the patch to support OpenMP 5.0 "declare mapper"
functionality for C++.  As with the previously-posted version, arrays
of structs whose elements would be mapped via a user-defined mapper
remain unsupported.

(Previous versions were posted here:
  https://gcc.gnu.org/pipermail/gcc-patches/2022-September/601560.html
  https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591983.html)

This version of the patch uses a magic VAR_DECL instead of a magic
FUNCTION_DECL for representing mappers, which simplifies parsing
somewhat, and slightly reduces the number of places that need special-case
handling in the FE.  We use the DECL_INITIAL of the VAR_DECL to hold the
OMP_DECLARE_MAPPER definition.  To make types agree, we use the type of
the object to be mapped for both the var decl and the OMP_DECLARE_MAPPER
node itself.  Hence the OMP_DECLARE_MAPPER looks like a magic constant
of struct type in this particular case.

The magic var decl can go in all the places that the "declare mapper"
function decl went previously: at the top level of the program,
within a class definition (including template classes), and within a
function definition (including template functions).  In the class case
we conceptually use the C++-17-ism of definining the var decl "inline
static", equivalent to e.g.:

   [template ...]
   class bla {
 static inline omp declare mapper ... = #define omp declare mapper ..."
   };

(though of course we don't restrict the "declare mapper"-in-class syntax
to C++-17.)

The new representation necessitates some changes to template
instantiation.  In particular, declare mappers may trigger implicitly,
so we must make sure they are instantiated before they are needed (see
changes to mark_used, etc.).

I've rearranged the processing done by the gimplify_scan_omp_clauses and
gimplify_adjust_omp_clauses functions so the order of the phases can
remain intact in the presence of declared mappers.  To do this, most
gimplification of clauses in gimplify_scan_omp_clauses has been moved
to gimplify_adjust_omp_clauses.  This allows e.g. struct sibling-list
handling and topological clause sorting to work with the non-gimplified
form of clauses in the latter function -- including those that arise
from mapper expansion.  This seems to work well now.

Relative to the last-posted version, this patch brings forward various
refactoring that was previously done by the C and Fortran "declare mapper"
support patches -- aiming to reduce churn.  E.g. nested mapper finding
and mapper instantiation has been moved to c-family/c-omp.cc so it can
be shared between C and C++, and omp_name_type in omp-general.h (used
as the key to hash mapper definitions) is already templatized ready for
Fortran support.

This patch does not synthesize default mappers that map each of a struct's
elements individually: whole-struct mappings are still done by copying
the block of memory containing the struct.  That works fine apart from
cases where a struct has a member that is a reference (to a pointer).
We could fix that by synthesizing a mapper for such cases (only), but
that hasn't been attempted yet.  (I think that means Jakub's concerns
about blow-up of element mappings won't be a problem until that's done.)

New tests added in {gcc,libgomp}/c-c++-common have been restricted to
C++ for now, as the equivalent C parser changes to "declare mapper"
support are still TBD (as are any Fortran FE adjustments that might be
necessary due to various changes here and elsewhere).

This patch depends on the in-review or approved-but-pending-other-patches
patches:

  "OpenMP/OpenACC: Rework clause expansion and nested struct handling"
  https://gcc.gnu.org/pipermail/gcc-patches/2022-September/601837.html
  (aka https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603792.html)
  [approved, but breaks Fortran mapping a bit without...]

  "OpenMP: Pointers and member mappings"
  https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603794.html
  [...this one, which is unreviewed]

  "OpenMP/OpenACC: Unordered/non-constant component offset runtime diagnostic"
  https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603793.html
  [unreviewed also -- "QoI" improvement to above]

  "OpenMP: lvalue parsing for map/to/from clauses (C++)"
  https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605367.html
  [reviewed, but needs a little revision]

2022-11-30  Julian Brown  

gcc/c-family/
* c-common.h (omp_mapper_list): Add forward declaration.
(c_omp_find_nested_mappers, c_omp_instantiate_mappers): Add prototypes.
* c-omp.cc (c_omp_find_nested_mappers): New function.
(remap_mapper_decl_info): New struct.
(remap_mapper_decl_1, omp_instantiate_mapper,
c_omp_instantiate_mappers): New functions.

gcc/cp/
* constexpr.cc (reduced_constant_expression_p): Add OMP_DECLARE_MAPPER
case.
(cxx_eval_constant_expression, potential_constant_expression_1):
Likewise.
* cp-g