aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-10-10 09:07:30 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-10-10 09:07:30 +0200
commit94e7f906ca5c73fb79d21ec54733e9e75a96c2b4 (patch)
tree5f686002d13f0905df1681a9408a9d96b23ee258 /gcc/c-family
parent6ea20bd0218fd6386cef3701befa653cee6f1101 (diff)
downloadgcc-94e7f906ca5c73fb79d21ec54733e9e75a96c2b4.zip
gcc-94e7f906ca5c73fb79d21ec54733e9e75a96c2b4.tar.gz
gcc-94e7f906ca5c73fb79d21ec54733e9e75a96c2b4.tar.bz2
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
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog12
-rw-r--r--gcc/c-family/c-attribs.c13
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-family/c-omp.c134
4 files changed, 159 insertions, 2 deletions
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 <jakub@redhat.com>
+
+ * 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 <msebor@redhat.com>
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<tree> 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;
+}