Hi Jakub,

Revised patch – changes are:
* cp-gimplify.c's cxx_omp_predetermined_mapping (twice 3 lines removed as 
proposed)
* gimplify.c's omp_notice_variable: changes how returned 'kind' is used.

Namely:

Pre-commit follow-up version to the 'LGTM patch':
As instructed, I have removed the two-times three lines
from cp-gimplify.c's cxx_omp_predetermined_mapping.

However, I made a thinko regarding 'nflags |= kind;' which just
happened to work for a test case – the nflags value differs
from the enum value.
[See gimplify.c's omp_notice_variable; see also line 9610+
for the full set of mappings].

For two items + unreachable, I think 'if' is simpler than
'switch', hence, I used it. Alternatively, one could split-off
the case block of ll. 9610+ and use a function call for both.
Thoughts?

OK?

Tobias

On 5/26/20 5:43 PM, Jakub Jelinek via Gcc-patches wrote:

On Tue, May 26, 2020 at 04:06:04PM +0200, Jakub Jelinek wrote:
On Mon, May 25, 2020 at 07:10:31PM +0200, Tobias Burnus wrote:
+enum omp_clause_defaultmap_kind
+cxx_omp_predetermined_mapping (tree decl)
+{
+  enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
+  if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+    return OMP_CLAUSE_DEFAULTMAP_TO;
I don't like the above 3 lines, do you need it for anything?
Static data members certainly aren't covered and it is unlikely we want to
predetermine them mapped.
And forgot, for this the behavior is already specified in 5.0 that any
reference to this should result in map(tofrom:this[:1]).
It is not implemented yet, but we'll need to implement it some other way
than through this hook.

      Jakub

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
[OpenMP] Fix mapping of artificial variables (PR94874)

gcc/c-family/ChangeLog:

	* c-common.h (c_omp_predetermined_mapping): Declare.
	* c-omp.c (c_omp_predetermined_mapping): New.

gcc/c/ChangeLog:

	* c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Redefine.

gcc/cp/ChangeLog:

	* cp-gimplify.c (cxx_omp_predetermined_mapping): New.
	* cp-objcp-common.h (LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Redfine.
	* cp-tree.h (cxx_omp_predetermined_mapping): Declare.

gcc/fortran/ChangeLog:

	* f95-lang.c (LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Redefine.
	* trans-openmp.c (gfc_omp_predetermined_mapping): New.
	* trans.h (gfc_omp_predetermined_mapping): Declare.

gcc/ChangeLog:

	* gimplify.c (omp_notice_variable): Use new hook.
	* langhooks-def.h (lhd_omp_predetermined_mapping): Declare.
	(LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Define
	(LANG_HOOKS_DECLS): Add it.
	* langhooks.c (lhd_omp_predetermined_sharing): Remove bogus unused attr.
	(lhd_omp_predetermined_mapping): New.
	* langhooks.h (struct lang_hooks_for_decls): Add new hook.

gcc/testsuite/ChangeLog
2020-06-03  Thomas Schwinge  <tho...@codesourcery.com>
            Tobias Burnus  <tob...@codesourcery.com>

        PR middle-end/94874
        * c-c++-common/gomp/pr94874.c: New.

 gcc/c-family/c-common.h                   |  1 +
 gcc/c-family/c-omp.c                      | 24 +++++++++++++++++++++++-
 gcc/c/c-objc-common.h                     |  3 +++
 gcc/cp/cp-gimplify.c                      | 19 ++++++++++++++++++-
 gcc/cp/cp-objcp-common.h                  |  2 ++
 gcc/cp/cp-tree.h                          |  1 +
 gcc/fortran/f95-lang.c                    |  2 ++
 gcc/fortran/trans-openmp.c                | 25 ++++++++++++++++++++++++-
 gcc/fortran/trans.h                       |  1 +
 gcc/gimplify.c                            | 13 ++++++++++++-
 gcc/langhooks-def.h                       |  3 +++
 gcc/langhooks.c                           | 13 ++++++++++++-
 gcc/langhooks.h                           |  4 ++++
 gcc/testsuite/c-c++-common/gomp/pr94874.c | 25 +++++++++++++++++++++++++
 14 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 7c1a6370aae..c74b23db05c 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1206,6 +1206,7 @@ extern tree c_omp_declare_simd_clauses_to_numbers (tree, tree);
 extern void c_omp_declare_simd_clauses_to_decls (tree, tree);
 extern bool c_omp_predefined_variable (tree);
 extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree);
+extern enum omp_clause_defaultmap_kind c_omp_predetermined_mapping (tree);
 extern tree c_omp_check_context_selector (location_t, tree);
 extern void c_omp_mark_declare_variant (location_t, tree, tree);
 extern const char *c_omp_map_clause_name (tree, bool);
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 51c18a4ba08..6f8fba350ed 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -2104,7 +2104,8 @@ c_omp_predefined_variable (tree decl)
   return false;
 }
 
-/* True if OpenMP sharing attribute of DECL is predetermined.  */
+/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute of DECL
+   is predetermined.  */
 
 enum omp_clause_default_kind
 c_omp_predetermined_sharing (tree decl)
@@ -2123,6 +2124,27 @@ c_omp_predetermined_sharing (tree decl)
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+/* OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED unless OpenMP mapping attribute
+   of DECL is predetermined.  */
+
+enum omp_clause_defaultmap_kind
+c_omp_predetermined_mapping (tree decl)
+{
+  /* Predetermine artificial variables holding integral values, those
+     are usually result of gimplify_one_sizepos or SAVE_EXPR
+     gimplification.  */
+  if (VAR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
+    return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
+
+  if (c_omp_predefined_variable (decl))
+    return OMP_CLAUSE_DEFAULTMAP_TO;
+
+  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
+}
+
+
 /* Diagnose errors in an OpenMP context selector, return CTX if
    it is correct or error_mark_node otherwise.  */
 
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index bfdb2797ff4..5471fc7e355 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -107,6 +107,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing
 
+#undef LANG_HOOKS_OMP_PREDETERMINED_MAPPING
+#define LANG_HOOKS_OMP_PREDETERMINED_MAPPING c_omp_predetermined_mapping
+
 #undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR
 #define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR c_omp_clause_copy_ctor
 
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index d6723e44ec4..7fc70ada8b4 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -2267,7 +2267,8 @@ cxx_omp_const_qual_no_mutable (tree decl)
   return false;
 }
 
-/* True if OpenMP sharing attribute of DECL is predetermined.  */
+/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
+   of DECL is predetermined.  */
 
 enum omp_clause_default_kind
 cxx_omp_predetermined_sharing_1 (tree decl)
@@ -2321,6 +2322,22 @@ cxx_omp_predetermined_sharing (tree decl)
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+enum omp_clause_defaultmap_kind
+cxx_omp_predetermined_mapping (tree decl)
+{
+  /* Predetermine artificial variables holding integral values, those
+     are usually result of gimplify_one_sizepos or SAVE_EXPR
+     gimplification.  */
+  if (VAR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && INTEGRAL_TYPE_P (TREE_TYPE (decl))
+      && !(DECL_LANG_SPECIFIC (decl)
+	   && DECL_OMP_PRIVATIZED_MEMBER (decl)))
+    return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
+
+  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
+}
+
 /* Finalize an implicitly determined clause.  */
 
 void
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index ff802dc3b41..de8d606fe2c 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -162,6 +162,8 @@ extern tree cxx_simulate_enum_decl (location_t, const char *,
 
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
+#undef LANG_HOOKS_OMP_PREDETERMINED_MAPPING
+#define LANG_HOOKS_OMP_PREDETERMINED_MAPPING cxx_omp_predetermined_mapping
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
 #define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR cxx_omp_clause_default_ctor
 #undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index db125a3a1db..1775b0a4327 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7781,6 +7781,7 @@ extern void cp_genericize			(tree);
 extern bool cxx_omp_const_qual_no_mutable	(tree);
 extern enum omp_clause_default_kind cxx_omp_predetermined_sharing_1 (tree);
 extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree);
+extern enum omp_clause_defaultmap_kind cxx_omp_predetermined_mapping (tree);
 extern tree cxx_omp_clause_default_ctor		(tree, tree, tree);
 extern tree cxx_omp_clause_copy_ctor		(tree, tree, tree);
 extern tree cxx_omp_clause_assign_op		(tree, tree, tree);
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 44ebe3e294d..da8c35f47b0 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -118,6 +118,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #undef LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT
 #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
+#undef LANG_HOOKS_OMP_PREDETERMINED_MAPPING
 #undef LANG_HOOKS_OMP_REPORT_DECL
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
 #undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR
@@ -153,6 +154,7 @@ static const struct attribute_spec gfc_attribute_table[] =
 #define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT	gfc_omp_check_optional_argument
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE	gfc_omp_privatize_by_reference
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING	gfc_omp_predetermined_sharing
+#define LANG_HOOKS_OMP_PREDETERMINED_MAPPING	gfc_omp_predetermined_mapping
 #define LANG_HOOKS_OMP_REPORT_DECL		gfc_omp_report_decl
 #define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR	gfc_omp_clause_default_ctor
 #define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR		gfc_omp_clause_copy_ctor
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index e27ce41b7ce..7e2f6256c43 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -207,7 +207,8 @@ gfc_omp_privatize_by_reference (const_tree decl)
   return false;
 }
 
-/* True if OpenMP sharing attribute of DECL is predetermined.  */
+/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
+   of DECL is predetermined.  */
 
 enum omp_clause_default_kind
 gfc_omp_predetermined_sharing (tree decl)
@@ -278,6 +279,28 @@ gfc_omp_predetermined_sharing (tree decl)
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+
+/* OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED unless OpenMP mapping attribute
+   of DECL is predetermined.  */
+
+enum omp_clause_defaultmap_kind
+gfc_omp_predetermined_mapping (tree decl)
+{
+  if (DECL_ARTIFICIAL (decl)
+      && ! GFC_DECL_RESULT (decl)
+      && ! (DECL_LANG_SPECIFIC (decl)
+	    && GFC_DECL_SAVED_DESCRIPTOR (decl)))
+    return OMP_CLAUSE_DEFAULTMAP_TO;
+
+  /* These are either array or derived parameters, or vtables.  */
+  if (VAR_P (decl) && TREE_READONLY (decl)
+      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+    return OMP_CLAUSE_DEFAULTMAP_TO;
+
+  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
+}
+
+
 /* Return decl that should be used when reporting DEFAULT(NONE)
    diagnostics.  */
 
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index bd96cdf86fc..e126fe92782 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -803,6 +803,7 @@ tree gfc_omp_check_optional_argument (tree, bool);
 tree gfc_omp_array_data (tree, bool);
 bool gfc_omp_privatize_by_reference (const_tree);
 enum omp_clause_default_kind gfc_omp_predetermined_sharing (tree);
+enum omp_clause_defaultmap_kind gfc_omp_predetermined_mapping (tree);
 tree gfc_omp_report_decl (tree);
 tree gfc_omp_clause_default_ctor (tree, tree, tree);
 tree gfc_omp_clause_copy_ctor (tree, tree, tree);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 7f00d97baa1..cb08b26dc65 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7432,6 +7432,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 	      if (!is_declare_target)
 		{
 		  int gdmk;
+		  enum omp_clause_defaultmap_kind kind;
 		  if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
 		      || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
 			  && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
@@ -7441,7 +7442,17 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 		    gdmk = GDMK_SCALAR;
 		  else
 		    gdmk = GDMK_AGGREGATE;
-		  if (ctx->defaultmap[gdmk] == 0)
+		  kind = lang_hooks.decls.omp_predetermined_mapping (decl);
+		  if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
+		    {
+		      if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
+			nflags |= GOVD_FIRSTPRIVATE;
+		      else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
+			nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
+		      else
+			gcc_unreachable ();
+		    }
+		  else if (ctx->defaultmap[gdmk] == 0)
 		    {
 		      tree d = lang_hooks.decls.omp_report_decl (decl);
 		      error ("%qE not specified in enclosing %<target%>",
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 82aeb653085..6e4e2cc9367 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -79,6 +79,7 @@ extern bool lhd_handle_option (size_t, const char *, HOST_WIDE_INT, int,
 /* Declarations for tree gimplification hooks.  */
 extern int lhd_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
 extern enum omp_clause_default_kind lhd_omp_predetermined_sharing (tree);
+extern enum omp_clause_defaultmap_kind lhd_omp_predetermined_mapping (tree);
 extern tree lhd_omp_assignment (tree, tree, tree);
 extern void lhd_omp_finish_clause (tree, gimple_seq *);
 struct gimplify_omp_ctx;
@@ -246,6 +247,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
 #define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT hook_tree_tree_bool_null
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_const_tree_false
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
+#define LANG_HOOKS_OMP_PREDETERMINED_MAPPING lhd_omp_predetermined_mapping
 #define LANG_HOOKS_OMP_REPORT_DECL lhd_pass_through_t
 #define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR hook_bool_tree_bool_false
 #define LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE hook_bool_tree_bool_false
@@ -274,6 +276,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
   LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT, \
   LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
   LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
+  LANG_HOOKS_OMP_PREDETERMINED_MAPPING, \
   LANG_HOOKS_OMP_REPORT_DECL, \
   LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR, \
   LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 5e3216da631..1cb7cda5b79 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -579,13 +579,24 @@ lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSE
    predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */
 
 enum omp_clause_default_kind
-lhd_omp_predetermined_sharing (tree decl ATTRIBUTE_UNUSED)
+lhd_omp_predetermined_sharing (tree decl)
 {
   if (DECL_ARTIFICIAL (decl))
     return OMP_CLAUSE_DEFAULT_SHARED;
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+/* Return sharing kind if OpenMP mapping attribute of DECL is
+   predetermined, OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED otherwise.  */
+
+enum omp_clause_defaultmap_kind
+lhd_omp_predetermined_mapping (tree decl)
+{
+  if (DECL_ARTIFICIAL (decl))
+    return OMP_CLAUSE_DEFAULTMAP_TO;
+  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
+}
+
 /* Generate code to copy SRC to DST.  */
 
 tree
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 83069a9cf7f..2bd5a67cd37 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -252,6 +252,10 @@ struct lang_hooks_for_decls
      predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */
   enum omp_clause_default_kind (*omp_predetermined_sharing) (tree);
 
+  /* Return mapping kind if OpenMP mapping attribute of DECL is
+     predetermined, OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED otherwise.  */
+  enum omp_clause_defaultmap_kind (*omp_predetermined_mapping) (tree);
+
   /* Return decl that should be reported for DEFAULT(NONE) failure
      diagnostics.  Usually the DECL passed in.  */
   tree (*omp_report_decl) (tree);
diff --git a/gcc/testsuite/c-c++-common/gomp/pr94874.c b/gcc/testsuite/c-c++-common/gomp/pr94874.c
new file mode 100644
index 00000000000..9c67f83a5da
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr94874.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+#include <stddef.h>
+
+size_t
+vla (int array_li)
+{
+  float array[array_li];
+  size_t size1, size2;
+
+#pragma omp parallel default(none) shared(size1, array)
+  size1 = sizeof array;
+
+#pragma omp target defaultmap(none) map(from:size2) map(alloc:array)
+  size2 = sizeof array;
+
+  return size1 + size2;
+}
+
+/* { dg-final { scan-tree-dump "omp parallel .*shared\\(array_li\.\[0-9\]\\)" "gimple" } } */
+/* C */
+/* { dg-final { scan-tree-dump "omp target .*private\\(array_li\.\[0-9\]\\)" "gimple" { target { ! c++ } } } } */
+/* C++ */
+/* { dg-final { scan-tree-dump "omp target .*firstprivate\\(array_li\.\[0-9\]\\)" "gimple" { target { c++ } } } } */

Reply via email to