From 94e7f906ca5c73fb79d21ec54733e9e75a96c2b4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 10 Oct 2019 09:07:30 +0200 Subject: c-common.h (c_omp_check_context_selector, [...]): Declare. c-family/ * c-common.h (c_omp_check_context_selector, c_omp_get_context_selector): Declare. * c-omp.c (c_omp_declare_simd_clauses_to_numbers): Fix spelling in diagnostic message. (c_omp_check_context_selector, c_omp_get_context_selector): New functions. * c-attribs.c (c_common_attribute_table): Add "omp declare variant" attribute. (handle_omp_declare_variant_attribute): New function. c/ * c-parser.c (c_parser_omp_all_clauses): Add NESTED_P argument, if true, terminate processing on closing paren and don't skip to end of pragma line. (c_parser_omp_declare_simd): Handle also declare variant. (omp_construct_selectors, omp_device_selectors, omp_implementation_selectors, omp_user_selectors): New variables. (c_parser_omp_context_selector, c_parser_omp_context_selector_specification, c_finish_omp_declare_variant): New functions. (c_finish_omp_declare_simd): Handle both declare simd and declare variant. (c_parser_omp_declare): Handle declare variant. cp/ * parser.h (struct cp_omp_declare_simd_data): Add variant_p member. * parser.c (cp_ensure_no_omp_declare_simd): Handle both declare simd and declare variant. (cp_parser_oacc_all_clauses): Formatting fix. (cp_parser_omp_all_clauses): Add NESTED_P argument, if true, terminate processing on closing paren and don't skip to end of pragma line. (cp_parser_omp_declare_simd): Add VARIANT_P argument. Handle also declare variant. (omp_construct_selectors, omp_device_selectors, omp_implementation_selectors, omp_user_selectors): New variables. (cp_parser_omp_context_selector, cp_parser_omp_context_selector_specification, cp_finish_omp_declare_variant): New functions. (cp_parser_late_parsing_omp_declare_simd): Handle also declare variant. (cp_parser_omp_declare): Handle declare variant. testsuite/ * c-c++-common/gomp/declare-variant-1.c: New test. * c-c++-common/gomp/declare-variant-2.c: New test. * c-c++-common/gomp/declare-variant-3.c: New test. * g++.dg/gomp/this-1.C: Adjust for diagnostic message spelling fix. * gcc.dg/gomp/declare-variant-1.c: New test. * gcc.dg/gomp/declare-variant-2.c: New test. From-SVN: r276789 --- gcc/c-family/ChangeLog | 12 +++++ gcc/c-family/c-attribs.c | 13 +++++ gcc/c-family/c-common.h | 2 + gcc/c-family/c-omp.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 159 insertions(+), 2 deletions(-) (limited to 'gcc/c-family') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 398ba6d..598fea4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,15 @@ +2019-10-10 Jakub Jelinek + + * c-common.h (c_omp_check_context_selector, + c_omp_get_context_selector): Declare. + * c-omp.c (c_omp_declare_simd_clauses_to_numbers): Fix spelling + in diagnostic message. + (c_omp_check_context_selector, c_omp_get_context_selector): New + functions. + * c-attribs.c (c_common_attribute_table): Add "omp declare variant" + attribute. + (handle_omp_declare_variant_attribute): New function. + 2019-10-09 Martin Sebor PR tree-optimization/90879 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 6500b99..917d483 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -140,6 +140,8 @@ static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *); static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *); static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *); +static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int, + bool *); static tree handle_simd_attribute (tree *, tree, tree, int, bool *); static tree handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *); @@ -442,6 +444,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_returns_nonnull_attribute, NULL }, { "omp declare simd", 0, -1, true, false, false, false, handle_omp_declare_simd_attribute, NULL }, + { "omp declare variant", 0, -1, true, false, false, false, + handle_omp_declare_variant_attribute, NULL }, { "simd", 0, 1, true, false, false, false, handle_simd_attribute, NULL }, { "omp declare target", 0, -1, true, false, false, false, @@ -3064,6 +3068,15 @@ handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *) return NULL_TREE; } +/* Handle an "omp declare variant" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_omp_declare_variant_attribute (tree *, tree, tree, int, bool *) +{ + return NULL_TREE; +} + /* Handle a "simd" attribute. */ static tree diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 1e13aaa..eabe689 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1189,6 +1189,8 @@ 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 tree c_omp_check_context_selector (location_t, tree); +extern tree c_omp_get_context_selector (tree, const char *, const char *); /* Return next tree in the chain for chain_next walking of tree nodes. */ static inline tree diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index 0048289..5426256 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -2011,7 +2011,7 @@ c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses) if (arg == NULL_TREE) { error_at (OMP_CLAUSE_LOCATION (c), - "%qD is not an function argument", decl); + "%qD is not a function argument", decl); continue; } OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx); @@ -2026,7 +2026,7 @@ c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses) if (arg == NULL_TREE) { error_at (OMP_CLAUSE_LOCATION (c), - "%qD is not an function argument", decl); + "%qD is not a function argument", decl); continue; } OMP_CLAUSE_LINEAR_STEP (c) @@ -2120,3 +2120,133 @@ c_omp_predetermined_sharing (tree decl) return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } + +/* Diagnose errors in an OpenMP context selector, return CTX if + it is correct or error_mark_node otherwise. */ + +tree +c_omp_check_context_selector (location_t loc, tree ctx) +{ + /* Each trait-set-selector-name can only be specified once. + There are just 4 set names. */ + for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) + for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + error_at (loc, "selector set %qs specified more than once", + IDENTIFIER_POINTER (TREE_PURPOSE (t1))); + return error_mark_node; + } + for (tree t = ctx; t; t = TREE_CHAIN (t)) + { + /* Each trait-selector-name can only be specified once. */ + if (list_length (TREE_VALUE (t)) < 5) + { + for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) + for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + error_at (loc, + "selector %qs specified more than once in set %qs", + IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + IDENTIFIER_POINTER (TREE_PURPOSE (t))); + return error_mark_node; + } + } + else + { + hash_set pset; + for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) + if (pset.add (TREE_PURPOSE (t1))) + { + error_at (loc, + "selector %qs specified more than once in set %qs", + IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + IDENTIFIER_POINTER (TREE_PURPOSE (t))); + return error_mark_node; + } + } + + static const char *const kind[] = { + "host", "nohost", "cpu", "gpu", "fpga", "any", NULL }; + static const char *const vendor[] = { + "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel", + "llvm", "pgi", "ti", "unknown", NULL }; + static const char *const extension[] = { NULL }; + static const char *const atomic_default_mem_order[] = { + "seq_cst", "relaxed", "acq_rel", NULL }; + struct known_properties { const char *set; const char *selector; + const char *const *props; }; + known_properties props[] = { + { "device", "kind", kind }, + { "implementation", "vendor", vendor }, + { "implementation", "extension", extension }, + { "implementation", "atomic_default_mem_order", + atomic_default_mem_order } }; + for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) + for (unsigned i = 0; i < ARRAY_SIZE (props); i++) + if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + props[i].selector) + && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), + props[i].set)) + for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + for (unsigned j = 0; ; j++) + { + if (props[i].props[j] == NULL) + { + if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + " score")) + break; + if (props[i].props == atomic_default_mem_order) + { + error_at (loc, + "incorrect property %qs of %qs selector", + IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + "atomic_default_mem_order"); + return error_mark_node; + } + else + warning_at (loc, 0, + "unknown property %qs of %qs selector", + IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + props[i].selector); + break; + } + else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + props[i].props[j])) + { + if (props[i].props == atomic_default_mem_order + && t2 != TREE_VALUE (t1)) + { + tree t3 = TREE_VALUE (t1); + if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), + " score") + && t2 == TREE_CHAIN (TREE_VALUE (t1))) + break; + error_at (loc, + "%qs selector must have a single property", + "atomic_default_mem_order"); + return error_mark_node; + } + break; + } + } + } + return ctx; +} + +/* From context selector CTX, return trait-selector with name SEL in + trait-selector-set with name SET if any, or NULL_TREE if not found. */ + +tree +c_omp_get_context_selector (tree ctx, const char *set, const char *sel) +{ + tree setid = get_identifier (set); + tree selid = get_identifier (sel); + for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) + if (TREE_PURPOSE (t1) == setid) + for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t2) == selid) + return t2; + return NULL_TREE; +} -- cgit v1.1