aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-pragma.h1
-rw-r--r--gcc/c/c-parser.cc17
-rw-r--r--gcc/c/c-typeck.cc23
-rw-r--r--gcc/cp/parser.cc10
-rw-r--r--gcc/cp/pt.cc1
-rw-r--r--gcc/cp/semantics.cc29
-rw-r--r--gcc/gimplify.cc15
-rw-r--r--gcc/testsuite/c-c++-common/gomp/dispatch-11.c84
-rw-r--r--gcc/testsuite/c-c++-common/gomp/dispatch-12.c53
-rw-r--r--gcc/tree-core.h3
-rw-r--r--gcc/tree-pretty-print.cc6
-rw-r--r--gcc/tree.cc2
12 files changed, 228 insertions, 16 deletions
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index c95a602..df5625d 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -134,6 +134,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_INDIRECT,
PRAGMA_OMP_CLAUSE_INIT,
PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR,
+ PRAGMA_OMP_CLAUSE_INTEROP,
PRAGMA_OMP_CLAUSE_LASTPRIVATE,
PRAGMA_OMP_CLAUSE_LINEAR,
PRAGMA_OMP_CLAUSE_LINK,
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index ca4a6b3..f3ed610 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -15786,6 +15786,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OMP_CLAUSE_INIT;
else if (!strcmp ("is_device_ptr", p))
result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
+ else if (!strcmp ("interop", p))
+ result = PRAGMA_OMP_CLAUSE_INTEROP;
break;
case 'l':
if (!strcmp ("lastprivate", p))
@@ -20569,6 +20571,16 @@ c_parser_omp_clause_use (c_parser *parser, tree list)
return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE, list);
}
+/* OpenMP 6.0:
+ interop ( variable-list ) */
+
+static tree
+c_parser_omp_clause_interop (c_parser *parser, tree list)
+{
+ check_no_duplicate_clause (list, OMP_CLAUSE_INTEROP, "interop");
+ return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_INTEROP, list);
+}
+
/* Parse all OpenACC clauses. The set clauses allowed by the directive
is a bitmask in MASK. Return the list of clauses found. */
@@ -21076,6 +21088,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_omp_clause_use (parser, clauses);
c_name = "use";
break;
+ case PRAGMA_OMP_CLAUSE_INTEROP:
+ clauses = c_parser_omp_clause_interop (parser, clauses);
+ c_name = "interop";
+ break;
case PRAGMA_OMP_CLAUSE_MAP:
clauses = c_parser_omp_clause_map (parser, clauses);
c_name = "map";
@@ -25078,6 +25094,7 @@ c_parser_omp_dispatch_body (c_parser *parser)
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index f6f63ca..970fe68 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -17091,16 +17091,27 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
error_at (OMP_CLAUSE_LOCATION (c),
"%qD appears more than once in action clauses", t);
remove = true;
+ break;
}
- else if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init] */
+ bitmap_set_bit (&generic_head, DECL_UID (t));
+ /* FALLTHRU */
+ case OMP_CLAUSE_INTEROP:
+ if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init] */
!c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qD must be of %<omp_interop_t%>", OMP_CLAUSE_DECL (c));
- else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD must be of %<omp_interop_t%>",
+ OMP_CLAUSE_DECL (c));
+ remove = true;
+ }
+ else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
&& TREE_READONLY (OMP_CLAUSE_DECL (c)))
- error_at (OMP_CLAUSE_LOCATION (c),
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
"%qD shall not be const", OMP_CLAUSE_DECL (c));
- bitmap_set_bit (&generic_head, DECL_UID (t));
+ remove = true;
+ }
pc = &OMP_CLAUSE_CHAIN (c);
break;
default:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index fa9945b..f449ebd 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -38335,6 +38335,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_INDIRECT;
else if (!strcmp ("init", p))
result = PRAGMA_OMP_CLAUSE_INIT;
+ else if (!strcmp ("interop", p))
+ result = PRAGMA_OMP_CLAUSE_INTEROP;
else if (!strcmp ("is_device_ptr", p))
result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
break;
@@ -43336,6 +43338,13 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE, clauses);
c_name = "use";
break;
+ case PRAGMA_OMP_CLAUSE_INTEROP:
+ check_no_duplicate_clause (clauses, OMP_CLAUSE_INTEROP, "interop",
+ token->location);
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_INTEROP,
+ clauses);
+ c_name = "interop";
+ break;
case PRAGMA_OMP_CLAUSE_DETACH:
clauses = cp_parser_omp_clause_detach (parser, clauses);
c_name = "detach";
@@ -49728,6 +49737,7 @@ cp_parser_omp_dispatch_body (cp_parser *parser)
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 74d0d86..5b79188 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -17893,6 +17893,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
/* FALLTHRU */
case OMP_CLAUSE_DESTROY:
case OMP_CLAUSE_USE:
+ case OMP_CLAUSE_INTEROP:
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_stmt (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
break;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 328de39..d58dd02 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -9448,20 +9448,31 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
error_at (OMP_CLAUSE_LOCATION (c),
"%qD appears more than once in action clauses", t);
remove = true;
+ break;
}
+ bitmap_set_bit (&generic_head, DECL_UID (t));
+ /* FALLTHRU */
+ case OMP_CLAUSE_INTEROP:
if (!processing_template_decl)
{
- if (/* ort == C_ORT_OMP_INTEROP [uncomment for depobj init] */
- !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qD must be of %<omp_interop_t%>",
- OMP_CLAUSE_DECL (c));
- else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE
+ if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) && */
+ !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD must be of %<omp_interop_t%>",
+ OMP_CLAUSE_DECL (c));
+ remove = true;
+ }
+ else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
&& TREE_READONLY (OMP_CLAUSE_DECL (c)))
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qD shall not be const", OMP_CLAUSE_DECL (c));
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD shall not be const", OMP_CLAUSE_DECL (c));
+ remove = true;
+ }
}
- bitmap_set_bit (&generic_head, DECL_UID (t));
pc = &OMP_CLAUSE_CHAIN (c);
break;
default:
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index d6612a8..7b2466a 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4071,6 +4071,20 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
vars there. */
bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
+ tree dispatch_interop = NULL_TREE;
+ if (flag_openmp
+ && gimplify_omp_ctxp != NULL
+ && gimplify_omp_ctxp->code == OMP_DISPATCH
+ && gimplify_omp_ctxp->clauses
+ && (dispatch_interop = omp_find_clause (gimplify_omp_ctxp->clauses,
+ OMP_CLAUSE_INTEROP)) != NULL_TREE)
+ /* FIXME: When implementing 'append_args, use the 'device_num' of
+ the argument. */
+ error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
+ "number of list items in %<interop%> clause exceeds number of "
+ "%<append_args%> items for %<declare variant%> candidate %qD",
+ fndecl);
+
/* Gimplify the function arguments. */
if (nargs > 0)
{
@@ -13400,6 +13414,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_BIND:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE_INTEROP:
break;
case OMP_CLAUSE_ORDER:
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-11.c b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c
new file mode 100644
index 0000000..7f1d806
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c
@@ -0,0 +1,84 @@
+/* { dg-additional-options "-fdump-tree-original" } */
+
+/* The following definitions are in omp_lib, which cannot be included
+ in gcc/testsuite/ */
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_interop_none = 0,
+ __omp_interop_t_max__ = __UINTPTR_MAX__
+} omp_interop_t;
+
+
+float repl1();
+#pragma omp declare variant(repl1) match(construct={dispatch})
+float base1();
+
+void repl2(int *, int *);
+#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y)
+void base2(int *x, int *y);
+
+
+float
+dupl (int *a, int *b)
+{
+ omp_interop_t obj1, obj2;
+ float x;
+
+ #pragma omp dispatch interop ( obj1 ) interop(obj2) /* { dg-error "too many 'interop' clauses" } */
+ x = base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( obj1) nocontext(1) interop (obj2 ) /* { dg-error "too many 'interop' clauses" } */
+ base2 (a, b);
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
+ return x;
+}
+
+
+float
+test (int *a, int *b)
+{
+ omp_interop_t obj1, obj2;
+ float x, y;
+
+ #pragma omp dispatch interop ( obj1 )
+ x = base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( obj1, obj1 ) /* Twice the same - should be fine. */
+ x = base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch novariants(1) interop(obj2, obj1)
+ y = base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float base1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop(obj2, obj1)
+ base2 (a, b);
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl2'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop(obj2) nocontext(1)
+ base2 (a, b);
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
+ return x + y;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\) novariants\\(1\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp dispatch nocontext\\(1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-12.c b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c
new file mode 100644
index 0000000..ea190c7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c
@@ -0,0 +1,53 @@
+/* The following definitions are in omp_lib, which cannot be included
+ in gcc/testsuite/ */
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_interop_none = 0,
+ __omp_interop_t_max__ = __UINTPTR_MAX__
+} omp_interop_t;
+
+
+void repl1();
+#pragma omp declare variant(repl1) match(construct={dispatch})
+void base1();
+
+void
+test ()
+{
+ const omp_interop_t obj1 = omp_interop_none;
+ omp_interop_t obj2[2];
+ const omp_interop_t *obj3;
+ short x;
+
+ #pragma omp dispatch interop ( obj1, obj2, obj1 ) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */
+ base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( obj3 ) /* { dg-error "'obj3' must be of 'omp_interop_t'" } */
+ base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( obj1 )
+ base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( obj2 ) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */
+ base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
+
+ #pragma omp dispatch interop ( x ) /* { dg-error "'x' must be of 'omp_interop_t'" } */
+ base1 ();
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 620d0ad..1776c15 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -387,6 +387,9 @@ enum omp_clause_code {
/* OpenMP clause: use (variable-list ). */
OMP_CLAUSE_USE,
+ /* OpenMP clause: interop (variable-list). */
+ OMP_CLAUSE_INTEROP,
+
/* OpenACC clause: gang [(gang-argument-list)].
Where
gang-argument-list: [gang-argument-list, ] gang-argument
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index c50aa04..cacef94 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1578,7 +1578,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
spc, flags, false);
pp_right_paren (pp);
break;
-
+ case OMP_CLAUSE_INTEROP:
+ pp_string (pp, "interop(");
+ dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false);
+ pp_right_paren (pp);
+ break;
case OMP_CLAUSE_IF_PRESENT:
pp_string (pp, "if_present");
break;
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 40ebfa1..6350dd4 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -274,6 +274,7 @@ unsigned const char omp_clause_num_ops[] =
1, /* OMP_CLAUSE_DESTROY */
2, /* OMP_CLAUSE_INIT */
1, /* OMP_CLAUSE_USE */
+ 1, /* OMP_CLAUSE_INTEROP */
2, /* OMP_CLAUSE_GANG */
1, /* OMP_CLAUSE_ASYNC */
1, /* OMP_CLAUSE_WAIT */
@@ -375,6 +376,7 @@ const char * const omp_clause_code_name[] =
"destroy",
"init",
"use",
+ "interop",
"gang",
"async",
"wait",