summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-08-10 12:18:25 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-08-10 12:18:25 +0200
commit77eb117f588686e6fb018d103fc3d1899be9b008 (patch)
tree9a022bfea1239471ef385682ffd6de3991c16408
parent5b7ed762347ea9e82a3982b57975747de0943eb4 (diff)
tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_TYPE.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_TYPE. (enum omp_clause_device_type_kind): New enum. (struct tree_omp_clause): Add subcode.device_type_kind. * tree.h (OMP_CLAUSE_DEVICE_TYPE_KIND): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries for device_type clause. (walk_tree_1): Handle OMP_CLAUSE_DEVICE_TYPE. * tree-pretty-print.c (dump_omp_clause): Likewise. c-family/ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE. c/ * c-parser.c (c_parser_omp_clause_name): Parse device_type. (c_parser_omp_clause_device_type): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE. (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE. (c_parser_omp_declare_target): Handle device_type clauses. Remove diagnostics for declare target with clauses nested in clause-less declare target declaration-definition-seq. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE. cp/ * parser.c (cp_parser_omp_clause_name): Parse device_type. (cp_parser_omp_clause_device_type): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE. (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE. (cp_parser_omp_declare_target): Handle device_type clauses. Remove diagnostics for declare target with clauses nested in clause-less declare target declaration-definition-seq. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE. testsuite/ * c-c++-common/gomp/declare-target-2.c: Don't expect error for declare target with clauses in between declare target without clauses and end declare target. * c-c++-common/gomp/declare-target-4.c: New test. From-SVN: r274252
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-pragma.h1
-rw-r--r--gcc/c/ChangeLog11
-rw-r--r--gcc/c/c-parser.c93
-rw-r--r--gcc/c/c-typeck.c1
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/parser.c100
-rw-r--r--gcc/cp/semantics.c1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-target-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-target-4.c44
-rw-r--r--gcc/tree-core.h11
-rw-r--r--gcc/tree-pretty-print.c19
-rw-r--r--gcc/tree.c3
-rw-r--r--gcc/tree.h3
16 files changed, 306 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 56913a0377d..4ce2f4ef4e2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2019-08-10 Jakub Jelinek <jakub@redhat.com>
+ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_TYPE.
+ (enum omp_clause_device_type_kind): New enum.
+ (struct tree_omp_clause): Add subcode.device_type_kind.
+ * tree.h (OMP_CLAUSE_DEVICE_TYPE_KIND): Define.
+ * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries
+ for device_type clause.
+ (walk_tree_1): Handle OMP_CLAUSE_DEVICE_TYPE.
+ * tree-pretty-print.c (dump_omp_clause): Likewise.
+
PR target/91408
* config/i386/mmx.md (usadv8qi): Use register_operand instead of
vector_operand.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 36beddcd7f2..507e536e3ca 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_omp_clause): Add
+ PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+
2019-08-07 Jakub Jelinek <jakub@redhat.com>
* c-pragma.h (enum pragma_omp_clause): Add
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 803dc1b2ac6..e0aa774555a 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -93,6 +93,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_DEFAULTMAP,
PRAGMA_OMP_CLAUSE_DEPEND,
PRAGMA_OMP_CLAUSE_DEVICE,
+ PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
PRAGMA_OMP_CLAUSE_FINAL,
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 55621d68e16..335801b3697 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,14 @@
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_clause_name): Parse device_type.
+ (c_parser_omp_clause_device_type): New function.
+ (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (c_parser_omp_declare_target): Handle device_type clauses. Remove
+ diagnostics for declare target with clauses nested in clause-less
+ declare target declaration-definition-seq.
+ * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
+
2019-08-09 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (check_no_duplicate_clause): Simplify using
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 055e6500333..81919a89cc6 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -11720,6 +11720,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
else if (!strcmp ("device_resident", p))
result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+ else if (!strcmp ("device_type", p))
+ result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
else if (!strcmp ("dist_schedule", p))
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
break;
@@ -14863,6 +14865,50 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
return list;
}
+/* OpenMP 5.0:
+ device_type ( host | nohost | any ) */
+
+static tree
+c_parser_omp_clause_device_type (c_parser *parser, tree list)
+{
+ location_t clause_loc = c_parser_peek_token (parser)->location;
+ enum omp_clause_device_type_kind kind;
+ tree c;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp ("host", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+ else if (strcmp ("nohost", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+ else if (strcmp ("any", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
+ "device_type"); */
+ c_parser_consume_token (parser);
+ parens.skip_until_found_close (parser);
+ c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
+ OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
+ parens.skip_until_found_close (parser);
+ return list;
+}
+
/* OpenMP 4.0:
to ( variable-list ) */
@@ -15350,6 +15396,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_omp_clause_proc_bind (parser, clauses);
c_name = "proc_bind";
break;
+ case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+ clauses = c_parser_omp_clause_device_type (parser, clauses);
+ c_name = "device_type";
+ break;
case PRAGMA_OMP_CLAUSE_SAFELEN:
clauses = c_parser_omp_clause_safelen (parser, clauses);
c_name = "safelen";
@@ -18997,13 +19047,15 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
#define OMP_DECLARE_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
static void
c_parser_omp_declare_target (c_parser *parser)
{
- location_t loc = c_parser_peek_token (parser)->location;
tree clauses = NULL_TREE;
+ int device_type = 0;
+ bool only_device_type = true;
if (c_parser_next_token_is (parser, CPP_NAME))
clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
"#pragma omp declare target");
@@ -19020,16 +19072,18 @@ c_parser_omp_declare_target (c_parser *parser)
current_omp_declare_target_attribute++;
return;
}
- if (current_omp_declare_target_attribute)
- error_at (loc, "%<#pragma omp declare target%> with clauses in between "
- "%<#pragma omp declare target%> without clauses and "
- "%<#pragma omp end declare target%>");
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ continue;
tree t = OMP_CLAUSE_DECL (c), id;
tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
tree at2 = lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (t));
+ only_device_type = false;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
{
id = get_identifier ("omp declare target link");
@@ -19062,7 +19116,34 @@ c_parser_omp_declare_target (c_parser *parser)
}
}
}
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ continue;
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target host",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target host");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target nohost",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target nohost");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
}
+ if (device_type && only_device_type)
+ warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+ "directive with only %<device_type%> clauses ignored");
}
static void
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 1d865aa7719..2bbf0e21fb9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14690,6 +14690,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_PRIORITY:
case OMP_CLAUSE_GRAINSIZE:
case OMP_CLAUSE_NUM_TASKS:
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8fab25e2ab..e32582514f7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_clause_name): Parse device_type.
+ (cp_parser_omp_clause_device_type): New function.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (cp_parser_omp_declare_target): Handle device_type clauses. Remove
+ diagnostics for declare target with clauses nested in clause-less
+ declare target declaration-definition-seq.
+ * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
+
2019-08-09 Jakub Jelinek <jakub@redhat.com>
* parser.c (check_no_duplicate_clause): Simplify using
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b5196f6184b..b56cc6924f4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -32510,6 +32510,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
else if (!strcmp ("device_resident", p))
result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+ else if (!strcmp ("device_type", p))
+ result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
else if (!strcmp ("dist_schedule", p))
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
break;
@@ -35321,6 +35323,56 @@ cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
return list;
}
+/* OpenMP 5.0:
+ device_type ( host | nohost | any ) */
+
+static tree
+cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c;
+ enum omp_clause_device_type_kind kind;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("host", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+ else if (strcmp ("nohost", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+ else if (strcmp ("any", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+ goto resync_fail;
+
+ c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
+ location); */
+ OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
/* OpenACC:
async [( int-expr )] */
@@ -35849,6 +35901,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
token->location);
c_name = "proc_bind";
break;
+ case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+ clauses = cp_parser_omp_clause_device_type (parser, clauses,
+ token->location);
+ c_name = "device_type";
+ break;
case PRAGMA_OMP_CLAUSE_SAFELEN:
clauses = cp_parser_omp_clause_safelen (parser, clauses,
token->location);
@@ -39831,12 +39888,15 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
#define OMP_DECLARE_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
static void
cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
tree clauses = NULL_TREE;
+ int device_type = 0;
+ bool only_device_type = true;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
clauses
= cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
@@ -39854,17 +39914,18 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
scope_chain->omp_declare_target_attribute++;
return;
}
- if (scope_chain->omp_declare_target_attribute)
- error_at (pragma_tok->location,
- "%<#pragma omp declare target%> with clauses in between "
- "%<#pragma omp declare target%> without clauses and "
- "%<#pragma omp end declare target%>");
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ continue;
tree t = OMP_CLAUSE_DECL (c), id;
tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
tree at2 = lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (t));
+ only_device_type = false;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
{
id = get_identifier ("omp declare target link");
@@ -39897,7 +39958,34 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
}
}
}
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ continue;
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target host",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target host");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target nohost",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target nohost");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
}
+ if (device_type && only_device_type)
+ warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+ "directive with only %<device_type%> clauses ignored");
}
static void
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9fd759c22c9..7ac1ba058e5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7578,6 +7578,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_NOGROUP:
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3fec121d6c7..17387f6a7bc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2019-08-10 Jakub Jelinek <jakub@redhat.com>
+ * c-c++-common/gomp/declare-target-2.c: Don't expect error for
+ declare target with clauses in between declare target without clauses
+ and end declare target.
+ * c-c++-common/gomp/declare-target-4.c: New test.
+
PR target/91408
* gcc.target/i386/pr91408.c: New test.
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-2.c b/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
index 1135a1d00b4..c7a325c6155 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
@@ -3,7 +3,7 @@
extern int a;
#pragma omp declare target
-#pragma omp declare target to (a) /* { dg-error "with clauses in between" } */
+#pragma omp declare target to (a)
#pragma omp end declare target
int b;
#pragma omp declare target to (b) link (b) /* { dg-error "appears more than once on the same .declare target. directive" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-4.c b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c
new file mode 100644
index 00000000000..887a815e84a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare target device_type (any) /* { dg-warning "directive with only 'device_type' clauses ignored" } */
+
+void f1 (void) {}
+void f2 (void);
+#pragma omp declare target to (f1) device_type (any) to (f2)
+
+void f3 (void) {}
+void f4 (void) {}
+#pragma omp declare target device_type (host) to (f3)
+#pragma omp declare target to (f4) device_type (nohost)
+
+#pragma omp declare target
+void f5 (void);
+void f6 (void) {}
+void f7 (void) {}
+#pragma omp declare target to (f7)
+void f8 (void) {}
+#pragma omp declare target to (f8, f5)
+#pragma omp declare target to (f5) to(f8)
+#pragma omp declare target to (f8) device_type (host)
+void f9 (void) {}
+#pragma omp declare target to (f9) device_type (nohost)
+#pragma omp declare target to (f9)
+void f10 (void) {}
+#pragma omp declare target device_type (any) to (f10)
+void f11 (void) {}
+#pragma omp end declare target
+
+void f12 (void) {}
+#pragma omp declare target device_type (any) to (f12)
+#pragma omp declare target to (f12) device_type (host)
+void f13 (void) {}
+#pragma omp declare target device_type (host) to (f13)
+#pragma omp declare target to (f13) device_type (nohost)
+void f14 (void) {}
+#pragma omp declare target device_type (nohost) to (f14)
+#pragma omp declare target device_type (any) to (f14)
+void f15 (void) {}
+#pragma omp declare target device_type (host) to (f15) device_type (nohost)
+void f16 (void) {}
+#pragma omp declare target device_type (any) to (f15) device_type (any)
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 8216a606718..0979180dd0b 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -415,6 +415,9 @@ enum omp_clause_code {
/* OpenMP clause: simdlen (constant-integer-expression). */
OMP_CLAUSE_SIMDLEN,
+ /* OpenMP clause: device_type ({host,nohost,any}). */
+ OMP_CLAUSE_DEVICE_TYPE,
+
/* OpenMP clause: for. */
OMP_CLAUSE_FOR,
@@ -1468,6 +1471,13 @@ enum omp_clause_proc_bind_kind
OMP_CLAUSE_PROC_BIND_LAST
};
+enum omp_clause_device_type_kind
+{
+ OMP_CLAUSE_DEVICE_TYPE_HOST = 1,
+ OMP_CLAUSE_DEVICE_TYPE_NOHOST = 2,
+ OMP_CLAUSE_DEVICE_TYPE_ANY = 3
+};
+
enum omp_clause_linear_kind
{
OMP_CLAUSE_LINEAR_DEFAULT,
@@ -1544,6 +1554,7 @@ struct GTY(()) tree_omp_clause {
enum tree_code if_modifier;
enum omp_clause_defaultmap_kind defaultmap_kind;
enum omp_clause_bind_kind bind_kind;
+ enum omp_clause_device_type_kind device_type_kind;
/* The dimension a OMP_CLAUSE__GRIDDIM_ clause of a gridified target
construct describes. */
unsigned int dimension;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 8091a0af7f3..53b3f55a3e6 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -951,6 +951,25 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_right_paren (pp);
break;
+ case OMP_CLAUSE_DEVICE_TYPE:
+ pp_string (pp, "device_type(");
+ switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause))
+ {
+ case OMP_CLAUSE_DEVICE_TYPE_HOST:
+ pp_string (pp, "host");
+ break;
+ case OMP_CLAUSE_DEVICE_TYPE_NOHOST:
+ pp_string (pp, "nohost");
+ break;
+ case OMP_CLAUSE_DEVICE_TYPE_ANY:
+ pp_string (pp, "any");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ pp_right_paren (pp);
+ break;
+
case OMP_CLAUSE_SAFELEN:
pp_string (pp, "safelen(");
dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
diff --git a/gcc/tree.c b/gcc/tree.c
index 1f2aac4ffa5..154ef3ac38f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -332,6 +332,7 @@ unsigned const char omp_clause_num_ops[] =
0, /* OMP_CLAUSE_PROC_BIND */
1, /* OMP_CLAUSE_SAFELEN */
1, /* OMP_CLAUSE_SIMDLEN */
+ 0, /* OMP_CLAUSE_DEVICE_TYPE */
0, /* OMP_CLAUSE_FOR */
0, /* OMP_CLAUSE_PARALLEL */
0, /* OMP_CLAUSE_SECTIONS */
@@ -416,6 +417,7 @@ const char * const omp_clause_code_name[] =
"proc_bind",
"safelen",
"simdlen",
+ "device_type",
"for",
"parallel",
"sections",
@@ -12404,6 +12406,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_INBRANCH:
case OMP_CLAUSE_NOTINBRANCH:
case OMP_CLAUSE_FOR:
diff --git a/gcc/tree.h b/gcc/tree.h
index ce75b0cdc25..94dbb95a78a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1620,6 +1620,9 @@ class auto_suppress_location_wrappers
#define OMP_CLAUSE_PROC_BIND_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind)
+#define OMP_CLAUSE_DEVICE_TYPE_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind)
+
#define OMP_CLAUSE_COLLAPSE_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 0)
#define OMP_CLAUSE_COLLAPSE_ITERVAR(NODE) \