From 93535a2b40367e6f68433295b37dc52c0e9c2c55 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Wed, 3 Jun 2020 12:28:25 +0200 Subject: [PATCH] [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 Tobias Burnus 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 | 22 +++++++++++++++++++- 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, 134 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/gomp/pr94874.c 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..6c29be9d836 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,25 @@ 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; + + if (c_omp_predefined_variable (decl)) + return OMP_CLAUSE_DEFAULTMAP_TO; + + 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 %", 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 + +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++ } } } } */ -- 2.30.2